1 // Created on: 2000-08-03
2 // Created by: data exchange team
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <XCAFDoc_ShapeTool.hxx>
18 #include <BRep_Builder.hxx>
20 #include <gp_Trsf.hxx>
21 #include <Standard_Type.hxx>
22 #include <TCollection_AsciiString.hxx>
23 #include <TCollection_ExtendedString.hxx>
24 #include <TCollection_HAsciiString.hxx>
25 #include <TColStd_SequenceOfHAsciiString.hxx>
26 #include <TDataStd_Name.hxx>
27 #include <TDataStd_TreeNode.hxx>
28 #include <TDataStd_UAttribute.hxx>
29 #include <TDF_Attribute.hxx>
30 #include <TDF_ChildIDIterator.hxx>
31 #include <TDF_ChildIterator.hxx>
32 #include <TDF_Label.hxx>
33 #include <TDF_LabelMap.hxx>
34 #include <TDF_LabelSequence.hxx>
35 #include <TDF_RelocationTable.hxx>
36 #include <TDF_Tool.hxx>
37 #include <TDocStd_Document.hxx>
38 #include <TNaming_Builder.hxx>
39 #include <TNaming_Tool.hxx>
40 #include <TopLoc_IndexedMapOfLocation.hxx>
41 #include <TopLoc_Location.hxx>
42 #include <TopoDS_Compound.hxx>
43 #include <TopoDS_Iterator.hxx>
44 #include <TopoDS_Shape.hxx>
45 #include <TopTools_ListOfShape.hxx>
46 #include <TopTools_MapOfOrientedShape.hxx>
47 #include <XCAFDoc.hxx>
48 #include <XCAFDoc_GraphNode.hxx>
49 #include <XCAFDoc_Location.hxx>
50 #include <XCAFDoc_ShapeMapTool.hxx>
52 IMPLEMENT_DERIVED_ATTRIBUTE_WITH_TYPE(XCAFDoc_ShapeTool,TDataStd_GenericEmpty,"xcaf","ShapeTool")
54 static Standard_Boolean theAutoNaming = Standard_True;
56 // attribute methods //////////////////////////////////////////////////
58 //=======================================================================
61 //=======================================================================
63 const Standard_GUID& XCAFDoc_ShapeTool::GetID()
65 static Standard_GUID ShapeToolID ("efd212ee-6dfd-11d4-b9c8-0060b0ee281b");
70 //=======================================================================
73 //=======================================================================
75 Handle(XCAFDoc_ShapeTool) XCAFDoc_ShapeTool::Set(const TDF_Label& L)
77 Handle(XCAFDoc_ShapeTool) A;
78 if (!L.FindAttribute (XCAFDoc_ShapeTool::GetID(), A)) {
79 A = new XCAFDoc_ShapeTool ();
87 //=======================================================================
88 //function : Constructor
90 //=======================================================================
92 XCAFDoc_ShapeTool::XCAFDoc_ShapeTool()
94 hasSimpleShapes = Standard_False;
98 //=======================================================================
101 //=======================================================================
103 const Standard_GUID& XCAFDoc_ShapeTool::ID() const
108 // Auxiliary methods //////////////////////////////////////////////////
110 //=======================================================================
111 //function : SetLabelNameByLink
113 //=======================================================================
114 static void SetLabelNameByLink(const TDF_Label L)
116 Handle(TDataStd_TreeNode) Node;
117 if (! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
118 ! Node->HasFather()) {
120 std::cout<<"Error: XCAFDoc_ShapeTool, SetLabelNameByLink(): NO NODE"<<std::endl;
124 TCollection_AsciiString Entry;
125 TDF_Tool::Entry ( Node->Father()->Label(), Entry );
126 Entry.Insert(1, "=>[");
129 TDataStd_Name::Set(L, TCollection_ExtendedString( Entry ));
133 //=======================================================================
134 //function : SetLabelNameByShape
136 //=======================================================================
137 static void SetLabelNameByShape(const TDF_Label L)
140 if (XCAFDoc_ShapeTool::GetShape(L, S) &&
141 ! L.IsAttribute(TDataStd_Name::GetID()) ) {
142 Standard_SStream Stream;
143 // TopAbs_ShapeEnum Type = S.ShapeType();
144 // if (Type == TopAbs_COMPOUND) Stream<<"ASSEMBLY";
146 TopAbs::Print(S.ShapeType(), Stream);
147 TCollection_AsciiString aName (Stream.str().c_str());
148 TDataStd_Name::Set(L, TCollection_ExtendedString(aName));
153 //=======================================================================
154 //function : SearchUsingMap
156 //=======================================================================
158 Standard_Boolean XCAFDoc_ShapeTool::SearchUsingMap(const TopoDS_Shape &S, TDF_Label &L,
159 const Standard_Boolean findWithoutLoc,
160 const Standard_Boolean findSubShape) const
163 if(myShapeLabels.IsBound(S)) {
164 L = myShapeLabels.Find(S);
165 return Standard_True;
170 if(myShapeLabels.IsBound(S0)) {
171 TDF_Label L1 = myShapeLabels.Find(S0);
172 TDF_LabelSequence Labels;
173 if(GetUsers(L1, Labels, Standard_True)) {
174 for(Standard_Integer i=1; i<=Labels.Length(); i++) {
175 TopoDS_Shape c = GetShape(Labels.Value(i));
178 return Standard_True;
184 return Standard_True;
188 if(hasSimpleShapes) {
189 if(mySimpleShapes.IsBound(S)) {
190 L = mySimpleShapes.Find(S);
191 return Standard_True;
193 if(mySimpleShapes.IsBound(S0)) {
194 L = mySimpleShapes.Find(S0);
195 return Standard_True;
199 if(!findSubShape) return Standard_False;
200 TDF_Label mainL = FindMainShapeUsingMap(S);
201 if(mainL.IsNull()) return Standard_False;
202 L = AddSubShape(mainL,S);
203 return !L.IsNull();//Standard_True;
207 //=======================================================================
210 //=======================================================================
212 Standard_Boolean XCAFDoc_ShapeTool::Search (const TopoDS_Shape &S,
214 const Standard_Boolean findInstance,
215 const Standard_Boolean findComponent,
216 const Standard_Boolean findSubShape) const
218 // search among shapes
219 Standard_Boolean isLocated = ! S.Location().IsIdentity();
222 // try to find top-level instance
223 if ( findInstance && FindShape ( S, L, Standard_True ) )
224 return Standard_True;
225 // try to find component of assembly
226 if ( findComponent ) {
227 TDF_LabelSequence labels;
228 GetShapes ( labels );
229 for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
230 if ( ! IsAssembly ( labels.Value(i) ) ) continue;
231 TDF_LabelSequence comp;
232 GetComponents ( labels.Value(i), comp );
233 for ( Standard_Integer j=1; j <= comp.Length(); j++ ) {
234 TopoDS_Shape c = GetShape ( comp.Value(j) );
235 if ( c.IsSame ( S ) ) {
237 return Standard_True;
243 // try to find top-level simple shape
244 if ( FindShape ( S, L, Standard_False ) ) return Standard_True;
247 if ( ! findSubShape ) return Standard_False;
248 TDF_Label mainL = FindMainShape ( S );
249 if ( mainL.IsNull() ) return Standard_False;
250 L = AddSubShape ( mainL, S );
251 return !L.IsNull();//Standard_True;
254 //=======================================================================
255 //function : FindShape
257 //=======================================================================
259 Standard_Boolean XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S,
261 const Standard_Boolean findInstance) const
263 // search for null-located shape
265 if ( ! findInstance ) {
270 // this code is used instead of the following for performance reasons
271 if (TNaming_Tool::HasLabel(Label(), S0)) {
273 L = TNaming_Tool::Label(Label(), S0, TransDef);
276 return Standard_False;
279 return Standard_True;
281 // Try to find shape manually
282 TDF_ChildIDIterator it(Label(), TNaming_NamedShape::GetID());
283 for (; it.More(); it.Next()) {
284 TDF_Label aLabel = it.Value()->Label();
285 Handle(TNaming_NamedShape) NS;
286 if ( aLabel.FindAttribute(TNaming_NamedShape::GetID(), NS) &&
287 S0.IsSame ( TNaming_Tool::GetShape(NS) ) ) {
289 return Standard_True;
294 return Standard_False;
297 //=======================================================================
298 //function : FindShape
300 //=======================================================================
302 TDF_Label XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S,
303 const Standard_Boolean findInstance) const
306 if (FindShape(S, L, findInstance))
311 //=======================================================================
312 //function : GetShape
314 //=======================================================================
316 Standard_Boolean XCAFDoc_ShapeTool::GetShape (const TDF_Label& L, TopoDS_Shape& S)
318 Handle(XCAFDoc_Location) LocationAttribute;
321 TopoDS_Compound EmptyComp;
323 B.MakeCompound(EmptyComp);
327 // for instance, get referred shape
328 Handle(TDataStd_TreeNode) Node;
329 if ( L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather() &&
330 L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute)) {
331 if ( ! GetShape(Node->Father()->Label(), S) ) return Standard_False;
332 S.Move ( LocationAttribute->Get(), Standard_False );
333 return Standard_True;
336 // else just return shape on this label
337 Handle(TNaming_NamedShape) NS;
338 if ( ! L.FindAttribute(TNaming_NamedShape::GetID(), NS) ) return Standard_False;
339 S = TNaming_Tool::GetShape(NS);
340 return Standard_True;
343 //=======================================================================
344 //function : GetShape
346 //=======================================================================
348 TopoDS_Shape XCAFDoc_ShapeTool::GetShape(const TDF_Label& L)
355 //=======================================================================
356 //function : NewShape
358 //=======================================================================
360 TDF_Label XCAFDoc_ShapeTool::NewShape() const
362 TopoDS_Compound aShape;
364 tdsB.MakeCompound ( aShape );
367 TDF_Label aLabel = aTag.NewChild(Label());
369 TNaming_Builder tnBuild(aLabel);
370 tnBuild.Generated(aShape);
375 //=======================================================================
376 //function : SetShape
378 //=======================================================================
380 void XCAFDoc_ShapeTool::SetShape (const TDF_Label& L, const TopoDS_Shape& S)
382 TNaming_Builder tnBuild(L);
383 tnBuild.Generated(S);
384 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(L);
385 // if ( ! L.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
386 // A = XCAFDoc_ShapeMapTool::Set(L);
387 // L.AddAttribute(A);
391 if(!myShapeLabels.IsBound(S)) {
392 myShapeLabels.Bind(S,L);
396 //=======================================================================
397 //function : MakeReference
399 //=======================================================================
401 void XCAFDoc_ShapeTool::MakeReference (const TDF_Label &L,
402 const TDF_Label &refL,
403 const TopLoc_Location &loc)
406 XCAFDoc_Location::Set(L, loc);
409 Handle(TDataStd_TreeNode) refNode, mainNode;
410 mainNode = TDataStd_TreeNode::Set ( refL, XCAFDoc::ShapeRefGUID() );
411 refNode = TDataStd_TreeNode::Set ( L, XCAFDoc::ShapeRefGUID() );
412 refNode->Remove(); // abv: fix against bug in TreeNode::Append()
413 mainNode->Append(refNode);
416 SetLabelNameByLink(L);
419 //=======================================================================
420 //function : addShape
422 //=======================================================================
424 TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly)
426 TDF_Label ShapeLabel;
429 // search if the shape already exists (with the same location)
430 if ( S.IsNull() || FindShape ( S, ShapeLabel, Standard_True ) ) return ShapeLabel;
432 // else add a new label
433 ShapeLabel = aTag.NewChild(Label());
435 // if shape has location, make a reference to the same shape without location
436 if ( ! S.Location().IsIdentity() /*&& FindShape ( S, L )*/ ) {
440 TDF_Label L = addShape ( S0, makeAssembly );
441 MakeReference ( ShapeLabel, L, S.Location() );
445 // else add a shape to a label
446 TNaming_Builder tnBuild(ShapeLabel);
447 tnBuild.Generated(S);
449 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
450 // if ( ! ShapeLabel.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
451 // A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
452 // ShapeLabel.AddAttribute(A);
457 SetLabelNameByShape(ShapeLabel);
459 // if shape is Compound and flag is set, create assembly
460 if ( makeAssembly && S.ShapeType() == TopAbs_COMPOUND ) {
461 // mark assembly by assigning UAttribute
462 Handle(TDataStd_UAttribute) Uattr;
463 Uattr = TDataStd_UAttribute::Set ( ShapeLabel, XCAFDoc::AssemblyGUID() );
465 TDataStd_Name::Set(ShapeLabel, TCollection_ExtendedString("ASSEMBLY"));
467 // iterate on components
468 TopoDS_Iterator Iterator(S);
469 for (; Iterator.More(); Iterator.Next()) {
470 // get label for component`s shape
471 TopoDS_Shape Scomp = Iterator.Value(), S0 = Scomp;
474 TDF_Label compL = addShape ( S0, makeAssembly );
476 // add a component as reference
477 TDF_Label RefLabel = aTag.NewChild(ShapeLabel);
478 MakeReference ( RefLabel, compL, Scomp.Location() );
482 if(!IsAssembly(ShapeLabel)) {
483 //const TopTools_IndexedMapOfShape tmpMap = A->GetMap();
484 //for(Standard_Integer i=1; i<=tmpMap.Extent(); i++)
485 //mySubShapes.Bind(tmpMap.FindKey(i),ShapeLabel);
486 for(Standard_Integer i=1; i<=A->GetMap().Extent(); i++)
488 TopoDS_Shape aSh = A->GetMap().FindKey(i);
489 mySubShapes.Bind(aSh,ShapeLabel);
490 //if shape has location, make a reference to the same shape without location
491 if (!aSh.Location().IsIdentity()) {
492 TopoDS_Shape S0 = aSh;
495 mySubShapes.Bind(S0, ShapeLabel);
498 //mySubShapes.Bind(ShapeLabel,A->GetMap());
505 //=======================================================================
506 //function : prepareAssembly
507 //purpose : auxiliary
508 //=======================================================================
509 static Standard_Boolean prepareAssembly (const TopoDS_Shape& theShape,
510 TopoDS_Shape& theOUTShape)
512 // iterate on components
513 theOUTShape = theShape;
514 if (theShape.ShapeType() == TopAbs_COMPOUND) {
516 // check if shape if frosen
517 if (!theOUTShape.Free())
518 theOUTShape.Free(Standard_True);
520 TopTools_SequenceOfShape aSubShapeSeq;
521 TopoDS_Iterator Iterator(theShape);
522 for (; Iterator.More(); Iterator.Next())
523 aSubShapeSeq.Append(Iterator.Value());
524 for (Standard_Integer i = 1; i <= aSubShapeSeq.Length(); i++) {
525 TopoDS_Shape Scomp = aSubShapeSeq.Value(i);
526 TopoDS_Shape aNewScomp;
527 B.Remove(theOUTShape, Scomp);
528 prepareAssembly( Scomp, aNewScomp );
529 TopLoc_Location aLoc;
530 aLoc = aNewScomp.Location();
531 if ( aLoc.IsIdentity() ) {
532 // create an "empty" location
534 aTrsf.SetScale(gp_Pnt(0,0,0), 1);
535 aLoc = TopLoc_Location( aTrsf );
536 aNewScomp.Location( aLoc, Standard_False );
538 B.Add(theOUTShape, aNewScomp);
541 return Standard_True;
545 //=======================================================================
546 //function : AddShape
548 //=======================================================================
550 TDF_Label XCAFDoc_ShapeTool::AddShape (const TopoDS_Shape& theShape,
551 const Standard_Boolean makeAssembly,
552 const Standard_Boolean makePrepare)
554 // PTV 17.02.2003 to avoid components without location.
555 TopoDS_Shape S = theShape;
556 if ( makePrepare && makeAssembly && S.ShapeType() == TopAbs_COMPOUND )
557 prepareAssembly( theShape, S ); // OCC1669
559 TDF_Label L = addShape(S,makeAssembly);
561 if(!myShapeLabels.IsBound(S)) {
562 myShapeLabels.Bind(S,L);
567 //return addShape( S, makeAssembly );
570 //=======================================================================
571 //function : RemoveShape
573 //=======================================================================
575 Standard_Boolean XCAFDoc_ShapeTool::RemoveShape (const TDF_Label& L,
576 const Standard_Boolean removeCompletely) const
578 if ( ! IsTopLevel ( L ) || ! IsFree ( L ) ) return Standard_False;
580 Handle(TDataStd_TreeNode) aNode;
582 if (removeCompletely &&
583 L.FindAttribute (XCAFDoc::ShapeRefGUID(), aNode) &&
584 aNode->HasFather() &&
585 L.IsAttribute (XCAFDoc_Location::GetID()))
587 aLabel = aNode->Father()->Label();
590 L.ForgetAllAttributes (Standard_True);
592 if (removeCompletely && !aLabel.IsNull())
594 return RemoveShape(aLabel);
596 return Standard_True;
600 //=======================================================================
603 //=======================================================================
605 void XCAFDoc_ShapeTool::Init()
607 hasSimpleShapes = Standard_False;
611 //=======================================================================
612 //function : SetAutoNaming
614 //=======================================================================
616 void XCAFDoc_ShapeTool::SetAutoNaming (const Standard_Boolean V)
622 //=======================================================================
623 //function : AutoNaming
625 //=======================================================================
627 Standard_Boolean XCAFDoc_ShapeTool::AutoNaming()
629 return theAutoNaming;
633 //=======================================================================
634 //function : ComputeShapes
636 //=======================================================================
638 void XCAFDoc_ShapeTool::ComputeShapes(const TDF_Label& L)
640 TDF_ChildIterator it(L);
641 for(; it.More(); it.Next()) {
642 TDF_Label L1 = it.Value();
645 if(!myShapeLabels.IsBound(S)) {
646 mySimpleShapes.Bind(S,L1);
654 //=======================================================================
655 //function : ComputeSimpleShapes
657 //=======================================================================
659 void XCAFDoc_ShapeTool::ComputeSimpleShapes()
661 ComputeShapes(Label());
662 hasSimpleShapes = Standard_True;
666 //=======================================================================
667 //function : GetShapes
669 //=======================================================================
671 void XCAFDoc_ShapeTool::GetShapes(TDF_LabelSequence& Labels) const
675 TDF_ChildIterator it(Label());
676 for (; it.More(); it.Next()) {
677 TDF_Label L = it.Value();
679 if ( GetShape ( L, S ) ) Labels.Append ( L );
684 //=======================================================================
685 //function : GetFreeShapes
687 //=======================================================================
689 void XCAFDoc_ShapeTool::GetFreeShapes (TDF_LabelSequence& FreeLabels) const
693 TDF_ChildIterator it(Label());
694 for (; it.More(); it.Next()) {
695 TDF_Label L = it.Value();
697 if ( GetShape ( L, S ) && IsFree ( L ) ) FreeLabels.Append ( L );
701 //=======================================================================
702 //function : IsTopLevel
704 //=======================================================================
706 Standard_Boolean XCAFDoc_ShapeTool::IsTopLevel (const TDF_Label& L) const
708 return L.Father() == Label();
711 //=======================================================================
714 //=======================================================================
716 Standard_Boolean XCAFDoc_ShapeTool::IsShape (const TDF_Label& L)
718 return IsSimpleShape ( L ) || IsAssembly ( L ) || IsReference ( L );
721 //=======================================================================
722 //function : IsSimpleShape
724 //=======================================================================
726 Standard_Boolean XCAFDoc_ShapeTool::IsSimpleShape (const TDF_Label& L)
728 Handle(TNaming_NamedShape) NS;
729 return L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) &&
730 ! IsAssembly ( L ) && ! IsReference ( L );
733 //=======================================================================
734 //function : IsReference
736 //=======================================================================
738 Standard_Boolean XCAFDoc_ShapeTool::IsReference (const TDF_Label& L)
740 Handle(TDataStd_TreeNode) Node;
741 return L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather();
744 //=======================================================================
745 //function : IsAssembly
747 //=======================================================================
749 Standard_Boolean XCAFDoc_ShapeTool::IsAssembly (const TDF_Label& L)
751 Handle(TDataStd_UAttribute) Uattr;
752 return L.FindAttribute(XCAFDoc::AssemblyGUID(), Uattr);
755 //=======================================================================
756 //function : IsComponent
758 //=======================================================================
760 Standard_Boolean XCAFDoc_ShapeTool::IsComponent (const TDF_Label& L)
762 return IsReference ( L ) && IsAssembly ( L.Father() );
765 //=======================================================================
766 //function : IsCompound
768 //=======================================================================
770 Standard_Boolean XCAFDoc_ShapeTool::IsCompound (const TDF_Label& L)
772 Handle(TDataStd_Name) Name;
773 if (L.FindAttribute(TDataStd_Name::GetID(),Name)) {
774 TCollection_ExtendedString estr1 = Name->Get();
775 TCollection_ExtendedString estr2("COMPOUND");
777 return Standard_True;
780 return Standard_False;
783 //=======================================================================
784 //function : IsSubShape
786 //=======================================================================
788 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label& L)
790 return IsSimpleShape ( L ) && IsShape ( L.Father() );
793 //=======================================================================
796 //=======================================================================
798 Standard_Boolean XCAFDoc_ShapeTool::IsFree (const TDF_Label& L)
800 Handle(TDataStd_TreeNode) Node;
801 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
802 ! Node->HasFirst() ) return Standard_True;
804 return Standard_False;
807 //=======================================================================
808 //function : GetUsers
809 //purpose : Returns number of users (0 if shape is free)
810 //=======================================================================
812 Standard_Integer XCAFDoc_ShapeTool::GetUsers (const TDF_Label& L,
813 TDF_LabelSequence& Labels,
814 const Standard_Boolean getsubchilds)
816 Standard_Integer NbUsers=0;
817 Handle(TDataStd_TreeNode) Node ;
819 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ) return NbUsers;
821 Node = Node->First();
822 while ( ! Node.IsNull() ) {
824 if ( getsubchilds ) {
825 TDF_Label underL = Node->Label().Father();
826 NbUsers += GetUsers ( underL, Labels, getsubchilds );
829 Labels.Append(Node->Label());
836 //=======================================================================
837 //function : NbComponents
839 //=======================================================================
841 Standard_Integer XCAFDoc_ShapeTool::NbComponents (const TDF_Label& L,
842 const Standard_Boolean getsubchilds)
844 TDF_LabelSequence subLabels;
845 GetComponents (L, subLabels, getsubchilds);
846 return subLabels.Length();
849 //=======================================================================
850 //function : GetComponents
852 //=======================================================================
854 Standard_Boolean XCAFDoc_ShapeTool::GetComponents (const TDF_Label& L, TDF_LabelSequence& Labels,
855 const Standard_Boolean getsubchilds)
857 if ( ! IsAssembly(L) ) return Standard_False;
859 TDF_ChildIterator It(L);
860 for (; It.More(); It.Next() ) {
861 TDF_Label comp = It.Value();
862 if ( IsComponent ( comp ) ) {
863 if ( getsubchilds ) {
865 if ( GetReferredShape ( comp, underL ) )
866 GetComponents ( underL, Labels, getsubchilds);
868 Labels.Append ( comp );
871 return Standard_True;
874 //=======================================================================
875 //function : GetLocation
877 //=======================================================================
879 TopLoc_Location XCAFDoc_ShapeTool::GetLocation (const TDF_Label& L)
881 Handle(XCAFDoc_Location) LocationAttribute;
882 if (L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute))
883 return LocationAttribute->Get();
885 Handle(TNaming_NamedShape) NS;
887 if ( L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) ) {
888 S = TNaming_Tool::GetShape(NS);
893 //=======================================================================
894 //function : GetReferredShape
896 //=======================================================================
898 Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L,
901 if ( ! IsReference(L) ) return Standard_False;
903 Handle (TDataStd_TreeNode) Node;
904 L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node);
905 Label = Node->Father()->Label();
906 return Standard_True;
909 //=======================================================================
910 //function : AddComponent
912 //=======================================================================
914 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
915 const TDF_Label& compL,
916 const TopLoc_Location &Loc)
920 // check that shape is assembly
921 if ( ! IsAssembly(assembly) ) {
922 // if it is simple shape, make it assembly
923 if ( IsSimpleShape(assembly) )
924 TDataStd_UAttribute::Set ( assembly, XCAFDoc::AssemblyGUID() );
928 // add a component as reference
930 L = aTag.NewChild(assembly);
931 MakeReference ( L, compL, Loc );
933 // map shape to label
935 if (GetShape(L, aShape))
937 if (!myShapeLabels.IsBound(aShape))
938 myShapeLabels.Bind(aShape, L);
944 //=======================================================================
945 //function : AddComponent
947 //=======================================================================
949 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
950 const TopoDS_Shape& comp,
951 const Standard_Boolean expand)
953 // get label for component`s shape
954 TopoDS_Shape S0 = comp;
958 compL = AddShape ( S0, expand );
960 // add component by its label
961 return AddComponent ( assembly, compL, comp.Location() );
964 //=======================================================================
965 //function : RemoveComponent
967 //=======================================================================
969 void XCAFDoc_ShapeTool::RemoveComponent (const TDF_Label& comp) const
971 if ( IsComponent(comp) )
973 comp.ForgetAllAttributes();
977 //=======================================================================
978 //function : UpdateAssemblies
980 //=======================================================================
982 void XCAFDoc_ShapeTool::UpdateAssemblies()
984 // We start from the free shapes (roots in the assembly structure)
985 TDF_LabelSequence aRootLabels;
986 GetFreeShapes(aRootLabels);
988 // Iterate over the free shapes
989 TDF_LabelMap anUpdated;
990 for ( TDF_LabelSequence::Iterator anIt(aRootLabels); anIt.More(); anIt.Next() )
992 TDF_Label aRefLabel = anIt.Value();
993 if (IsReference(aRefLabel))
995 GetReferredShape(aRefLabel, aRefLabel);
997 const TDF_Label& aRootLab = aRefLabel;
998 TopoDS_Shape anAssemblyShape;
999 updateComponent(aRootLab, anAssemblyShape, anUpdated);
1003 //=======================================================================
1004 //function : IsSubShape
1006 //=======================================================================
1008 //static Standard_Boolean CheckSubShape (const TopoDS_Shape &S, const TopoDS_Shape &sub)
1010 // if ( S.IsSame ( sub ) ) return Standard_True;
1012 // if ( S.ShapeType() >= sub.ShapeType() ) return Standard_False;
1014 // for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
1015 // if ( CheckSubShape ( it.Value(), sub ) ) return Standard_True;
1017 // return Standard_False;
1020 //=======================================================================
1021 //function : IsSubShape
1023 //=======================================================================
1025 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label &shapeL,
1026 const TopoDS_Shape &sub) const
1028 Handle(XCAFDoc_ShapeMapTool) A;
1029 if (!shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A))
1031 TopoDS_Shape aShape = GetShape(shapeL);
1032 if (aShape.IsNull())
1033 return Standard_False;
1034 A = XCAFDoc_ShapeMapTool::Set(shapeL);
1035 A->SetShape(aShape);
1038 return A->IsSubShape(sub);
1041 //=======================================================================
1042 //function : FindSubShape
1044 //=======================================================================
1046 Standard_Boolean XCAFDoc_ShapeTool::FindSubShape (const TDF_Label &shapeL,
1047 const TopoDS_Shape &sub,
1051 return Standard_False;
1053 if (TNaming_Tool::HasLabel(Label(), sub)) {
1055 L = TNaming_Tool::Label(Label(), sub, TransDef);
1057 return Standard_False;
1058 if (L.Father() == shapeL)
1059 return Standard_True;
1063 return Standard_False;
1066 // if subshape was found wrong, try to do it manually
1067 // it can be possible if several part shapes has the same subshapes
1069 TDF_ChildIterator aChldLabIt(shapeL);
1070 for (; aChldLabIt.More(); aChldLabIt.Next() ) {
1071 TDF_Label aSubLabel = aChldLabIt.Value();
1072 Handle(TNaming_NamedShape) NS;
1073 if (!aSubLabel.FindAttribute(TNaming_NamedShape::GetID(), NS))
1075 TopoDS_Shape aSubShape = TNaming_Tool::GetShape(NS);
1076 if (!aSubShape.IsNull() && aSubShape.IsSame(sub)) {
1078 return Standard_True;
1082 return Standard_False;
1085 //=======================================================================
1086 //function : AddSubShape
1088 //=======================================================================
1090 TDF_Label XCAFDoc_ShapeTool::AddSubShape (const TDF_Label &shapeL,
1091 const TopoDS_Shape &sub) const
1094 AddSubShape(shapeL, sub, L);
1099 //=======================================================================
1100 //function : AddSubShape
1102 //=======================================================================
1104 Standard_Boolean XCAFDoc_ShapeTool::AddSubShape(const TDF_Label &shapeL,
1105 const TopoDS_Shape &sub,
1106 TDF_Label &addedSubShapeL) const
1108 addedSubShapeL = TDF_Label();
1109 // Check if adding subshape is possible
1110 if (!IsSimpleShape(shapeL) || !IsTopLevel(shapeL))
1111 return Standard_False;
1113 TopoDS_Shape aSubShape = sub;
1114 Standard_Boolean isDefined = Standard_True;
1115 if (!IsSubShape(shapeL, sub))
1117 isDefined = Standard_False;
1118 // Try to find a subshape as a part of the main shape.
1119 // If location of subshape has been removed,
1120 // take the shape with the location from the main shape
1121 if (sub.Location().IsIdentity())
1123 TDF_LabelSequence aShapeLSeq;
1124 for (TopoDS_Iterator it(GetShape(shapeL)); it.More() && !isDefined; it.Next())
1126 TopoDS_Shape aShape = it.Value();
1127 if (sub.IsSame(aShape.Located(TopLoc_Location())))
1129 isDefined = Standard_True;
1136 return Standard_False;
1138 // Try to find already existed subshape
1139 if (FindSubShape(shapeL, aSubShape, addedSubShapeL))
1140 return Standard_False;
1143 addedSubShapeL = aTag.NewChild(shapeL);
1144 TNaming_Builder tnBuild(addedSubShapeL);
1145 tnBuild.Generated(aSubShape);
1147 return Standard_True;
1151 //=======================================================================
1152 //function : FindMainShapeUsingMap
1154 //=======================================================================
1156 TDF_Label XCAFDoc_ShapeTool::FindMainShapeUsingMap(const TopoDS_Shape &sub) const
1158 //for(Standard_Integer i=1; i<=myNotAssemblies.Length(); i++) {
1159 // TDF_Label L = myNotAssemblies.Value(i);
1160 // if(IsSubShape(L,sub)) return L;
1162 if(mySubShapes.IsBound(sub))
1163 return mySubShapes.Find(sub);
1169 //=======================================================================
1170 //function : FindMainShape
1172 //=======================================================================
1174 TDF_Label XCAFDoc_ShapeTool::FindMainShape (const TopoDS_Shape &sub) const
1176 TDF_ChildIterator it(Label());
1177 for (; it.More(); it.Next()) {
1178 TDF_Label L = it.Value();
1180 if ( IsSimpleShape( L ) && IsSubShape ( L, sub ) ) return L;
1187 //=======================================================================
1188 //function : GetSubShapes
1190 //=======================================================================
1192 Standard_Boolean XCAFDoc_ShapeTool::GetSubShapes (const TDF_Label &L,
1193 TDF_LabelSequence& Labels)
1195 TDF_ChildIterator It(L);
1196 for (; It.More(); It.Next() ) {
1197 TDF_Label sub = It.Value();
1198 if ( IsSubShape ( sub ) ) Labels.Append ( sub );
1200 return Labels.Length() >0;
1203 //=======================================================================
1204 //function : BaseLabel
1206 //=======================================================================
1208 TDF_Label XCAFDoc_ShapeTool::BaseLabel () const
1213 //=======================================================================
1214 //function : DumpAssembly
1215 //purpose : recursive part of Dump()
1216 //=======================================================================
1218 static void DumpAssembly(Standard_OStream& theDumpLog,
1220 const Standard_Integer level,
1221 const Standard_Boolean deep)
1224 XCAFDoc_ShapeTool::GetShape(L, S);
1227 for (Standard_Integer i=0; i<level; i++)
1230 TCollection_AsciiString Entry;
1231 TDF_Tool::Entry(L, Entry);
1233 if(XCAFDoc_ShapeTool::IsAssembly(L))
1235 theDumpLog<<"ASSEMBLY ";
1237 else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
1239 if(L.Father().Father().Father().IsRoot())
1240 theDumpLog<<"PART ";
1244 theDumpLog<<"INSTANCE ";
1246 TopAbs::Print(S.ShapeType(), theDumpLog);
1248 theDumpLog<<" "<<Entry;
1249 if(XCAFDoc_ShapeTool::IsReference(L))
1251 Handle(TDataStd_TreeNode) aRef;
1252 L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
1253 TDF_Tool::Entry(aRef->Father()->Label(), Entry);
1254 theDumpLog<<" (refers to "<<Entry<<")";
1256 Handle(TDataStd_Name) Name;
1257 if (L.FindAttribute(TDataStd_Name::GetID(), Name))
1258 theDumpLog<<" \""<<Name->Get()<<"\" ";
1261 theDumpLog<<"("<<*(void**)&S.TShape();
1262 if (! S.Location().IsIdentity())
1263 theDumpLog<<", "<< *(void**)&S.Location();
1266 theDumpLog<<std::endl;
1268 Handle(TDataStd_TreeNode) Node;
1269 TDF_ChildIterator NodeIterator(L);
1270 for (; NodeIterator.More(); NodeIterator.Next()) {
1271 DumpAssembly(theDumpLog, NodeIterator.Value(), level+1, deep);
1274 theDumpLog<<std::endl;
1277 //=======================================================================
1280 //=======================================================================
1282 Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog, const Standard_Boolean deep) const
1284 Standard_Integer level = 0;
1285 // TopTools_SequenceOfShape SeqShapes;
1286 TDF_LabelSequence SeqLabels;
1287 GetShapes( SeqLabels);
1289 if (SeqLabels.Length()>0) theDumpLog<<std::endl;
1291 for (i=1; i<=SeqLabels.Length(); i++) {
1292 DumpAssembly(theDumpLog, SeqLabels.Value(i), level, deep);
1296 GetFreeShapes(SeqLabels);
1297 theDumpLog<<std::endl<<"Free Shapes: "<<SeqLabels.Length()<<std::endl;
1298 for (i = 1; i<=SeqLabels.Length(); i++) {
1299 DumpShape(theDumpLog, SeqLabels.Value(i), level, deep);
1300 theDumpLog<<std::endl;
1305 //=======================================================================
1307 //purpose : override
1308 //=======================================================================
1310 Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog) const
1312 TDF_Attribute::Dump (theDumpLog);
1313 Dump (theDumpLog, Standard_False);
1317 //=======================================================================
1318 //function : DumpShape
1320 //=======================================================================
1322 void XCAFDoc_ShapeTool::DumpShape(Standard_OStream& theDumpLog, const TDF_Label& L,const Standard_Integer level,const Standard_Boolean deep)
1325 if(! XCAFDoc_ShapeTool::GetShape(L, S) ) return;
1326 for (Standard_Integer i=0; i<level; i++)
1329 if(XCAFDoc_ShapeTool::IsAssembly(L))
1331 theDumpLog<<"ASSEMBLY ";
1333 else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
1335 if(L.Father().Father().Father().IsRoot())
1336 theDumpLog<<"PART ";
1340 theDumpLog<<"INSTANCE ";
1342 TopAbs::Print(S.ShapeType(), theDumpLog);
1344 TCollection_AsciiString Entry;
1345 TDF_Tool::Entry(L, Entry);
1346 theDumpLog<<" "<<Entry;
1347 if(XCAFDoc_ShapeTool::IsReference(L))
1349 Handle(TDataStd_TreeNode) aRef;
1350 L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
1351 TDF_Tool::Entry(aRef->Father()->Label(), Entry);
1352 theDumpLog<<" (refers to "<<Entry<<")";
1354 //std::cout<<std::endl;
1355 Handle(TDataStd_Name) Name;
1356 if (L.FindAttribute(TDataStd_Name::GetID(),Name))
1357 theDumpLog<<" \""<<Name->Get()<<"\" ";
1360 theDumpLog<<"("<<*(void**)&S.TShape();
1361 if (! S.Location().IsIdentity())
1362 theDumpLog<<", "<< *(void**)&S.Location();
1367 //=======================================================================
1368 //function : IsExternRef
1370 //=======================================================================
1372 Standard_Boolean XCAFDoc_ShapeTool::IsExternRef(const TDF_Label& L)
1374 Handle(TDataStd_UAttribute) Uattr;
1375 return L.FindAttribute(XCAFDoc::ExternRefGUID(), Uattr);
1378 //=======================================================================
1379 //function : SetExternRefs
1381 //=======================================================================
1383 void XCAFDoc_ShapeTool::SetExternRefs(const TDF_Label& L,
1384 const TColStd_SequenceOfHAsciiString& SHAS) const
1386 TDF_Label ShapeLabel = L.NewChild();
1387 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1388 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1389 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1390 Handle(TCollection_HAsciiString) str = SHAS(i);
1391 TCollection_ExtendedString extstr(str->String());
1392 TDataStd_Name::Set(tmplbl,extstr);
1396 //=======================================================================
1397 //function : SetExternRefs
1399 //=======================================================================
1401 TDF_Label XCAFDoc_ShapeTool::SetExternRefs(const TColStd_SequenceOfHAsciiString& SHAS) const
1403 TDF_Label ShapeLabel;
1406 ShapeLabel = aTag.NewChild(Label());
1407 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1408 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1409 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1410 Handle(TCollection_HAsciiString) str = SHAS(i);
1411 TCollection_ExtendedString extstr(str->String());
1412 TDataStd_Name::Set(tmplbl,extstr);
1417 //=======================================================================
1418 //function : GetExternRefs
1420 //=======================================================================
1422 void XCAFDoc_ShapeTool::GetExternRefs(const TDF_Label& L,
1423 TColStd_SequenceOfHAsciiString& SHAS)
1425 Handle(TDataStd_Name) TDN;
1427 for(Standard_Integer i=1; i<=L.NbChildren(); i++) {
1428 tmplbl = L.FindChild(i);
1429 if(tmplbl.FindAttribute(TDataStd_Name::GetID(),TDN)) {
1430 TCollection_ExtendedString extstr = TDN->Get();
1431 Handle(TCollection_HAsciiString) str =
1432 new TCollection_HAsciiString(TCollection_AsciiString(extstr));
1438 // API: API work with SHUO (Specified Higher Usage Occurrence) structure
1440 //=======================================================================
1441 //function : GetSHUO
1443 //=======================================================================
1445 Standard_Boolean XCAFDoc_ShapeTool::GetSHUO (const TDF_Label& SHUOLabel,
1446 Handle(XCAFDoc_GraphNode)& aSHUOAttr)
1448 if ( !SHUOLabel.FindAttribute( XCAFDoc::SHUORefGUID(), aSHUOAttr ) )
1449 return Standard_False;
1450 return Standard_True;
1453 //=======================================================================
1454 //function : GetAllComponentSHUO
1456 //=======================================================================
1458 Standard_Boolean XCAFDoc_ShapeTool::GetAllComponentSHUO (const TDF_Label& theCompLabel,
1459 TDF_AttributeSequence& theSHUOAttrs)
1461 TDF_ChildIterator it(theCompLabel);
1462 for (; it.More(); it.Next()) {
1463 TDF_Label L = it.Value();
1464 Handle(XCAFDoc_GraphNode) aSHUOAttr;
1465 if ( GetSHUO( L, aSHUOAttr ) )
1466 theSHUOAttrs.Append( aSHUOAttr );
1468 return (theSHUOAttrs.Length() > 0);
1471 //=======================================================================
1472 //function : SetSHUO
1474 //=======================================================================
1476 Standard_Boolean XCAFDoc_ShapeTool::SetSHUO (const TDF_LabelSequence& labels,
1477 Handle(XCAFDoc_GraphNode)& MainSHUOAttr) const
1479 MainSHUOAttr.Nullify();
1480 // check number of labels
1481 if (labels.Length() < 2)
1482 return Standard_False;
1483 // check is all labels contains components of any assemblyies
1485 for (i = 1; i <= labels.Length(); i++)
1486 if ( !IsComponent(labels.Value(i)) )
1487 return Standard_False;
1490 TDF_Label UpperSubL = aTag.NewChild( labels( 1 ) );
1491 if (theAutoNaming) {
1492 TCollection_ExtendedString Entry("SHUO");
1493 TDataStd_Name::Set(UpperSubL, TCollection_ExtendedString( Entry ));
1495 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1496 aUpperSHUO = XCAFDoc_GraphNode::Set( UpperSubL, XCAFDoc::SHUORefGUID() );
1497 // init out argument by main upper usage SHUO
1498 MainSHUOAttr = aUpperSHUO;
1499 // add other next_usage occurrences.
1500 for (i = 2; i <= labels.Length(); i++) {
1501 TDF_Label NextSubL = aTag.NewChild( labels( i ) );
1502 if (theAutoNaming) {
1503 TCollection_ExtendedString EntrySub("SHUO-");
1505 TDataStd_Name::Set(NextSubL, TCollection_ExtendedString( EntrySub ));
1507 Handle(XCAFDoc_GraphNode) aNextSHUO;
1508 aNextSHUO = XCAFDoc_GraphNode::Set( NextSubL, XCAFDoc::SHUORefGUID() );
1510 aUpperSHUO->SetChild( aNextSHUO );
1511 aNextSHUO->SetFather( aUpperSHUO );
1512 // now lets next_usage become upper_usage for next level of SHUO
1513 aUpperSHUO = aNextSHUO;
1514 UpperSubL = NextSubL;
1517 return Standard_True;
1520 //=======================================================================
1521 //function : GetSHUOUpperUsage
1523 //=======================================================================
1525 Standard_Boolean XCAFDoc_ShapeTool::GetSHUOUpperUsage (const TDF_Label& NextUsageL,
1526 TDF_LabelSequence& aLabels)
1528 Handle(XCAFDoc_GraphNode) aNextSHUO;
1529 if( !GetSHUO( NextUsageL, aNextSHUO ) || aNextSHUO->NbFathers()<1 )
1530 return Standard_False;
1532 // get upper_usage SHAO
1533 for (Standard_Integer i = 1; i <= aNextSHUO->NbFathers(); i++)
1534 aLabels.Append( aNextSHUO->GetFather(i)->Label() );
1535 return Standard_True;
1538 //=======================================================================
1539 //function : GetSHUONextUsage
1541 //=======================================================================
1543 Standard_Boolean XCAFDoc_ShapeTool::GetSHUONextUsage (const TDF_Label& UpperUsageL,
1544 TDF_LabelSequence& aLabels)
1546 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1547 if ( !GetSHUO( UpperUsageL, aUpperSHUO ) || aUpperSHUO->NbChildren()<1 )
1548 return Standard_False;
1549 // get upper_usage SHAO
1550 for (Standard_Integer i = 1; i <= aUpperSHUO->NbChildren(); i++)
1551 aLabels.Append( aUpperSHUO->GetChild(i)->Label() );
1552 return Standard_True;
1555 //=======================================================================
1556 //function : RemoveSHUO
1558 //=======================================================================
1560 Standard_Boolean XCAFDoc_ShapeTool::RemoveSHUO (const TDF_Label& L) const
1562 L.ForgetAllAttributes (Standard_True);
1563 return Standard_True;
1566 //=======================================================================
1567 //function : checkForShape
1568 //purpose : auxiliary
1569 //=======================================================================
1571 static Standard_Boolean checkForShape (const TopoDS_Shape& theShape,
1572 const TopoDS_Shape& theCurSh,
1573 const TDF_Label& theUserL,
1574 TDF_LabelSequence& theLabels)
1576 // the label of an assembly which contains this component
1577 TDF_Label aSuperUserL = theUserL.Father();
1578 TopLoc_Location aSupLoc, aCompLoc;
1579 aSupLoc = ::XCAFDoc_ShapeTool::GetLocation ( aSuperUserL );
1580 aCompLoc = ::XCAFDoc_ShapeTool::GetLocation ( theUserL );
1581 TopoDS_Shape aCopySh = theCurSh;
1582 aCompLoc = aCompLoc.Multiplied( theCurSh.Location() );
1583 aSupLoc = aSupLoc.Multiplied( aCompLoc );
1584 aCopySh.Location( aSupLoc, Standard_False );
1585 if ( aCopySh.IsSame( theShape ) ) {
1586 theLabels.Prepend( theUserL );
1587 return Standard_True;
1589 // try to search deeply (upper by assembly structure)
1590 TDF_LabelSequence aNewLabels;
1591 for (Standard_Integer j = 1; j <= theLabels.Length(); j++)
1592 aNewLabels.Append( theLabels.Value( j ) );
1593 aNewLabels.Prepend( theUserL );
1594 TDF_LabelSequence aUsers;
1595 ::XCAFDoc_ShapeTool::GetUsers( aSuperUserL, aUsers );
1596 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1597 if ( checkForShape( theShape, aCopySh, aUsers.Value( i ), aNewLabels ) ) {
1599 theLabels = aNewLabels;
1600 return Standard_True;
1602 return Standard_False;
1605 //=======================================================================
1606 //function : FindComponent
1608 //=======================================================================
1610 Standard_Boolean XCAFDoc_ShapeTool::FindComponent (const TopoDS_Shape& theShape,
1611 TDF_LabelSequence& theLabels) const
1614 // search for a top-level shape that corresponds to this component
1615 TopoDS_Shape S0 = theShape;
1616 TopLoc_Location loc;
1617 S0.Location ( loc );
1618 TDF_Label aRefL = FindShape( S0 );
1620 return Standard_False; // cannot find top-level shape.
1622 TDF_LabelSequence aUsers;
1623 ::XCAFDoc_ShapeTool::GetUsers( aRefL, aUsers );
1624 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1625 if ( checkForShape( theShape, S0, aUsers.Value( i ), theLabels ) )
1628 return (theLabels.Length() > 0);
1631 //=======================================================================
1632 //function : getShapesOfSHUO
1633 //purpose : auxiliary
1634 //=======================================================================
1636 static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLocMap,
1637 const Handle(XCAFDoc_ShapeTool)& theSTool,
1638 const TDF_Label& theSHUOlab,
1639 TopoDS_Shape& theShape)
1641 Handle(XCAFDoc_GraphNode) SHUO;
1642 TDF_LabelSequence aLabSeq;
1643 theSTool->GetSHUONextUsage( theSHUOlab, aLabSeq );
1644 if (aLabSeq.Length() >= 1)
1645 for (Standard_Integer i = 1; i <= aLabSeq.Length(); i++) {
1646 TDF_Label aSubCompL = aLabSeq.Value( i );
1647 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSubCompL.Father() );
1648 // create new map of laocation (to not merge locations from different shapes)
1649 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1650 for (Standard_Integer m = 1; m <= theaPrevLocMap.Extent(); m++)
1651 aNewPrevLocMap.Add( theaPrevLocMap.FindKey( m ) );
1652 aNewPrevLocMap.Add( compLoc );
1653 // got for the new sublocations and corresponding shape
1654 getShapesOfSHUO( aNewPrevLocMap, theSTool, aSubCompL, theShape );
1657 TopoDS_Shape aSHUO_NUSh = theSTool->GetShape ( theSHUOlab.Father() );
1658 if ( aSHUO_NUSh.IsNull() ) return Standard_False;
1659 // cause got shape with location already.
1660 TopLoc_Location nullLoc;
1661 aSHUO_NUSh.Location ( nullLoc );
1662 // multiply the locations
1663 Standard_Integer intMapLenght = theaPrevLocMap.Extent();
1664 if ( intMapLenght < 1 )
1665 return Standard_False; // should not be, but to avoid exception...?
1666 TopLoc_Location SupcompLoc;
1667 SupcompLoc = theaPrevLocMap.FindKey( intMapLenght );
1668 if (intMapLenght > 1) {
1669 Standard_Integer l = intMapLenght - 1;
1671 SupcompLoc = theaPrevLocMap.FindKey( l ).Multiplied( SupcompLoc );
1675 aSHUO_NUSh.Location( SupcompLoc, Standard_False );
1676 theShape = aSHUO_NUSh;
1678 return (!theShape.IsNull());
1681 //=======================================================================
1682 //function : GetSHUOInstance
1684 //=======================================================================
1686 TopoDS_Shape XCAFDoc_ShapeTool::GetSHUOInstance (const Handle(XCAFDoc_GraphNode)& theSHUO) const
1688 TopoDS_Shape aShape;
1689 if (theSHUO.IsNull())
1692 TDF_Label aSHUOlab = theSHUO->Label();
1693 // get location of the assembly
1694 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1695 // get location of the component
1696 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1697 TopLoc_IndexedMapOfLocation aPrevLocMap;
1698 // get previous set location
1699 if ( !loc.IsIdentity() )
1700 aPrevLocMap.Add( loc );
1701 aPrevLocMap.Add( compLoc );
1702 // get shape by recurse method
1703 const Handle(XCAFDoc_ShapeTool)& STool = this;
1704 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1709 //=======================================================================
1710 //function : getUsersShapesOfSHUO
1711 //purpose : auxiliary
1712 //=======================================================================
1714 static Standard_Boolean getUsersShapesOfSHUO (TopLoc_IndexedMapOfLocation& aPrevLocMap,
1715 const Handle(XCAFDoc_ShapeTool)& STool,
1716 const TDF_Label& aSHUOlab,
1717 const TDF_Label& theUserL,
1718 TopTools_SequenceOfShape& theSHUOShapeSeq)
1720 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1721 // get location of the assembly
1722 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( theUserL.Father() );
1723 // get location of the component
1724 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( theUserL );
1725 // get previous set location
1726 aNewPrevLocMap.Add( loc );
1727 aNewPrevLocMap.Add( compLoc );
1729 for (i = 1; i <= aPrevLocMap.Extent(); i++)
1730 aNewPrevLocMap.Add( aPrevLocMap.FindKey(i) );
1731 TDF_Label L = theUserL.Father();
1732 TDF_LabelSequence usersLab;
1733 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1734 if (usersLab.Length() == 0) {
1735 TopoDS_Shape aShape;
1736 getShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aShape );
1737 if (!aShape.IsNull()) {
1738 theSHUOShapeSeq.Append(aShape);
1739 return Standard_True;
1742 // now iterates on users of this assembly as component
1743 for ( i = 1; i <= usersLab.Length(); i++ ) {
1744 TDF_Label aNewUserL = usersLab.Value(i);
1745 getUsersShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aNewUserL, theSHUOShapeSeq );
1748 return (theSHUOShapeSeq.Length() > 1);
1751 //=======================================================================
1752 //function : GetAllSHUOInstances
1753 //purpose : auxiliary
1754 //=======================================================================
1756 Standard_Boolean XCAFDoc_ShapeTool::GetAllSHUOInstances (const Handle(XCAFDoc_GraphNode)& theSHUO,
1757 TopTools_SequenceOfShape& theSHUOShapeSeq) const
1759 if (theSHUO.IsNull())
1760 return Standard_False;
1762 TDF_Label aSHUOlab = theSHUO->Label();
1763 TopLoc_IndexedMapOfLocation aPrevLocMap;
1764 // get location of the assembly
1765 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1766 // get location of the component
1767 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1768 // get previous set location
1769 if ( !loc.IsIdentity() )
1770 aPrevLocMap.Add( loc );
1771 aPrevLocMap.Add( compLoc );
1772 // get label of assembly
1773 TDF_Label L = aSHUOlab.Father().Father();
1774 TDF_LabelSequence usersLab;
1775 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1776 TopoDS_Shape aShape;
1777 const Handle(XCAFDoc_ShapeTool)& STool = this;
1778 if (usersLab.Length() == 0) {
1779 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1780 if (!aShape.IsNull()) {
1781 theSHUOShapeSeq.Append(aShape);
1782 return Standard_True;
1785 // now iterates on users of this assembly as component
1786 for (Standard_Integer i = 1; i <= usersLab.Length(); i++) {
1787 TDF_Label aUserL = usersLab.Value(i);
1788 getUsersShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aUserL, theSHUOShapeSeq );
1791 return (theSHUOShapeSeq.Length() > 1);
1794 //=======================================================================
1795 //function : SetInstanceSHUO
1797 //=======================================================================
1799 Handle(XCAFDoc_GraphNode) XCAFDoc_ShapeTool::SetInstanceSHUO (const TopoDS_Shape& theShape) const
1801 Handle(XCAFDoc_GraphNode) SHUO;
1802 TDF_LabelSequence aLabels;
1803 if ( FindComponent( theShape, aLabels ) )
1804 // set shuo structure on labels of component-assembly structure
1805 SetSHUO( aLabels, SHUO );
1809 //=======================================================================
1810 //function : FindSHUO
1812 //=======================================================================
1814 Standard_Boolean XCAFDoc_ShapeTool::FindSHUO (const TDF_LabelSequence& theLabels,
1815 Handle(XCAFDoc_GraphNode)& theSHUOAttr)
1817 TDF_AttributeSequence SHUOAttrs;
1818 TDF_Label aCompLabel = theLabels.Value(1);
1819 if (! ::XCAFDoc_ShapeTool::GetAllComponentSHUO( aCompLabel, SHUOAttrs ) )
1820 return Standard_False;
1821 // WARNING: manage that each SHUO upper_usage have only one SHUO next_usage
1822 for (Standard_Integer i = 1; i <= SHUOAttrs.Length(); i++) {
1823 TDF_LabelSequence aCondidate;
1824 Handle(XCAFDoc_GraphNode) anSHUO = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1825 aCondidate.Append( anSHUO->Label().Father() );
1826 while (anSHUO->NbChildren()) {
1827 anSHUO = anSHUO->GetChild( 1 );
1828 aCondidate.Append( anSHUO->Label().Father() );
1830 // check the label sequences
1831 Standard_Boolean isEqual = Standard_True;
1832 if (theLabels.Length() != aCondidate.Length())
1833 isEqual = Standard_False;
1835 for (Standard_Integer li = 1; li <= theLabels.Length(); li++)
1836 if ( theLabels.Value(li) != aCondidate.Value(li) ) {
1837 isEqual = Standard_False;
1843 theSHUOAttr = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1846 return ( !theSHUOAttr.IsNull() );
1849 //=======================================================================
1852 //=======================================================================
1853 Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& theShapeL)
1855 if (theShapeL.IsNull() || IsAssembly(theShapeL))
1856 return Standard_False;
1858 TopoDS_Shape aShape = GetShape(theShapeL);
1859 if (aShape.IsNull())
1860 return Standard_False;
1862 TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
1863 Standard_Boolean isExpandedType = aShapeType == TopAbs_COMPOUND || aShapeType == TopAbs_COMPSOLID ||
1864 aShapeType == TopAbs_SHELL || aShapeType == TopAbs_WIRE;
1867 TopoDS_Iterator anIter(aShape);
1868 for(; anIter.More(); anIter.Next())
1870 const TopoDS_Shape& aChildShape = anIter.Value();
1871 TDF_Label aChild, aPart;
1873 // Find child shape as subshape of expanded shape
1874 FindSubShape(theShapeL, aChildShape, aChild);
1875 Handle(TDataStd_Name) anAttr;
1876 //make child (if color isn't set or if it is compound)
1877 if (aChild.IsNull()) {
1878 aChild = AddSubShape(theShapeL, aChildShape);
1882 aChild.FindAttribute(TDataStd_Name::GetID(), anAttr);
1885 // Try to find child shape as already existed part
1886 aPart = FindShape(aChildShape.Located(TopLoc_Location()));
1887 if (aPart.IsNull()) {
1888 // Create new part to link child shape
1889 aPart = AddShape(aChildShape.Located(TopLoc_Location()), Standard_False, Standard_False);
1891 // Add shape manually, if already existed subshape found instead of creation of new part
1892 if (!aPart.IsNull() && !IsTopLevel(aPart)) {
1893 if (!GetReferredShape(aPart, aPart)) {
1895 aPart = aTag.NewChild(Label());
1896 SetShape(aPart, aChildShape.Located(TopLoc_Location()));
1901 if (!anAttr.IsNull()) {
1902 TDataStd_Name::Set(aPart, anAttr->Get());
1905 Standard_SStream Stream;
1906 TopAbs::Print(aChildShape.ShapeType(), Stream);
1907 TCollection_AsciiString aName(Stream.str().c_str());
1908 TDataStd_Name::Set(aPart, TCollection_ExtendedString(aName));
1910 MakeReference(aChild, aPart, aChildShape.Location());
1911 makeSubShape(theShapeL, aPart, aChildShape, aChildShape.Location());
1913 //set assembly attribute
1914 TDataStd_UAttribute::Set(theShapeL, XCAFDoc::AssemblyGUID());
1915 return Standard_True;
1917 return Standard_False;
1920 //=======================================================================
1921 //function : makeSubShape
1923 //=======================================================================
1925 void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& theMainShapeL,
1926 const TDF_Label& thePart,
1927 const TopoDS_Shape& theShape,
1928 const TopLoc_Location& theLoc)
1930 TopoDS_Iterator anIter(theShape);
1931 Standard_Boolean isCompoundPart = (GetShape(thePart).ShapeType() == TopAbs_COMPOUND);
1932 Standard_Boolean isAssembly = IsAssembly(thePart);
1934 for(; anIter.More(); anIter.Next()) {
1935 const TopoDS_Shape& aChildShape = anIter.Value();
1936 TDF_Label aChildLabel;
1937 FindSubShape(theMainShapeL, aChildShape, aChildLabel);
1938 if(!aChildLabel.IsNull()) {
1940 aChildLabel.ForgetAllAttributes();
1941 makeSubShape(theMainShapeL, thePart, aChildShape, theLoc);
1945 Handle(TDataStd_Name) anAttr;
1946 aChildLabel.FindAttribute(TDataStd_Name::GetID(), anAttr);
1947 TopLoc_Location aSubLoc;
1948 // Calculate location for subshapes of compound parts
1949 aSubLoc = aChildShape.Location();
1951 aSubLoc = theLoc.Inverted() * aSubLoc;
1953 TDF_Label aSubLabel;
1954 // Identical location and empty location are not the same for ShapeTool, so try to process both
1955 // in case of aSubLoc is not identical, the second Add try will not affect algorithm.
1956 Standard_Boolean isNewSubL;
1957 isNewSubL = AddSubShape(thePart, aChildShape.Located(aSubLoc, Standard_False), aSubLabel);
1958 if (aSubLabel.IsNull())
1960 isNewSubL = AddSubShape(thePart, aChildShape.Located(TopLoc_Location()), aSubLabel);
1963 //set name to sub shape
1964 if (!anAttr.IsNull()) {
1965 TDataStd_Name::Set(aSubLabel, anAttr->Get());
1968 Standard_SStream Stream;
1969 TopAbs::Print(aChildShape.ShapeType(), Stream);
1970 TCollection_AsciiString aName(Stream.str().c_str());
1971 TDataStd_Name::Set(aSubLabel, TCollection_ExtendedString(aName));
1973 // Create auxiliary link, it will be removed during moving attributes
1974 MakeReference(aSubLabel, aChildLabel, aChildShape.Location());
1977 aChildLabel.ForgetAllAttributes();
1981 makeSubShape(theMainShapeL, thePart, aChildShape, theLoc);
1985 //=======================================================================
1986 //function : updateComponent
1988 //=======================================================================
1990 Standard_Boolean XCAFDoc_ShapeTool::updateComponent(const TDF_Label& theItemLabel,
1991 TopoDS_Shape& theUpdatedShape,
1992 TDF_LabelMap& theUpdated) const
1994 if ( !IsAssembly(theItemLabel) )
1995 return Standard_False; // Do nothing for non-assemblies
1997 // Get the currently stored compound for the assembly
1998 TopoDS_Shape aCurrentRootShape;
1999 GetShape(theItemLabel, aCurrentRootShape);
2001 // Check if the given assembly is already updated
2002 if (theUpdated.Contains(theItemLabel)) {
2003 theUpdatedShape = aCurrentRootShape;
2004 return Standard_True;
2007 TopTools_MapOfOrientedShape aCurrentRootShapeMap (aCurrentRootShape.NbChildren());
2009 // Get components of the assembly
2010 TDF_LabelSequence aComponentLabs;
2011 GetComponents(theItemLabel, aComponentLabs);
2013 // This flag indicates whether to update the compound of the assembly
2014 Standard_Boolean isModified = Standard_False;
2016 // Compare the number of components in XDE structure with the number of
2017 // components in topological structure. A component may happen to be removed,
2018 // so we have to update the assembly compound
2019 const Standard_Integer aNumTopoComponents = aCurrentRootShape.NbChildren();
2021 if ( aNumTopoComponents != aComponentLabs.Length() )
2022 isModified = Standard_True;
2024 // Iterate over the assembly components. If at least one component is
2025 // modified (this is the recursive check), then the actually stored
2026 // compound has to be updated
2027 TopTools_ListOfShape aComponentShapes;
2029 for ( TDF_LabelSequence::Iterator aCompIt(aComponentLabs); aCompIt.More(); aCompIt.Next() )
2031 const TDF_Label& aComponentLab = aCompIt.Value();
2033 // Take the referred assembly item (ultimately, a part for an instance)
2034 TDF_Label aComponentRefLab;
2035 GetReferredShape(aComponentLab, aComponentRefLab);
2037 // Shape comes with some placement transformation here
2038 TopoDS_Shape aComponentShape;
2039 GetShape(aComponentLab, aComponentShape);
2040 TopLoc_Location aComponentLoc = aComponentShape.Location();
2042 // If the component is a sub-assembly, then its associated compound
2043 // has to be processed in the same manner
2044 if ( IsAssembly(aComponentRefLab) )
2047 if ( updateComponent(aComponentRefLab, aComponentShape, theUpdated) )
2049 isModified = Standard_True;
2050 aComponentShape.Location(aComponentLoc, Standard_False); // Apply placement
2055 // Search for a part in the actual compound of the ultimate assembly.
2056 // If the part is there, then the compound is up-to-date, so it does not require rebuilding
2059 if (aCurrentRootShapeMap.IsEmpty())
2061 // optimize search for next labels in aComponentLabs
2062 for (TopoDS_Iterator aTopoIt(aCurrentRootShape); aTopoIt.More(); aTopoIt.Next())
2064 aCurrentRootShapeMap.Add (aTopoIt.Value());
2067 if (!aCurrentRootShapeMap.Contains (aComponentShape))
2069 // Part has been modified somewhere, so the compound has to be rebuilt
2070 isModified = Standard_True;
2075 // Fill the list of shapes composing a new compound for the assembly
2076 aComponentShapes.Append(aComponentShape);
2079 // If any component is modified, we update the currently stored shape
2082 TopoDS_Compound anUpdatedCompound;
2084 aBB.MakeCompound(anUpdatedCompound);
2086 // Compose new compound
2087 for ( TopTools_ListIteratorOfListOfShape aShapeIt(aComponentShapes); aShapeIt.More(); aShapeIt.Next() )
2089 aBB.Add( anUpdatedCompound, aShapeIt.Value() );
2092 // Store the updated shape as an output
2093 theUpdatedShape = anUpdatedCompound;
2095 // Use topological naming services to store the updated shape in XDE
2096 TNaming_Builder NB(theItemLabel);
2097 NB.Generated(theUpdatedShape);
2101 theUpdated.Add(theItemLabel);
2106 //=======================================================================
2107 //function : GetNamedProperties
2109 //=======================================================================
2111 Handle(TDataStd_NamedData) XCAFDoc_ShapeTool::GetNamedProperties (const TDF_Label& theLabel,
2112 const Standard_Boolean theToCreate) const
2114 Handle(TDataStd_NamedData) aNamedProperty;
2115 if (!theLabel.FindAttribute(TDataStd_NamedData::GetID(), aNamedProperty) && theToCreate)
2117 aNamedProperty = TDataStd_NamedData::Set(theLabel);
2120 return aNamedProperty;
2123 //=======================================================================
2124 //function : GetNamedProperties
2126 //=======================================================================
2128 Handle(TDataStd_NamedData) XCAFDoc_ShapeTool::GetNamedProperties (const TopoDS_Shape& theShape,
2129 const Standard_Boolean theToCreate) const
2131 Handle(TDataStd_NamedData) aNamedProperty;
2133 if (!Search (theShape, aLabel))
2134 return aNamedProperty;
2136 aNamedProperty = GetNamedProperties (aLabel, theToCreate);
2138 return aNamedProperty;
2141 //=======================================================================
2142 //function : DumpJson
2144 //=======================================================================
2145 void XCAFDoc_ShapeTool::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
2147 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
2149 OCCT_DUMP_BASE_CLASS (theOStream, theDepth, TDF_Attribute)
2151 for (XCAFDoc_DataMapOfShapeLabel::Iterator aShapeLabelIt (myShapeLabels); aShapeLabelIt.More(); aShapeLabelIt.Next())
2153 const TopoDS_Shape aShape = aShapeLabelIt.Key();
2154 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, &aShape)
2156 TCollection_AsciiString aShapeLabel;
2157 TDF_Tool::Entry (aShapeLabelIt.Value(), aShapeLabel);
2158 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aShapeLabel)
2161 for (XCAFDoc_DataMapOfShapeLabel::Iterator aSubShapeIt (mySubShapes); aSubShapeIt.More(); aSubShapeIt.Next())
2163 const TopoDS_Shape aSubShape = aSubShapeIt.Key();
2164 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, &aSubShape)
2166 TCollection_AsciiString aSubShapeLabel;
2167 TDF_Tool::Entry (aSubShapeIt.Value(), aSubShapeLabel);
2168 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aSubShapeLabel)
2171 for (XCAFDoc_DataMapOfShapeLabel::Iterator aSimpleShapeIt (mySimpleShapes); aSimpleShapeIt.More(); aSimpleShapeIt.Next())
2173 const TopoDS_Shape aSimpleShape = aSimpleShapeIt.Key();
2174 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, &aSimpleShape)
2176 TCollection_AsciiString aSimpleShapeLabel;
2177 TDF_Tool::Entry (aSimpleShapeIt.Value(), aSimpleShapeLabel);
2178 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, aSimpleShapeLabel)
2181 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, hasSimpleShapes)