From a83d71c7c858a2356a99775ecf8285be2c7b95af Mon Sep 17 00:00:00 2001 From: Jean-Marie Verdun Date: Sun, 9 Jul 2017 21:57:06 +0200 Subject: [PATCH] Add initial code for hierarchical STEP exporter --- src/Mod/Import/App/ImportOCAF.cpp | 92 +++++++++++++++++++++++++-- src/Mod/Import/App/ImportOCAF.h | 8 ++- src/Mod/Import/Gui/AppImportGuiPy.cpp | 62 ++++++++++++++---- 3 files changed, 143 insertions(+), 19 deletions(-) diff --git a/src/Mod/Import/App/ImportOCAF.cpp b/src/Mod/Import/App/ImportOCAF.cpp index ac44bda6e4..6187f4d0c4 100644 --- a/src/Mod/Import/App/ImportOCAF.cpp +++ b/src/Mod/Import/App/ImportOCAF.cpp @@ -26,6 +26,22 @@ # define WNT // avoid conflict with GUID #endif #ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include // for Precision::Confusion() +# include +# include +# include # include # include # include @@ -462,16 +478,55 @@ ExportOCAF::ExportOCAF(Handle(TDocStd_Document) h, bool explicitPlacement) aColorTool = XCAFDoc_DocumentTool::ColorTool(pDoc->Main()); if (keepExplicitPlacement) { - rootLabel = aShapeTool->NewShape(); - TDataStd_Name::Set(rootLabel, "ASSEMBLY"); - //Interface_Static::SetIVal("write.step.assembly",1); + // rootLabel = aShapeTool->NewShape(); + // TDataStd_Name::Set(rootLabel, "ASSEMBLY"); + Interface_Static::SetIVal("write.step.assembly",1); } else { rootLabel = TDF_TagSource::NewChild(pDoc->Main()); } } -void ExportOCAF::saveShape(Part::Feature* part, const std::vector& colors) + +// This function create an Assembly node into an XCAF document with it's relative placement information + +void ExportOCAF::createNode(App::Part* part, int& root_id, std::vector & hierarchical_label,std::vector & hierarchical_loc) +{ + TDF_Label shapeLabel = aShapeTool->NewShape(); + TDF_Label return_value; + Handle(TDataStd_Name) N; + TDataStd_Name::Set(shapeLabel, TCollection_ExtendedString(part->Label.getValue(), 1)); + Base::Placement pl = part->Placement.getValue(); + Base::Rotation rot(pl.getRotation()); + Base::Vector3d axis; + double angle; + rot.getValue(axis, angle); + gp_Trsf trf; + trf.SetRotation(gp_Ax1(gp_Pnt(), gp_Dir(axis.x, axis.y, axis.z)), angle); + trf.SetTranslationPart(gp_Vec(pl.getPosition().x,pl.getPosition().y,pl.getPosition().z)); + TopLoc_Location MyLoc = TopLoc_Location(trf); + XCAFDoc_Location::Set(shapeLabel,TopLoc_Location(trf)); + + hierarchical_label.push_back(shapeLabel); + hierarchical_loc.push_back(MyLoc); + root_id=hierarchical_label.size(); +} + +void ExportOCAF::ComputeDoc(int labels) +{ + puts("Recomputing the Doc"); + // XCAFDoc_DocumentTool::ShapeTool(labels)->ComputeShapes(labels); + puts(" ========================================================= "); + // XCAFDoc_DocumentTool::ShapeTool(labels)->Dump(std::cerr,true); + puts(" ========================================================= "); + aShapeTool->Dump(std::cerr); +} + + + + + +int ExportOCAF::saveShape(Part::Feature* part, const std::vector& colors, std::vector & hierarchical_label,std::vector & hierarchical_loc) { const TopoDS_Shape& shape = part->Shape.getValue(); if (shape.IsNull()) @@ -479,6 +534,18 @@ void ExportOCAF::saveShape(Part::Feature* part, const std::vector& c TopoDS_Shape baseShape; TopLoc_Location aLoc; + Handle(TDataStd_Name) N; + + Base::Placement pl = part->Placement.getValue(); + Base::Rotation rot(pl.getRotation()); + Base::Vector3d axis; + double angle; + rot.getValue(axis, angle); + gp_Trsf trf; + trf.SetRotation(gp_Ax1(gp_Pnt(0.,0.,0.), gp_Dir(axis.x, axis.y, axis.z)), angle); + trf.SetTranslationPart(gp_Vec(pl.getPosition().x,pl.getPosition().y,pl.getPosition().z)); + TopLoc_Location MyLoc = TopLoc_Location(trf); + if (keepExplicitPlacement) { // http://www.opencascade.org/org/forum/thread_18813/?forum=3 aLoc = shape.Location(); @@ -541,6 +608,23 @@ void ExportOCAF::saveShape(Part::Feature* part, const std::vector& c col.SetValues(mat[0],mat[1],mat[2],Quantity_TOC_RGB); aColorTool->SetColor(shapeLabel, col, XCAFDoc_ColorGen); } + hierarchical_label.push_back(shapeLabel); + hierarchical_loc.push_back(MyLoc); + return(hierarchical_label.size()); + +} + +// This function is moving a "standard" node into an Assembly node within an XCAF doc + +void ExportOCAF::push_node(int root_id, int node_id, std::vector & hierarchical_label,std::vector & hierarchical_loc) +{ + TDF_Label root; + TDF_Label node; + root = hierarchical_label.at(root_id-1); + node = hierarchical_label.at(node_id-1); + + XCAFDoc_DocumentTool::ShapeTool(root)->AddComponent(root, node, hierarchical_loc.at(node_id-1)); + } // ---------------------------------------------------------------------------- diff --git a/src/Mod/Import/App/ImportOCAF.h b/src/Mod/Import/App/ImportOCAF.h index 6a502cf5a3..fdaba6fb57 100644 --- a/src/Mod/Import/App/ImportOCAF.h +++ b/src/Mod/Import/App/ImportOCAF.h @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -77,8 +78,13 @@ private: class ImportExport ExportOCAF { public: + void createNode(App::Part* part, int& root_it, std::vector & hierarchical_label,std::vector & hierarchical_loc); + void ComputeDoc(int labels); ExportOCAF(Handle(TDocStd_Document) h, bool explicitPlacement); - void saveShape(Part::Feature* part, const std::vector&); + int saveShape(Part::Feature* part, const std::vector&, std::vector & hierarchical_label,std::vector & hierarchical_loc); + void push_node(int root, int node, std::vector & hierarchical_label,std::vector & hierarchical_loc); + + private: Handle(TDocStd_Document) pDoc; diff --git a/src/Mod/Import/Gui/AppImportGuiPy.cpp b/src/Mod/Import/Gui/AppImportGuiPy.cpp index 7fe080618e..79a811fcb6 100644 --- a/src/Mod/Import/Gui/AppImportGuiPy.cpp +++ b/src/Mod/Import/Gui/AppImportGuiPy.cpp @@ -431,6 +431,47 @@ private: return Py::None(); } + int export_app_object(App::DocumentObject* obj, Import::ExportOCAF ocaf, int root_node, + std::vector & hierarchical_label, + std::vector & hierarchical_loc) + { + std::vector local_label; + int root_id; + int return_label; + + + if (obj->getTypeId().isDerivedFrom(App::Part::getClassTypeId())) { + App::Part* part = static_cast(obj); + // I shall recusrively select the elements and call back + std::vector entries = part->Group.getValues(); + std::vector::iterator it; + + for ( it = entries.begin(); it != entries.end(); it++ ) { + int new_label; + new_label=export_app_object((*it),ocaf,new_label,hierarchical_label,hierarchical_loc); + local_label.push_back(new_label); + } + ocaf.createNode(part,root_id,hierarchical_label,hierarchical_loc); + std::vector::iterator label_it; + for ( label_it = local_label.begin(); label_it != local_label.end(); label_it++ ) { + ocaf.push_node(root_id,(*label_it), hierarchical_label,hierarchical_loc); + } + return_label=root_id; + } + if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + Part::Feature* part = static_cast(obj); + std::vector colors; + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); + if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { + colors = static_cast(vp)->DiffuseColor.getValues(); + if (colors.empty()) + colors.push_back(static_cast(vp)->ShapeColor.getValue()); + } + return_label=ocaf.saveShape(part, colors,hierarchical_label,hierarchical_loc); + } + return(return_label); + } + Py::Object exporter(const Py::Tuple& args) { PyObject* object; @@ -451,24 +492,17 @@ private: bool keepExplicitPlacement = list.size() > 1; Import::ExportOCAF ocaf(hDoc, keepExplicitPlacement); + // That stuff is exporting a list of selected oject into FreeCAD Tree + + int label=-1; for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { PyObject* item = (*it).ptr(); if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); - if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - Part::Feature* part = static_cast(obj); - std::vector colors; - Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); - if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { - colors = static_cast(vp)->DiffuseColor.getValues(); - if (colors.empty()) - colors.push_back(static_cast(vp)->ShapeColor.getValue()); - } - ocaf.saveShape(part, colors); - } - else { - Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue()); - } + std::vector hierarchical_label; + std::vector hierarchical_loc; + label=export_app_object(obj,ocaf,label, hierarchical_label, hierarchical_loc); + ocaf.ComputeDoc(label); } }