From: akz Date: Mon, 21 Nov 2016 09:18:08 +0000 (+0300) Subject: 0028104: Extract sub-assembly (XDE). Added new functionality to XCAFDoc_Editor that... X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=bd34f77a0ad2f6ce4486c2734d82756f3df8f477;p=occt-copy.git 0028104: Extract sub-assembly (XDE). Added new functionality to XCAFDoc_Editor that extracts labels and put them as components of the specified label --- diff --git a/src/XCAFDoc/XCAFDoc_Editor.cxx b/src/XCAFDoc/XCAFDoc_Editor.cxx index 89ce9da326..eda583afe0 100644 --- a/src/XCAFDoc/XCAFDoc_Editor.cxx +++ b/src/XCAFDoc/XCAFDoc_Editor.cxx @@ -16,19 +16,29 @@ #include #include +#include +#include + +#include +#include +#include #include #include -#include +#include #include #include +#include +#include #include #include -#include #include +#include +#include #include -#include +#include #include +#include #include #include @@ -128,6 +138,118 @@ Standard_Boolean XCAFDoc_Editor::Expand (const TDF_Label& Doc, const Standard_Bo return result; } +//======================================================================= +//function : ExtractAttributes +//purpose : +//======================================================================= + +void XCAFDoc_Editor::ExtractAttributes(const TDF_Label theOld, TDF_Label& theNew) +{ + if (theOld.IsEqual(theNew)) + return; + + // Color + Handle(XCAFDoc_ColorTool) aNewColorTool = XCAFDoc_DocumentTool::ColorTool(theNew); + Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(theOld); + Quantity_Color aColor; + if (aColorTool->GetColor(theOld, XCAFDoc_ColorSurf, aColor)) + aNewColorTool->SetColor(theNew, aColor, XCAFDoc_ColorSurf); + if (aColorTool->GetColor(theOld, XCAFDoc_ColorCurv, aColor)) + aNewColorTool->SetColor(theNew, aColor, XCAFDoc_ColorCurv); + if (aColorTool->GetColor(theOld, XCAFDoc_ColorGen, aColor)) + aNewColorTool->SetColor(theNew, aColor, XCAFDoc_ColorGen); + if (!aColorTool->IsVisible(theOld)) + aNewColorTool->SetVisibility(theNew, Standard_False); + + // Layer + Handle(XCAFDoc_LayerTool) aNewLayerTool = XCAFDoc_DocumentTool::LayerTool(theNew); + Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool(theOld); + Handle(TColStd_HSequenceOfExtendedString) aLayers; + aLayerTool->GetLayers(theOld, aLayers); + for (int j = 1; j <= aLayers->Length(); j++) + { + aNewLayerTool->SetLayer(theNew, aLayers->Value(j)); + } + + // Material + Handle(XCAFDoc_MaterialTool) aNewMatTool = XCAFDoc_DocumentTool::MaterialTool(theNew); + Handle(XCAFDoc_MaterialTool) aMatTool = XCAFDoc_DocumentTool::MaterialTool(theOld); + Handle(TDataStd_TreeNode) aMatNode; + if (theOld.FindAttribute(XCAFDoc::MaterialRefGUID(), aMatNode) && aMatNode->HasFather()) + { + TDF_Label aMatL = aMatNode->Father()->Label(); + Handle(TCollection_HAsciiString) aName; + Handle(TCollection_HAsciiString) aDescription; + Standard_Real aDensity; + Handle(TCollection_HAsciiString) aDensName; + Handle(TCollection_HAsciiString) aDensValType; + if (aMatTool->GetMaterial(aMatL, aName, aDescription, aDensity, aDensName, aDensValType)) + { + if (aName->Length() != 0) + aNewMatTool->SetMaterial(theNew, aName, aDescription, aDensity, aDensName, aDensValType); + } + } + + // Attributes + Handle(TDF_Attribute) tAtt; + // Finds the target attributes or creates them empty. + for (TDF_AttributeIterator attItr(theOld); attItr.More(); attItr.Next()) + { + const Handle(TDF_Attribute) sAtt = attItr.Value(); + // protect against color and layer coping without link to colors and layers. + if (sAtt->IsKind(STANDARD_TYPE(TDataStd_TreeNode)) || sAtt->IsKind(STANDARD_TYPE(XCAFDoc_GraphNode))) + continue; + // do not copy shape, it is already copied + if (sAtt->IsKind(STANDARD_TYPE(TNaming_NamedShape))) + continue; + const Standard_GUID& id = sAtt->ID(); + if (!theNew.FindAttribute(id, tAtt)) + { + tAtt = sAtt->NewEmpty(); + theNew.AddAttribute(tAtt); + } + Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable(); + sAtt->Paste(tAtt, aRT); + } +} + +//======================================================================= +//function : ExtractSubAssembly +//purpose : +//======================================================================= + +void XCAFDoc_Editor::ExtractSubAssembly (const TDF_LabelSequence& theSrcLabels, const TDF_Label theDstLabel) +{ + Handle(XCAFDoc_ShapeTool) aNewShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDstLabel); + + // Get original label + TDF_Label aDstAssembly; + if (!aNewShapeTool->GetReferredShape(theDstLabel, aDstAssembly)) + aDstAssembly = theDstLabel; + + // Copy an each original shape to the new document + TDF_LabelSequence::Iterator it(theSrcLabels); + for (; it.More(); it.Next()) + { + TDF_Label aRefLabel, aLabel = it.Value(); + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(aLabel); + if (!aShapeTool->GetReferredShape(aLabel, aRefLabel)) + aRefLabel = aLabel; + + TopoDS_Shape anOriginalShape = aShapeTool->GetShape(aRefLabel); + Standard_Boolean isAssembly = aShapeTool->IsAssembly(aRefLabel); + + TDF_Label aNewLabel = aNewShapeTool->AddShape(anOriginalShape, isAssembly); + TDF_LabelMap aMap; + copyLabel(aRefLabel, aNewLabel, aMap); + + TopLoc_Location aLoc; + if (aLabel != aRefLabel) + aLoc = aShapeTool->GetLocation(aLabel); + aNewShapeTool->AddComponent(aDstAssembly, aNewLabel, aLoc); + } +} + //======================================================================= //function : getParams //purpose : Get colors layers and name @@ -213,4 +335,76 @@ Standard_Boolean XCAFDoc_Editor::setParams (const TDF_Label& Doc, const TDF_Labe TDataStd_Name::Set(Label, TCollection_ExtendedString(aName)); } return Standard_True; -} \ No newline at end of file +} + +//======================================================================= +//function : copyLabel +//purpose : +//======================================================================= + +void XCAFDoc_Editor::copyLabel(const TDF_Label& theOld, TDF_Label& theNew, TDF_LabelMap& theMap) +{ + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theOld); + Handle(XCAFDoc_ShapeTool) aNewShapeTool = XCAFDoc_DocumentTool::ShapeTool(theNew); + ExtractAttributes(theOld, theNew); + + TDF_Label anOld = theOld; + if (aShapeTool->IsReference(anOld)) + aShapeTool->GetReferredShape(anOld, anOld); + if (!theMap.Add(anOld)) + return; + TDF_Label aNew = theNew; + if (aNewShapeTool->IsReference(aNew)) + aNewShapeTool->GetReferredShape(aNew, aNew); + + TDF_LabelSequence anOldComp, aNewComp; + if (aShapeTool->IsAssembly(anOld)) + aShapeTool->GetComponents(anOld, anOldComp); + else + aShapeTool->GetSubShapes(anOld, anOldComp); + if (aShapeTool->IsAssembly(anOld) && !aNewShapeTool->IsAssembly(aNew)) + { + aNewShapeTool->Expand(aNew); + } + else if (!aShapeTool->IsAssembly(anOld)) + { + if (aNewShapeTool->IsAssembly(aNew)) + { + // clear assembly structure + TDF_LabelSequence aSeq; + aNewShapeTool->GetComponents(aNew, aSeq); + for (Standard_Integer i = aSeq.Lower(); i <= aSeq.Upper(); i++) + { + TDF_Label aCompLabel; + aNewShapeTool->GetReferredShape(aSeq.Value(i), aCompLabel); + aNewShapeTool->RemoveComponent(aSeq.Value(i)); + aNewShapeTool->RemoveShape(aCompLabel); + } + Handle(TDataStd_UAttribute) anUattr; + aNew.FindAttribute(XCAFDoc::AssemblyGUID(), anUattr); + aNew.ForgetAttribute(anUattr->ID()); + aNewShapeTool->SetShape(aNew, aShapeTool->GetShape(anOld)); + } + + for (int i = anOldComp.Lower(); i <= anOldComp.Upper(); i++) + { + aNewShapeTool->AddSubShape(aNew, aShapeTool->GetShape(anOldComp.Value(i))); + } + } + + if (aNewShapeTool->IsAssembly(aNew)) + aNewShapeTool->GetComponents(aNew, aNewComp); + else + aNewShapeTool->GetSubShapes(aNew, aNewComp); + + if (anOldComp.Length() == aNewComp.Length()) + { + for (Standard_Integer i = 1; i <= anOldComp.Length(); i++) + { + TDF_Label aNewL = aNewComp.Value(i); + TDF_Label anOldL = anOldComp.Value(i); + copyLabel(anOldL, aNewL, theMap); + } + } + ExtractAttributes(anOld, aNew); +} diff --git a/src/XCAFDoc/XCAFDoc_Editor.hxx b/src/XCAFDoc/XCAFDoc_Editor.hxx index 341faeed04..a4e94762f5 100644 --- a/src/XCAFDoc/XCAFDoc_Editor.hxx +++ b/src/XCAFDoc/XCAFDoc_Editor.hxx @@ -23,8 +23,10 @@ #include #include #include +#include #include +class TDocStd_Document; //! Tool for edit structure of document. @@ -41,8 +43,11 @@ public: //! Convert all compounds in Doc to assembly Standard_EXPORT static Standard_Boolean Expand (const TDF_Label& Doc, const Standard_Boolean recursively = Standard_True) ; + //! Extracts attributes (including colors, materials and layers) of theOld label and copy to theNew + Standard_EXPORT static void ExtractAttributes (const TDF_Label theOld, TDF_Label& theNew); - + //! Extracts passed labels and put them as a component of theDstLabel + Standard_EXPORT static void ExtractSubAssembly (const TDF_LabelSequence& theSrcLabels, const TDF_Label theDstLabel); protected: @@ -59,7 +64,8 @@ private: //! Set colors, layers and name from Label Standard_EXPORT static Standard_Boolean setParams (const TDF_Label& Doc, const TDF_Label& Label, const TDF_LabelSequence& Colors, const TDF_LabelSequence& Layers, const Handle(TDataStd_Name)& Name) ; - + //! + Standard_EXPORT static void copyLabel (const TDF_Label& theOld, TDF_Label& theNew, TDF_LabelMap& theMap); }; diff --git a/src/XDEDRAW/XDEDRAW.cxx b/src/XDEDRAW/XDEDRAW.cxx index 9a425cfe7d..46041a81a9 100644 --- a/src/XDEDRAW/XDEDRAW.cxx +++ b/src/XDEDRAW/XDEDRAW.cxx @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -1050,6 +1051,56 @@ static Standard_Integer testDoc (Draw_Interpretor&, return 0; } +//======================================================================= +//function : extructSubAssembly +//purpose : +//======================================================================= +static Standard_Integer extractSubAssembly (Draw_Interpretor& di, + Standard_Integer argc, + const char** argv) +{ + if (argc != 5) + { + di.PrintHelp("XExtract"); + return 1; + } + + Handle(TDocStd_Document) aSrcDoc, aDstDoc; + DDocStd::GetDocument (argv[1], aSrcDoc); + if (aSrcDoc.IsNull()) + { + di << argv[1] << " is not a document\n"; + return 1; + } + + DDocStd::GetDocument (argv[3], aDstDoc); + if (aDstDoc.IsNull()) + { + di << argv[3] << " is not a document\n"; + return 1; + } + + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (aSrcDoc->Main()); + + TDF_Label aSrcLabel, aDstLabel; + TDF_Tool::Label(aSrcDoc->GetData(), argv[2], aSrcLabel); + if (aSrcLabel.IsNull() || !aShapeTool->IsShape ( aSrcLabel )) + { + di << argv[2] << "[" << argv[1] << "] is not a valid label\n"; + return 1; + } + + TDF_Tool::Label(aDstDoc->GetData(), argv[4], aDstLabel); + if (aDstLabel.IsNull() || !aShapeTool->IsShape ( aSrcLabel )) + { + di << argv[4] << "[" << argv[3] << "] is not a valid label\n"; + return 1; + } + + TDF_LabelSequence aSeq; aSeq.Append(aSrcLabel); + XCAFDoc_Editor::ExtractSubAssembly(aSeq, aDstLabel); + return 0; +} //======================================================================= //function : Init @@ -1122,6 +1173,11 @@ void XDEDRAW::Init(Draw_Interpretor& di) __FILE__, XShowFaceBoundary, g); di.Add ("XTestDoc", "XTestDoc shape", __FILE__, testDoc, g); + di.Add ("XExtract", + "XExtract SrcDoc SrcLabel DstDoc DstLabel\t: " + "Extracts given SrcLabel from SrcDoc into given DstLabel of DstDoc", + __FILE__, extractSubAssembly, g); + // Specialized commands XDEDRAW_Shapes::InitCommands ( di ); XDEDRAW_Colors::InitCommands ( di );