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))
+ {
+ 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);
+ 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 :
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
return 0;
}
+//=======================================================================
+//function : Compact
+//purpose :
+//=======================================================================
+static Standard_Integer Compact(Draw_Interpretor& di,
+ Standard_Integer argc,
+ const char** argv)
+{
+ if (argc < 2)
+ {
+ di << "Use: " << argv[0] << " [-info] Doc [{shLabel1 shLabel2 ...}|{shape1 shape2 ...}]" << "\n";
+ return 1;
+ }
+ Standard_Integer anArgcInd = 1;
+ Standard_Boolean toPrintInfo = Standard_False;
+ if (argc > 2)
+ {
+ TCollection_AsciiString aFirstArg(argv[anArgcInd]);
+ aFirstArg.LowerCase();
+ if (aFirstArg.IsEqual("-info"))
+ {
+ toPrintInfo = Standard_True;
+ anArgcInd++;
+ }
+ }
+ Handle(TDocStd_Document) aDoc;
+ DDocStd::GetDocument(argv[anArgcInd], aDoc);
+ if (aDoc.IsNull())
+ {
+ di << "Syntax error: " << argv[anArgcInd] << " is not a document" << "\n";
+ return 1;
+ }
+ if (argc == 2)
+ {
+ if (!XCAFDoc_Editor::Compact(aDoc->Main()) && toPrintInfo)
+ {
+ di << "The document does not contain any assembly shapes" << "\n";
+ }
+ }
+ else
+ {
+ Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(aDoc->Main());
+ for (Standard_Integer anInd = anArgcInd + 1; anInd < argc; anInd++)
+ {
+ 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())
+ {
+ if (!XCAFDoc_Editor::Compact(aDoc->Main(), aLabel) && toPrintInfo)
+ {
+ di << argv[anInd] << " is not assembly" << "\n";
+ // continue iteration
+ }
+ }
+ else
+ {
+ di << "Syntax error: " << argv[anInd] << " is not a shape" << "\n";
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
//=======================================================================
//function : WriteVrml
//purpose : Write DECAF document to Vrml
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);
--- /dev/null
+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
--- /dev/null
+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