]> OCCT Git - occt-copy.git/commitdiff
0028104: Extract sub-assembly (XDE). Added new functionality to XCAFDoc_Editor that... CR28104
authorakz <akz@opencascade.com>
Mon, 21 Nov 2016 09:18:08 +0000 (12:18 +0300)
committerakz <akz@opencascade.com>
Mon, 21 Nov 2016 09:18:08 +0000 (12:18 +0300)
src/XCAFDoc/XCAFDoc_Editor.cxx
src/XCAFDoc/XCAFDoc_Editor.hxx
src/XDEDRAW/XDEDRAW.cxx

index 89ce9da326326872714b6b7a0e8e995b136a62e5..eda583afe0567a741492be37180f3a1c7e2cdbd4 100644 (file)
 #include <XCAFDoc_Editor.hxx>
 #include <XCAFDoc.hxx>
 
+#include <BRep_Builder.hxx>
+#include <TopoDS.hxx>
+
+#include <Quantity_Color.hxx>
+#include <TDF_AttributeIterator.hxx>
+#include <TDF_ChildIterator.hxx>
 #include <TDF_Label.hxx>
 #include <TDF_LabelSequence.hxx>
-#include <TDF_ChildIterator.hxx>
+#include <TDF_RelocationTable.hxx>
 #include <TDataStd_Name.hxx>
 #include <TDataStd_UAttribute.hxx>
+#include <TDataStd_TreeNode.hxx>
+#include <TDocStd_Document.hxx>
 #include <TopLoc_Location.hxx>
 #include <TopoDS_Shape.hxx>
 
-#include <XCAFDoc_DocumentTool.hxx>
 #include <XCAFDoc_ColorTool.hxx>
+#include <XCAFDoc_DocumentTool.hxx>
+#include <XCAFDoc_GraphNode.hxx>
 #include <XCAFDoc_LayerTool.hxx>
-#include <XCAFDoc_ShapeTool.hxx>
+#include <XCAFDoc_MaterialTool.hxx>
 #include <XCAFDoc_ShapeMapTool.hxx>
+#include <XCAFDoc_ShapeTool.hxx>
 #include <XCAFDoc_Location.hxx>
 #include <TNaming_NamedShape.hxx>
 
@@ -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);
+}
index 341faeed04ee6e470ab17948e928df5067884977..a4e94762f575927dd923319014a3f0b6bf659397 100644 (file)
 #include <Standard_Boolean.hxx>
 #include <TDataStd_Name.hxx>
 #include <TDF_Label.hxx>
+#include <TDF_LabelMap.hxx>
 #include <TDF_LabelSequence.hxx>
 
+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);
 
 
 };
index 9a425cfe7d45aa422bf051633eb9ff99b95503ca..46041a81a91a65f2d097afa6ae84bedb8c3dd718 100644 (file)
@@ -70,6 +70,7 @@
 #include <XCAFDoc_DimTol.hxx>
 #include <XCAFDoc_Dimension.hxx>
 #include <XCAFDoc_Datum.hxx>
+#include <XCAFDoc_Editor.hxx>
 #include <XCAFDoc_GeomTolerance.hxx>
 #include <XCAFDoc_DocumentTool.hxx>
 #include <XCAFDoc_GraphNode.hxx>
@@ -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 );