// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#include <XCAFDoc_ShapeTool.ixx>
-#include <XCAFDoc.hxx>
+#include <XCAFDoc_ShapeTool.hxx>
-#include <TDF_Tool.hxx>
+#include <BRep_Builder.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Trsf.hxx>
+#include <Standard_GUID.hxx>
+#include <Standard_Type.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TCollection_ExtendedString.hxx>
+#include <TCollection_HAsciiString.hxx>
+#include <TColStd_SequenceOfHAsciiString.hxx>
+#include <TDataStd_ChildNodeIterator.hxx>
+#include <TDataStd_Name.hxx>
+#include <TDataStd_TreeNode.hxx>
+#include <TDataStd_UAttribute.hxx>
+#include <TDF_Attribute.hxx>
+#include <TDF_ChildIDIterator.hxx>
+#include <TDF_ChildIterator.hxx>
#include <TDF_Label.hxx>
#include <TDF_LabelMap.hxx>
#include <TDF_LabelSequence.hxx>
-#include <TDF_ChildIterator.hxx>
-#include <TDF_ChildIDIterator.hxx>
#include <TDF_MapIteratorOfLabelMap.hxx>
-
-#include <TDataStd_Name.hxx>
-#include <TDataStd_TreeNode.hxx>
-#include <TDataStd_ChildNodeIterator.hxx>
-#include <TDataStd_UAttribute.hxx>
-
+#include <TDF_RelocationTable.hxx>
+#include <TDF_Tool.hxx>
#include <TDocStd_Document.hxx>
-
#include <TNaming_Builder.hxx>
#include <TNaming_NamedShape.hxx>
#include <TNaming_Tool.hxx>
-
+#include <TopLoc_IndexedMapOfLocation.hxx>
#include <TopLoc_Location.hxx>
+#include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
-#include <TopoDS_Compound.hxx>
-#include <BRep_Builder.hxx>
-#include <XCAFDoc_Location.hxx>
-
-#include <TCollection_AsciiString.hxx>
-#include <TCollection_HAsciiString.hxx>
-#include <TCollection_ExtendedString.hxx>
-#include <TColStd_SequenceOfHAsciiString.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfOrientedShape.hxx>
+#include <XCAFDoc.hxx>
#include <XCAFDoc_GraphNode.hxx>
-#include <TopLoc_IndexedMapOfLocation.hxx>
-#include <gp_Trsf.hxx>
-#include <gp_Pnt.hxx>
+#include <XCAFDoc_Location.hxx>
#include <XCAFDoc_ShapeMapTool.hxx>
+IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_ShapeTool,TDF_Attribute)
+
static Standard_Boolean theAutoNaming = Standard_True;
// attribute methods //////////////////////////////////////////////////
Handle(TDataStd_TreeNode) Node;
if (! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
! Node->HasFather()) {
- cout<<"Error: XCAFDoc_ShapeTool, SetLabelNameByLink(): NO NODE"<<endl;
+#ifdef OCCT_DEBUG
+ std::cout<<"Error: XCAFDoc_ShapeTool, SetLabelNameByLink(): NO NODE"<<std::endl;
+#endif
return;
}
TCollection_AsciiString Entry;
if (TNaming_Tool::HasLabel(Label(), S0)) {
int TransDef = 0;
L = TNaming_Tool::Label(Label(), S0, TransDef);
- return Standard_True;
}
-/*
- TDF_ChildIDIterator it(myLabel,TNaming_NamedShape::GetID());
+ else
+ return Standard_False;
+
+ if (IsTopLevel(L))
+ return Standard_True;
+
+ // Try to find shape manually
+ TDF_ChildIDIterator it(Label(), TNaming_NamedShape::GetID());
for (; it.More(); it.Next()) {
TDF_Label aLabel = it.Value()->Label();
Handle(TNaming_NamedShape) NS;
if ( aLabel.FindAttribute(TNaming_NamedShape::GetID(), NS) &&
- S0.IsSame ( TNaming_Tool::GetShape(NS) ) ) {
+ S0.IsSame ( TNaming_Tool::GetShape(NS) ) ) {
L = aLabel;
return Standard_True;
}
}
-*/
+
+ L = TDF_Label();
return Standard_False;
}
const Standard_Boolean findInstance) const
{
TDF_Label L;
- FindShape ( S, L, findInstance );
- return L;
+ if (FindShape(S, L, findInstance))
+ return L;
+ return TDF_Label();
}
//=======================================================================
if(!myShapeLabels.IsBound(S)) {
myShapeLabels.Bind(S,L);
}
-
- //:abv 31.10.01: update assemblies that refer a shape
- TDF_LabelSequence Labels;
- if ( GetUsers ( L, Labels, Standard_True ) ) {
- for ( Standard_Integer i=Labels.Length(); i >=1; i-- )
- UpdateAssembly ( Labels(i) );
- }
}
//=======================================================================
TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
const TDF_Label& compL,
- const TopLoc_Location &Loc) const
+ const TopLoc_Location &Loc)
{
TDF_Label L;
L = aTag.NewChild(assembly);
MakeReference ( L, compL, Loc );
- // update assembly`s TopoDS_Shape
- UpdateAssembly ( assembly );
+ // map shape to label
+ TopoDS_Shape aShape;
+ if (GetShape(L, aShape))
+ {
+ if (!myShapeLabels.IsBound(aShape))
+ myShapeLabels.Bind(aShape, L);
+ }
+
return L;
}
void XCAFDoc_ShapeTool::RemoveComponent (const TDF_Label& comp) const
{
- if ( IsComponent(comp) ) {
+ if ( IsComponent(comp) )
+ {
comp.ForgetAllAttributes();
- UpdateAssembly(comp.Father());
}
}
//=======================================================================
-//function : UpdateAssembly
+//function : UpdateAssemblies
//purpose :
//=======================================================================
-void XCAFDoc_ShapeTool::UpdateAssembly (const TDF_Label& L) const
+void XCAFDoc_ShapeTool::UpdateAssemblies()
{
- if ( ! IsAssembly(L) ) return;
-
- TopoDS_Compound newassembly;
- BRep_Builder b;
- b.MakeCompound(newassembly);
+ // We start from the free shapes (roots in the assembly structure)
+ TDF_LabelSequence aRootLabels;
+ GetFreeShapes(aRootLabels);
- TDF_ChildIterator chldLabIt(L);
- for (; chldLabIt.More(); chldLabIt.Next() ) {
- TDF_Label subLabel = chldLabIt.Value();
- if ( IsComponent ( subLabel ) ) {
- b.Add(newassembly, GetShape(subLabel));
+ // Iterate over the free shapes
+ TDF_LabelMap anUpdated;
+ for ( TDF_LabelSequence::Iterator anIt(aRootLabels); anIt.More(); anIt.Next() )
+ {
+ TDF_Label aRefLabel = anIt.Value();
+ if (IsReference(aRefLabel))
+ {
+ GetReferredShape(aRefLabel, aRefLabel);
}
+ const TDF_Label& aRootLab = aRefLabel;
+ TopoDS_Shape anAssemblyShape;
+ updateComponent(aRootLab, anAssemblyShape, anUpdated);
}
- TNaming_Builder tnBuild(L);
- tnBuild.Generated(newassembly);
}
//=======================================================================
const TopoDS_Shape &sub) const
{
Handle(XCAFDoc_ShapeMapTool) A;
- if ( ! shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) )
- return Standard_False;
-
- //TopoDS_Shape S = GetShape ( shapeL );
- //return ! S.IsNull() && CheckSubShape ( S, sub );
+ if (!shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A))
+ {
+ TopoDS_Shape aShape = GetShape(shapeL);
+ if (aShape.IsNull())
+ return Standard_False;
+ A = XCAFDoc_ShapeMapTool::Set(shapeL);
+ A->SetShape(aShape);
+ }
return A->IsSubShape(sub);
}
const TopoDS_Shape &sub,
TDF_Label &L) const
{
- // this code is used instead of the following for performance reasons
- if ( TNaming_Tool::HasLabel(Label(), sub) ) {
+ if (sub.IsNull())
+ return Standard_False;
+
+ if (TNaming_Tool::HasLabel(Label(), sub)) {
int TransDef = 0;
L = TNaming_Tool::Label(Label(), sub, TransDef);
- return ( ! L.IsNull() && L.Father() == shapeL );
+ if (L.IsNull())
+ return Standard_False;
+ if (L.Father() == shapeL)
+ return Standard_True;
+ }
+ else
+ {
+ return Standard_False;
}
-/*
- TDF_ChildIterator chldLabIt(shapeL);
- for (; chldLabIt.More(); chldLabIt.Next() ) {
- TDF_Label subLabel = chldLabIt.Value();
- TopoDS_Shape S;
- if ( GetShape ( subLabel, S ) && S.IsSame ( sub ) ) {
- L = subLabel;
+ // if subshape was found wrong, try to do it manually
+ // it can be possible if several part shapes has the same subshapes
+ L = TDF_Label();
+ TDF_ChildIterator aChldLabIt(shapeL);
+ for (; aChldLabIt.More(); aChldLabIt.Next() ) {
+ TDF_Label aSubLabel = aChldLabIt.Value();
+ Handle(TNaming_NamedShape) NS;
+ if (!aSubLabel.FindAttribute(TNaming_NamedShape::GetID(), NS))
+ continue;
+ TopoDS_Shape aSubShape = TNaming_Tool::GetShape(NS);
+ if (!aSubShape.IsNull() && aSubShape.IsSame(sub)) {
+ L = aSubLabel;
return Standard_True;
}
}
-*/
+
return Standard_False;
}
const TopoDS_Shape &sub) const
{
TDF_Label L;
+ if (!IsSimpleShape(shapeL) || !IsTopLevel(shapeL))
+ return L;
+
if ( FindSubShape ( shapeL, sub, L ) ) return L;
- if ( ! IsSubShape ( shapeL, sub ) ) return L;
+ if (!IsSubShape(shapeL, sub))
+ return TDF_Label();
TDF_TagSource aTag;
L = aTag.NewChild(shapeL);
TNaming_Builder tnBuild(L);
tnBuild.Generated(sub);
-// if(!mySubShapes.IsBound(sub))
-// mySubShapes.Bind(sub,L);
-
return L;
}
+//=======================================================================
+//function : AddSubShape
+//purpose :
+//=======================================================================
+
+Standard_Boolean XCAFDoc_ShapeTool::AddSubShape(const TDF_Label &shapeL,
+ const TopoDS_Shape &sub,
+ TDF_Label &addedSubShapeL) const
+{
+ addedSubShapeL = TDF_Label();
+ // Check if adding subshape is possible
+ if (!IsSimpleShape(shapeL) || !IsTopLevel(shapeL))
+ return Standard_False;
+
+ // Try to find already existed subshape
+ if (FindSubShape(shapeL, sub, addedSubShapeL))
+ return Standard_False;
+
+ if (!IsSubShape(shapeL, sub))
+ return Standard_False;
+
+ TDF_TagSource aTag;
+ addedSubShapeL = aTag.NewChild(shapeL);
+ TNaming_Builder tnBuild(addedSubShapeL);
+ tnBuild.Generated(sub);
+
+ return Standard_True;
+}
+
//=======================================================================
//function : FindMainShapeUsingMap
TDF_ChildIterator it(Label());
for (; it.More(); it.Next()) {
TDF_Label L = it.Value();
- if ( ! IsAssembly ( L ) && IsSubShape ( L, sub ) ) return L;
+
+ if ( IsSimpleShape( L ) && IsSubShape ( L, sub ) ) return L;
}
TDF_Label L0;
return L0;
//purpose : recursive part of Dump()
//=======================================================================
-static void DumpAssembly(const TDF_Label L,
+static void DumpAssembly(Standard_OStream& theDumpLog,
+ const TDF_Label L,
const Standard_Integer level,
const Standard_Boolean deep)
{
+ TopoDS_Shape S;
+ XCAFDoc_ShapeTool::GetShape(L, S);
+ if(S.IsNull())
+ return;
for (Standard_Integer i=0; i<level; i++)
- cout<<"\t";
+ theDumpLog<<"\t";
TCollection_AsciiString Entry;
TDF_Tool::Entry(L, Entry);
+
+ if(XCAFDoc_ShapeTool::IsAssembly(L))
+ {
+ theDumpLog<<"ASSEMBLY ";
+ }
+ else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
+ {
+ if(L.Father().Father().Father().IsRoot())
+ theDumpLog<<"PART ";
+ }
+ else
+ {
+ theDumpLog<<"INSTANCE ";
+ }
+ TopAbs::Print(S.ShapeType(), theDumpLog);
- cout<<"ASSEMBLY "<<Entry;
+ theDumpLog<<" "<<Entry;
+ if(XCAFDoc_ShapeTool::IsReference(L))
+ {
+ Handle(TDataStd_TreeNode) aRef;
+ L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
+ TDF_Tool::Entry(aRef->Father()->Label(), Entry);
+ theDumpLog<<" (refers to "<<Entry<<")";
+ }
Handle(TDataStd_Name) Name;
if (L.FindAttribute(TDataStd_Name::GetID(), Name))
- cout<<" "<<Name->Get();
+ theDumpLog<<" \""<<Name->Get()<<"\" ";
if (deep) {
- TopoDS_Shape S;
- XCAFDoc_ShapeTool::GetShape(L, S);
- cout<<"("<<*(void**)&S.TShape();
+ theDumpLog<<"("<<*(void**)&S.TShape();
if (! S.Location().IsIdentity())
- cout<<", "<< *(void**)&S.Location();
- cout<<") ";
+ theDumpLog<<", "<< *(void**)&S.Location();
+ theDumpLog<<") ";
}
- cout<<endl;
+ theDumpLog<<std::endl;
Handle(TDataStd_TreeNode) Node;
- TDF_ChildIDIterator NodeIterator(L, XCAFDoc::ShapeRefGUID());
+ TDF_ChildIterator NodeIterator(L);
for (; NodeIterator.More(); NodeIterator.Next()) {
- Node = Handle(TDataStd_TreeNode)::DownCast(NodeIterator.Value());
- if (Node->HasFather()) {
- if (Node->Father()->Label().HasChild())
- DumpAssembly(Node->Father()->Label(), level+1, deep);
- else {
- XCAFDoc_ShapeTool::DumpShape(Node->Father()->Label(), level+1, deep);
- cout<<endl;
- }
- }
+ DumpAssembly(theDumpLog, NodeIterator.Value(), level+1, deep);
}
+ if(level == 0)
+ theDumpLog<<std::endl;
}
//=======================================================================
//purpose :
//=======================================================================
-void XCAFDoc_ShapeTool::Dump(const Standard_Boolean deep) const
+Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog, const Standard_Boolean deep) const
{
Standard_Integer level = 0;
// TopTools_SequenceOfShape SeqShapes;
TDF_LabelSequence SeqLabels;
GetShapes( SeqLabels);
- if (SeqLabels.Length()>0) cout<<endl;
+ if (SeqLabels.Length()>0) theDumpLog<<std::endl;
Standard_Integer i;
for (i=1; i<=SeqLabels.Length(); i++) {
- DumpAssembly(SeqLabels.Value(i), level, deep);
+ DumpAssembly(theDumpLog, SeqLabels.Value(i), level, deep);
}
SeqLabels.Clear();
GetFreeShapes(SeqLabels);
- cout<<endl<<"Free Shapes: "<<SeqLabels.Length()<<endl;
+ theDumpLog<<std::endl<<"Free Shapes: "<<SeqLabels.Length()<<std::endl;
for (i = 1; i<=SeqLabels.Length(); i++) {
- DumpShape(SeqLabels.Value(i), level, deep);
- cout<<endl;
+ DumpShape(theDumpLog, SeqLabels.Value(i), level, deep);
+ theDumpLog<<std::endl;
}
+ return theDumpLog;
+}
+
+//=======================================================================
+//function : Dump
+//purpose : override
+//=======================================================================
+
+Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog) const
+{
+ TDF_Attribute::Dump (theDumpLog);
+ Dump (theDumpLog, Standard_False);
+ return theDumpLog;
}
//=======================================================================
//purpose :
//=======================================================================
-void XCAFDoc_ShapeTool::DumpShape(const TDF_Label& L,const Standard_Integer level,const Standard_Boolean deep)
+void XCAFDoc_ShapeTool::DumpShape(Standard_OStream& theDumpLog, const TDF_Label& L,const Standard_Integer level,const Standard_Boolean deep)
{
TopoDS_Shape S;
if(! XCAFDoc_ShapeTool::GetShape(L, S) ) return;
for (Standard_Integer i=0; i<level; i++)
- cout<<"\t";
+ theDumpLog<<"\t";
- if (S.ShapeType() == TopAbs_COMPOUND) cout<<"ASSEMBLY";
- else TopAbs::Print(S.ShapeType(), cout);
+ if(XCAFDoc_ShapeTool::IsAssembly(L))
+ {
+ theDumpLog<<"ASSEMBLY ";
+ }
+ else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
+ {
+ if(L.Father().Father().Father().IsRoot())
+ theDumpLog<<"PART ";
+ }
+ else
+ {
+ theDumpLog<<"INSTANCE ";
+ }
+ TopAbs::Print(S.ShapeType(), theDumpLog);
TCollection_AsciiString Entry;
TDF_Tool::Entry(L, Entry);
- cout<<" "<<Entry;
- //cout<<endl;
+ theDumpLog<<" "<<Entry;
+ if(XCAFDoc_ShapeTool::IsReference(L))
+ {
+ Handle(TDataStd_TreeNode) aRef;
+ L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
+ TDF_Tool::Entry(aRef->Father()->Label(), Entry);
+ theDumpLog<<" (refers to "<<Entry<<")";
+ }
+ //std::cout<<std::endl;
Handle(TDataStd_Name) Name;
if (L.FindAttribute(TDataStd_Name::GetID(),Name))
- cout<<" "<<Name->Get();
+ theDumpLog<<" \""<<Name->Get()<<"\" ";
if (deep) {
- cout<<"("<<*(void**)&S.TShape();
+ theDumpLog<<"("<<*(void**)&S.TShape();
if (! S.Location().IsIdentity())
- cout<<", "<< *(void**)&S.Location();
- cout<<") ";
+ theDumpLog<<", "<< *(void**)&S.Location();
+ theDumpLog<<") ";
}
}
}
return ( !theSHUOAttr.IsNull() );
}
+
+//=======================================================================
+//function : Expand
+//purpose :
+//=======================================================================
+Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& theShapeL)
+{
+ if (theShapeL.IsNull() || IsAssembly(theShapeL))
+ return Standard_False;
+
+ TopoDS_Shape aShape = GetShape(theShapeL);
+ if (aShape.IsNull())
+ return Standard_False;
+
+ TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
+ Standard_Boolean isExpandedType = aShapeType == TopAbs_COMPOUND || aShapeType == TopAbs_COMPSOLID ||
+ aShapeType == TopAbs_SHELL || aShapeType == TopAbs_WIRE;
+ if (isExpandedType)
+ {
+ TopoDS_Iterator anIter(aShape);
+ for(; anIter.More(); anIter.Next())
+ {
+ const TopoDS_Shape& aChildShape = anIter.Value();
+ TDF_Label aChild, aPart;
+
+ // Find child shape as subshape of expanded shape
+ FindSubShape(theShapeL, aChildShape, aChild);
+ Handle(TDataStd_Name) anAttr;
+ //make child (if color isn't set or if it is compound)
+ if (aChild.IsNull()) {
+ aChild = AddSubShape(theShapeL, aChildShape);
+ }
+ else {
+ //get name
+ aChild.FindAttribute(TDataStd_Name::GetID(), anAttr);
+ }
+
+ // Try to find child shape as already existed part
+ aPart = FindShape(aChildShape.Located(TopLoc_Location()));
+ if (aPart.IsNull()) {
+ // Create new part to link child shape
+ aPart = AddShape(aChildShape.Located(TopLoc_Location()), Standard_False, Standard_False);
+ }
+ // Add shape manually, if already existed subshape found instead of creation of new part
+ if (!aPart.IsNull() && !IsTopLevel(aPart)) {
+ if (!GetReferredShape(aPart, aPart)) {
+ TDF_TagSource aTag;
+ aPart = aTag.NewChild(Label());
+ SetShape(aPart, aChildShape.Located(TopLoc_Location()));
+ }
+ }
+
+ // set name to part
+ if (!anAttr.IsNull()) {
+ TDataStd_Name::Set(aPart, anAttr->Get());
+ }
+ else {
+ Standard_SStream Stream;
+ TopAbs::Print(aChildShape.ShapeType(), Stream);
+ TCollection_AsciiString aName(Stream.str().c_str());
+ TDataStd_Name::Set(aPart, TCollection_ExtendedString(aName));
+ }
+ MakeReference(aChild, aPart, aChildShape.Location());
+ makeSubShape(theShapeL, aPart, aChildShape, aChildShape.Location());
+ }
+ //set assembly attribute
+ TDataStd_UAttribute::Set(theShapeL, XCAFDoc::AssemblyGUID());
+ return Standard_True;
+ }
+ return Standard_False;
+}
+
+//=======================================================================
+//function : makeSubShape
+//purpose :
+//=======================================================================
+
+void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& theMainShapeL,
+ const TDF_Label& thePart,
+ const TopoDS_Shape& theShape,
+ const TopLoc_Location& theLoc)
+{
+ TopoDS_Iterator anIter(theShape);
+ Standard_Boolean isCompoundPart = (GetShape(thePart).ShapeType() == TopAbs_COMPOUND);
+ Standard_Boolean isAssembly = IsAssembly(thePart);
+
+ for(; anIter.More(); anIter.Next()) {
+ const TopoDS_Shape& aChildShape = anIter.Value();
+ TDF_Label aChildLabel;
+ FindSubShape(theMainShapeL, aChildShape, aChildLabel);
+ if(!aChildLabel.IsNull()) {
+ if (isAssembly) {
+ aChildLabel.ForgetAllAttributes();
+ makeSubShape(theMainShapeL, thePart, aChildShape, theLoc);
+ continue;
+ }
+ //get name
+ Handle(TDataStd_Name) anAttr;
+ aChildLabel.FindAttribute(TDataStd_Name::GetID(), anAttr);
+ TopLoc_Location aSubLoc;
+ // Calculate location for subshapes of compound parts
+ aSubLoc = aChildShape.Location();
+ if (isCompoundPart)
+ aSubLoc = theLoc.Inverted() * aSubLoc;
+ //make subshape
+ TDF_Label aSubLabel;
+ // Identical location and empty location are not the same for ShapeTool, so try to process both
+ // in case of aSubLoc is not identical, the second Add try will not affect algorithm.
+ Standard_Boolean isNewSubL;
+ isNewSubL = AddSubShape(thePart, aChildShape.Located(aSubLoc), aSubLabel);
+ if (aSubLabel.IsNull())
+ {
+ isNewSubL = AddSubShape(thePart, aChildShape.Located(TopLoc_Location()), aSubLabel);
+ }
+ if (isNewSubL){
+ //set name to sub shape
+ if (!anAttr.IsNull()) {
+ TDataStd_Name::Set(aSubLabel, anAttr->Get());
+ }
+ else {
+ Standard_SStream Stream;
+ TopAbs::Print(aChildShape.ShapeType(), Stream);
+ TCollection_AsciiString aName(Stream.str().c_str());
+ TDataStd_Name::Set(aSubLabel, TCollection_ExtendedString(aName));
+ }
+ // Create auxiliary link, it will be removed during moving attributes
+ MakeReference(aSubLabel, aChildLabel, aChildShape.Location());
+ }
+ else {
+ aChildLabel.ForgetAllAttributes();
+ }
+ }
+
+ makeSubShape(theMainShapeL, thePart, aChildShape, theLoc);
+ }
+}
+
+//=======================================================================
+//function : updateComponent
+//purpose :
+//=======================================================================
+
+Standard_Boolean XCAFDoc_ShapeTool::updateComponent(const TDF_Label& theItemLabel,
+ TopoDS_Shape& theUpdatedShape,
+ TDF_LabelMap& theUpdated) const
+{
+ if ( !IsAssembly(theItemLabel) )
+ return Standard_False; // Do nothing for non-assemblies
+
+ // Get the currently stored compound for the assembly
+ TopoDS_Shape aCurrentRootShape;
+ GetShape(theItemLabel, aCurrentRootShape);
+
+ // Check if the given assembly is already updated
+ if (theUpdated.Contains(theItemLabel)) {
+ theUpdatedShape = aCurrentRootShape;
+ return Standard_True;
+ }
+
+ TopTools_MapOfOrientedShape aCurrentRootShapeMap (aCurrentRootShape.NbChildren());
+
+ // Get components of the assembly
+ TDF_LabelSequence aComponentLabs;
+ GetComponents(theItemLabel, aComponentLabs);
+
+ // This flag indicates whether to update the compound of the assembly
+ Standard_Boolean isModified = Standard_False;
+
+ // Compare the number of components in XDE structure with the number of
+ // components in topological structure. A component may happen to be removed,
+ // so we have to update the assembly compound
+ const Standard_Integer aNumTopoComponents = aCurrentRootShape.NbChildren();
+ //
+ if ( aNumTopoComponents != aComponentLabs.Length() )
+ isModified = Standard_True;
+
+ // Iterate over the assembly components. If at least one component is
+ // modified (this is the recursive check), then the actually stored
+ // compound has to be updated
+ TopTools_ListOfShape aComponentShapes;
+ //
+ for ( TDF_LabelSequence::Iterator aCompIt(aComponentLabs); aCompIt.More(); aCompIt.Next() )
+ {
+ const TDF_Label& aComponentLab = aCompIt.Value();
+
+ // Take the referred assembly item (ultimately, a part for an instance)
+ TDF_Label aComponentRefLab;
+ GetReferredShape(aComponentLab, aComponentRefLab);
+
+ // Shape comes with some placement transformation here
+ TopoDS_Shape aComponentShape;
+ GetShape(aComponentLab, aComponentShape);
+ TopLoc_Location aComponentLoc = aComponentShape.Location();
+
+ // If the component is a sub-assembly, then its associated compound
+ // has to be processed in the same manner
+ if ( IsAssembly(aComponentRefLab) )
+ {
+ // Recursive call
+ if ( updateComponent(aComponentRefLab, aComponentShape, theUpdated) )
+ {
+ isModified = Standard_True;
+ aComponentShape.Location(aComponentLoc); // Apply placement
+ }
+ }
+ else
+ {
+ // Search for a part in the actual compound of the ultimate assembly.
+ // If the part is there, then the compound is up-to-date, so it does not require rebuilding
+ if (!isModified)
+ {
+ if (aCurrentRootShapeMap.IsEmpty())
+ {
+ // optimize search for next labels in aComponentLabs
+ for (TopoDS_Iterator aTopoIt(aCurrentRootShape); aTopoIt.More(); aTopoIt.Next())
+ {
+ aCurrentRootShapeMap.Add (aTopoIt.Value());
+ }
+ }
+ if (!aCurrentRootShapeMap.Contains (aComponentShape))
+ {
+ // Part has been modified somewhere, so the compound has to be rebuilt
+ isModified = Standard_True;
+ }
+ }
+ }
+
+ // Fill the list of shapes composing a new compound for the assembly
+ aComponentShapes.Append(aComponentShape);
+ }
+
+ // If any component is modified, we update the currently stored shape
+ if ( isModified )
+ {
+ TopoDS_Compound anUpdatedCompound;
+ BRep_Builder aBB;
+ aBB.MakeCompound(anUpdatedCompound);
+
+ // Compose new compound
+ for ( TopTools_ListIteratorOfListOfShape aShapeIt(aComponentShapes); aShapeIt.More(); aShapeIt.Next() )
+ {
+ aBB.Add( anUpdatedCompound, aShapeIt.Value() );
+ }
+
+ // Store the updated shape as an output
+ theUpdatedShape = anUpdatedCompound;
+
+ // Use topological naming services to store the updated shape in XDE
+ TNaming_Builder NB(theItemLabel);
+ NB.Generated(theUpdatedShape);
+ }
+
+ if (isModified)
+ theUpdated.Add(theItemLabel);
+
+ return isModified;
+}
+
+//=======================================================================
+//function : GetNamedProperties
+//purpose :
+//=======================================================================
+
+Handle(TDataStd_NamedData) XCAFDoc_ShapeTool::GetNamedProperties (const TDF_Label& theLabel,
+ const Standard_Boolean theToCreate) const
+{
+ Handle(TDataStd_NamedData) aNamedProperty;
+ if (!theLabel.FindAttribute(TDataStd_NamedData::GetID(), aNamedProperty) && theToCreate)
+ {
+ aNamedProperty = TDataStd_NamedData::Set(theLabel);
+ }
+
+ return aNamedProperty;
+}
+
+//=======================================================================
+//function : GetNamedProperties
+//purpose :
+//=======================================================================
+
+Handle(TDataStd_NamedData) XCAFDoc_ShapeTool::GetNamedProperties (const TopoDS_Shape& theShape,
+ const Standard_Boolean theToCreate) const
+{
+ Handle(TDataStd_NamedData) aNamedProperty;
+ TDF_Label aLabel;
+ if (!Search (theShape, aLabel))
+ return aNamedProperty;
+
+ aNamedProperty = GetNamedProperties (aLabel, theToCreate);
+
+ return aNamedProperty;
+}
+
+//=======================================================================
+//function : DumpJson
+//purpose :
+//=======================================================================
+void XCAFDoc_ShapeTool::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
+{
+ OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
+
+ OCCT_DUMP_BASE_CLASS (theOStream, theDepth, TDF_Attribute)
+
+ for (XCAFDoc_DataMapOfShapeLabel::Iterator aShapeLabelIt (myShapeLabels); aShapeLabelIt.More(); aShapeLabelIt.Next())
+ {
+ OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &aShapeLabelIt.Key())
+
+ TCollection_AsciiString aShapeLabel;
+ TDF_Tool::Entry (aShapeLabelIt.Value(), aShapeLabel);
+ OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aShapeLabel)
+ }
+
+ for (XCAFDoc_DataMapOfShapeLabel::Iterator aSubShapeIt (mySubShapes); aSubShapeIt.More(); aSubShapeIt.Next())
+ {
+ OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &aSubShapeIt.Key())
+
+ TCollection_AsciiString aSubShape;
+ TDF_Tool::Entry (aSubShapeIt.Value(), aSubShape);
+ OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aSubShape)
+ }
+
+ for (XCAFDoc_DataMapOfShapeLabel::Iterator aSimpleShapeIt (mySimpleShapes); aSimpleShapeIt.More(); aSimpleShapeIt.Next())
+ {
+ OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &aSimpleShapeIt.Key())
+
+ TCollection_AsciiString aSimpleShape;
+ TDF_Tool::Entry (aSimpleShapeIt.Value(), aSimpleShape);
+ OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aSimpleShape)
+ }
+
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, hasSimpleShapes)
+}