diff --git a/src/Mod/Import/Gui/AppImportGuiPy.cpp b/src/Mod/Import/Gui/AppImportGuiPy.cpp index c429e5f5c..5da7a7dfa 100644 --- a/src/Mod/Import/Gui/AppImportGuiPy.cpp +++ b/src/Mod/Import/Gui/AppImportGuiPy.cpp @@ -37,6 +37,7 @@ # include # include # include +# include # include # include # include @@ -71,6 +72,191 @@ #include #include + + +class ImportOCAF +{ +public: + ImportOCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name) + : pDoc(h), doc(d), default_name(name) + { + aShapeTool = XCAFDoc_DocumentTool::ShapeTool (pDoc->Main()); + aColorTool = XCAFDoc_DocumentTool::ColorTool(pDoc->Main()); + } + + void loadShapes(); + +private: + void loadShapes(const TDF_Label& label, const TopLoc_Location&, const std::string& partname, bool isRef); + void createShape(const TDF_Label& label, const TopLoc_Location&, const std::string&); + void createShape(const TopoDS_Shape& label, const TopLoc_Location&, const std::string&); + +private: + Handle_TDocStd_Document pDoc; + App::Document* doc; + Handle_XCAFDoc_ShapeTool aShapeTool; + Handle_XCAFDoc_ColorTool aColorTool; + std::string default_name; + std::set myRefShapes; + static const int HashUpper = INT_MAX; +}; + +void ImportOCAF::loadShapes() +{ + myRefShapes.clear(); + loadShapes(pDoc->Main(), TopLoc_Location(), default_name, false); +} + +void ImportOCAF::loadShapes(const TDF_Label& label, const TopLoc_Location& loc, const std::string& defaultname, bool isRef) +{ + int hash = 0; + TopoDS_Shape aShape; + if (aShapeTool->GetShape(label,aShape)) { + hash = aShape.HashCode(HashUpper); + } + + Handle(TDataStd_Name) name; + std::string part_name = defaultname; + if (label.FindAttribute(TDataStd_Name::GetID(),name)) { + TCollection_ExtendedString extstr = name->Get(); + char* str = new char[extstr.LengthOfCString()+1]; + extstr.ToUTF8CString(str); + part_name = str; + delete [] str; + if (part_name.empty()) { + part_name = defaultname; + } + else { + bool ws=true; + for (std::string::iterator it = part_name.begin(); it != part_name.end(); ++it) { + if (*it != ' ') { + ws = false; + break; + } + } + if (ws) + part_name = defaultname; + } + } + + TopLoc_Location part_loc = loc; + Handle(XCAFDoc_Location) hLoc; + if (label.FindAttribute(XCAFDoc_Location::GetID(), hLoc)) { + part_loc = hLoc->Get(); + } + +#ifdef FC_DEBUG + Base::Console().Message("H:%d, N:%s, T:%d, A:%d, S:%d, C:%d, SS:%d, F:%d, R:%d, C:%d, SS:%d\n", + hash, + part_name.c_str(), + aShapeTool->IsTopLevel(label), + aShapeTool->IsAssembly(label), + aShapeTool->IsShape(label), + aShapeTool->IsCompound(label), + aShapeTool->IsSimpleShape(label), + aShapeTool->IsFree(label), + aShapeTool->IsReference(label), + aShapeTool->IsComponent(label), + aShapeTool->IsSubShape(label) + ); +#endif + + TDF_Label ref; + if (aShapeTool->IsReference(label) && aShapeTool->GetReferredShape(label, ref)) { + loadShapes(ref, part_loc, part_name, true); + } + + if (isRef || myRefShapes.find(hash) == myRefShapes.end()) { + TopoDS_Shape aShape; + if (isRef && aShapeTool->GetShape(label, aShape)) + myRefShapes.insert(aShape.HashCode(HashUpper)); + + if (aShapeTool->IsSimpleShape(label) && (isRef || aShapeTool->IsFree(label))) { + if (isRef) + createShape( label, loc, defaultname ); + else + createShape( label, part_loc, part_name ); + } + else { + for (TDF_ChildIterator it(label); it.More(); it.Next()) { + loadShapes(it.Value(), part_loc, part_name, isRef); + } + } + } +} + +void ImportOCAF::createShape(const TDF_Label& label, const TopLoc_Location& loc, const std::string& name) +{ + const TopoDS_Shape& aShape = aShapeTool->GetShape(label); + if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND) { + TopExp_Explorer xp; + int ctSolids = 0, ctShells = 0; + for (xp.Init(aShape, TopAbs_SOLID); xp.More(); xp.Next(), ctSolids++) + createShape(xp.Current(), loc, name); + for (xp.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next(), ctShells++) + createShape(xp.Current(), loc, name); + if (ctSolids > 0 || ctShells > 0) + return; + } + + createShape(aShape, loc, name); +} + +void ImportOCAF::createShape(const TopoDS_Shape& aShape, const TopLoc_Location& loc, const std::string& name) +{ + Part::Feature* part = static_cast(doc->addObject("Part::Feature")); + if (!loc.IsIdentity()) + part->Shape.setValue(aShape.Located(loc)); + else + part->Shape.setValue(aShape); + part->Label.setValue(name); + + Quantity_Color aColor; + App::Color color(0.8f,0.8f,0.8f); + if (aColorTool->GetColor(aShape, XCAFDoc_ColorGen, aColor) || + aColorTool->GetColor(aShape, XCAFDoc_ColorSurf, aColor) || + aColorTool->GetColor(aShape, XCAFDoc_ColorCurv, aColor)) { + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); + if (vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) { + color.r = aColor.Red(); + color.g = aColor.Green(); + color.b = aColor.Blue(); + static_cast(vp)->ShapeColor.setValue(color); + } + } + + TopTools_IndexedMapOfShape faces; + TopExp_Explorer xp(aShape,TopAbs_FACE); + while (xp.More()) { + faces.Add(xp.Current()); + xp.Next(); + } + bool found_face_color = false; + std::vector faceColors; + faceColors.resize(faces.Extent(), color); + xp.Init(aShape,TopAbs_FACE); + while (xp.More()) { + if (aColorTool->GetColor(xp.Current(), XCAFDoc_ColorGen, aColor) || + aColorTool->GetColor(xp.Current(), XCAFDoc_ColorSurf, aColor) || + aColorTool->GetColor(xp.Current(), XCAFDoc_ColorCurv, aColor)) { + int index = faces.FindIndex(xp.Current()); + color.r = aColor.Red(); + color.g = aColor.Green(); + color.b = aColor.Blue(); + faceColors[index-1] = color; + found_face_color = true; + } + xp.Next(); + } + + if (found_face_color) { + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); + if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { + static_cast(vp)->DiffuseColor.setValues(faceColors); + } + } +} + class ImportXCAF { public: @@ -190,6 +376,12 @@ private: { TopoDS_Shape aShape; if (aShapeTool->GetShape(label,aShape)) { + //if (aShapeTool->IsReference(label)) { + // TDF_Label reflabel; + // if (aShapeTool->GetReferredShape(label, reflabel)) { + // loadShapes(reflabel); + // } + //} if (aShapeTool->IsTopLevel(label)) { int ctSolids = 0, ctShells = 0, ctComps = 0; // add the shapes @@ -248,6 +440,18 @@ private: delete [] str; } +#if 0 + // http://www.opencascade.org/org/forum/thread_15174/ + if (aShapeTool->IsAssembly(label)) { + TDF_LabelSequence shapeLabels; + aShapeTool->GetComponents(label, shapeLabels); + Standard_Integer nbShapes = shapeLabels.Length(); + for (Standard_Integer i = 1; i <= nbShapes; i++) { + loadShapes(shapeLabels.Value(i)); + } + } +#endif + if (label.HasChild()) { TDF_ChildIterator it; for (it.Initialize(label); it.More(); it.Next()) { @@ -313,6 +517,9 @@ static PyObject * importer(PyObject *self, PyObject *args) IGESControl_Controller::Init(); Interface_Static::SetIVal("read.surfacecurve.mode",3); IGESCAFControl_Reader aReader; + aReader.SetColorMode(true); + aReader.SetNameMode(true); + aReader.SetLayerMode(true); if (aReader.ReadFile((Standard_CString)Name) != IFSelect_RetDone) { PyErr_SetString(PyExc_Exception, "cannot read IGES file"); return 0; @@ -330,8 +537,13 @@ static PyObject * importer(PyObject *self, PyObject *args) return 0; } +#if 1 + ImportOCAF ocaf(hDoc, pcDoc, file.fileNamePure()); + ocaf.loadShapes(); +#else ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure()); xcaf.loadShapes(); +#endif pcDoc->recompute(); }