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.ixx>
17 #include <XCAFDoc.hxx>
19 #include <TDF_Tool.hxx>
20 #include <TDF_Label.hxx>
21 #include <TDF_LabelMap.hxx>
22 #include <TDF_LabelSequence.hxx>
23 #include <TDF_ChildIterator.hxx>
24 #include <TDF_ChildIDIterator.hxx>
25 #include <TDF_MapIteratorOfLabelMap.hxx>
27 #include <TDataStd_Name.hxx>
28 #include <TDataStd_TreeNode.hxx>
29 #include <TDataStd_ChildNodeIterator.hxx>
30 #include <TDataStd_UAttribute.hxx>
32 #include <TDocStd_Document.hxx>
34 #include <TNaming_Builder.hxx>
35 #include <TNaming_NamedShape.hxx>
36 #include <TNaming_Tool.hxx>
38 #include <TopLoc_Location.hxx>
39 #include <TopoDS_Iterator.hxx>
40 #include <TopoDS_Shape.hxx>
41 #include <TopoDS_Compound.hxx>
42 #include <BRep_Builder.hxx>
43 #include <XCAFDoc_Location.hxx>
45 #include <TCollection_AsciiString.hxx>
46 #include <TCollection_HAsciiString.hxx>
47 #include <TCollection_ExtendedString.hxx>
48 #include <TColStd_SequenceOfHAsciiString.hxx>
49 #include <XCAFDoc_GraphNode.hxx>
50 #include <TopLoc_IndexedMapOfLocation.hxx>
51 #include <gp_Trsf.hxx>
53 #include <XCAFDoc_ShapeMapTool.hxx>
55 static Standard_Boolean theAutoNaming = Standard_True;
57 // attribute methods //////////////////////////////////////////////////
59 //=======================================================================
62 //=======================================================================
64 const Standard_GUID& XCAFDoc_ShapeTool::GetID()
66 static Standard_GUID ShapeToolID ("efd212ee-6dfd-11d4-b9c8-0060b0ee281b");
71 //=======================================================================
74 //=======================================================================
76 Handle(XCAFDoc_ShapeTool) XCAFDoc_ShapeTool::Set(const TDF_Label& L)
78 Handle(XCAFDoc_ShapeTool) A;
79 if (!L.FindAttribute (XCAFDoc_ShapeTool::GetID(), A)) {
80 A = new XCAFDoc_ShapeTool ();
88 //=======================================================================
89 //function : Constructor
91 //=======================================================================
93 XCAFDoc_ShapeTool::XCAFDoc_ShapeTool()
95 hasSimpleShapes = Standard_False;
99 //=======================================================================
102 //=======================================================================
104 const Standard_GUID& XCAFDoc_ShapeTool::ID() const
109 //=======================================================================
112 //=======================================================================
114 void XCAFDoc_ShapeTool::Restore(const Handle(TDF_Attribute)& /*with*/)
118 //=======================================================================
119 //function : NewEmpty
121 //=======================================================================
123 Handle(TDF_Attribute) XCAFDoc_ShapeTool::NewEmpty() const
125 return new XCAFDoc_ShapeTool;
128 //=======================================================================
131 //=======================================================================
133 void XCAFDoc_ShapeTool::Paste (const Handle(TDF_Attribute)& /*into*/,
134 const Handle(TDF_RelocationTable)& /*RT*/) const
138 // Auxiliary methods //////////////////////////////////////////////////
140 //=======================================================================
141 //function : SetLabelNameByLink
143 //=======================================================================
144 static void SetLabelNameByLink(const TDF_Label L)
146 Handle(TDataStd_TreeNode) Node;
147 if (! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
148 ! Node->HasFather()) {
149 cout<<"Error: XCAFDoc_ShapeTool, SetLabelNameByLink(): NO NODE"<<endl;
152 TCollection_AsciiString Entry;
153 TDF_Tool::Entry ( Node->Father()->Label(), Entry );
154 Entry.Insert(1, "=>[");
157 TDataStd_Name::Set(L, TCollection_ExtendedString( Entry ));
161 //=======================================================================
162 //function : SetLabelNameByShape
164 //=======================================================================
165 static void SetLabelNameByShape(const TDF_Label L)
168 if (XCAFDoc_ShapeTool::GetShape(L, S) &&
169 ! L.IsAttribute(TDataStd_Name::GetID()) ) {
170 Standard_SStream Stream;
171 // TopAbs_ShapeEnum Type = S.ShapeType();
172 // if (Type == TopAbs_COMPOUND) Stream<<"ASSEMBLY";
174 TopAbs::Print(S.ShapeType(), Stream);
175 TCollection_AsciiString aName (Stream.str().c_str());
176 TDataStd_Name::Set(L, TCollection_ExtendedString(aName));
181 //=======================================================================
182 //function : SearchUsingMap
184 //=======================================================================
186 Standard_Boolean XCAFDoc_ShapeTool::SearchUsingMap(const TopoDS_Shape &S, TDF_Label &L,
187 const Standard_Boolean findWithoutLoc,
188 const Standard_Boolean findSubShape) const
191 if(myShapeLabels.IsBound(S)) {
192 L = myShapeLabels.Find(S);
193 return Standard_True;
198 if(myShapeLabels.IsBound(S0)) {
199 TDF_Label L1 = myShapeLabels.Find(S0);
200 TDF_LabelSequence Labels;
201 if(GetUsers(L1, Labels, Standard_True)) {
202 for(Standard_Integer i=1; i<=Labels.Length(); i++) {
203 TopoDS_Shape c = GetShape(Labels.Value(i));
206 return Standard_True;
212 return Standard_True;
216 if(hasSimpleShapes) {
217 if(mySimpleShapes.IsBound(S)) {
218 L = mySimpleShapes.Find(S);
219 return Standard_True;
221 if(mySimpleShapes.IsBound(S0)) {
222 L = mySimpleShapes.Find(S0);
223 return Standard_True;
227 if(!findSubShape) return Standard_False;
228 TDF_Label mainL = FindMainShapeUsingMap(S);
229 if(mainL.IsNull()) return Standard_False;
230 L = AddSubShape(mainL,S);
231 return !L.IsNull();//Standard_True;
235 //=======================================================================
238 //=======================================================================
240 Standard_Boolean XCAFDoc_ShapeTool::Search (const TopoDS_Shape &S,
242 const Standard_Boolean findInstance,
243 const Standard_Boolean findComponent,
244 const Standard_Boolean findSubShape) const
246 // search among shapes
247 Standard_Boolean isLocated = ! S.Location().IsIdentity();
250 // try to find top-level instance
251 if ( findInstance && FindShape ( S, L, Standard_True ) )
252 return Standard_True;
253 // try to find component of assembly
254 if ( findComponent ) {
255 TDF_LabelSequence labels;
256 GetShapes ( labels );
257 for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
258 if ( ! IsAssembly ( labels.Value(i) ) ) continue;
259 TDF_LabelSequence comp;
260 GetComponents ( labels.Value(i), comp );
261 for ( Standard_Integer j=1; j <= comp.Length(); j++ ) {
262 TopoDS_Shape c = GetShape ( comp.Value(j) );
263 if ( c.IsSame ( S ) ) {
265 return Standard_True;
271 // try to find top-level simple shape
272 if ( FindShape ( S, L, Standard_False ) ) return Standard_True;
275 if ( ! findSubShape ) return Standard_False;
276 TDF_Label mainL = FindMainShape ( S );
277 if ( mainL.IsNull() ) return Standard_False;
278 L = AddSubShape ( mainL, S );
279 return !L.IsNull();//Standard_True;
282 //=======================================================================
283 //function : FindShape
285 //=======================================================================
287 Standard_Boolean XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S,
289 const Standard_Boolean findInstance) const
291 // search for null-located shape
293 if ( ! findInstance ) {
298 // this code is used instead of the following for performance reasons
299 if (TNaming_Tool::HasLabel(Label(), S0)) {
301 L = TNaming_Tool::Label(Label(), S0, TransDef);
302 return Standard_True;
305 TDF_ChildIDIterator it(myLabel,TNaming_NamedShape::GetID());
306 for (; it.More(); it.Next()) {
307 TDF_Label aLabel = it.Value()->Label();
308 Handle(TNaming_NamedShape) NS;
309 if ( aLabel.FindAttribute(TNaming_NamedShape::GetID(), NS) &&
310 S0.IsSame ( TNaming_Tool::GetShape(NS) ) ) {
312 return Standard_True;
316 return Standard_False;
319 //=======================================================================
320 //function : FindShape
322 //=======================================================================
324 TDF_Label XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S,
325 const Standard_Boolean findInstance) const
328 FindShape ( S, L, findInstance );
332 //=======================================================================
333 //function : GetShape
335 //=======================================================================
337 Standard_Boolean XCAFDoc_ShapeTool::GetShape (const TDF_Label& L, TopoDS_Shape& S)
339 Handle(XCAFDoc_Location) LocationAttribute;
342 TopoDS_Compound EmptyComp;
344 B.MakeCompound(EmptyComp);
348 // for instance, get referred shape
349 Handle(TDataStd_TreeNode) Node;
350 if ( L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather() &&
351 L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute)) {
352 if ( ! GetShape(Node->Father()->Label(), S) ) return Standard_False;
353 S.Move ( LocationAttribute->Get() );
354 return Standard_True;
357 // else just return shape on this label
358 Handle(TNaming_NamedShape) NS;
359 if ( ! L.FindAttribute(TNaming_NamedShape::GetID(), NS) ) return Standard_False;
360 S = TNaming_Tool::GetShape(NS);
361 return Standard_True;
364 //=======================================================================
365 //function : GetShape
367 //=======================================================================
369 TopoDS_Shape XCAFDoc_ShapeTool::GetShape(const TDF_Label& L)
376 //=======================================================================
377 //function : NewShape
379 //=======================================================================
381 TDF_Label XCAFDoc_ShapeTool::NewShape() const
383 TopoDS_Compound aShape;
385 tdsB.MakeCompound ( aShape );
388 TDF_Label aLabel = aTag.NewChild(Label());
390 TNaming_Builder tnBuild(aLabel);
391 tnBuild.Generated(aShape);
396 //=======================================================================
397 //function : SetShape
399 //=======================================================================
401 void XCAFDoc_ShapeTool::SetShape (const TDF_Label& L, const TopoDS_Shape& S)
403 TNaming_Builder tnBuild(L);
404 tnBuild.Generated(S);
405 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(L);
406 // if ( ! L.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
407 // A = XCAFDoc_ShapeMapTool::Set(L);
408 // L.AddAttribute(A);
412 if(!myShapeLabels.IsBound(S)) {
413 myShapeLabels.Bind(S,L);
416 //:abv 31.10.01: update assemblies that refer a shape
417 TDF_LabelSequence Labels;
418 if ( GetUsers ( L, Labels, Standard_True ) ) {
419 for ( Standard_Integer i=Labels.Length(); i >=1; i-- )
420 UpdateAssembly ( Labels(i) );
424 //=======================================================================
425 //function : MakeReference
427 //=======================================================================
429 void XCAFDoc_ShapeTool::MakeReference (const TDF_Label &L,
430 const TDF_Label &refL,
431 const TopLoc_Location &loc)
434 XCAFDoc_Location::Set(L, loc);
437 Handle(TDataStd_TreeNode) refNode, mainNode;
438 mainNode = TDataStd_TreeNode::Set ( refL, XCAFDoc::ShapeRefGUID() );
439 refNode = TDataStd_TreeNode::Set ( L, XCAFDoc::ShapeRefGUID() );
440 refNode->Remove(); // abv: fix against bug in TreeNode::Append()
441 mainNode->Append(refNode);
444 SetLabelNameByLink(L);
447 //=======================================================================
448 //function : addShape
450 //=======================================================================
452 TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly)
454 TDF_Label ShapeLabel;
457 // search if the shape already exists (with the same location)
458 if ( S.IsNull() || FindShape ( S, ShapeLabel, Standard_True ) ) return ShapeLabel;
460 // else add a new label
461 ShapeLabel = aTag.NewChild(Label());
463 // if shape has location, make a reference to the same shape without location
464 if ( ! S.Location().IsIdentity() /*&& FindShape ( S, L )*/ ) {
468 TDF_Label L = addShape ( S0, makeAssembly );
469 MakeReference ( ShapeLabel, L, S.Location() );
473 // else add a shape to a label
474 TNaming_Builder tnBuild(ShapeLabel);
475 tnBuild.Generated(S);
477 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
478 // if ( ! ShapeLabel.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
479 // A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
480 // ShapeLabel.AddAttribute(A);
485 SetLabelNameByShape(ShapeLabel);
487 // if shape is Compound and flag is set, create assembly
488 if ( makeAssembly && S.ShapeType() == TopAbs_COMPOUND ) {
489 // mark assembly by assigning UAttribute
490 Handle(TDataStd_UAttribute) Uattr;
491 Uattr = TDataStd_UAttribute::Set ( ShapeLabel, XCAFDoc::AssemblyGUID() );
493 TDataStd_Name::Set(ShapeLabel, TCollection_ExtendedString("ASSEMBLY"));
495 // iterate on components
496 TopoDS_Iterator Iterator(S);
497 for (; Iterator.More(); Iterator.Next()) {
498 // get label for component`s shape
499 TopoDS_Shape Scomp = Iterator.Value(), S0 = Scomp;
502 TDF_Label compL = addShape ( S0, makeAssembly );
504 // add a component as reference
505 TDF_Label RefLabel = aTag.NewChild(ShapeLabel);
506 MakeReference ( RefLabel, compL, Scomp.Location() );
510 if(!IsAssembly(ShapeLabel)) {
511 //const TopTools_IndexedMapOfShape tmpMap = A->GetMap();
512 //for(Standard_Integer i=1; i<=tmpMap.Extent(); i++)
513 //mySubShapes.Bind(tmpMap.FindKey(i),ShapeLabel);
514 for(Standard_Integer i=1; i<=A->GetMap().Extent(); i++)
516 TopoDS_Shape aSh = A->GetMap().FindKey(i);
517 mySubShapes.Bind(aSh,ShapeLabel);
519 //mySubShapes.Bind(ShapeLabel,A->GetMap());
526 //=======================================================================
527 //function : prepareAssembly
529 //=======================================================================
530 static Standard_Boolean prepareAssembly (const TopoDS_Shape& theShape,
531 TopoDS_Shape& theOUTShape)
533 // iterate on components
534 theOUTShape = theShape;
535 if (theShape.ShapeType() == TopAbs_COMPOUND) {
537 // check if shape if frosen
538 if (!theOUTShape.Free())
539 theOUTShape.Free(Standard_True);
541 TopTools_SequenceOfShape aSubShapeSeq;
542 TopoDS_Iterator Iterator(theShape);
543 for (; Iterator.More(); Iterator.Next())
544 aSubShapeSeq.Append(Iterator.Value());
545 for (Standard_Integer i = 1; i <= aSubShapeSeq.Length(); i++) {
546 TopoDS_Shape Scomp = aSubShapeSeq.Value(i);
547 TopoDS_Shape aNewScomp;
548 B.Remove(theOUTShape, Scomp);
549 prepareAssembly( Scomp, aNewScomp );
550 TopLoc_Location aLoc;
551 aLoc = aNewScomp.Location();
552 if ( aLoc.IsIdentity() ) {
553 // create an "empty" location
555 aTrsf.SetScale(gp_Pnt(0,0,0), 1);
556 aLoc = TopLoc_Location( aTrsf );
557 aNewScomp.Location( aLoc );
559 B.Add(theOUTShape, aNewScomp);
562 return Standard_True;
566 //=======================================================================
567 //function : AddShape
569 //=======================================================================
571 TDF_Label XCAFDoc_ShapeTool::AddShape (const TopoDS_Shape& theShape,
572 const Standard_Boolean makeAssembly,
573 const Standard_Boolean makePrepare)
575 // PTV 17.02.2003 to avoid components without location.
576 TopoDS_Shape S = theShape;
577 if ( makePrepare && makeAssembly && S.ShapeType() == TopAbs_COMPOUND )
578 prepareAssembly( theShape, S ); // OCC1669
580 TDF_Label L = addShape(S,makeAssembly);
582 if(!myShapeLabels.IsBound(S)) {
583 myShapeLabels.Bind(S,L);
588 //return addShape( S, makeAssembly );
591 //=======================================================================
592 //function : RemoveShape
594 //=======================================================================
596 Standard_Boolean XCAFDoc_ShapeTool::RemoveShape (const TDF_Label& L,
597 const Standard_Boolean removeCompletely) const
599 if ( ! IsTopLevel ( L ) || ! IsFree ( L ) ) return Standard_False;
601 Handle(TDataStd_TreeNode) aNode;
603 if (removeCompletely &&
604 L.FindAttribute (XCAFDoc::ShapeRefGUID(), aNode) &&
605 aNode->HasFather() &&
606 L.IsAttribute (XCAFDoc_Location::GetID()))
608 aLabel = aNode->Father()->Label();
611 L.ForgetAllAttributes (Standard_True);
613 if (removeCompletely && !aLabel.IsNull())
615 return RemoveShape(aLabel);
617 return Standard_True;
621 //=======================================================================
624 //=======================================================================
626 void XCAFDoc_ShapeTool::Init()
628 hasSimpleShapes = Standard_False;
632 //=======================================================================
633 //function : SetAutoNaming
635 //=======================================================================
637 void XCAFDoc_ShapeTool::SetAutoNaming (const Standard_Boolean V)
643 //=======================================================================
644 //function : AutoNaming
646 //=======================================================================
648 Standard_Boolean XCAFDoc_ShapeTool::AutoNaming()
650 return theAutoNaming;
654 //=======================================================================
655 //function : ComputeShapes
657 //=======================================================================
659 void XCAFDoc_ShapeTool::ComputeShapes(const TDF_Label& L)
661 TDF_ChildIterator it(L);
662 for(; it.More(); it.Next()) {
663 TDF_Label L1 = it.Value();
666 if(!myShapeLabels.IsBound(S)) {
667 mySimpleShapes.Bind(S,L1);
675 //=======================================================================
676 //function : ComputeSimpleShapes
678 //=======================================================================
680 void XCAFDoc_ShapeTool::ComputeSimpleShapes()
682 ComputeShapes(Label());
683 hasSimpleShapes = Standard_True;
687 //=======================================================================
688 //function : GetShapes
690 //=======================================================================
692 void XCAFDoc_ShapeTool::GetShapes(TDF_LabelSequence& Labels) const
696 TDF_ChildIterator it(Label());
697 for (; it.More(); it.Next()) {
698 TDF_Label L = it.Value();
700 if ( GetShape ( L, S ) ) Labels.Append ( L );
705 //=======================================================================
706 //function : GetFreeShapes
708 //=======================================================================
710 void XCAFDoc_ShapeTool::GetFreeShapes (TDF_LabelSequence& FreeLabels) const
714 TDF_ChildIterator it(Label());
715 for (; it.More(); it.Next()) {
716 TDF_Label L = it.Value();
718 if ( GetShape ( L, S ) && IsFree ( L ) ) FreeLabels.Append ( L );
722 //=======================================================================
723 //function : IsTopLevel
725 //=======================================================================
727 Standard_Boolean XCAFDoc_ShapeTool::IsTopLevel (const TDF_Label& L) const
729 return L.Father() == Label();
732 //=======================================================================
735 //=======================================================================
737 Standard_Boolean XCAFDoc_ShapeTool::IsShape (const TDF_Label& L)
739 return IsSimpleShape ( L ) || IsAssembly ( L ) || IsReference ( L );
742 //=======================================================================
743 //function : IsSimpleShape
745 //=======================================================================
747 Standard_Boolean XCAFDoc_ShapeTool::IsSimpleShape (const TDF_Label& L)
749 Handle(TNaming_NamedShape) NS;
750 return L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) &&
751 ! IsAssembly ( L ) && ! IsReference ( L );
754 //=======================================================================
755 //function : IsReference
757 //=======================================================================
759 Standard_Boolean XCAFDoc_ShapeTool::IsReference (const TDF_Label& L)
761 Handle(TDataStd_TreeNode) Node;
762 return L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather();
765 //=======================================================================
766 //function : IsAssembly
768 //=======================================================================
770 Standard_Boolean XCAFDoc_ShapeTool::IsAssembly (const TDF_Label& L)
772 Handle(TDataStd_UAttribute) Uattr;
773 return L.FindAttribute(XCAFDoc::AssemblyGUID(), Uattr);
776 //=======================================================================
777 //function : IsComponent
779 //=======================================================================
781 Standard_Boolean XCAFDoc_ShapeTool::IsComponent (const TDF_Label& L)
783 return IsReference ( L ) && IsAssembly ( L.Father() );
786 //=======================================================================
787 //function : IsCompound
789 //=======================================================================
791 Standard_Boolean XCAFDoc_ShapeTool::IsCompound (const TDF_Label& L)
793 Handle(TDataStd_Name) Name;
794 if (L.FindAttribute(TDataStd_Name::GetID(),Name)) {
795 TCollection_ExtendedString estr1 = Name->Get();
796 TCollection_ExtendedString estr2("COMPOUND");
798 return Standard_True;
801 return Standard_False;
804 //=======================================================================
805 //function : IsSubShape
807 //=======================================================================
809 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label& L)
811 return IsSimpleShape ( L ) && IsShape ( L.Father() );
814 //=======================================================================
817 //=======================================================================
819 Standard_Boolean XCAFDoc_ShapeTool::IsFree (const TDF_Label& L)
821 Handle(TDataStd_TreeNode) Node;
822 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
823 ! Node->HasFirst() ) return Standard_True;
825 return Standard_False;
828 //=======================================================================
829 //function : GetUsers
830 //purpose : Returns number of users (0 if shape is free)
831 //=======================================================================
833 Standard_Integer XCAFDoc_ShapeTool::GetUsers (const TDF_Label& L,
834 TDF_LabelSequence& Labels,
835 const Standard_Boolean getsubchilds)
837 Standard_Integer NbUsers=0;
838 Handle(TDataStd_TreeNode) Node ;
840 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ) return NbUsers;
842 Node = Node->First();
843 while ( ! Node.IsNull() ) {
845 if ( getsubchilds ) {
846 TDF_Label underL = Node->Label().Father();
847 NbUsers += GetUsers ( underL, Labels, getsubchilds );
850 Labels.Append(Node->Label());
857 //=======================================================================
858 //function : NbComponents
860 //=======================================================================
862 Standard_Integer XCAFDoc_ShapeTool::NbComponents (const TDF_Label& L,
863 const Standard_Boolean getsubchilds)
865 TDF_LabelSequence subLabels;
866 GetComponents (L, subLabels, getsubchilds);
867 return subLabels.Length();
870 //=======================================================================
871 //function : GetComponents
873 //=======================================================================
875 Standard_Boolean XCAFDoc_ShapeTool::GetComponents (const TDF_Label& L, TDF_LabelSequence& Labels,
876 const Standard_Boolean getsubchilds)
878 if ( ! IsAssembly(L) ) return Standard_False;
880 TDF_ChildIterator It(L);
881 for (; It.More(); It.Next() ) {
882 TDF_Label comp = It.Value();
883 if ( IsComponent ( comp ) ) {
884 if ( getsubchilds ) {
886 if ( GetReferredShape ( comp, underL ) )
887 GetComponents ( underL, Labels, getsubchilds);
889 Labels.Append ( comp );
892 return Standard_True;
895 //=======================================================================
896 //function : GetLocation
898 //=======================================================================
900 TopLoc_Location XCAFDoc_ShapeTool::GetLocation (const TDF_Label& L)
902 Handle(XCAFDoc_Location) LocationAttribute;
903 if (L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute))
904 return LocationAttribute->Get();
906 Handle(TNaming_NamedShape) NS;
908 if ( L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) ) {
909 S = TNaming_Tool::GetShape(NS);
914 //=======================================================================
915 //function : GetReferredShape
917 //=======================================================================
919 Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L,
922 if ( ! IsReference(L) ) return Standard_False;
924 Handle (TDataStd_TreeNode) Node;
925 L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node);
926 Label = Node->Father()->Label();
927 return Standard_True;
930 //=======================================================================
931 //function : AddComponent
933 //=======================================================================
935 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
936 const TDF_Label& compL,
937 const TopLoc_Location &Loc) const
941 // check that shape is assembly
942 if ( ! IsAssembly(assembly) ) {
943 // if it is simple shape, make it assembly
944 if ( IsSimpleShape(assembly) )
945 TDataStd_UAttribute::Set ( assembly, XCAFDoc::AssemblyGUID() );
949 // add a component as reference
951 L = aTag.NewChild(assembly);
952 MakeReference ( L, compL, Loc );
954 // update assembly`s TopoDS_Shape
955 UpdateAssembly ( assembly );
959 //=======================================================================
960 //function : AddComponent
962 //=======================================================================
964 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
965 const TopoDS_Shape& comp,
966 const Standard_Boolean expand)
968 // get label for component`s shape
969 TopoDS_Shape S0 = comp;
973 compL = AddShape ( S0, expand );
975 // add component by its label
976 return AddComponent ( assembly, compL, comp.Location() );
979 //=======================================================================
980 //function : RemoveComponent
982 //=======================================================================
984 void XCAFDoc_ShapeTool::RemoveComponent (const TDF_Label& comp) const
986 if ( IsComponent(comp) ) {
987 comp.ForgetAllAttributes();
988 UpdateAssembly(comp.Father());
992 //=======================================================================
993 //function : UpdateAssembly
995 //=======================================================================
997 void XCAFDoc_ShapeTool::UpdateAssembly (const TDF_Label& L) const
999 if ( ! IsAssembly(L) ) return;
1001 TopoDS_Compound newassembly;
1003 b.MakeCompound(newassembly);
1005 TDF_ChildIterator chldLabIt(L);
1006 for (; chldLabIt.More(); chldLabIt.Next() ) {
1007 TDF_Label subLabel = chldLabIt.Value();
1008 if ( IsComponent ( subLabel ) ) {
1009 b.Add(newassembly, GetShape(subLabel));
1012 TNaming_Builder tnBuild(L);
1013 tnBuild.Generated(newassembly);
1016 //=======================================================================
1017 //function : IsSubShape
1019 //=======================================================================
1021 //static Standard_Boolean CheckSubShape (const TopoDS_Shape &S, const TopoDS_Shape &sub)
1023 // if ( S.IsSame ( sub ) ) return Standard_True;
1025 // if ( S.ShapeType() >= sub.ShapeType() ) return Standard_False;
1027 // for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
1028 // if ( CheckSubShape ( it.Value(), sub ) ) return Standard_True;
1030 // return Standard_False;
1033 //=======================================================================
1034 //function : IsSubShape
1036 //=======================================================================
1038 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label &shapeL,
1039 const TopoDS_Shape &sub) const
1041 Handle(XCAFDoc_ShapeMapTool) A;
1042 if ( ! shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) )
1043 return Standard_False;
1045 //TopoDS_Shape S = GetShape ( shapeL );
1046 //return ! S.IsNull() && CheckSubShape ( S, sub );
1048 return A->IsSubShape(sub);
1051 //=======================================================================
1052 //function : FindSubShape
1054 //=======================================================================
1056 Standard_Boolean XCAFDoc_ShapeTool::FindSubShape (const TDF_Label &shapeL,
1057 const TopoDS_Shape &sub,
1060 // this code is used instead of the following for performance reasons
1061 if ( TNaming_Tool::HasLabel(Label(), sub) ) {
1063 L = TNaming_Tool::Label(Label(), sub, TransDef);
1064 return ( ! L.IsNull() && L.Father() == shapeL );
1068 TDF_ChildIterator chldLabIt(shapeL);
1069 for (; chldLabIt.More(); chldLabIt.Next() ) {
1070 TDF_Label subLabel = chldLabIt.Value();
1072 if ( GetShape ( subLabel, S ) && S.IsSame ( sub ) ) {
1074 return Standard_True;
1078 return Standard_False;
1081 //=======================================================================
1082 //function : AddSubShape
1084 //=======================================================================
1086 TDF_Label XCAFDoc_ShapeTool::AddSubShape (const TDF_Label &shapeL,
1087 const TopoDS_Shape &sub) const
1090 if ( FindSubShape ( shapeL, sub, L ) ) return L;
1092 if ( ! IsSubShape ( shapeL, sub ) ) return L;
1095 L = aTag.NewChild(shapeL);
1097 TNaming_Builder tnBuild(L);
1098 tnBuild.Generated(sub);
1100 // if(!mySubShapes.IsBound(sub))
1101 // mySubShapes.Bind(sub,L);
1107 //=======================================================================
1108 //function : FindMainShapeUsingMap
1110 //=======================================================================
1112 TDF_Label XCAFDoc_ShapeTool::FindMainShapeUsingMap(const TopoDS_Shape &sub) const
1114 //for(Standard_Integer i=1; i<=myNotAssemblies.Length(); i++) {
1115 // TDF_Label L = myNotAssemblies.Value(i);
1116 // if(IsSubShape(L,sub)) return L;
1118 if(mySubShapes.IsBound(sub))
1119 return mySubShapes.Find(sub);
1125 //=======================================================================
1126 //function : FindMainShape
1128 //=======================================================================
1130 TDF_Label XCAFDoc_ShapeTool::FindMainShape (const TopoDS_Shape &sub) const
1132 TDF_ChildIterator it(Label());
1133 for (; it.More(); it.Next()) {
1134 TDF_Label L = it.Value();
1135 if ( ! IsAssembly ( L ) && IsSubShape ( L, sub ) ) return L;
1142 //=======================================================================
1143 //function : GetSubShapes
1145 //=======================================================================
1147 Standard_Boolean XCAFDoc_ShapeTool::GetSubShapes (const TDF_Label &L,
1148 TDF_LabelSequence& Labels)
1150 TDF_ChildIterator It(L);
1151 for (; It.More(); It.Next() ) {
1152 TDF_Label sub = It.Value();
1153 if ( IsSubShape ( sub ) ) Labels.Append ( sub );
1155 return Labels.Length() >0;
1158 //=======================================================================
1159 //function : BaseLabel
1161 //=======================================================================
1163 TDF_Label XCAFDoc_ShapeTool::BaseLabel () const
1168 //=======================================================================
1169 //function : DumpAssembly
1170 //purpose : recursive part of Dump()
1171 //=======================================================================
1173 static void DumpAssembly(const TDF_Label L,
1174 const Standard_Integer level,
1175 const Standard_Boolean deep)
1177 for (Standard_Integer i=0; i<level; i++)
1180 TCollection_AsciiString Entry;
1181 TDF_Tool::Entry(L, Entry);
1183 cout<<"ASSEMBLY "<<Entry;
1184 Handle(TDataStd_Name) Name;
1185 if (L.FindAttribute(TDataStd_Name::GetID(), Name))
1186 cout<<" "<<Name->Get();
1190 XCAFDoc_ShapeTool::GetShape(L, S);
1191 cout<<"("<<*(void**)&S.TShape();
1192 if (! S.Location().IsIdentity())
1193 cout<<", "<< *(void**)&S.Location();
1198 Handle(TDataStd_TreeNode) Node;
1199 TDF_ChildIDIterator NodeIterator(L, XCAFDoc::ShapeRefGUID());
1200 for (; NodeIterator.More(); NodeIterator.Next()) {
1201 Node = Handle(TDataStd_TreeNode)::DownCast(NodeIterator.Value());
1202 if (Node->HasFather()) {
1203 if (Node->Father()->Label().HasChild())
1204 DumpAssembly(Node->Father()->Label(), level+1, deep);
1206 XCAFDoc_ShapeTool::DumpShape(Node->Father()->Label(), level+1, deep);
1213 //=======================================================================
1216 //=======================================================================
1218 void XCAFDoc_ShapeTool::Dump(const Standard_Boolean deep) const
1220 Standard_Integer level = 0;
1221 // TopTools_SequenceOfShape SeqShapes;
1222 TDF_LabelSequence SeqLabels;
1223 GetShapes( SeqLabels);
1225 if (SeqLabels.Length()>0) cout<<endl;
1227 for (i=1; i<=SeqLabels.Length(); i++) {
1228 DumpAssembly(SeqLabels.Value(i), level, deep);
1232 GetFreeShapes(SeqLabels);
1233 cout<<endl<<"Free Shapes: "<<SeqLabels.Length()<<endl;
1234 for (i = 1; i<=SeqLabels.Length(); i++) {
1235 DumpShape(SeqLabels.Value(i), level, deep);
1240 //=======================================================================
1241 //function : DumpShape
1243 //=======================================================================
1245 void XCAFDoc_ShapeTool::DumpShape(const TDF_Label& L,const Standard_Integer level,const Standard_Boolean deep)
1248 if(! XCAFDoc_ShapeTool::GetShape(L, S) ) return;
1249 for (Standard_Integer i=0; i<level; i++)
1252 if (S.ShapeType() == TopAbs_COMPOUND) cout<<"ASSEMBLY";
1253 else TopAbs::Print(S.ShapeType(), cout);
1255 TCollection_AsciiString Entry;
1256 TDF_Tool::Entry(L, Entry);
1259 Handle(TDataStd_Name) Name;
1260 if (L.FindAttribute(TDataStd_Name::GetID(),Name))
1261 cout<<" "<<Name->Get();
1264 cout<<"("<<*(void**)&S.TShape();
1265 if (! S.Location().IsIdentity())
1266 cout<<", "<< *(void**)&S.Location();
1271 //=======================================================================
1272 //function : IsExternRef
1274 //=======================================================================
1276 Standard_Boolean XCAFDoc_ShapeTool::IsExternRef(const TDF_Label& L)
1278 Handle(TDataStd_UAttribute) Uattr;
1279 return L.FindAttribute(XCAFDoc::ExternRefGUID(), Uattr);
1282 //=======================================================================
1283 //function : SetExternRefs
1285 //=======================================================================
1287 void XCAFDoc_ShapeTool::SetExternRefs(const TDF_Label& L,
1288 const TColStd_SequenceOfHAsciiString& SHAS) const
1290 TDF_Label ShapeLabel = L.NewChild();
1291 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1292 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1293 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1294 Handle(TCollection_HAsciiString) str = SHAS(i);
1295 TCollection_ExtendedString extstr(str->String());
1296 TDataStd_Name::Set(tmplbl,extstr);
1300 //=======================================================================
1301 //function : SetExternRefs
1303 //=======================================================================
1305 TDF_Label XCAFDoc_ShapeTool::SetExternRefs(const TColStd_SequenceOfHAsciiString& SHAS) const
1307 TDF_Label ShapeLabel;
1310 ShapeLabel = aTag.NewChild(Label());
1311 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1312 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1313 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1314 Handle(TCollection_HAsciiString) str = SHAS(i);
1315 TCollection_ExtendedString extstr(str->String());
1316 TDataStd_Name::Set(tmplbl,extstr);
1321 //=======================================================================
1322 //function : GetExternRefs
1324 //=======================================================================
1326 void XCAFDoc_ShapeTool::GetExternRefs(const TDF_Label& L,
1327 TColStd_SequenceOfHAsciiString& SHAS)
1329 Handle(TDataStd_Name) TDN;
1331 for(Standard_Integer i=1; i<=L.NbChildren(); i++) {
1332 tmplbl = L.FindChild(i);
1333 if(tmplbl.FindAttribute(TDataStd_Name::GetID(),TDN)) {
1334 TCollection_ExtendedString extstr = TDN->Get();
1335 Handle(TCollection_HAsciiString) str =
1336 new TCollection_HAsciiString(TCollection_AsciiString(extstr, '?'));
1342 // API: API work with SHUO (Specified Higher Usage Occurrance) structure
1344 //=======================================================================
1345 //function : GetSHUO
1347 //=======================================================================
1349 Standard_Boolean XCAFDoc_ShapeTool::GetSHUO (const TDF_Label& SHUOLabel,
1350 Handle(XCAFDoc_GraphNode)& aSHUOAttr)
1352 if ( !SHUOLabel.FindAttribute( XCAFDoc::SHUORefGUID(), aSHUOAttr ) )
1353 return Standard_False;
1354 return Standard_True;
1357 //=======================================================================
1358 //function : GetAllComponentSHUO
1360 //=======================================================================
1362 Standard_Boolean XCAFDoc_ShapeTool::GetAllComponentSHUO (const TDF_Label& theCompLabel,
1363 TDF_AttributeSequence& theSHUOAttrs)
1365 TDF_ChildIterator it(theCompLabel);
1366 for (; it.More(); it.Next()) {
1367 TDF_Label L = it.Value();
1368 Handle(XCAFDoc_GraphNode) aSHUOAttr;
1369 if ( GetSHUO( L, aSHUOAttr ) )
1370 theSHUOAttrs.Append( aSHUOAttr );
1372 return (theSHUOAttrs.Length() > 0);
1375 //=======================================================================
1376 //function : SetSHUO
1378 //=======================================================================
1380 Standard_Boolean XCAFDoc_ShapeTool::SetSHUO (const TDF_LabelSequence& labels,
1381 Handle(XCAFDoc_GraphNode)& MainSHUOAttr) const
1383 MainSHUOAttr.Nullify();
1384 // check number of labels
1385 if (labels.Length() < 2)
1386 return Standard_False;
1387 // check is all labels contains components of any assemblyies
1389 for (i = 1; i <= labels.Length(); i++)
1390 if ( !IsComponent(labels.Value(i)) )
1391 return Standard_False;
1394 TDF_Label UpperSubL = aTag.NewChild( labels( 1 ) );
1395 if (theAutoNaming) {
1396 TCollection_ExtendedString Entry("SHUO");
1397 TDataStd_Name::Set(UpperSubL, TCollection_ExtendedString( Entry ));
1399 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1400 aUpperSHUO = XCAFDoc_GraphNode::Set( UpperSubL, XCAFDoc::SHUORefGUID() );
1401 // init out argument by main upper usage SHUO
1402 MainSHUOAttr = aUpperSHUO;
1403 // add other next_usage occurrences.
1404 for (i = 2; i <= labels.Length(); i++) {
1405 TDF_Label NextSubL = aTag.NewChild( labels( i ) );
1406 if (theAutoNaming) {
1407 TCollection_ExtendedString EntrySub("SHUO-");
1409 TDataStd_Name::Set(NextSubL, TCollection_ExtendedString( EntrySub ));
1411 Handle(XCAFDoc_GraphNode) aNextSHUO;
1412 aNextSHUO = XCAFDoc_GraphNode::Set( NextSubL, XCAFDoc::SHUORefGUID() );
1414 aUpperSHUO->SetChild( aNextSHUO );
1415 aNextSHUO->SetFather( aUpperSHUO );
1416 // now lets next_usage become upper_usage for next level of SHUO
1417 aUpperSHUO = aNextSHUO;
1418 UpperSubL = NextSubL;
1421 return Standard_True;
1424 //=======================================================================
1425 //function : GetSHUOUpperUsage
1427 //=======================================================================
1429 Standard_Boolean XCAFDoc_ShapeTool::GetSHUOUpperUsage (const TDF_Label& NextUsageL,
1430 TDF_LabelSequence& aLabels)
1432 Handle(XCAFDoc_GraphNode) aNextSHUO;
1433 if( !GetSHUO( NextUsageL, aNextSHUO ) || aNextSHUO->NbFathers()<1 )
1434 return Standard_False;
1436 // get upper_usage SHAO
1437 for (Standard_Integer i = 1; i <= aNextSHUO->NbFathers(); i++)
1438 aLabels.Append( aNextSHUO->GetFather(i)->Label() );
1439 return Standard_True;
1442 //=======================================================================
1443 //function : GetSHUONextUsage
1445 //=======================================================================
1447 Standard_Boolean XCAFDoc_ShapeTool::GetSHUONextUsage (const TDF_Label& UpperUsageL,
1448 TDF_LabelSequence& aLabels)
1450 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1451 if ( !GetSHUO( UpperUsageL, aUpperSHUO ) || aUpperSHUO->NbChildren()<1 )
1452 return Standard_False;
1453 // get upper_usage SHAO
1454 for (Standard_Integer i = 1; i <= aUpperSHUO->NbChildren(); i++)
1455 aLabels.Append( aUpperSHUO->GetChild(i)->Label() );
1456 return Standard_True;
1459 //=======================================================================
1460 //function : RemoveSHUO
1462 //=======================================================================
1464 Standard_Boolean XCAFDoc_ShapeTool::RemoveSHUO (const TDF_Label& L) const
1466 L.ForgetAllAttributes (Standard_True);
1467 return Standard_True;
1470 //=======================================================================
1471 //function : checkForShape
1472 //purpose : auxilary
1473 //=======================================================================
1475 static Standard_Boolean checkForShape (const TopoDS_Shape& theShape,
1476 const TopoDS_Shape& theCurSh,
1477 const TDF_Label& theUserL,
1478 TDF_LabelSequence& theLabels)
1480 // the label of an assembly which contains this component
1481 TDF_Label aSuperUserL = theUserL.Father();
1482 TopLoc_Location aSupLoc, aCompLoc;
1483 aSupLoc = ::XCAFDoc_ShapeTool::GetLocation ( aSuperUserL );
1484 aCompLoc = ::XCAFDoc_ShapeTool::GetLocation ( theUserL );
1485 TopoDS_Shape aCopySh = theCurSh;
1486 aCompLoc = aCompLoc.Multiplied( theCurSh.Location() );
1487 aSupLoc = aSupLoc.Multiplied( aCompLoc );
1488 aCopySh.Location( aSupLoc );
1489 if ( aCopySh.IsSame( theShape ) ) {
1490 theLabels.Prepend( theUserL );
1491 return Standard_True;
1493 // try to search deeply (upper by assmebly structure)
1494 TDF_LabelSequence aNewLabels;
1495 for (Standard_Integer j = 1; j <= theLabels.Length(); j++)
1496 aNewLabels.Append( theLabels.Value( j ) );
1497 aNewLabels.Prepend( theUserL );
1498 TDF_LabelSequence aUsers;
1499 ::XCAFDoc_ShapeTool::GetUsers( aSuperUserL, aUsers );
1500 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1501 if ( checkForShape( theShape, aCopySh, aUsers.Value( i ), aNewLabels ) ) {
1503 theLabels = aNewLabels;
1504 return Standard_True;
1506 return Standard_False;
1509 //=======================================================================
1510 //function : FindComponent
1512 //=======================================================================
1514 Standard_Boolean XCAFDoc_ShapeTool::FindComponent (const TopoDS_Shape& theShape,
1515 TDF_LabelSequence& theLabels) const
1518 // search for a top-level shape that corresponds to this component
1519 TopoDS_Shape S0 = theShape;
1520 TopLoc_Location loc;
1521 S0.Location ( loc );
1522 TDF_Label aRefL = FindShape( S0 );
1524 return Standard_False; // cannot find top-level shape.
1526 TDF_LabelSequence aUsers;
1527 ::XCAFDoc_ShapeTool::GetUsers( aRefL, aUsers );
1528 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1529 if ( checkForShape( theShape, S0, aUsers.Value( i ), theLabels ) )
1532 return (theLabels.Length() > 0);
1535 //=======================================================================
1536 //function : getShapesOfSHUO
1537 //purpose : auxilary
1538 //=======================================================================
1540 static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLocMap,
1541 const Handle(XCAFDoc_ShapeTool)& theSTool,
1542 const TDF_Label& theSHUOlab,
1543 TopoDS_Shape& theShape)
1545 Handle(XCAFDoc_GraphNode) SHUO;
1546 TDF_LabelSequence aLabSeq;
1547 theSTool->GetSHUONextUsage( theSHUOlab, aLabSeq );
1548 if (aLabSeq.Length() >= 1)
1549 for (Standard_Integer i = 1; i <= aLabSeq.Length(); i++) {
1550 TDF_Label aSubCompL = aLabSeq.Value( i );
1551 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSubCompL.Father() );
1552 // create new map of laocation (to not merge locations from different shapes)
1553 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1554 for (Standard_Integer m = 1; m <= theaPrevLocMap.Extent(); m++)
1555 aNewPrevLocMap.Add( theaPrevLocMap.FindKey( m ) );
1556 aNewPrevLocMap.Add( compLoc );
1557 // got for the new sublocations and corresponding shape
1558 getShapesOfSHUO( aNewPrevLocMap, theSTool, aSubCompL, theShape );
1561 TopoDS_Shape aSHUO_NUSh = theSTool->GetShape ( theSHUOlab.Father() );
1562 if ( aSHUO_NUSh.IsNull() ) return Standard_False;
1563 // cause got shape with location already.
1564 TopLoc_Location nullLoc;
1565 aSHUO_NUSh.Location ( nullLoc );
1566 // multiply the locations
1567 Standard_Integer intMapLenght = theaPrevLocMap.Extent();
1568 if ( intMapLenght < 1 )
1569 return Standard_False; // should not be, but to avoid exception...?
1570 TopLoc_Location SupcompLoc;
1571 SupcompLoc = theaPrevLocMap.FindKey( intMapLenght );
1572 if (intMapLenght > 1) {
1573 Standard_Integer l = intMapLenght - 1;
1575 SupcompLoc = theaPrevLocMap.FindKey( l ).Multiplied( SupcompLoc );
1579 aSHUO_NUSh.Location( SupcompLoc );
1580 theShape = aSHUO_NUSh;
1582 return (!theShape.IsNull());
1585 //=======================================================================
1586 //function : GetSHUOInstance
1588 //=======================================================================
1590 TopoDS_Shape XCAFDoc_ShapeTool::GetSHUOInstance (const Handle(XCAFDoc_GraphNode)& theSHUO) const
1592 TopoDS_Shape aShape;
1593 if (theSHUO.IsNull())
1596 TDF_Label aSHUOlab = theSHUO->Label();
1597 // get location of the assembly
1598 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1599 // get location of the component
1600 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1601 TopLoc_IndexedMapOfLocation aPrevLocMap;
1602 // get previous setted location
1603 if ( !loc.IsIdentity() )
1604 aPrevLocMap.Add( loc );
1605 aPrevLocMap.Add( compLoc );
1606 // get shape by recurse method
1607 const Handle(XCAFDoc_ShapeTool)& STool = this;
1608 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1613 //=======================================================================
1614 //function : getUsersShapesOfSHUO
1615 //purpose : auxilary
1616 //=======================================================================
1618 static Standard_Boolean getUsersShapesOfSHUO (TopLoc_IndexedMapOfLocation& aPrevLocMap,
1619 const Handle(XCAFDoc_ShapeTool)& STool,
1620 const TDF_Label& aSHUOlab,
1621 const TDF_Label& theUserL,
1622 TopTools_SequenceOfShape& theSHUOShapeSeq)
1624 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1625 // get location of the assembly
1626 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( theUserL.Father() );
1627 // get location of the component
1628 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( theUserL );
1629 // get previous setted location
1630 aNewPrevLocMap.Add( loc );
1631 aNewPrevLocMap.Add( compLoc );
1633 for (i = 1; i <= aPrevLocMap.Extent(); i++)
1634 aNewPrevLocMap.Add( aPrevLocMap.FindKey(i) );
1635 TDF_Label L = theUserL.Father();
1636 TDF_LabelSequence usersLab;
1637 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1638 if (usersLab.Length() == 0) {
1639 TopoDS_Shape aShape;
1640 getShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aShape );
1641 if (!aShape.IsNull()) {
1642 theSHUOShapeSeq.Append(aShape);
1643 return Standard_True;
1646 // now iterates on users of this assembly as component
1647 for ( i = 1; i <= usersLab.Length(); i++ ) {
1648 TDF_Label aNewUserL = usersLab.Value(i);
1649 getUsersShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aNewUserL, theSHUOShapeSeq );
1652 return (theSHUOShapeSeq.Length() > 1);
1655 //=======================================================================
1656 //function : GetAllSHUOInstances
1657 //purpose : auxilary
1658 //=======================================================================
1660 Standard_Boolean XCAFDoc_ShapeTool::GetAllSHUOInstances (const Handle(XCAFDoc_GraphNode)& theSHUO,
1661 TopTools_SequenceOfShape& theSHUOShapeSeq) const
1663 if (theSHUO.IsNull())
1664 return Standard_False;
1666 TDF_Label aSHUOlab = theSHUO->Label();
1667 TopLoc_IndexedMapOfLocation aPrevLocMap;
1668 // get location of the assembly
1669 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1670 // get location of the component
1671 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1672 // get previous setted location
1673 if ( !loc.IsIdentity() )
1674 aPrevLocMap.Add( loc );
1675 aPrevLocMap.Add( compLoc );
1676 // get label of assembly
1677 TDF_Label L = aSHUOlab.Father().Father();
1678 TDF_LabelSequence usersLab;
1679 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1680 TopoDS_Shape aShape;
1681 const Handle(XCAFDoc_ShapeTool)& STool = this;
1682 if (usersLab.Length() == 0) {
1683 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1684 if (!aShape.IsNull()) {
1685 theSHUOShapeSeq.Append(aShape);
1686 return Standard_True;
1689 // now iterates on users of this assembly as component
1690 for (Standard_Integer i = 1; i <= usersLab.Length(); i++) {
1691 TDF_Label aUserL = usersLab.Value(i);
1692 getUsersShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aUserL, theSHUOShapeSeq );
1695 return (theSHUOShapeSeq.Length() > 1);
1698 //=======================================================================
1699 //function : SetInstanceSHUO
1701 //=======================================================================
1703 Handle(XCAFDoc_GraphNode) XCAFDoc_ShapeTool::SetInstanceSHUO (const TopoDS_Shape& theShape) const
1705 Handle(XCAFDoc_GraphNode) SHUO;
1706 TDF_LabelSequence aLabels;
1707 if ( FindComponent( theShape, aLabels ) )
1708 // set shuo structure on labels of component-assembly structure
1709 SetSHUO( aLabels, SHUO );
1713 //=======================================================================
1714 //function : FindSHUO
1716 //=======================================================================
1718 Standard_Boolean XCAFDoc_ShapeTool::FindSHUO (const TDF_LabelSequence& theLabels,
1719 Handle(XCAFDoc_GraphNode)& theSHUOAttr)
1721 TDF_AttributeSequence SHUOAttrs;
1722 TDF_Label aCompLabel = theLabels.Value(1);
1723 if (! ::XCAFDoc_ShapeTool::GetAllComponentSHUO( aCompLabel, SHUOAttrs ) )
1724 return Standard_False;
1725 // WARNING: manage that each SHUO upper_usage have only one SHUO next_usage
1726 for (Standard_Integer i = 1; i <= SHUOAttrs.Length(); i++) {
1727 TDF_LabelSequence aCondidate;
1728 Handle(XCAFDoc_GraphNode) anSHUO = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1729 aCondidate.Append( anSHUO->Label().Father() );
1730 while (anSHUO->NbChildren()) {
1731 anSHUO = anSHUO->GetChild( 1 );
1732 aCondidate.Append( anSHUO->Label().Father() );
1734 // check the label sequences
1735 Standard_Boolean isEqual = Standard_True;
1736 if (theLabels.Length() != aCondidate.Length())
1737 isEqual = Standard_False;
1739 for (Standard_Integer li = 1; li <= theLabels.Length(); li++)
1740 if ( theLabels.Value(li) != aCondidate.Value(li) ) {
1741 isEqual = Standard_False;
1747 theSHUOAttr = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1750 return ( !theSHUOAttr.IsNull() );