| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #if defined(__MINGW32__) |
| | # define WNT |
| | #endif |
| | #include <Quantity_ColorRGBA.hxx> |
| | #include <Standard_Failure.hxx> |
| | #include <Standard_Version.hxx> |
| | #include <TDF_Label.hxx> |
| | #include <TDF_LabelSequence.hxx> |
| | #include <TDataStd_Name.hxx> |
| | #include <TDocStd_Document.hxx> |
| | #include <TopExp_Explorer.hxx> |
| | #include <TopTools_IndexedMapOfShape.hxx> |
| | #include <XCAFDoc_DocumentTool.hxx> |
| | #include <XCAFDoc_Location.hxx> |
| | #include <gp_Ax1.hxx> |
| | #include <gp_Dir.hxx> |
| | #include <gp_Pln.hxx> |
| | #include <gp_Trsf.hxx> |
| |
|
| |
|
| | #include <App/Document.h> |
| | #include <App/DocumentObject.h> |
| | #include <App/Part.h> |
| | #include <Mod/Part/App/Interface.h> |
| | #include <Mod/Part/App/PartFeature.h> |
| |
|
| | #include "ExportOCAF.h" |
| | #include "Tools.h" |
| |
|
| |
|
| | using namespace Import; |
| |
|
| |
|
| | ExportOCAF::ExportOCAF(Handle(TDocStd_Document) hDoc, bool explicitPlacement) |
| | : pDoc(hDoc) |
| | , keepExplicitPlacement(explicitPlacement) |
| | { |
| | aShapeTool = XCAFDoc_DocumentTool::ShapeTool(pDoc->Main()); |
| | aColorTool = XCAFDoc_DocumentTool::ColorTool(pDoc->Main()); |
| |
|
| | if (keepExplicitPlacement) { |
| | |
| | |
| | Part::Interface::writeStepAssembly(Part::Interface::Assembly::Auto); |
| | } |
| | else { |
| | rootLabel = TDF_TagSource::NewChild(pDoc->Main()); |
| | } |
| | } |
| |
|
| | ExportOCAF::~ExportOCAF() = default; |
| |
|
| | std::vector<App::DocumentObject*> ExportOCAF::filterPart(App::Part* part) const |
| | { |
| | |
| | |
| | std::vector<App::DocumentObject*> entries = part->Group.getValues(); |
| |
|
| | |
| | Base::Type featureBase = Base::Type::fromName("PartDesign::FeatureBase"); |
| | std::vector<App::DocumentObject*> filterType; |
| | for (auto it : entries) { |
| | std::vector<App::DocumentObject*> outList = it->getOutList(); |
| | for (auto jt : outList) { |
| | if (jt->getTypeId() == featureBase) { |
| | filterType.push_back(jt); |
| | } |
| | } |
| | } |
| |
|
| | |
| | if (!filterType.empty()) { |
| | std::vector<App::DocumentObject*> keepObjects; |
| | for (auto it : entries) { |
| | std::vector<App::DocumentObject*> inList = it->getInList(); |
| | bool accept = true; |
| | for (auto jt : inList) { |
| | if (auto kt = std::ranges::find(filterType, jt); kt != filterType.end()) { |
| | accept = false; |
| | break; |
| | } |
| | } |
| |
|
| | if (accept) { |
| | keepObjects.push_back(it); |
| | } |
| | } |
| |
|
| | entries.swap(keepObjects); |
| | } |
| |
|
| | return entries; |
| | } |
| |
|
| | void ExportOCAF::exportObjects(std::vector<App::DocumentObject*>& objs) |
| | { |
| | |
| | std::vector<TDF_Label> hierarchical_label; |
| | std::vector<TopLoc_Location> hierarchical_loc; |
| | std::vector<App::DocumentObject*> hierarchical_part; |
| | for (auto obj : objs) { |
| | exportObject(obj, hierarchical_label, hierarchical_loc, hierarchical_part); |
| | } |
| |
|
| | |
| | std::vector<TDF_Label> FreeLabels; |
| | std::vector<int> part_id; |
| | getFreeLabels(hierarchical_label, FreeLabels, part_id); |
| |
|
| | std::vector<std::vector<Base::Color>> Colors; |
| | getPartColors(hierarchical_part, FreeLabels, part_id, Colors); |
| | reallocateFreeShape(hierarchical_part, FreeLabels, part_id, Colors); |
| |
|
| | |
| | |
| | XCAFDoc_DocumentTool::ShapeTool(pDoc->Main())->UpdateAssemblies(); |
| | } |
| |
|
| | int ExportOCAF::exportObject( |
| | App::DocumentObject* obj, |
| | std::vector<TDF_Label>& hierarchical_label, |
| | std::vector<TopLoc_Location>& hierarchical_loc, |
| | std::vector<App::DocumentObject*>& hierarchical_part |
| | ) |
| | { |
| | std::vector<int> local_label; |
| | int root_id; |
| | int return_label = -1; |
| |
|
| | if (obj->isDerivedFrom<App::Part>()) { |
| | App::Part* part = static_cast<App::Part*>(obj); |
| | |
| | std::vector<App::DocumentObject*> entries = part->Group.getValues(); |
| | std::vector<App::DocumentObject*>::iterator it; |
| |
|
| | if (filterBaseFeature) { |
| | entries = filterPart(part); |
| | } |
| |
|
| | for (it = entries.begin(); it != entries.end(); ++it) { |
| | int new_label = 0; |
| | new_label = exportObject((*it), hierarchical_label, hierarchical_loc, hierarchical_part); |
| | local_label.push_back(new_label); |
| | } |
| |
|
| | createNode(part, root_id, hierarchical_label, hierarchical_loc, hierarchical_part); |
| | std::vector<int>::iterator label_it; |
| | for (label_it = local_label.begin(); label_it != local_label.end(); ++label_it) { |
| | pushNode(root_id, (*label_it), hierarchical_label, hierarchical_loc); |
| | } |
| |
|
| | return_label = root_id; |
| | } |
| |
|
| | if (obj->isDerivedFrom<Part::Feature>()) { |
| | Part::Feature* part = static_cast<Part::Feature*>(obj); |
| | std::vector<Base::Color> colors; |
| | findColors(part, colors); |
| |
|
| | return_label = saveShape(part, colors, hierarchical_label, hierarchical_loc, hierarchical_part); |
| | } |
| |
|
| | return return_label; |
| | } |
| |
|
| | |
| | |
| | void ExportOCAF::createNode( |
| | App::Part* part, |
| | int& root_id, |
| | std::vector<TDF_Label>& hierarchical_label, |
| | std::vector<TopLoc_Location>& hierarchical_loc, |
| | std::vector<App::DocumentObject*>& hierarchical_part |
| | ) |
| | { |
| | TDF_Label shapeLabel = aShapeTool->NewShape(); |
| | Handle(TDataStd_Name) N; |
| | TDataStd_Name::Set(shapeLabel, TCollection_ExtendedString(part->Label.getValue(), true)); |
| |
|
| | 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); |
| | hierarchical_part.push_back(part); |
| | root_id = hierarchical_label.size(); |
| | } |
| |
|
| | int ExportOCAF::saveShape( |
| | Part::Feature* part, |
| | const std::vector<Base::Color>& colors, |
| | std::vector<TDF_Label>& hierarchical_label, |
| | std::vector<TopLoc_Location>& hierarchical_loc, |
| | std::vector<App::DocumentObject*>& hierarchical_part |
| | ) |
| | { |
| | const TopoDS_Shape& shape = part->Shape.getValue(); |
| | if (shape.IsNull()) { |
| | return -1; |
| | } |
| |
|
| | 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) { |
| | |
| | aLoc = shape.Location(); |
| | baseShape = shape.Located(TopLoc_Location()); |
| | } |
| | else { |
| | baseShape = shape; |
| | } |
| |
|
| | |
| | TDF_Label shapeLabel = aShapeTool->NewShape(); |
| | aShapeTool->SetShape(shapeLabel, baseShape); |
| |
|
| | TDataStd_Name::Set(shapeLabel, TCollection_ExtendedString(part->Label.getValue(), true)); |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | Quantity_ColorRGBA col; |
| |
|
| | std::set<int> face_index; |
| | TopTools_IndexedMapOfShape faces; |
| | TopExp_Explorer xp(baseShape, TopAbs_FACE); |
| | while (xp.More()) { |
| | face_index.insert(faces.Add(xp.Current())); |
| | xp.Next(); |
| | } |
| |
|
| | |
| | if (colors.size() == face_index.size()) { |
| | xp.Init(baseShape, TopAbs_FACE); |
| | while (xp.More()) { |
| | int index = faces.FindIndex(xp.Current()); |
| | if (face_index.find(index) != face_index.end()) { |
| | face_index.erase(index); |
| |
|
| | |
| | |
| | |
| | |
| | TDF_Label faceLabel = aShapeTool->AddSubShape(shapeLabel, xp.Current()); |
| | |
| | if (!faceLabel.IsNull()) { |
| | aShapeTool->SetShape(faceLabel, xp.Current()); |
| | } |
| | else { |
| | aShapeTool->FindShape(xp.Current(), faceLabel); |
| | } |
| |
|
| | if (!faceLabel.IsNull()) { |
| | const Base::Color& color = colors[index - 1]; |
| | col = Tools::convertColor(color); |
| | aColorTool->SetColor(faceLabel, col, XCAFDoc_ColorSurf); |
| | } |
| | } |
| | xp.Next(); |
| | } |
| | } |
| | else if (!colors.empty()) { |
| | Base::Color color = colors.front(); |
| | col = Tools::convertColor(color); |
| | aColorTool->SetColor(shapeLabel, col, XCAFDoc_ColorGen); |
| | } |
| |
|
| | hierarchical_label.push_back(shapeLabel); |
| | hierarchical_loc.push_back(MyLoc); |
| | hierarchical_part.push_back(part); |
| |
|
| | return (hierarchical_label.size()); |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | void ExportOCAF::getFreeLabels( |
| | std::vector<TDF_Label>& hierarchical_label, |
| | std::vector<TDF_Label>& labels, |
| | std::vector<int>& label_part_id |
| | ) |
| | { |
| | TDF_LabelSequence FreeLabels; |
| | aShapeTool->GetFreeShapes(FreeLabels); |
| | int n = FreeLabels.Length(); |
| | for (int i = 1; i <= n; i++) { |
| | TDF_Label label = FreeLabels.Value(i); |
| | for (std::size_t j = 0; j < hierarchical_label.size(); j++) { |
| | if (label == hierarchical_label.at(j)) { |
| | labels.push_back(label); |
| | label_part_id.push_back(j); |
| | } |
| | } |
| | } |
| | } |
| |
|
| | void ExportOCAF::getPartColors( |
| | std::vector<App::DocumentObject*> hierarchical_part, |
| | std::vector<TDF_Label> FreeLabels, |
| | std::vector<int> part_id, |
| | std::vector<std::vector<Base::Color>>& Colors |
| | ) const |
| | { |
| | |
| | std::size_t n = FreeLabels.size(); |
| | for (std::size_t i = 0; i < n; i++) { |
| | std::vector<Base::Color> colors; |
| | Part::Feature* part = static_cast<Part::Feature*>(hierarchical_part.at(part_id.at(i))); |
| | findColors(part, colors); |
| | Colors.push_back(colors); |
| | } |
| | } |
| |
|
| | void ExportOCAF::reallocateFreeShape( |
| | std::vector<App::DocumentObject*> hierarchical_part, |
| | std::vector<TDF_Label> FreeLabels, |
| | std::vector<int> part_id, |
| | std::vector<std::vector<Base::Color>>& Colors |
| | ) |
| | { |
| | std::size_t n = FreeLabels.size(); |
| | for (std::size_t i = 0; i < n; i++) { |
| | TDF_Label label = FreeLabels.at(i); |
| | |
| | if (hierarchical_part.at(part_id.at(i))->isDerivedFrom<Part::Feature>()) { |
| | Part::Feature* part = static_cast<Part::Feature*>(hierarchical_part.at(part_id.at(i))); |
| | aShapeTool->SetShape(label, part->Shape.getValue()); |
| | |
| | std::vector<Base::Color> colors; |
| | colors = Colors.at(i); |
| | TopoDS_Shape baseShape = part->Shape.getValue(); |
| |
|
| | |
| | Quantity_ColorRGBA col; |
| |
|
| | std::set<int> face_index; |
| | TopTools_IndexedMapOfShape faces; |
| | TopExp_Explorer xp(baseShape, TopAbs_FACE); |
| | while (xp.More()) { |
| | face_index.insert(faces.Add(xp.Current())); |
| | xp.Next(); |
| | } |
| |
|
| | |
| | if (colors.size() == face_index.size()) { |
| | xp.Init(baseShape, TopAbs_FACE); |
| | while (xp.More()) { |
| | int index = faces.FindIndex(xp.Current()); |
| | if (face_index.find(index) != face_index.end()) { |
| | face_index.erase(index); |
| |
|
| | |
| | |
| | |
| | |
| | TDF_Label faceLabel = aShapeTool->AddSubShape(label, xp.Current()); |
| | |
| | if (!faceLabel.IsNull()) { |
| | aShapeTool->SetShape(faceLabel, xp.Current()); |
| | } |
| | else { |
| | aShapeTool->FindShape(xp.Current(), faceLabel); |
| | } |
| |
|
| | if (!faceLabel.IsNull()) { |
| | const Base::Color& color = colors[index - 1]; |
| | col = Tools::convertColor(color); |
| | aColorTool->SetColor(faceLabel, col, XCAFDoc_ColorSurf); |
| | } |
| | } |
| |
|
| | xp.Next(); |
| | } |
| | } |
| | else if (!colors.empty()) { |
| | Base::Color color = colors.front(); |
| | col = Tools::convertColor(color); |
| | aColorTool->SetColor(label, col, XCAFDoc_ColorGen); |
| | } |
| | } |
| | } |
| | } |
| |
|
| | |
| | void ExportOCAF::pushNode( |
| | int root_id, |
| | int node_id, |
| | std::vector<TDF_Label>& hierarchical_label, |
| | std::vector<TopLoc_Location>& hierarchical_loc |
| | ) |
| | { |
| | auto isValidIndex = [&](std::size_t root, std::size_t node) { |
| | |
| | if (root >= hierarchical_label.size()) { |
| | return false; |
| | } |
| | if (node >= hierarchical_label.size() || node >= hierarchical_loc.size()) { |
| | return false; |
| | } |
| |
|
| | return true; |
| | |
| | }; |
| | if (isValidIndex(root_id - 1, node_id - 1)) { |
| | TDF_Label root; |
| | TDF_Label node; |
| | TopLoc_Location locn; |
| | root = hierarchical_label.at(root_id - 1); |
| | node = hierarchical_label.at(node_id - 1); |
| | locn = hierarchical_loc.at(node_id - 1); |
| |
|
| | XCAFDoc_DocumentTool::ShapeTool(root)->AddComponent(root, node, locn); |
| | } |
| | } |
| |
|
| | |
| |
|
| | ExportOCAFCmd::ExportOCAFCmd(Handle(TDocStd_Document) h, bool explicitPlacement) |
| | : ExportOCAF(h, explicitPlacement) |
| | {} |
| |
|
| | void ExportOCAFCmd::findColors(Part::Feature* part, std::vector<Base::Color>& colors) const |
| | { |
| | std::map<Part::Feature*, std::vector<Base::Color>>::const_iterator it = partColors.find(part); |
| | if (it != partColors.end()) { |
| | colors = it->second; |
| | } |
| | } |
| |
|