diff --git a/src/Mod/Import/App/ImportOCAF2.cpp b/src/Mod/Import/App/ImportOCAF2.cpp index 8247f080e5..7d8dec7a98 100644 --- a/src/Mod/Import/App/ImportOCAF2.cpp +++ b/src/Mod/Import/App/ImportOCAF2.cpp @@ -53,12 +53,15 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include @@ -178,15 +181,15 @@ ImportOCAF2::ImportOCAF2(Handle(TDocStd_Document) h, App::Document* d, const std auto hGrp = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/Mod/Import/hSTEP"); - merge = hGrp->GetBool("ReadShapeCompoundMode", true); + merge = hGrp->GetBool("ReadShapeCompoundMode", false); hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Import"); - useLinkGroup = hGrp->GetBool("UseLinkGroup",true); + useLinkGroup = !hGrp->GetBool("UseAppPart",true); + useLegacyImporter = hGrp->GetBool("UseLegacyImporter",false); useBaseName = hGrp->GetBool("UseBaseName",true); importHidden = hGrp->GetBool("ImportHiddenObject",true); reduceObjects = hGrp->GetBool("ReduceObjects",true); showProgress = hGrp->GetBool("ShowProgress",true); - expandCompound = hGrp->GetBool("ExpandCompound",true); if(d->isSaved()) { Base::FileInfo fi(d->FileName.getValue()); @@ -200,11 +203,6 @@ ImportOCAF2::ImportOCAF2(Handle(TDocStd_Document) h, App::Document* d, const std defaultEdgeColor.setPackedValue(hGrp->GetUnsigned("DefaultShapeLineColor",421075455UL)); defaultEdgeColor.a = 0; - - if(useLinkGroup) { - // Interface_Static::SetIVal("read.stepcaf.subshapes.name",1); - aShapeTool->SetAutoNaming(Standard_False); - } } ImportOCAF2::~ImportOCAF2() @@ -244,9 +242,12 @@ std::string ImportOCAF2::getLabelName(TDF_Label label) { return name; } -void ImportOCAF2::setObjectName(Info &info, TDF_Label label) { +void ImportOCAF2::setObjectName(Info &info, TDF_Label label, bool checkExistingName) { if(!info.obj) return; + std::string name = getLabelName(label); + if (!checkExistingName || info.baseName.size() < name.size()) + info.baseName = std::move(name); info.baseName = getLabelName(label); if(info.baseName.size()) info.obj->Label.setValue(info.baseName.c_str()); @@ -299,56 +300,34 @@ bool ImportOCAF2::getColor(const TopoDS_Shape &shape, Info &info, bool check, bo return ret; } -App::DocumentObject *ImportOCAF2::expandShape( - App::Document *doc, TDF_Label label, const TopoDS_Shape &shape) -{ - if(shape.IsNull() || !TopExp_Explorer(shape,TopAbs_VERTEX).More()) - return nullptr; +struct ImportOCAF2::ColorInfo { + Part::TopoShape tshape; + std::vector faceColors; + std::vector edgeColors; + App::Color faceColor; + App::Color edgeColor; + bool hasFaceColor = false; + bool hasEdgeColor = false; +}; - // When saved as compound, STEP file does not support instance sharing, - // meaning that even if the source compound may contain child shapes of - // shared instances, or multiple hierarchies, those information are lost - // when saved to STEP, everything become flat and duplicated. So the code - // below is not necessary. -#if 0 - auto baseShape = shape.Located(TopLoc_Location()); - auto it = myShapes.find(baseShape); - if(it!=myShapes.end()) { - auto link = static_cast(doc->addObject("App::Link","Link")); - link->Visibility.setValue(false); - link->setLink(-1,it->second.obj); - setPlacement(&link->Placement,shape); - return link; +// Check for uniform color +static void mergeColor(bool &hasColors, App::Color &color, std::vector &colors) { + if(colors.empty()) + return; + if(!hasColors) { + colors.clear(); + return; } -#endif - std::vector objs; - - if(shape.ShapeType() == TopAbs_COMPOUND) { - for(TopoDS_Iterator it(shape,0,0);it.More();it.Next()) { - TDF_Label childLabel; - if(!label.IsNull()) - aShapeTool->FindSubShape(label,it.Value(),childLabel); - auto child = expandShape(doc,childLabel,it.Value()); - if(child) { - objs.push_back(child); - Info info; - info.free = false; - info.obj = child; - myShapes.emplace(it.Value().Located(TopLoc_Location()),info); - } + hasColors = false; + auto &firstColor = colors[0]; + for(auto &c : colors) { + if(c!=firstColor) { + hasColors = true; + return; } - if(objs.empty()) - return nullptr; - auto compound = static_cast(doc->addObject("Part::Compound2","Compound")); - compound->Links.setValues(objs); - // compound->Visibility.setValue(false); - setPlacement(&compound->Placement,shape); - return compound; } - Info info; - info.obj = nullptr; - createObject(doc,label,shape,info,false); - return info.obj; + color = firstColor; + colors.clear(); } bool ImportOCAF2::createObject(App::Document *doc, TDF_Label label, @@ -363,19 +342,14 @@ bool ImportOCAF2::createObject(App::Document *doc, TDF_Label label, bool hasFaceColors = false; bool hasEdgeColors = false; - Part::TopoShape tshape(shape); - std::vector faceColors; - std::vector edgeColors; + ColorInfo colors; + colors.tshape.setShape(shape); + Part::TopoShape &tshape = colors.tshape; TDF_LabelSequence seq; if(!label.IsNull() && aShapeTool->GetSubShapes(label,seq)) { - - TopTools_IndexedMapOfShape faceMap,edgeMap; - TopExp::MapShapes(tshape.getShape(), TopAbs_FACE, faceMap); - TopExp::MapShapes(tshape.getShape(), TopAbs_EDGE, edgeMap); - - faceColors.assign(faceMap.Extent(),info.faceColor); - edgeColors.assign(edgeMap.Extent(),info.edgeColor); + colors.faceColors.assign(tshape.countSubShapes(TopAbs_FACE),info.faceColor); + colors.edgeColors.assign(tshape.countSubShapes(TopAbs_EDGE),info.edgeColor); // Two passes to get sub shape colors. First pass, look for solid, and // second pass look for face and edges. This allows lower level // subshape to override color of higher level ones. @@ -391,40 +365,42 @@ bool ImportOCAF2::createObject(App::Document *doc, TDF_Label label, }else if(j!=0) continue; - bool foundFaceColor=false,foundEdgeColor=false; + bool foundFaceColor = false; + bool checkSubFaceColor = false; + bool checkSubEdgeColor = false; App::Color faceColor,edgeColor; Quantity_ColorRGBA aColor; if(aColorTool->GetColor(l, XCAFDoc_ColorSurf, aColor) || aColorTool->GetColor(l, XCAFDoc_ColorGen, aColor)) { - faceColor = convertColor(aColor); foundFaceColor = true; + faceColor = convertColor(aColor); + checkSubFaceColor = faceColor!=info.faceColor; } if(aColorTool->GetColor(l, XCAFDoc_ColorCurv, aColor)) { edgeColor = convertColor(aColor); - foundEdgeColor = true; - if(j==0 && foundFaceColor && faceColors.size() && edgeColor==faceColor) { + checkSubEdgeColor = edgeColor!=info.edgeColor; + if(j==0 && foundFaceColor && colors.faceColors.size() && edgeColor==faceColor) { // Do not set edge the same color as face - foundEdgeColor = false; + checkSubEdgeColor = false; } } - if(foundFaceColor) { + if(checkSubFaceColor) { for(TopExp_Explorer exp(subShape,TopAbs_FACE);exp.More();exp.Next()) { - int idx = faceMap.FindIndex(exp.Current())-1; - if(idx>=0 && idx<(int)faceColors.size()) { - faceColors[idx] = faceColor; + int idx = tshape.findShape(exp.Current())-1; + if(idx>=0 && idx<(int)colors.faceColors.size()) { + colors.faceColors[idx] = faceColor; hasFaceColors = true; info.hasFaceColor = true; - }else - assert(0); + } } } - if(foundEdgeColor) { + if(checkSubEdgeColor) { for(TopExp_Explorer exp(subShape,TopAbs_EDGE);exp.More();exp.Next()) { - int idx = edgeMap.FindIndex(exp.Current())-1; - if(idx>=0 && idx<(int)edgeColors.size()) { - edgeColors[idx] = edgeColor; + int idx = tshape.findShape(exp.Current())-1; + if(idx>=0 && idx<(int)colors.edgeColors.size()) { + colors.edgeColors[idx] = edgeColor; hasEdgeColors = true; info.hasEdgeColor = true; } @@ -439,23 +415,24 @@ bool ImportOCAF2::createObject(App::Document *doc, TDF_Label label, if(newDoc && (mode==ObjectPerDoc || mode==ObjectPerDir)) doc = getDocument(doc,label); - if(expandCompound && - (tshape.countSubShapes(TopAbs_SOLID)>1 || - (!tshape.countSubShapes(TopAbs_SOLID) && tshape.countSubShapes(TopAbs_SHELL)>1))) - { - feature = dynamic_cast(expandShape(doc,label,shape)); - assert(feature); - } else { - feature = static_cast(doc->addObject("Part::Feature",tshape.shapeName().c_str())); - feature->Shape.setValue(shape); - // feature->Visibility.setValue(false); - } + mergeColor(hasFaceColors,info.faceColor,colors.faceColors); + mergeColor(hasEdgeColors,info.edgeColor,colors.edgeColors); + + colors.faceColor = info.faceColor; + colors.edgeColor = info.edgeColor; + colors.hasFaceColor = info.hasFaceColor; + colors.hasEdgeColor = info.hasEdgeColor; + + feature = static_cast(doc->addObject("Part::Feature",tshape.shapeName().c_str())); + feature->Shape.setValue(shape); + // feature->Visibility.setValue(false); + applyFaceColors(feature,{info.faceColor}); applyEdgeColors(feature,{info.edgeColor}); - if(hasFaceColors) - applyFaceColors(feature,faceColors); - if(hasEdgeColors) - applyEdgeColors(feature,edgeColors); + if(colors.faceColors.size()) + applyFaceColors(feature,colors.faceColors); + if(colors.edgeColors.size()) + applyEdgeColors(feature,colors.edgeColors); info.propPlacement = &feature->Placement; info.obj = feature; @@ -471,6 +448,9 @@ App::Document *ImportOCAF2::getDocument(App::Document *doc, TDF_Label label) { return doc; auto newDoc = App::GetApplication().newDocument(name.c_str(),name.c_str(),false); + myNewDocuments.push_back(newDoc); + newDoc->setUndoMode(0); + std::ostringstream ss; Base::FileInfo fi(doc->FileName.getValue()); std::string path = fi.dirPath(); @@ -492,11 +472,37 @@ App::Document *ImportOCAF2::getDocument(App::Document *doc, TDF_Label label) { break; } } + std::string fname = newDoc->Label.getValue(); + // First, try save file using more descriptive label name. + // Replace some common invalid characters + boost::replace_if(fname, boost::is_any_of("<>:\"/\\|?*"), '_'); for(int i=0;i<1000;++i) { ss.str(""); - ss << path << '/' << newDoc->getName() << ".fcstd"; + ss << path << '/' << fname; if(i>0) ss << '_' << std::setfill('0') << std::setw(3) << i; + ss << ".fcstd"; + Base::FileInfo fi(ss.str()); + if(!fi.exists()) { + // No way to be sure the file name is legal, so just create one. + Base::ofstream of(fi); + if (!of) + continue; + of.close(); + fi.deleteFile(); + if(!newDoc->saveAs(fi.filePath().c_str())) + break; + return newDoc; + } + } + + // Using label as file name failed, fall back to internal name + for(int i=0;i<1000;++i) { + ss.str(""); + ss << path << '/' << newDoc->getName(); + if(i>0) + ss << '_' << std::setfill('0') << std::setw(3) << i; + ss << ".fcstd"; Base::FileInfo fi(ss.str()); if(!fi.exists()) { if(!newDoc->saveAs(fi.filePath().c_str())) @@ -525,7 +531,6 @@ bool ImportOCAF2::createGroup(App::Document *doc, Info &info, const TopoDS_Shape myCollapsedObjects.emplace(info.obj,info.propPlacement); return true; } - auto group = static_cast(doc->addObject("App::LinkGroup","LinkGroup")); for(auto &child : children) { if(child->getDocument()!=doc) { auto link = static_cast(doc->addObject("App::Link","Link")); @@ -539,11 +544,23 @@ bool ImportOCAF2::createGroup(App::Document *doc, Info &info, const TopoDS_Shape } // child->Visibility.setValue(false); } - // group->Visibility.setValue(false); - group->ElementList.setValues(children); - group->VisibilityList.setValue(visibilities); + App::DocumentObject *group; + if(!useLinkGroup) { + auto part = static_cast(doc->addObject("App::Part","Part")); + group = part; + int i=0; + for(auto child : children) + child->Visibility.setValue(visibilities[i++]); + part->addObjects(children); + info.propPlacement = &part->Placement; + } else { + auto linkGroup = static_cast(doc->addObject("App::LinkGroup","LinkGroup")); + group = linkGroup; + linkGroup->ElementList.setValues(children); + linkGroup->VisibilityList.setValue(visibilities); + info.propPlacement = &linkGroup->Placement; + } info.obj = group; - info.propPlacement = &group->Placement; if(getColor(shape,info,false,true)) { if(info.hasFaceColor) applyLinkColor(group,-1,info.faceColor); @@ -553,13 +570,16 @@ bool ImportOCAF2::createGroup(App::Document *doc, Info &info, const TopoDS_Shape App::DocumentObject* ImportOCAF2::loadShapes() { - if(!useLinkGroup) { + if(useLegacyImporter) { ImportLegacy legacy(*this); legacy.setMerge(merge); legacy.loadShapes(); return nullptr; } + // Interface_Static::SetIVal("read.stepcaf.subshapes.name",1); + aShapeTool->SetAutoNaming(Standard_False); + if(FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) dumpLabels(pDoc->Main(),aShapeTool,aColorTool); @@ -573,6 +593,8 @@ App::DocumentObject* ImportOCAF2::loadShapes() myShapes.clear(); myNames.clear(); myCollapsedObjects.clear(); + myNewDocuments.clear(); + myDocumentStack.clear(); std::vector objs; aShapeTool->GetFreeShapes (labels); @@ -619,12 +641,14 @@ App::DocumentObject* ImportOCAF2::loadShapes() std::vector > objNames; for(auto obj : App::Document::getDependencyList(objs,App::Document::DepSort)) objNames.emplace_back(obj->getDocument(),obj->getNameInDocument()); - for(auto &v : objNames) - v.first->removeObject(v.second.c_str()); + for(auto rit=objNames.rbegin(); rit!=objNames.rend(); ++rit) + rit->first->removeObject(rit->second.c_str()); ret = feature; ret->recomputeFeature(true); } sequencer = nullptr; + for (auto doc : myNewDocuments) + doc->setUndoMode(1); return ret; } @@ -712,31 +736,92 @@ App::DocumentObject *ImportOCAF2::loadShape(App::Document *doc, if(baseOnly) return it->second.obj; - std::map shuoColors; - if(!useLinkGroup) - getSHUOColors(label,shuoColors,false); + if (doc != it->second.obj->getDocument()) { + // Check if we need to move the object to this document to avoid + // dependency loop + auto &info = it->second; + auto objDoc = info.obj->getDocument(); + for (auto &v : myDocumentStack) { + if (v.doc != objDoc) + continue; + // v.children is the pending children objects in upper hierarchy + // that is yet to be grouped under a new group object in that + // hierarchy. It is possible that the lower hierarchy here refers to + // one of the children in upper hierarchy. To avoid dependency loop, + // we need to move that child object to this hierarchy, and convert + // the higher hierarchy child into an App::Link. + auto res = doc->copyObject({info.obj}, true); + if (!res.empty()) { + auto copyObj = res[0]; + auto it = std::find(v.children.begin(), v.children.end(), info.obj); + if (it != v.children.end()) { + auto link = static_cast(info.obj->getDocument()->addObject("App::Link","Link")); + link->setLink(-1,copyObj); + if (info.propPlacement) + link->Placement.setValue(info.propPlacement->getValue()); + *it = link; + } + std::set objSet; + std::vector props; + std::map> newLinks; + for (auto inObj : info.obj->getInList()) { + if (inObj->getDocument()==doc || !objSet.insert(inObj).second) + continue; + props.clear(); + inObj->getPropertyList(props); + std::vector propsFound; + for (auto prop : props) { + if (prop->getContainer() != inObj) + continue; + if (auto propLink = Base::freecad_dynamic_cast(prop)) { + for (auto link : propLink->linkedObjects()) { + if (link == info.obj) + propsFound.emplace_back(prop); + } + } + } + if (propsFound.size()) { + auto link = static_cast(doc->addObject("App::Link","Link")); + link->setLink(-1,copyObj); + if (info.propPlacement) + link->Placement.setValue(info.propPlacement->getValue()); + newLinks[link] = std::move(propsFound); + } + } + for (const auto &v : newLinks) { + for (const auto &propT : v.second) { + if (auto propLink = Base::freecad_dynamic_cast(propT.getProperty())) { + std::unique_ptr copy( + propLink->CopyOnLinkReplace(propT.getObject(), info.obj, v.first)); + if (copy) + propLink->Paste(*copy); + } + } + } + info.obj->getDocument()->removeObject(info.obj->getNameInDocument()); + info.obj = copyObj; + info.propPlacement = Base::freecad_dynamic_cast( + copyObj->getPropertyByName("Placement")); + } + } + } auto info = it->second; getColor(shape,info,true); - if(shuoColors.empty() && info.free && doc==info.obj->getDocument()) { + if(info.free && doc==info.obj->getDocument()) { it->second.free = false; - auto name = getLabelName(label); - if(info.faceColor!=it->second.faceColor || - info.edgeColor!=it->second.edgeColor || - (name.size() && info.baseName.size() && name!=info.baseName)) - { - auto compound = static_cast(doc->addObject("Part::Compound2","Compound")); - compound->Links.setValue(info.obj); - // compound->Visibility.setValue(false); - info.propPlacement = &compound->Placement; - if(info.faceColor!=it->second.faceColor) - applyFaceColors(compound,{info.faceColor}); - if(info.edgeColor!=it->second.edgeColor) - applyEdgeColors(compound,{info.edgeColor}); - info.obj = compound; - setObjectName(info,label); + if(info.faceColor!=it->second.faceColor) { + info.faceColor = it->second.faceColor; + if (auto feature = Base::freecad_dynamic_cast(info.obj)) + applyFaceColors(feature,{info.faceColor}); } + if(info.edgeColor!=it->second.edgeColor) { + info.edgeColor = it->second.edgeColor; + if (auto feature = Base::freecad_dynamic_cast(info.obj)) + applyEdgeColors(feature,{info.edgeColor}); + } + setObjectName(info, label, true); setPlacement(info.propPlacement,shape); myNames.emplace(label,info.obj->getNameInDocument()); return info.obj; @@ -752,8 +837,6 @@ App::DocumentObject *ImportOCAF2::loadShape(App::Document *doc, applyLinkColor(link,-1,info.faceColor); myNames.emplace(label,link->getNameInDocument()); - if(shuoColors.size()) - applyElementColors(link,shuoColors); return link; } @@ -779,6 +862,12 @@ bool ImportOCAF2::createAssembly(App::Document *_doc, if(newDoc) doc = getDocument(_doc,label); + bool pushed = false; + if (myDocumentStack.empty() || myDocumentStack.back().doc != doc) { + pushed = true; + myDocumentStack.emplace_back(doc, children); + } + for(TopoDS_Iterator it(shape,0,0);it.More();it.Next()) { TopoDS_Shape childShape = it.Value(); if(childShape.IsNull()) @@ -818,8 +907,16 @@ bool ImportOCAF2::createAssembly(App::Document *_doc, assert(visibilities.size() == children.size()); if(children.empty()) { - if(doc!=_doc) + if(doc!=_doc) { + for (;;) { + auto it = std::find(myNewDocuments.begin(), myNewDocuments.end(), doc); + if (it == myNewDocuments.end()) + break; + myNewDocuments.erase(it); + } App::GetApplication().closeDocument(doc->getName()); + } else if (pushed) + myNewDocuments.pop_back(); return false; } @@ -870,14 +967,13 @@ bool ImportOCAF2::createAssembly(App::Document *_doc, } } - if(children.empty()) - return false; - - if(!createGroup(doc,info,shape,children,visibilities,shuoColors.empty())) - return false; - if(shuoColors.size()) + bool res = createGroup(doc,info,shape,children,visibilities,shuoColors.empty()); + if (res && shuoColors.size()) applyElementColors(info.obj,shuoColors); - return true; + + if (pushed) + myDocumentStack.pop_back(); + return res; } // ---------------------------------------------------------------------------- @@ -1206,7 +1302,7 @@ TDF_Label ExportOCAF2::exportObject(App::DocumentObject* parentObj, // retrieve OCAF computed shape, in case the current object returns // a new shape every time Part::Feature::getTopoShape() is called. auto baseShape = aShapeTool->GetShape(it->second); - shape.setShape(baseShape.Located(shape.getShape().Location())); + shape.setShape(Part::TopoShape::located(baseShape,shape.getShape().Location()),false); if(!parent.IsNull()) label = aShapeTool->AddComponent(parent,shape.getShape(),Standard_False); else @@ -1230,7 +1326,7 @@ TDF_Label ExportOCAF2::exportObject(App::DocumentObject* parentObj, if(!aShapeTool->FindShape(shape.getShape(),label)) { auto baseShape = linkedShape; auto linked = links.empty()?obj:links.back(); - baseShape.setShape(baseShape.getShape().Located(TopLoc_Location())); + baseShape.setShape(baseShape.getShape().Located(TopLoc_Location()),false); label = aShapeTool->NewShape(); aShapeTool->SetShape(label,baseShape.getShape()); setupObject(label,linked,baseShape,prefix); @@ -1245,15 +1341,15 @@ TDF_Label ExportOCAF2::exportObject(App::DocumentObject* parentObj, // because OCCT does not respect shape style sharing when not // exporting assembly if(!keepPlacement || shape.getPlacement() == Base::Placement()) - shape.setShape(shape.getShape().Located(TopLoc_Location())); + shape.setShape(shape.getShape().Located(TopLoc_Location()),false); else { Base::Matrix4D mat = shape.getTransform(); - shape.setShape(shape.getShape().Located(TopLoc_Location())); + shape.setShape(shape.getShape().Located(TopLoc_Location()),false); // Transform with copy to conceal the transformation shape.transformShape(mat, true); // Even if the shape has no transformation, TopoShape still sets // a TopLoc_Location, so we need to clear it again. - shape.setShape(shape.getShape().Located(TopLoc_Location())); + shape.setShape(shape.getShape().Located(TopLoc_Location()),false); } label = aShapeTool->AddShape(shape.getShape(),Standard_False, Standard_False); auto o = name?parentObj:obj; @@ -1337,9 +1433,13 @@ TDF_Label ExportOCAF2::exportObject(App::DocumentObject* parentObj, if (groupLinks.size() && groupLinks.back()==obj) groupLinks.pop_back(); +#if OCC_VERSION_HEX >= 0x070200 + aShapeTool->UpdateAssemblies(); +#endif + // Finished adding components. Now retrieve the computed non-located shape auto baseShape = shape; - baseShape.setShape(aShapeTool->GetShape(label)); + baseShape.setShape(aShapeTool->GetShape(label),false); myObjects.emplace(obj, label); for(auto link : links) @@ -1353,7 +1453,7 @@ TDF_Label ExportOCAF2::exportObject(App::DocumentObject* parentObj, if(!parent.IsNull()) { // If we are a component, swap in the base shape but keep our location. - shape.setShape(baseShape.getShape().Located(shape.getShape().Location())); + shape.setShape(Part::TopoShape::located(baseShape.getShape(),shape.getShape().Location()),false); label = aShapeTool->AddComponent(parent,label,shape.getShape().Location()); setupObject(label,name?parentObj:obj,shape,prefix,name); } diff --git a/src/Mod/Import/App/ImportOCAF2.h b/src/Mod/Import/App/ImportOCAF2.h index b967df5f02..5fa465787f 100644 --- a/src/Mod/Import/App/ImportOCAF2.h +++ b/src/Mod/Import/App/ImportOCAF2.h @@ -74,12 +74,12 @@ public: virtual ~ImportOCAF2(); App::DocumentObject* loadShapes(); void setMerge(bool enable) { merge=enable;}; + void setUseLegacyImporter(bool enable) { useLegacyImporter=enable; } void setUseLinkGroup(bool enable) { useLinkGroup=enable; } void setBaseName(bool enable) { useBaseName=enable; } void setImportHiddenObject(bool enable) {importHidden=enable;} void setReduceObjects(bool enable) {reduceObjects=enable;} void setShowProgress(bool enable) {showProgress=enable;} - void setExpandCompound(bool enable) {expandCompound=enable;} enum ImportMode { SingleDoc = 0, @@ -104,6 +104,8 @@ private: int free = true; }; + struct ColorInfo; + App::DocumentObject *loadShape(App::Document *doc, TDF_Label label, const TopoDS_Shape &shape, bool baseOnly=false, bool newDoc=true); App::Document *getDocument(App::Document *doc, TDF_Label label); @@ -116,9 +118,8 @@ private: const boost::dynamic_bitset<> &visibilities, bool canReduce=false); bool getColor(const TopoDS_Shape &shape, Info &info, bool check=false, bool noDefault=false); void getSHUOColors(TDF_Label label, std::map &colors, bool appendFirst); - void setObjectName(Info &info, TDF_Label label); + void setObjectName(Info &info, TDF_Label label, bool checkExistingName=false); std::string getLabelName(TDF_Label label); - App::DocumentObject *expandShape(App::Document *doc, TDF_Label label, const TopoDS_Shape &shape); virtual void applyEdgeColors(Part::Feature*, const std::vector&) {} virtual void applyFaceColors(Part::Feature*, const std::vector&) {} @@ -147,12 +148,12 @@ private: Handle(XCAFDoc_ColorTool) aColorTool; bool merge; std::string default_name; + bool useLegacyImporter; bool useLinkGroup; bool useBaseName; bool importHidden; bool reduceObjects; bool showProgress; - bool expandCompound; int mode; std::string filePath; @@ -161,6 +162,16 @@ private: std::unordered_map myNames; std::unordered_map myCollapsedObjects; + struct DocumentInfo { + App::Document *doc; + std::vector &children; + DocumentInfo(App::Document *d, std::vector &objs) + :doc(d), children(objs) + {} + }; + std::vector myDocumentStack; + std::vector myNewDocuments; + App::Color defaultFaceColor; App::Color defaultEdgeColor; diff --git a/src/Mod/Import/Gui/AppImportGuiPy.cpp b/src/Mod/Import/Gui/AppImportGuiPy.cpp index 8d6bc08038..b7b14f7c9c 100644 --- a/src/Mod/Import/Gui/AppImportGuiPy.cpp +++ b/src/Mod/Import/Gui/AppImportGuiPy.cpp @@ -297,12 +297,13 @@ private: if (!vp) return; if(colors.empty()) { - // vp->MapFaceColor.setValue(true); - // vp->MapLineColor.setValue(true); - // vp->updateColors(0,true); + vp->MapFaceColor.setValue(true); + vp->MapLineColor.setValue(true); + vp->MapTransparency.setValue(true); + vp->updateColors(0,true); return; } - // vp->MapFaceColor.setValue(false); + vp->MapFaceColor.setValue(false); if(colors.size() == 1) { vp->ShapeColor.setValue(colors.front()); vp->Transparency.setValue(100 * colors.front().a); @@ -315,7 +316,7 @@ private: auto vp = dynamic_cast(Gui::Application::Instance->getViewProvider(part)); if (!vp) return; - // vp->MapLineColor.setValue(false); + vp->MapLineColor.setValue(false); if(colors.size() == 1) vp->LineColor.setValue(colors.front()); else @@ -345,8 +346,7 @@ private: auto vp = Gui::Application::Instance->getViewProvider(obj); if(!vp) return; - (void)colors; - // vp->setElementColors(colors); + vp->setElementColors(colors); } }; @@ -399,10 +399,11 @@ private: PyObject *merge = Py_None; PyObject *useLinkGroup = Py_None; int mode = -1; - static char* kwd_list[] = {"name","docName","importHidden","merge","useLinkGroup","mode",nullptr}; - if (!PyArg_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "et|sO!O!O!i", + PyObject *legacy = Py_None; + static char* kwd_list[] = {"name","docName","importHidden","merge","useLinkGroup","mode","legacy",nullptr}; + if (!PyArg_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "et|sO!O!O!iO", kwd_list,"utf-8",&Name,&DocName,&PyBool_Type,&importHidden,&PyBool_Type,&merge, - &PyBool_Type,&useLinkGroup,&mode)) + &PyBool_Type,&useLinkGroup,&mode,&legacy)) throw Py::Exception(); std::string Utf8Name = std::string(Name); @@ -520,6 +521,8 @@ private: ocaf.setImportHiddenObject(PyObject_IsTrue(importHidden) ? true : false); if (useLinkGroup != Py_None) ocaf.setUseLinkGroup(PyObject_IsTrue(useLinkGroup) ? true : false); + if (legacy != Py_None) + ocaf.setUseLegacyImporter(PyObject_IsTrue(legacy)); ocaf.setMode(mode); auto ret = ocaf.loadShapes(); hApp->Close(hDoc);