]> OCCT Git - occt.git/commitdiff
0026302: Data Exchange - new functionality XCAFDoc_Editor::Compact() converting the... CR26302_3
authordpasukhi <dpasukhi@opencascade.com>
Tue, 26 Oct 2021 23:43:26 +0000 (02:43 +0300)
committerdpasukhi <dpasukhi@opencascade.com>
Thu, 28 Oct 2021 07:52:50 +0000 (10:52 +0300)
Added XCAFDoc_Editor::Compact method to convert from assembly shape to compound

src/XCAFDoc/XCAFDoc_Editor.cxx
src/XCAFDoc/XCAFDoc_Editor.hxx
src/XDEDRAW/XDEDRAW_Common.cxx
tests/bugs/xde/bug26302 [new file with mode: 0644]
tests/bugs/xde/bug26302_1 [new file with mode: 0644]

index dd92a88cfe2ef0592a7006ddb34572978e993eaa..9ee3d9bdb8fb02888914018e6127248c294dd5d1 100644 (file)
@@ -155,6 +155,114 @@ Standard_Boolean XCAFDoc_Editor::Expand (const TDF_Label& theDoc,
   return aResult;
 }
 
+//=======================================================================
+//function : Compact
+//purpose  : Converts assembly to compound
+//=======================================================================
+Standard_Boolean XCAFDoc_Editor::Compact(const TDF_Label& theDoc,
+                                         const TDF_Label& theAssemblyL)
+{
+  if (theAssemblyL.IsNull())
+  {
+    return Standard_False;
+  }
+  Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc);
+  TopoDS_Shape aS = aShapeTool->GetShape(theAssemblyL);
+  if (aS.IsNull() || aS.ShapeType() != TopAbs_COMPOUND || !aShapeTool->IsAssembly(theAssemblyL))
+  {
+    return Standard_False;
+  }
+  theAssemblyL.ForgetAttribute(XCAFDoc::AssemblyGUID());
+  TopoDS_Compound aCompound; // new compound for shape label
+  BRep_Builder aBuilder;
+  aBuilder.MakeCompound(aCompound);
+  // convert assembly to compound 
+  for (TDF_ChildIterator anIter(theAssemblyL); anIter.More(); anIter.Next())
+  {
+    TDF_Label aChild = anIter.Value();
+    TDF_Label aPart;
+    TopoDS_Shape aChildShape = aShapeTool->GetShape(aChild); // gets with own*ref location
+    if (!aShapeTool->GetReferredShape(aChild, aPart))
+    {
+      continue;
+    }
+    if (aChildShape.ShapeType() == TopAbs_COMPOUND && aShapeTool->IsAssembly(aPart))
+    {
+      // iterate next level if it needed
+      Compact(theDoc, aPart);
+    }
+    // get location
+    Handle(XCAFDoc_Location) aLocationAttribute;
+    aChild.FindAttribute(XCAFDoc_Location::GetID(), aLocationAttribute);
+
+    TopLoc_Location aLoc;
+    if (!aLocationAttribute.IsNull())
+    {
+      aLoc = aLocationAttribute->Get();
+    }
+    aChild.ForgetAllAttributes(Standard_False);
+    if (aChildShape.ShapeType() != TopAbs_COMPOUND)
+    {
+      //move shape
+      aShapeTool->SetShape(aChild, aChildShape);
+      aChildShape.Free(Standard_True);
+      aBuilder.Add(aCompound, aChildShape);
+      CloneMetaData(aPart, aChild, NULL);
+    }
+    // move subshapes
+    TDF_LabelSequence aSub;
+    aShapeTool->GetSubShapes(aPart, aSub);
+    for (TDF_LabelSequence::Iterator aSubIter(aSub); aSubIter.More(); aSubIter.Next())
+    {
+      TopoDS_Shape aShapeSub = aShapeTool->GetShape(aSubIter.Value()).Moved(aLoc); // gets with own*ref*father location
+      TDF_TagSource aTag;
+      TDF_Label aSubC = aTag.NewChild(theAssemblyL);
+      // set shape
+      aShapeTool->SetShape(aSubC, aShapeSub);
+      aSubC.ForgetAttribute(XCAFDoc_ShapeMapTool::GetID());
+      if (aChildShape.ShapeType() == TopAbs_COMPOUND)
+      {
+        aShapeSub.Free(Standard_True);
+        aBuilder.Add(aCompound, aShapeSub);
+      }
+      CloneMetaData(aSubIter.Value(), aSubC, NULL);
+    }
+    // if all references removed - delete all data
+    if (aShapeTool->IsFree(aPart))
+    {
+      aPart.ForgetAllAttributes();
+    }
+  }
+  aShapeTool->SetShape(theAssemblyL, aCompound);
+  aShapeTool->UpdateAssemblies();
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Compact
+//purpose  : Converts all assembly in theDoc to compound
+//=======================================================================
+Standard_Boolean XCAFDoc_Editor::Compact(const TDF_Label& theDoc)
+{
+  if (theDoc.IsNull())
+  {
+    return Standard_False;
+  }
+  Standard_Boolean aResult = Standard_False;
+  TDF_LabelSequence aShapeLabels;
+  Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc);
+  aShapeTool->GetFreeShapes(aShapeLabels);
+  for (TDF_LabelSequence::Iterator anIter(aShapeLabels); anIter.More(); anIter.Next())
+  {
+    const TDF_Label& aShapeL = anIter.Value();
+    if (Compact(theDoc, aShapeL))
+    {
+      aResult = Standard_True;
+    }
+  }
+  return aResult;
+}
+
 //=======================================================================
 //function : Extract
 //purpose  :
index 89ac8ac7cf0c92a3f097f6cf59efcd50aaa49c55..65f62d8ab9b712dcd7a3f645baf425458fe24e6c 100644 (file)
@@ -50,6 +50,22 @@ public:
   Standard_EXPORT static Standard_Boolean Expand(const TDF_Label& theDoc,
                                                  const Standard_Boolean theRecursively = Standard_True);
 
+  //! Replaces assembly's childs to referred parts with location, making simple compound.
+  //! All parts without users are removed.
+  //! This action has an opposite effect to Expand() operation
+  //! @param[in] theDoc input document
+  //! @param[in] theAssemblyL input assembly shape's label
+  //! @return True if assembly label was successful compressed
+  Standard_EXPORT static Standard_Boolean Compact(const TDF_Label& theDoc,
+                                                  const TDF_Label& theAssemblyL);
+
+  //! Converts all assembly shapes in the document to simple compounds.
+  //! All parts without users are removed.
+  //! This action has an opposite effect to Expand() operation
+  //! @param[in] theDoc input document
+  //! @return True if one or more assembly labels were successful compressed
+  Standard_EXPORT static Standard_Boolean Compact(const TDF_Label& theDoc);
+
   //! Clones all labels to a new position, keeping the structure with all the attributes
   //! @param[in] theSrcLabels original labels to copy from
   //! @param[in] theDstLabel label to set result as a component of or a main document's label to simply set new shape
index a0697110e3e4f6d83c73e203995c00e68178cdb2..15fe0d973814d2af70054c7cea20a630d75e9320 100644 (file)
@@ -693,6 +693,80 @@ static Standard_Integer Extract(Draw_Interpretor& di,
   return 0;
 }
 
+//=======================================================================
+//function : Compact
+//purpose  :
+//=======================================================================
+static Standard_Integer Compact(Draw_Interpretor& di,
+                                Standard_Integer argc,
+                                const char** argv)
+{
+  if (argc < 2)
+  {
+    di << "Syntax error: wrong number of arguments" << "\n";
+    return 1;
+  }
+  Standard_Boolean toPrintInfo = Standard_False;
+  Handle(TDocStd_Document) aDoc;
+  Handle(XCAFDoc_ShapeTool) aShapeTool;
+  TDF_LabelSequence aShLabels;
+  for (Standard_Integer anInd = 1; anInd < argc; anInd++)
+  {
+    if (TCollection_AsciiString::IsSameString(argv[anInd], "-info", false))
+    {
+      toPrintInfo = Standard_True;
+    }
+    else if (aDoc.IsNull())
+    {
+      DDocStd::GetDocument(argv[anInd], aDoc);
+      if (aDoc.IsNull())
+      {
+        di << "Syntax error: " << argv[anInd] << " is not a document" << "\n";
+        return 1;
+      }
+      aShapeTool = XCAFDoc_DocumentTool::ShapeTool(aDoc->Main());
+    }
+    else
+    {
+      TDF_Label aLabel;
+      TDF_Tool::Label(aDoc->GetData(), argv[anInd], aLabel);
+      if (aLabel.IsNull())
+      {
+        TopoDS_Shape aShape;
+        aShape = DBRep::Get(argv[anInd]);
+        aLabel = aShapeTool->FindShape(aShape);
+      }
+      if (!aLabel.IsNull())
+      {
+        aShLabels.Append(aLabel);
+      }
+      else
+      {
+        di << "Syntax error: " << argv[anInd] << " is not a shape" << "\n";
+        return 1;
+      }
+    }
+  }
+  if (aShLabels.IsEmpty())
+  {
+    if (!XCAFDoc_Editor::Compact(aDoc->Main()) && toPrintInfo)
+    {
+      di << "The document does not contain any assembly shapes" << "\n";
+    }
+  }
+  for (TDF_LabelSequence::Iterator anIter(aShLabels); anIter.More(); anIter.Next())
+  {
+    const TDF_Label& aLabel = anIter.Value();
+    if (!XCAFDoc_Editor::Compact(aDoc->Main(), aLabel) && toPrintInfo)
+    {
+      TCollection_AsciiString anEntry;
+      TDF_Tool::Entry(aLabel, anEntry);
+      di << anEntry << " is not assembly" << "\n";
+    }
+  }
+  return 0;
+}
+
 //=======================================================================
 //function : WriteVrml
 //purpose  : Write DECAF document to Vrml
@@ -764,6 +838,10 @@ void XDEDRAW_Common::InitCommands(Draw_Interpretor& di)
   di.Add("XExtract", "XExtract dstDoc [dstAssmblSh] srcDoc srcLabel1 srcLabel2 ...\t"
     "Extracts given srcLabel1 srcLabel2 ... from srcDoc into given Doc or assembly shape",
     __FILE__, Extract, g);
+  di.Add("XCompact", "XCompact [-info] Doc [{shLabel1 shLabel2 ...}|{shape1 shape2 ...}]\t"
+    "Converts assembly shapes to compound shapes on the all document or selected labels or shapes\t"
+    "  -info print information about skipped simple shapes"
+    __FILE__, Compact, g);
 
   di.Add("WriteVrml", "Doc filename [version VRML#1.0/VRML#2.0 (1/2): 2 by default] [representation shaded/wireframe/both (0/1/2): 0 by default]", __FILE__, WriteVrml, g);
 
diff --git a/tests/bugs/xde/bug26302 b/tests/bugs/xde/bug26302
new file mode 100644 (file)
index 0000000..21ca2f5
--- /dev/null
@@ -0,0 +1,85 @@
+puts "============================================================================"
+puts " 0026302: Data Exchange - new functionality XCAFDoc_Editor::Compact() converting the assembly to compound"
+puts "============================================================================"
+puts ""
+
+pload DCAF
+
+# Trims spaces and removed empty lines within multi-line string
+proc trimmedString { theString } {
+  set aString {}
+  foreach aLineIter [split $theString "\n"] { set aLine [string trimright $aLineIter]; if { $aLine != "" } { lappend aString $aLine } }
+  return [join $aString "\n"]
+}
+
+Close D -silent
+
+box b1 0 0 0 10 10 10 
+box b2 10 0 0 10 10 10 
+box b3 20 0 0 10 10 10 
+explode b1
+explode b2
+explode b3
+explode b1_1
+explode b2_1
+explode b3_1
+compound b1 b2 c1
+compound c1 b3 c2
+XNewDoc D
+XAddShape D c2 1
+XSetColor D b1 1 0 0 
+XSetColor D b2 0 1 0 
+XSetColor D b3 0 0 1 
+XSetColor D b1_1_4 1 1 0 
+XSetColor D b2_1_4 0 1 1 
+XSetColor D b3_1_4 1 0 1
+XSetColor D b1_1_3 1 0 1 
+XSetColor D b2_1_3 1 1 0 
+XSetColor D b3_1_3 0 1 1
+
+# Input structure of the document
+# ASSEMBLY COMPOUND 0:1:1:1 "ASSEMBLY"
+#         INSTANCE COMPOUND 0:1:1:1:1 (refers to 0:1:1:2) "=>[0:1:1:2]"
+#         INSTANCE SOLID 0:1:1:1:2 (refers to 0:1:1:5) "=>[0:1:1:5]"
+# ASSEMBLY COMPOUND 0:1:1:2 "ASSEMBLY"
+#         INSTANCE SOLID 0:1:1:2:1 (refers to 0:1:1:3) "=>[0:1:1:3]"
+#         INSTANCE SOLID 0:1:1:2:2 (refers to 0:1:1:4) "=>[0:1:1:4]"
+# PART SOLID 0:1:1:3 "SOLID"
+#         FACE 0:1:1:3:1
+#         FACE 0:1:1:3:2
+# PART SOLID 0:1:1:4 "SOLID"
+#         FACE 0:1:1:4:1
+#         FACE 0:1:1:4:2
+# PART SOLID 0:1:1:5 "SOLID"
+#         FACE 0:1:1:5:1
+#         FACE 0:1:1:5:2
+# Free Shapes: 1
+# ASSEMBLY COMPOUND  0:1:1:1 "ASSEMBLY"
+
+# Compress all shapes in the document
+XCompact D 
+
+# Output structure of the document
+set THE_REF_DUMP {
+PART COMPOUND 0:1:1:1 "ASSEMBLY" 
+       SOLID 0:1:1:1:2 "SOLID" 
+       SOLID 0:1:1:1:3 "SOLID" 
+       SOLID 0:1:1:1:4 "SOLID" 
+       FACE 0:1:1:1:5 "FACE" 
+       FACE 0:1:1:1:6 "FACE" 
+       FACE 0:1:1:1:7 "FACE" 
+       FACE 0:1:1:1:8 "FACE" 
+       FACE 0:1:1:1:9 "FACE" 
+       FACE 0:1:1:1:10 "FACE" 
+Free Shapes: 1
+PART COMPOUND  0:1:1:1 "ASSEMBLY" 
+}
+
+# Checking
+if { [trimmedString "[uplevel #0 Xdump D]"] != [trimmedString $THE_REF_DUMP] } {
+  puts "Error: incorrect document structure"
+}
+if { [regexp "Number of labels with color link = 9" [XStat D]] != 1 } {
+  puts "Error: incorrect attributes"
+}
+Close D -silent
diff --git a/tests/bugs/xde/bug26302_1 b/tests/bugs/xde/bug26302_1
new file mode 100644 (file)
index 0000000..175064b
--- /dev/null
@@ -0,0 +1,17 @@
+puts "============================================================================"
+puts " 0026302: Data Exchange - new functionality XCAFDoc_Editor::Compact() converting the assembly to compound"
+puts "============================================================================"
+puts ""
+
+pload DCAF
+
+Close D -silent
+
+ReadStep D [locate_data_file trj6_as1-ec-214.stp]
+XGetOneShape origin D
+XCompact D
+XGetOneShape comp D
+
+checkprops origin -equal comp
+
+Close D -silent