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.
17 #include <BRep_Builder.hxx>
19 #include <gp_Trsf.hxx>
20 #include <Standard_GUID.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_ChildNodeIterator.hxx>
27 #include <TDataStd_Name.hxx>
28 #include <TDataStd_TreeNode.hxx>
29 #include <TDataStd_UAttribute.hxx>
30 #include <TDF_Attribute.hxx>
31 #include <TDF_ChildIDIterator.hxx>
32 #include <TDF_ChildIterator.hxx>
33 #include <TDF_Label.hxx>
34 #include <TDF_LabelMap.hxx>
35 #include <TDF_LabelSequence.hxx>
36 #include <TDF_MapIteratorOfLabelMap.hxx>
37 #include <TDF_RelocationTable.hxx>
38 #include <TDF_Tool.hxx>
39 #include <TDocStd_Document.hxx>
40 #include <TNaming_Builder.hxx>
41 #include <TNaming_NamedShape.hxx>
42 #include <TNaming_Tool.hxx>
43 #include <TopLoc_IndexedMapOfLocation.hxx>
44 #include <TopLoc_Location.hxx>
45 #include <TopoDS_Compound.hxx>
46 #include <TopoDS_Iterator.hxx>
47 #include <TopoDS_Shape.hxx>
48 #include <TopTools_ListOfShape.hxx>
49 #include <XCAFDoc.hxx>
50 #include <XCAFDoc_GraphNode.hxx>
51 #include <XCAFDoc_Location.hxx>
52 #include <XCAFDoc_ShapeMapTool.hxx>
53 #include <XCAFDoc_ShapeTool.hxx>
55 IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_ShapeTool,TDF_Attribute)
57 static Standard_Boolean theAutoNaming = Standard_True;
59 // attribute methods //////////////////////////////////////////////////
61 //=======================================================================
64 //=======================================================================
66 const Standard_GUID& XCAFDoc_ShapeTool::GetID()
68 static Standard_GUID ShapeToolID ("efd212ee-6dfd-11d4-b9c8-0060b0ee281b");
73 //=======================================================================
76 //=======================================================================
78 Handle(XCAFDoc_ShapeTool) XCAFDoc_ShapeTool::Set(const TDF_Label& L)
80 Handle(XCAFDoc_ShapeTool) A;
81 if (!L.FindAttribute (XCAFDoc_ShapeTool::GetID(), A)) {
82 A = new XCAFDoc_ShapeTool ();
90 //=======================================================================
91 //function : Constructor
93 //=======================================================================
95 XCAFDoc_ShapeTool::XCAFDoc_ShapeTool()
97 hasSimpleShapes = Standard_False;
101 //=======================================================================
104 //=======================================================================
106 const Standard_GUID& XCAFDoc_ShapeTool::ID() const
111 //=======================================================================
114 //=======================================================================
116 void XCAFDoc_ShapeTool::Restore(const Handle(TDF_Attribute)& /*with*/)
120 //=======================================================================
121 //function : NewEmpty
123 //=======================================================================
125 Handle(TDF_Attribute) XCAFDoc_ShapeTool::NewEmpty() const
127 return new XCAFDoc_ShapeTool;
130 //=======================================================================
133 //=======================================================================
135 void XCAFDoc_ShapeTool::Paste (const Handle(TDF_Attribute)& /*into*/,
136 const Handle(TDF_RelocationTable)& /*RT*/) const
140 // Auxiliary methods //////////////////////////////////////////////////
142 //=======================================================================
143 //function : SetLabelNameByLink
145 //=======================================================================
146 static void SetLabelNameByLink(const TDF_Label L)
148 Handle(TDataStd_TreeNode) Node;
149 if (! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
150 ! Node->HasFather()) {
152 cout<<"Error: XCAFDoc_ShapeTool, SetLabelNameByLink(): NO NODE"<<endl;
156 TCollection_AsciiString Entry;
157 TDF_Tool::Entry ( Node->Father()->Label(), Entry );
158 Entry.Insert(1, "=>[");
161 TDataStd_Name::Set(L, TCollection_ExtendedString( Entry ));
165 //=======================================================================
166 //function : SetLabelNameByShape
168 //=======================================================================
169 static void SetLabelNameByShape(const TDF_Label L)
172 if (XCAFDoc_ShapeTool::GetShape(L, S) &&
173 ! L.IsAttribute(TDataStd_Name::GetID()) ) {
174 Standard_SStream Stream;
175 // TopAbs_ShapeEnum Type = S.ShapeType();
176 // if (Type == TopAbs_COMPOUND) Stream<<"ASSEMBLY";
178 TopAbs::Print(S.ShapeType(), Stream);
179 TCollection_AsciiString aName (Stream.str().c_str());
180 TDataStd_Name::Set(L, TCollection_ExtendedString(aName));
185 //=======================================================================
186 //function : SearchUsingMap
188 //=======================================================================
190 Standard_Boolean XCAFDoc_ShapeTool::SearchUsingMap(const TopoDS_Shape &S, TDF_Label &L,
191 const Standard_Boolean findWithoutLoc,
192 const Standard_Boolean findSubShape) const
195 if(myShapeLabels.IsBound(S)) {
196 L = myShapeLabels.Find(S);
197 return Standard_True;
202 if(myShapeLabels.IsBound(S0)) {
203 TDF_Label L1 = myShapeLabels.Find(S0);
204 TDF_LabelSequence Labels;
205 if(GetUsers(L1, Labels, Standard_True)) {
206 for(Standard_Integer i=1; i<=Labels.Length(); i++) {
207 TopoDS_Shape c = GetShape(Labels.Value(i));
210 return Standard_True;
216 return Standard_True;
220 if(hasSimpleShapes) {
221 if(mySimpleShapes.IsBound(S)) {
222 L = mySimpleShapes.Find(S);
223 return Standard_True;
225 if(mySimpleShapes.IsBound(S0)) {
226 L = mySimpleShapes.Find(S0);
227 return Standard_True;
231 if(!findSubShape) return Standard_False;
232 TDF_Label mainL = FindMainShapeUsingMap(S);
233 if(mainL.IsNull()) return Standard_False;
234 L = AddSubShape(mainL,S);
235 return !L.IsNull();//Standard_True;
239 //=======================================================================
242 //=======================================================================
244 Standard_Boolean XCAFDoc_ShapeTool::Search (const TopoDS_Shape &S,
246 const Standard_Boolean findInstance,
247 const Standard_Boolean findComponent,
248 const Standard_Boolean findSubShape) const
250 // search among shapes
251 Standard_Boolean isLocated = ! S.Location().IsIdentity();
254 // try to find top-level instance
255 if ( findInstance && FindShape ( S, L, Standard_True ) )
256 return Standard_True;
257 // try to find component of assembly
258 if ( findComponent ) {
259 TDF_LabelSequence labels;
260 GetShapes ( labels );
261 for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
262 if ( ! IsAssembly ( labels.Value(i) ) ) continue;
263 TDF_LabelSequence comp;
264 GetComponents ( labels.Value(i), comp );
265 for ( Standard_Integer j=1; j <= comp.Length(); j++ ) {
266 TopoDS_Shape c = GetShape ( comp.Value(j) );
267 if ( c.IsSame ( S ) ) {
269 return Standard_True;
275 // try to find top-level simple shape
276 if ( FindShape ( S, L, Standard_False ) ) return Standard_True;
279 if ( ! findSubShape ) return Standard_False;
280 TDF_Label mainL = FindMainShape ( S );
281 if ( mainL.IsNull() ) return Standard_False;
282 L = AddSubShape ( mainL, S );
283 return !L.IsNull();//Standard_True;
286 //=======================================================================
287 //function : FindShape
289 //=======================================================================
291 Standard_Boolean XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S,
293 const Standard_Boolean findInstance) const
295 // search for null-located shape
297 if ( ! findInstance ) {
302 // this code is used instead of the following for performance reasons
303 if (TNaming_Tool::HasLabel(Label(), S0)) {
305 L = TNaming_Tool::Label(Label(), S0, TransDef);
306 return Standard_True;
309 TDF_ChildIDIterator it(myLabel,TNaming_NamedShape::GetID());
310 for (; it.More(); it.Next()) {
311 TDF_Label aLabel = it.Value()->Label();
312 Handle(TNaming_NamedShape) NS;
313 if ( aLabel.FindAttribute(TNaming_NamedShape::GetID(), NS) &&
314 S0.IsSame ( TNaming_Tool::GetShape(NS) ) ) {
316 return Standard_True;
320 return Standard_False;
323 //=======================================================================
324 //function : FindShape
326 //=======================================================================
328 TDF_Label XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S,
329 const Standard_Boolean findInstance) const
332 if (FindShape(S, L, findInstance))
337 //=======================================================================
338 //function : GetShape
340 //=======================================================================
342 Standard_Boolean XCAFDoc_ShapeTool::GetShape (const TDF_Label& L, TopoDS_Shape& S)
344 Handle(XCAFDoc_Location) LocationAttribute;
347 TopoDS_Compound EmptyComp;
349 B.MakeCompound(EmptyComp);
353 // for instance, get referred shape
354 Handle(TDataStd_TreeNode) Node;
355 if ( L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather() &&
356 L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute)) {
357 if ( ! GetShape(Node->Father()->Label(), S) ) return Standard_False;
358 S.Move ( LocationAttribute->Get() );
359 return Standard_True;
362 // else just return shape on this label
363 Handle(TNaming_NamedShape) NS;
364 if ( ! L.FindAttribute(TNaming_NamedShape::GetID(), NS) ) return Standard_False;
365 S = TNaming_Tool::GetShape(NS);
366 return Standard_True;
369 //=======================================================================
370 //function : GetShape
372 //=======================================================================
374 TopoDS_Shape XCAFDoc_ShapeTool::GetShape(const TDF_Label& L)
381 //=======================================================================
382 //function : NewShape
384 //=======================================================================
386 TDF_Label XCAFDoc_ShapeTool::NewShape() const
388 TopoDS_Compound aShape;
390 tdsB.MakeCompound ( aShape );
393 TDF_Label aLabel = aTag.NewChild(Label());
395 TNaming_Builder tnBuild(aLabel);
396 tnBuild.Generated(aShape);
401 //=======================================================================
402 //function : SetShape
404 //=======================================================================
406 void XCAFDoc_ShapeTool::SetShape (const TDF_Label& L, const TopoDS_Shape& S)
408 TNaming_Builder tnBuild(L);
409 tnBuild.Generated(S);
410 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(L);
411 // if ( ! L.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
412 // A = XCAFDoc_ShapeMapTool::Set(L);
413 // L.AddAttribute(A);
417 if(!myShapeLabels.IsBound(S)) {
418 myShapeLabels.Bind(S,L);
422 //=======================================================================
423 //function : MakeReference
425 //=======================================================================
427 void XCAFDoc_ShapeTool::MakeReference (const TDF_Label &L,
428 const TDF_Label &refL,
429 const TopLoc_Location &loc)
432 XCAFDoc_Location::Set(L, loc);
435 Handle(TDataStd_TreeNode) refNode, mainNode;
436 mainNode = TDataStd_TreeNode::Set ( refL, XCAFDoc::ShapeRefGUID() );
437 refNode = TDataStd_TreeNode::Set ( L, XCAFDoc::ShapeRefGUID() );
438 refNode->Remove(); // abv: fix against bug in TreeNode::Append()
439 mainNode->Append(refNode);
442 SetLabelNameByLink(L);
445 //=======================================================================
446 //function : addShape
448 //=======================================================================
450 TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly)
452 TDF_Label ShapeLabel;
455 // search if the shape already exists (with the same location)
456 if ( S.IsNull() || FindShape ( S, ShapeLabel, Standard_True ) ) return ShapeLabel;
458 // else add a new label
459 ShapeLabel = aTag.NewChild(Label());
461 // if shape has location, make a reference to the same shape without location
462 if ( ! S.Location().IsIdentity() /*&& FindShape ( S, L )*/ ) {
466 TDF_Label L = addShape ( S0, makeAssembly );
467 MakeReference ( ShapeLabel, L, S.Location() );
471 // else add a shape to a label
472 TNaming_Builder tnBuild(ShapeLabel);
473 tnBuild.Generated(S);
475 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
476 // if ( ! ShapeLabel.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
477 // A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
478 // ShapeLabel.AddAttribute(A);
483 SetLabelNameByShape(ShapeLabel);
485 // if shape is Compound and flag is set, create assembly
486 if ( makeAssembly && S.ShapeType() == TopAbs_COMPOUND ) {
487 // mark assembly by assigning UAttribute
488 Handle(TDataStd_UAttribute) Uattr;
489 Uattr = TDataStd_UAttribute::Set ( ShapeLabel, XCAFDoc::AssemblyGUID() );
491 TDataStd_Name::Set(ShapeLabel, TCollection_ExtendedString("ASSEMBLY"));
493 // iterate on components
494 TopoDS_Iterator Iterator(S);
495 for (; Iterator.More(); Iterator.Next()) {
496 // get label for component`s shape
497 TopoDS_Shape Scomp = Iterator.Value(), S0 = Scomp;
500 TDF_Label compL = addShape ( S0, makeAssembly );
502 // add a component as reference
503 TDF_Label RefLabel = aTag.NewChild(ShapeLabel);
504 MakeReference ( RefLabel, compL, Scomp.Location() );
508 if(!IsAssembly(ShapeLabel)) {
509 //const TopTools_IndexedMapOfShape tmpMap = A->GetMap();
510 //for(Standard_Integer i=1; i<=tmpMap.Extent(); i++)
511 //mySubShapes.Bind(tmpMap.FindKey(i),ShapeLabel);
512 for(Standard_Integer i=1; i<=A->GetMap().Extent(); i++)
514 TopoDS_Shape aSh = A->GetMap().FindKey(i);
515 mySubShapes.Bind(aSh,ShapeLabel);
517 //mySubShapes.Bind(ShapeLabel,A->GetMap());
524 //=======================================================================
525 //function : prepareAssembly
527 //=======================================================================
528 static Standard_Boolean prepareAssembly (const TopoDS_Shape& theShape,
529 TopoDS_Shape& theOUTShape)
531 // iterate on components
532 theOUTShape = theShape;
533 if (theShape.ShapeType() == TopAbs_COMPOUND) {
535 // check if shape if frosen
536 if (!theOUTShape.Free())
537 theOUTShape.Free(Standard_True);
539 TopTools_SequenceOfShape aSubShapeSeq;
540 TopoDS_Iterator Iterator(theShape);
541 for (; Iterator.More(); Iterator.Next())
542 aSubShapeSeq.Append(Iterator.Value());
543 for (Standard_Integer i = 1; i <= aSubShapeSeq.Length(); i++) {
544 TopoDS_Shape Scomp = aSubShapeSeq.Value(i);
545 TopoDS_Shape aNewScomp;
546 B.Remove(theOUTShape, Scomp);
547 prepareAssembly( Scomp, aNewScomp );
548 TopLoc_Location aLoc;
549 aLoc = aNewScomp.Location();
550 if ( aLoc.IsIdentity() ) {
551 // create an "empty" location
553 aTrsf.SetScale(gp_Pnt(0,0,0), 1);
554 aLoc = TopLoc_Location( aTrsf );
555 aNewScomp.Location( aLoc );
557 B.Add(theOUTShape, aNewScomp);
560 return Standard_True;
564 //=======================================================================
565 //function : AddShape
567 //=======================================================================
569 TDF_Label XCAFDoc_ShapeTool::AddShape (const TopoDS_Shape& theShape,
570 const Standard_Boolean makeAssembly,
571 const Standard_Boolean makePrepare)
573 // PTV 17.02.2003 to avoid components without location.
574 TopoDS_Shape S = theShape;
575 if ( makePrepare && makeAssembly && S.ShapeType() == TopAbs_COMPOUND )
576 prepareAssembly( theShape, S ); // OCC1669
578 TDF_Label L = addShape(S,makeAssembly);
580 if(!myShapeLabels.IsBound(S)) {
581 myShapeLabels.Bind(S,L);
586 //return addShape( S, makeAssembly );
589 //=======================================================================
590 //function : RemoveShape
592 //=======================================================================
594 Standard_Boolean XCAFDoc_ShapeTool::RemoveShape (const TDF_Label& L,
595 const Standard_Boolean removeCompletely) const
597 if ( ! IsTopLevel ( L ) || ! IsFree ( L ) ) return Standard_False;
599 Handle(TDataStd_TreeNode) aNode;
601 if (removeCompletely &&
602 L.FindAttribute (XCAFDoc::ShapeRefGUID(), aNode) &&
603 aNode->HasFather() &&
604 L.IsAttribute (XCAFDoc_Location::GetID()))
606 aLabel = aNode->Father()->Label();
609 L.ForgetAllAttributes (Standard_True);
611 if (removeCompletely && !aLabel.IsNull())
613 return RemoveShape(aLabel);
615 return Standard_True;
619 //=======================================================================
622 //=======================================================================
624 void XCAFDoc_ShapeTool::Init()
626 hasSimpleShapes = Standard_False;
630 //=======================================================================
631 //function : SetAutoNaming
633 //=======================================================================
635 void XCAFDoc_ShapeTool::SetAutoNaming (const Standard_Boolean V)
641 //=======================================================================
642 //function : AutoNaming
644 //=======================================================================
646 Standard_Boolean XCAFDoc_ShapeTool::AutoNaming()
648 return theAutoNaming;
652 //=======================================================================
653 //function : ComputeShapes
655 //=======================================================================
657 void XCAFDoc_ShapeTool::ComputeShapes(const TDF_Label& L)
659 TDF_ChildIterator it(L);
660 for(; it.More(); it.Next()) {
661 TDF_Label L1 = it.Value();
664 if(!myShapeLabels.IsBound(S)) {
665 mySimpleShapes.Bind(S,L1);
673 //=======================================================================
674 //function : ComputeSimpleShapes
676 //=======================================================================
678 void XCAFDoc_ShapeTool::ComputeSimpleShapes()
680 ComputeShapes(Label());
681 hasSimpleShapes = Standard_True;
685 //=======================================================================
686 //function : GetShapes
688 //=======================================================================
690 void XCAFDoc_ShapeTool::GetShapes(TDF_LabelSequence& Labels) const
694 TDF_ChildIterator it(Label());
695 for (; it.More(); it.Next()) {
696 TDF_Label L = it.Value();
698 if ( GetShape ( L, S ) ) Labels.Append ( L );
703 //=======================================================================
704 //function : GetFreeShapes
706 //=======================================================================
708 void XCAFDoc_ShapeTool::GetFreeShapes (TDF_LabelSequence& FreeLabels) const
712 TDF_ChildIterator it(Label());
713 for (; it.More(); it.Next()) {
714 TDF_Label L = it.Value();
716 if ( GetShape ( L, S ) && IsFree ( L ) ) FreeLabels.Append ( L );
720 //=======================================================================
721 //function : IsTopLevel
723 //=======================================================================
725 Standard_Boolean XCAFDoc_ShapeTool::IsTopLevel (const TDF_Label& L) const
727 return L.Father() == Label();
730 //=======================================================================
733 //=======================================================================
735 Standard_Boolean XCAFDoc_ShapeTool::IsShape (const TDF_Label& L)
737 return IsSimpleShape ( L ) || IsAssembly ( L ) || IsReference ( L );
740 //=======================================================================
741 //function : IsSimpleShape
743 //=======================================================================
745 Standard_Boolean XCAFDoc_ShapeTool::IsSimpleShape (const TDF_Label& L)
747 Handle(TNaming_NamedShape) NS;
748 return L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) &&
749 ! IsAssembly ( L ) && ! IsReference ( L );
752 //=======================================================================
753 //function : IsReference
755 //=======================================================================
757 Standard_Boolean XCAFDoc_ShapeTool::IsReference (const TDF_Label& L)
759 Handle(TDataStd_TreeNode) Node;
760 return L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather();
763 //=======================================================================
764 //function : IsAssembly
766 //=======================================================================
768 Standard_Boolean XCAFDoc_ShapeTool::IsAssembly (const TDF_Label& L)
770 Handle(TDataStd_UAttribute) Uattr;
771 return L.FindAttribute(XCAFDoc::AssemblyGUID(), Uattr);
774 //=======================================================================
775 //function : IsComponent
777 //=======================================================================
779 Standard_Boolean XCAFDoc_ShapeTool::IsComponent (const TDF_Label& L)
781 return IsReference ( L ) && IsAssembly ( L.Father() );
784 //=======================================================================
785 //function : IsCompound
787 //=======================================================================
789 Standard_Boolean XCAFDoc_ShapeTool::IsCompound (const TDF_Label& L)
791 Handle(TDataStd_Name) Name;
792 if (L.FindAttribute(TDataStd_Name::GetID(),Name)) {
793 TCollection_ExtendedString estr1 = Name->Get();
794 TCollection_ExtendedString estr2("COMPOUND");
796 return Standard_True;
799 return Standard_False;
802 //=======================================================================
803 //function : IsSubShape
805 //=======================================================================
807 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label& L)
809 return IsSimpleShape ( L ) && IsShape ( L.Father() );
812 //=======================================================================
815 //=======================================================================
817 Standard_Boolean XCAFDoc_ShapeTool::IsFree (const TDF_Label& L)
819 Handle(TDataStd_TreeNode) Node;
820 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
821 ! Node->HasFirst() ) return Standard_True;
823 return Standard_False;
826 //=======================================================================
827 //function : GetUsers
828 //purpose : Returns number of users (0 if shape is free)
829 //=======================================================================
831 Standard_Integer XCAFDoc_ShapeTool::GetUsers (const TDF_Label& L,
832 TDF_LabelSequence& Labels,
833 const Standard_Boolean getsubchilds)
835 Standard_Integer NbUsers=0;
836 Handle(TDataStd_TreeNode) Node ;
838 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ) return NbUsers;
840 Node = Node->First();
841 while ( ! Node.IsNull() ) {
843 if ( getsubchilds ) {
844 TDF_Label underL = Node->Label().Father();
845 NbUsers += GetUsers ( underL, Labels, getsubchilds );
848 Labels.Append(Node->Label());
855 //=======================================================================
856 //function : NbComponents
858 //=======================================================================
860 Standard_Integer XCAFDoc_ShapeTool::NbComponents (const TDF_Label& L,
861 const Standard_Boolean getsubchilds)
863 TDF_LabelSequence subLabels;
864 GetComponents (L, subLabels, getsubchilds);
865 return subLabels.Length();
868 //=======================================================================
869 //function : GetComponents
871 //=======================================================================
873 Standard_Boolean XCAFDoc_ShapeTool::GetComponents (const TDF_Label& L, TDF_LabelSequence& Labels,
874 const Standard_Boolean getsubchilds)
876 if ( ! IsAssembly(L) ) return Standard_False;
878 TDF_ChildIterator It(L);
879 for (; It.More(); It.Next() ) {
880 TDF_Label comp = It.Value();
881 if ( IsComponent ( comp ) ) {
882 if ( getsubchilds ) {
884 if ( GetReferredShape ( comp, underL ) )
885 GetComponents ( underL, Labels, getsubchilds);
887 Labels.Append ( comp );
890 return Standard_True;
893 //=======================================================================
894 //function : GetLocation
896 //=======================================================================
898 TopLoc_Location XCAFDoc_ShapeTool::GetLocation (const TDF_Label& L)
900 Handle(XCAFDoc_Location) LocationAttribute;
901 if (L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute))
902 return LocationAttribute->Get();
904 Handle(TNaming_NamedShape) NS;
906 if ( L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) ) {
907 S = TNaming_Tool::GetShape(NS);
912 //=======================================================================
913 //function : GetReferredShape
915 //=======================================================================
917 Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L,
920 if ( ! IsReference(L) ) return Standard_False;
922 Handle (TDataStd_TreeNode) Node;
923 L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node);
924 Label = Node->Father()->Label();
925 return Standard_True;
928 //=======================================================================
929 //function : AddComponent
931 //=======================================================================
933 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
934 const TDF_Label& compL,
935 const TopLoc_Location &Loc)
939 // check that shape is assembly
940 if ( ! IsAssembly(assembly) ) {
941 // if it is simple shape, make it assembly
942 if ( IsSimpleShape(assembly) )
943 TDataStd_UAttribute::Set ( assembly, XCAFDoc::AssemblyGUID() );
947 // add a component as reference
949 L = aTag.NewChild(assembly);
950 MakeReference ( L, compL, Loc );
952 // map shape to label
954 if (GetShape(L, aShape))
956 if (!myShapeLabels.IsBound(aShape))
957 myShapeLabels.Bind(aShape, L);
963 //=======================================================================
964 //function : AddComponent
966 //=======================================================================
968 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
969 const TopoDS_Shape& comp,
970 const Standard_Boolean expand)
972 // get label for component`s shape
973 TopoDS_Shape S0 = comp;
977 compL = AddShape ( S0, expand );
979 // add component by its label
980 return AddComponent ( assembly, compL, comp.Location() );
983 //=======================================================================
984 //function : RemoveComponent
986 //=======================================================================
988 void XCAFDoc_ShapeTool::RemoveComponent (const TDF_Label& comp) const
990 if ( IsComponent(comp) )
992 comp.ForgetAllAttributes();
996 //=======================================================================
997 //function : UpdateAssemblies
999 //=======================================================================
1001 void XCAFDoc_ShapeTool::UpdateAssemblies()
1003 // We start from the free shapes (roots in the assembly structure)
1004 TDF_LabelSequence aRootLabels;
1005 GetFreeShapes(aRootLabels);
1007 // Iterate over the free shapes
1008 for ( TDF_LabelSequence::Iterator anIt(aRootLabels); anIt.More(); anIt.Next() )
1010 TDF_Label aRefLabel = anIt.Value();
1011 if (IsReference(aRefLabel))
1013 GetReferredShape(aRefLabel, aRefLabel);
1015 const TDF_Label& aRootLab = aRefLabel;
1016 TopoDS_Shape anAssemblyShape;
1017 updateComponent(aRootLab, anAssemblyShape);
1021 //=======================================================================
1022 //function : IsSubShape
1024 //=======================================================================
1026 //static Standard_Boolean CheckSubShape (const TopoDS_Shape &S, const TopoDS_Shape &sub)
1028 // if ( S.IsSame ( sub ) ) return Standard_True;
1030 // if ( S.ShapeType() >= sub.ShapeType() ) return Standard_False;
1032 // for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
1033 // if ( CheckSubShape ( it.Value(), sub ) ) return Standard_True;
1035 // return Standard_False;
1038 //=======================================================================
1039 //function : IsSubShape
1041 //=======================================================================
1043 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label &shapeL,
1044 const TopoDS_Shape &sub) const
1046 Handle(XCAFDoc_ShapeMapTool) A;
1047 if (!shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A))
1049 TopoDS_Shape aShape = GetShape(shapeL);
1050 if (aShape.IsNull())
1051 return Standard_False;
1052 A = XCAFDoc_ShapeMapTool::Set(shapeL);
1053 A->SetShape(aShape);
1056 return A->IsSubShape(sub);
1059 //=======================================================================
1060 //function : FindSubShape
1062 //=======================================================================
1064 Standard_Boolean XCAFDoc_ShapeTool::FindSubShape (const TDF_Label &shapeL,
1065 const TopoDS_Shape &sub,
1069 return Standard_False;
1071 if (TNaming_Tool::HasLabel(Label(), sub)) {
1073 L = TNaming_Tool::Label(Label(), sub, TransDef);
1075 return Standard_False;
1076 if (L.Father() == shapeL)
1077 return Standard_True;
1081 return Standard_False;
1084 // if subshape was found wrong, try to do it manually
1085 // it can be possible if several part shapes has the same subshapes
1087 TDF_ChildIterator aChldLabIt(shapeL);
1088 for (; aChldLabIt.More(); aChldLabIt.Next() ) {
1089 TDF_Label aSubLabel = aChldLabIt.Value();
1090 TopoDS_Shape aSubShape;
1091 if (GetShape(aSubLabel, aSubShape) && aSubShape.IsSame(sub)) {
1093 return Standard_True;
1096 return Standard_False;
1099 //=======================================================================
1100 //function : AddSubShape
1102 //=======================================================================
1104 TDF_Label XCAFDoc_ShapeTool::AddSubShape (const TDF_Label &shapeL,
1105 const TopoDS_Shape &sub) const
1108 if (!IsSimpleShape(shapeL) || !IsTopLevel(shapeL))
1111 if ( FindSubShape ( shapeL, sub, L ) ) return L;
1113 if (!IsSubShape(shapeL, sub))
1117 L = aTag.NewChild(shapeL);
1119 TNaming_Builder tnBuild(L);
1120 tnBuild.Generated(sub);
1122 // if(!mySubShapes.IsBound(sub))
1123 // mySubShapes.Bind(sub,L);
1129 //=======================================================================
1130 //function : FindMainShapeUsingMap
1132 //=======================================================================
1134 TDF_Label XCAFDoc_ShapeTool::FindMainShapeUsingMap(const TopoDS_Shape &sub) const
1136 //for(Standard_Integer i=1; i<=myNotAssemblies.Length(); i++) {
1137 // TDF_Label L = myNotAssemblies.Value(i);
1138 // if(IsSubShape(L,sub)) return L;
1140 if(mySubShapes.IsBound(sub))
1141 return mySubShapes.Find(sub);
1147 //=======================================================================
1148 //function : FindMainShape
1150 //=======================================================================
1152 TDF_Label XCAFDoc_ShapeTool::FindMainShape (const TopoDS_Shape &sub) const
1154 TDF_ChildIterator it(Label());
1155 for (; it.More(); it.Next()) {
1156 TDF_Label L = it.Value();
1157 if ( ! IsAssembly ( L ) && IsSubShape ( L, sub ) ) return L;
1164 //=======================================================================
1165 //function : GetSubShapes
1167 //=======================================================================
1169 Standard_Boolean XCAFDoc_ShapeTool::GetSubShapes (const TDF_Label &L,
1170 TDF_LabelSequence& Labels)
1172 TDF_ChildIterator It(L);
1173 for (; It.More(); It.Next() ) {
1174 TDF_Label sub = It.Value();
1175 if ( IsSubShape ( sub ) ) Labels.Append ( sub );
1177 return Labels.Length() >0;
1180 //=======================================================================
1181 //function : BaseLabel
1183 //=======================================================================
1185 TDF_Label XCAFDoc_ShapeTool::BaseLabel () const
1190 //=======================================================================
1191 //function : DumpAssembly
1192 //purpose : recursive part of Dump()
1193 //=======================================================================
1195 static void DumpAssembly(Standard_OStream& theDumpLog,
1197 const Standard_Integer level,
1198 const Standard_Boolean deep)
1201 XCAFDoc_ShapeTool::GetShape(L, S);
1204 for (Standard_Integer i=0; i<level; i++)
1207 TCollection_AsciiString Entry;
1208 TDF_Tool::Entry(L, Entry);
1210 if(XCAFDoc_ShapeTool::IsAssembly(L))
1212 theDumpLog<<"ASSEMBLY ";
1214 else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
1216 if(L.Father().Father().Father().IsRoot())
1217 theDumpLog<<"PART ";
1221 theDumpLog<<"INSTANCE ";
1223 TopAbs::Print(S.ShapeType(), theDumpLog);
1225 theDumpLog<<" "<<Entry;
1226 if(XCAFDoc_ShapeTool::IsReference(L))
1228 Handle(TDataStd_TreeNode) aRef;
1229 L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
1230 TDF_Tool::Entry(aRef->Father()->Label(), Entry);
1231 theDumpLog<<" (refers to "<<Entry<<")";
1233 Handle(TDataStd_Name) Name;
1234 if (L.FindAttribute(TDataStd_Name::GetID(), Name))
1235 theDumpLog<<" \""<<Name->Get()<<"\" ";
1238 theDumpLog<<"("<<*(void**)&S.TShape();
1239 if (! S.Location().IsIdentity())
1240 theDumpLog<<", "<< *(void**)&S.Location();
1245 Handle(TDataStd_TreeNode) Node;
1246 TDF_ChildIterator NodeIterator(L);
1247 for (; NodeIterator.More(); NodeIterator.Next()) {
1248 DumpAssembly(theDumpLog, NodeIterator.Value(), level+1, deep);
1254 //=======================================================================
1257 //=======================================================================
1259 Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog, const Standard_Boolean deep) const
1261 Standard_Integer level = 0;
1262 // TopTools_SequenceOfShape SeqShapes;
1263 TDF_LabelSequence SeqLabels;
1264 GetShapes( SeqLabels);
1266 if (SeqLabels.Length()>0) theDumpLog<<endl;
1268 for (i=1; i<=SeqLabels.Length(); i++) {
1269 DumpAssembly(theDumpLog, SeqLabels.Value(i), level, deep);
1273 GetFreeShapes(SeqLabels);
1274 theDumpLog<<endl<<"Free Shapes: "<<SeqLabels.Length()<<endl;
1275 for (i = 1; i<=SeqLabels.Length(); i++) {
1276 DumpShape(theDumpLog, SeqLabels.Value(i), level, deep);
1282 //=======================================================================
1284 //purpose : override
1285 //=======================================================================
1287 Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog) const
1289 TDF_Attribute::Dump (theDumpLog);
1290 Dump (theDumpLog, Standard_False);
1294 //=======================================================================
1295 //function : DumpShape
1297 //=======================================================================
1299 void XCAFDoc_ShapeTool::DumpShape(Standard_OStream& theDumpLog, const TDF_Label& L,const Standard_Integer level,const Standard_Boolean deep)
1302 if(! XCAFDoc_ShapeTool::GetShape(L, S) ) return;
1303 for (Standard_Integer i=0; i<level; i++)
1306 if(XCAFDoc_ShapeTool::IsAssembly(L))
1308 theDumpLog<<"ASSEMBLY ";
1310 else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
1312 if(L.Father().Father().Father().IsRoot())
1313 theDumpLog<<"PART ";
1317 theDumpLog<<"INSTANCE ";
1319 TopAbs::Print(S.ShapeType(), theDumpLog);
1321 TCollection_AsciiString Entry;
1322 TDF_Tool::Entry(L, Entry);
1323 theDumpLog<<" "<<Entry;
1324 if(XCAFDoc_ShapeTool::IsReference(L))
1326 Handle(TDataStd_TreeNode) aRef;
1327 L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
1328 TDF_Tool::Entry(aRef->Father()->Label(), Entry);
1329 theDumpLog<<" (refers to "<<Entry<<")";
1332 Handle(TDataStd_Name) Name;
1333 if (L.FindAttribute(TDataStd_Name::GetID(),Name))
1334 theDumpLog<<" \""<<Name->Get()<<"\" ";
1337 theDumpLog<<"("<<*(void**)&S.TShape();
1338 if (! S.Location().IsIdentity())
1339 theDumpLog<<", "<< *(void**)&S.Location();
1344 //=======================================================================
1345 //function : IsExternRef
1347 //=======================================================================
1349 Standard_Boolean XCAFDoc_ShapeTool::IsExternRef(const TDF_Label& L)
1351 Handle(TDataStd_UAttribute) Uattr;
1352 return L.FindAttribute(XCAFDoc::ExternRefGUID(), Uattr);
1355 //=======================================================================
1356 //function : SetExternRefs
1358 //=======================================================================
1360 void XCAFDoc_ShapeTool::SetExternRefs(const TDF_Label& L,
1361 const TColStd_SequenceOfHAsciiString& SHAS) const
1363 TDF_Label ShapeLabel = L.NewChild();
1364 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1365 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1366 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1367 Handle(TCollection_HAsciiString) str = SHAS(i);
1368 TCollection_ExtendedString extstr(str->String());
1369 TDataStd_Name::Set(tmplbl,extstr);
1373 //=======================================================================
1374 //function : SetExternRefs
1376 //=======================================================================
1378 TDF_Label XCAFDoc_ShapeTool::SetExternRefs(const TColStd_SequenceOfHAsciiString& SHAS) const
1380 TDF_Label ShapeLabel;
1383 ShapeLabel = aTag.NewChild(Label());
1384 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1385 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1386 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1387 Handle(TCollection_HAsciiString) str = SHAS(i);
1388 TCollection_ExtendedString extstr(str->String());
1389 TDataStd_Name::Set(tmplbl,extstr);
1394 //=======================================================================
1395 //function : GetExternRefs
1397 //=======================================================================
1399 void XCAFDoc_ShapeTool::GetExternRefs(const TDF_Label& L,
1400 TColStd_SequenceOfHAsciiString& SHAS)
1402 Handle(TDataStd_Name) TDN;
1404 for(Standard_Integer i=1; i<=L.NbChildren(); i++) {
1405 tmplbl = L.FindChild(i);
1406 if(tmplbl.FindAttribute(TDataStd_Name::GetID(),TDN)) {
1407 TCollection_ExtendedString extstr = TDN->Get();
1408 Handle(TCollection_HAsciiString) str =
1409 new TCollection_HAsciiString(TCollection_AsciiString(extstr, '?'));
1415 // API: API work with SHUO (Specified Higher Usage Occurrance) structure
1417 //=======================================================================
1418 //function : GetSHUO
1420 //=======================================================================
1422 Standard_Boolean XCAFDoc_ShapeTool::GetSHUO (const TDF_Label& SHUOLabel,
1423 Handle(XCAFDoc_GraphNode)& aSHUOAttr)
1425 if ( !SHUOLabel.FindAttribute( XCAFDoc::SHUORefGUID(), aSHUOAttr ) )
1426 return Standard_False;
1427 return Standard_True;
1430 //=======================================================================
1431 //function : GetAllComponentSHUO
1433 //=======================================================================
1435 Standard_Boolean XCAFDoc_ShapeTool::GetAllComponentSHUO (const TDF_Label& theCompLabel,
1436 TDF_AttributeSequence& theSHUOAttrs)
1438 TDF_ChildIterator it(theCompLabel);
1439 for (; it.More(); it.Next()) {
1440 TDF_Label L = it.Value();
1441 Handle(XCAFDoc_GraphNode) aSHUOAttr;
1442 if ( GetSHUO( L, aSHUOAttr ) )
1443 theSHUOAttrs.Append( aSHUOAttr );
1445 return (theSHUOAttrs.Length() > 0);
1448 //=======================================================================
1449 //function : SetSHUO
1451 //=======================================================================
1453 Standard_Boolean XCAFDoc_ShapeTool::SetSHUO (const TDF_LabelSequence& labels,
1454 Handle(XCAFDoc_GraphNode)& MainSHUOAttr) const
1456 MainSHUOAttr.Nullify();
1457 // check number of labels
1458 if (labels.Length() < 2)
1459 return Standard_False;
1460 // check is all labels contains components of any assemblyies
1462 for (i = 1; i <= labels.Length(); i++)
1463 if ( !IsComponent(labels.Value(i)) )
1464 return Standard_False;
1467 TDF_Label UpperSubL = aTag.NewChild( labels( 1 ) );
1468 if (theAutoNaming) {
1469 TCollection_ExtendedString Entry("SHUO");
1470 TDataStd_Name::Set(UpperSubL, TCollection_ExtendedString( Entry ));
1472 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1473 aUpperSHUO = XCAFDoc_GraphNode::Set( UpperSubL, XCAFDoc::SHUORefGUID() );
1474 // init out argument by main upper usage SHUO
1475 MainSHUOAttr = aUpperSHUO;
1476 // add other next_usage occurrences.
1477 for (i = 2; i <= labels.Length(); i++) {
1478 TDF_Label NextSubL = aTag.NewChild( labels( i ) );
1479 if (theAutoNaming) {
1480 TCollection_ExtendedString EntrySub("SHUO-");
1482 TDataStd_Name::Set(NextSubL, TCollection_ExtendedString( EntrySub ));
1484 Handle(XCAFDoc_GraphNode) aNextSHUO;
1485 aNextSHUO = XCAFDoc_GraphNode::Set( NextSubL, XCAFDoc::SHUORefGUID() );
1487 aUpperSHUO->SetChild( aNextSHUO );
1488 aNextSHUO->SetFather( aUpperSHUO );
1489 // now lets next_usage become upper_usage for next level of SHUO
1490 aUpperSHUO = aNextSHUO;
1491 UpperSubL = NextSubL;
1494 return Standard_True;
1497 //=======================================================================
1498 //function : GetSHUOUpperUsage
1500 //=======================================================================
1502 Standard_Boolean XCAFDoc_ShapeTool::GetSHUOUpperUsage (const TDF_Label& NextUsageL,
1503 TDF_LabelSequence& aLabels)
1505 Handle(XCAFDoc_GraphNode) aNextSHUO;
1506 if( !GetSHUO( NextUsageL, aNextSHUO ) || aNextSHUO->NbFathers()<1 )
1507 return Standard_False;
1509 // get upper_usage SHAO
1510 for (Standard_Integer i = 1; i <= aNextSHUO->NbFathers(); i++)
1511 aLabels.Append( aNextSHUO->GetFather(i)->Label() );
1512 return Standard_True;
1515 //=======================================================================
1516 //function : GetSHUONextUsage
1518 //=======================================================================
1520 Standard_Boolean XCAFDoc_ShapeTool::GetSHUONextUsage (const TDF_Label& UpperUsageL,
1521 TDF_LabelSequence& aLabels)
1523 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1524 if ( !GetSHUO( UpperUsageL, aUpperSHUO ) || aUpperSHUO->NbChildren()<1 )
1525 return Standard_False;
1526 // get upper_usage SHAO
1527 for (Standard_Integer i = 1; i <= aUpperSHUO->NbChildren(); i++)
1528 aLabels.Append( aUpperSHUO->GetChild(i)->Label() );
1529 return Standard_True;
1532 //=======================================================================
1533 //function : RemoveSHUO
1535 //=======================================================================
1537 Standard_Boolean XCAFDoc_ShapeTool::RemoveSHUO (const TDF_Label& L) const
1539 L.ForgetAllAttributes (Standard_True);
1540 return Standard_True;
1543 //=======================================================================
1544 //function : checkForShape
1545 //purpose : auxilary
1546 //=======================================================================
1548 static Standard_Boolean checkForShape (const TopoDS_Shape& theShape,
1549 const TopoDS_Shape& theCurSh,
1550 const TDF_Label& theUserL,
1551 TDF_LabelSequence& theLabels)
1553 // the label of an assembly which contains this component
1554 TDF_Label aSuperUserL = theUserL.Father();
1555 TopLoc_Location aSupLoc, aCompLoc;
1556 aSupLoc = ::XCAFDoc_ShapeTool::GetLocation ( aSuperUserL );
1557 aCompLoc = ::XCAFDoc_ShapeTool::GetLocation ( theUserL );
1558 TopoDS_Shape aCopySh = theCurSh;
1559 aCompLoc = aCompLoc.Multiplied( theCurSh.Location() );
1560 aSupLoc = aSupLoc.Multiplied( aCompLoc );
1561 aCopySh.Location( aSupLoc );
1562 if ( aCopySh.IsSame( theShape ) ) {
1563 theLabels.Prepend( theUserL );
1564 return Standard_True;
1566 // try to search deeply (upper by assmebly structure)
1567 TDF_LabelSequence aNewLabels;
1568 for (Standard_Integer j = 1; j <= theLabels.Length(); j++)
1569 aNewLabels.Append( theLabels.Value( j ) );
1570 aNewLabels.Prepend( theUserL );
1571 TDF_LabelSequence aUsers;
1572 ::XCAFDoc_ShapeTool::GetUsers( aSuperUserL, aUsers );
1573 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1574 if ( checkForShape( theShape, aCopySh, aUsers.Value( i ), aNewLabels ) ) {
1576 theLabels = aNewLabels;
1577 return Standard_True;
1579 return Standard_False;
1582 //=======================================================================
1583 //function : FindComponent
1585 //=======================================================================
1587 Standard_Boolean XCAFDoc_ShapeTool::FindComponent (const TopoDS_Shape& theShape,
1588 TDF_LabelSequence& theLabels) const
1591 // search for a top-level shape that corresponds to this component
1592 TopoDS_Shape S0 = theShape;
1593 TopLoc_Location loc;
1594 S0.Location ( loc );
1595 TDF_Label aRefL = FindShape( S0 );
1597 return Standard_False; // cannot find top-level shape.
1599 TDF_LabelSequence aUsers;
1600 ::XCAFDoc_ShapeTool::GetUsers( aRefL, aUsers );
1601 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1602 if ( checkForShape( theShape, S0, aUsers.Value( i ), theLabels ) )
1605 return (theLabels.Length() > 0);
1608 //=======================================================================
1609 //function : getShapesOfSHUO
1610 //purpose : auxilary
1611 //=======================================================================
1613 static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLocMap,
1614 const Handle(XCAFDoc_ShapeTool)& theSTool,
1615 const TDF_Label& theSHUOlab,
1616 TopoDS_Shape& theShape)
1618 Handle(XCAFDoc_GraphNode) SHUO;
1619 TDF_LabelSequence aLabSeq;
1620 theSTool->GetSHUONextUsage( theSHUOlab, aLabSeq );
1621 if (aLabSeq.Length() >= 1)
1622 for (Standard_Integer i = 1; i <= aLabSeq.Length(); i++) {
1623 TDF_Label aSubCompL = aLabSeq.Value( i );
1624 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSubCompL.Father() );
1625 // create new map of laocation (to not merge locations from different shapes)
1626 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1627 for (Standard_Integer m = 1; m <= theaPrevLocMap.Extent(); m++)
1628 aNewPrevLocMap.Add( theaPrevLocMap.FindKey( m ) );
1629 aNewPrevLocMap.Add( compLoc );
1630 // got for the new sublocations and corresponding shape
1631 getShapesOfSHUO( aNewPrevLocMap, theSTool, aSubCompL, theShape );
1634 TopoDS_Shape aSHUO_NUSh = theSTool->GetShape ( theSHUOlab.Father() );
1635 if ( aSHUO_NUSh.IsNull() ) return Standard_False;
1636 // cause got shape with location already.
1637 TopLoc_Location nullLoc;
1638 aSHUO_NUSh.Location ( nullLoc );
1639 // multiply the locations
1640 Standard_Integer intMapLenght = theaPrevLocMap.Extent();
1641 if ( intMapLenght < 1 )
1642 return Standard_False; // should not be, but to avoid exception...?
1643 TopLoc_Location SupcompLoc;
1644 SupcompLoc = theaPrevLocMap.FindKey( intMapLenght );
1645 if (intMapLenght > 1) {
1646 Standard_Integer l = intMapLenght - 1;
1648 SupcompLoc = theaPrevLocMap.FindKey( l ).Multiplied( SupcompLoc );
1652 aSHUO_NUSh.Location( SupcompLoc );
1653 theShape = aSHUO_NUSh;
1655 return (!theShape.IsNull());
1658 //=======================================================================
1659 //function : GetSHUOInstance
1661 //=======================================================================
1663 TopoDS_Shape XCAFDoc_ShapeTool::GetSHUOInstance (const Handle(XCAFDoc_GraphNode)& theSHUO) const
1665 TopoDS_Shape aShape;
1666 if (theSHUO.IsNull())
1669 TDF_Label aSHUOlab = theSHUO->Label();
1670 // get location of the assembly
1671 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1672 // get location of the component
1673 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1674 TopLoc_IndexedMapOfLocation aPrevLocMap;
1675 // get previous setted location
1676 if ( !loc.IsIdentity() )
1677 aPrevLocMap.Add( loc );
1678 aPrevLocMap.Add( compLoc );
1679 // get shape by recurse method
1680 const Handle(XCAFDoc_ShapeTool)& STool = this;
1681 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1686 //=======================================================================
1687 //function : getUsersShapesOfSHUO
1688 //purpose : auxilary
1689 //=======================================================================
1691 static Standard_Boolean getUsersShapesOfSHUO (TopLoc_IndexedMapOfLocation& aPrevLocMap,
1692 const Handle(XCAFDoc_ShapeTool)& STool,
1693 const TDF_Label& aSHUOlab,
1694 const TDF_Label& theUserL,
1695 TopTools_SequenceOfShape& theSHUOShapeSeq)
1697 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1698 // get location of the assembly
1699 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( theUserL.Father() );
1700 // get location of the component
1701 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( theUserL );
1702 // get previous setted location
1703 aNewPrevLocMap.Add( loc );
1704 aNewPrevLocMap.Add( compLoc );
1706 for (i = 1; i <= aPrevLocMap.Extent(); i++)
1707 aNewPrevLocMap.Add( aPrevLocMap.FindKey(i) );
1708 TDF_Label L = theUserL.Father();
1709 TDF_LabelSequence usersLab;
1710 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1711 if (usersLab.Length() == 0) {
1712 TopoDS_Shape aShape;
1713 getShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aShape );
1714 if (!aShape.IsNull()) {
1715 theSHUOShapeSeq.Append(aShape);
1716 return Standard_True;
1719 // now iterates on users of this assembly as component
1720 for ( i = 1; i <= usersLab.Length(); i++ ) {
1721 TDF_Label aNewUserL = usersLab.Value(i);
1722 getUsersShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aNewUserL, theSHUOShapeSeq );
1725 return (theSHUOShapeSeq.Length() > 1);
1728 //=======================================================================
1729 //function : GetAllSHUOInstances
1730 //purpose : auxilary
1731 //=======================================================================
1733 Standard_Boolean XCAFDoc_ShapeTool::GetAllSHUOInstances (const Handle(XCAFDoc_GraphNode)& theSHUO,
1734 TopTools_SequenceOfShape& theSHUOShapeSeq) const
1736 if (theSHUO.IsNull())
1737 return Standard_False;
1739 TDF_Label aSHUOlab = theSHUO->Label();
1740 TopLoc_IndexedMapOfLocation aPrevLocMap;
1741 // get location of the assembly
1742 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1743 // get location of the component
1744 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1745 // get previous setted location
1746 if ( !loc.IsIdentity() )
1747 aPrevLocMap.Add( loc );
1748 aPrevLocMap.Add( compLoc );
1749 // get label of assembly
1750 TDF_Label L = aSHUOlab.Father().Father();
1751 TDF_LabelSequence usersLab;
1752 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1753 TopoDS_Shape aShape;
1754 const Handle(XCAFDoc_ShapeTool)& STool = this;
1755 if (usersLab.Length() == 0) {
1756 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1757 if (!aShape.IsNull()) {
1758 theSHUOShapeSeq.Append(aShape);
1759 return Standard_True;
1762 // now iterates on users of this assembly as component
1763 for (Standard_Integer i = 1; i <= usersLab.Length(); i++) {
1764 TDF_Label aUserL = usersLab.Value(i);
1765 getUsersShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aUserL, theSHUOShapeSeq );
1768 return (theSHUOShapeSeq.Length() > 1);
1771 //=======================================================================
1772 //function : SetInstanceSHUO
1774 //=======================================================================
1776 Handle(XCAFDoc_GraphNode) XCAFDoc_ShapeTool::SetInstanceSHUO (const TopoDS_Shape& theShape) const
1778 Handle(XCAFDoc_GraphNode) SHUO;
1779 TDF_LabelSequence aLabels;
1780 if ( FindComponent( theShape, aLabels ) )
1781 // set shuo structure on labels of component-assembly structure
1782 SetSHUO( aLabels, SHUO );
1786 //=======================================================================
1787 //function : FindSHUO
1789 //=======================================================================
1791 Standard_Boolean XCAFDoc_ShapeTool::FindSHUO (const TDF_LabelSequence& theLabels,
1792 Handle(XCAFDoc_GraphNode)& theSHUOAttr)
1794 TDF_AttributeSequence SHUOAttrs;
1795 TDF_Label aCompLabel = theLabels.Value(1);
1796 if (! ::XCAFDoc_ShapeTool::GetAllComponentSHUO( aCompLabel, SHUOAttrs ) )
1797 return Standard_False;
1798 // WARNING: manage that each SHUO upper_usage have only one SHUO next_usage
1799 for (Standard_Integer i = 1; i <= SHUOAttrs.Length(); i++) {
1800 TDF_LabelSequence aCondidate;
1801 Handle(XCAFDoc_GraphNode) anSHUO = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1802 aCondidate.Append( anSHUO->Label().Father() );
1803 while (anSHUO->NbChildren()) {
1804 anSHUO = anSHUO->GetChild( 1 );
1805 aCondidate.Append( anSHUO->Label().Father() );
1807 // check the label sequences
1808 Standard_Boolean isEqual = Standard_True;
1809 if (theLabels.Length() != aCondidate.Length())
1810 isEqual = Standard_False;
1812 for (Standard_Integer li = 1; li <= theLabels.Length(); li++)
1813 if ( theLabels.Value(li) != aCondidate.Value(li) ) {
1814 isEqual = Standard_False;
1820 theSHUOAttr = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1823 return ( !theSHUOAttr.IsNull() );
1826 //=======================================================================
1829 //=======================================================================
1830 Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& theShapeL)
1832 if (theShapeL.IsNull() || IsAssembly(theShapeL))
1833 return Standard_False;
1835 TopoDS_Shape aShape = GetShape(theShapeL);
1836 if (aShape.IsNull())
1837 return Standard_False;
1839 TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
1840 Standard_Boolean isExpandedType = aShapeType == TopAbs_COMPOUND || aShapeType == TopAbs_COMPSOLID ||
1841 aShapeType == TopAbs_SHELL || aShapeType == TopAbs_WIRE;
1844 TopoDS_Iterator anIter(aShape);
1845 for(; anIter.More(); anIter.Next())
1847 const TopoDS_Shape& aChildShape = anIter.Value();
1848 TDF_Label aChild, aPart;
1850 // Find child shape as subshape of expanded shape
1851 FindSubShape(theShapeL, aChildShape, aChild);
1852 Handle(TDataStd_Name) anAttr;
1853 //make child (if color isn't set or if it is compound)
1854 if (aChild.IsNull()) {
1855 aChild = AddSubShape(theShapeL, aChildShape);
1859 aChild.FindAttribute(TDataStd_Name::GetID(), anAttr);
1862 // Try to find child shape as already existed part
1863 aPart = FindShape(aChildShape.Located(TopLoc_Location()));
1864 if (aPart.IsNull()) {
1865 // Create new part to link child shape
1866 aPart = AddShape(aChildShape.Located(TopLoc_Location()), Standard_False, Standard_False);
1868 // Add shape manually, if already existed subshape found instead of creation of new part
1869 if (!aPart.IsNull() && !IsTopLevel(aPart)) {
1870 if (!GetReferredShape(aPart, aPart)) {
1872 aPart = aTag.NewChild(Label());
1873 SetShape(aPart, aChildShape.Located(TopLoc_Location()));
1878 if (!anAttr.IsNull()) {
1879 TDataStd_Name::Set(aPart, anAttr->Get());
1882 Standard_SStream Stream;
1883 TopAbs::Print(aChildShape.ShapeType(), Stream);
1884 TCollection_AsciiString aName(Stream.str().c_str());
1885 TDataStd_Name::Set(aPart, TCollection_ExtendedString(aName));
1887 MakeReference(aChild, aPart, aChildShape.Location());
1888 makeSubShape(theShapeL, aPart, aChildShape, aChildShape.Location());
1890 //set assembly attribute
1891 TDataStd_UAttribute::Set(theShapeL, XCAFDoc::AssemblyGUID());
1892 return Standard_True;
1894 return Standard_False;
1897 //=======================================================================
1898 //function : makeSubShape
1900 //=======================================================================
1902 void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& theMainShapeL,
1903 const TDF_Label& thePart,
1904 const TopoDS_Shape& theShape,
1905 const TopLoc_Location& theLoc)
1907 TopoDS_Iterator anIter(theShape);
1908 Standard_Boolean isCompoundPart = (GetShape(thePart).ShapeType() == TopAbs_COMPOUND);
1909 Standard_Boolean isAssembly = IsAssembly(thePart);
1910 for(; anIter.More(); anIter.Next()) {
1911 const TopoDS_Shape& aChildShape = anIter.Value();
1912 TDF_Label aChildLabel;
1913 FindSubShape(theMainShapeL, aChildShape, aChildLabel);
1914 if(!aChildLabel.IsNull()) {
1916 aChildLabel.ForgetAllAttributes();
1917 makeSubShape(theMainShapeL, thePart, aChildShape, theLoc);
1922 Handle(TDataStd_Name) anAttr;
1923 aChildLabel.FindAttribute(TDataStd_Name::GetID(), anAttr);
1924 TopLoc_Location aSubLoc;
1925 // Calculate location for subshapes of compound parts
1927 aSubLoc = theLoc.Inverted() * aChildShape.Location();
1929 TDF_Label aSubLabel;
1930 if (!FindSubShape(thePart, aChildShape.Located(aSubLoc), aSubLabel)) {
1931 aSubLabel = AddSubShape(thePart, aChildShape.Located(aSubLoc));
1932 //set name to sub shape
1933 if (!anAttr.IsNull()) {
1934 TDataStd_Name::Set(aSubLabel, anAttr->Get());
1937 Standard_SStream Stream;
1938 TopAbs::Print(aChildShape.ShapeType(), Stream);
1939 TCollection_AsciiString aName(Stream.str().c_str());
1940 TDataStd_Name::Set(aSubLabel, TCollection_ExtendedString(aName));
1942 // Create auxiliary link, it will be removed during moving attributes
1943 MakeReference(aSubLabel, aChildLabel, aChildShape.Location());
1946 aChildLabel.ForgetAllAttributes();
1949 makeSubShape(theMainShapeL, thePart, aChildShape, theLoc);
1953 //=======================================================================
1954 //function : updateComponent
1956 //=======================================================================
1958 Standard_Boolean XCAFDoc_ShapeTool::updateComponent(const TDF_Label& theItemLabel,
1959 TopoDS_Shape& theUpdatedShape) const
1961 if ( !IsAssembly(theItemLabel) )
1962 return Standard_False; // Do nothing for non-assemblies
1964 // Get the currently stored compound for the assembly
1965 TopoDS_Shape aCurrentRootShape;
1966 GetShape(theItemLabel, aCurrentRootShape);
1968 // Get components of the assembly
1969 TDF_LabelSequence aComponentLabs;
1970 GetComponents(theItemLabel, aComponentLabs);
1972 // This flag indicates whether to update the compound of the assembly
1973 Standard_Boolean isModified = Standard_False;
1975 // Compare the number of components in XDE structure with the number of
1976 // components in topological structure. A component may happen to be removed,
1977 // so we have to update the assembly compound
1978 Standard_Integer aNumTopoComponents = aCurrentRootShape.NbChildren();
1980 if ( aNumTopoComponents != aComponentLabs.Length() )
1981 isModified = Standard_True;
1983 // Iterate over the assembly components. If at least one component is
1984 // modified (this is the recursive check), then the actually stored
1985 // compound has to be updated
1986 TopTools_ListOfShape aComponentShapes;
1988 for ( TDF_LabelSequence::Iterator aCompIt(aComponentLabs); aCompIt.More(); aCompIt.Next() )
1990 const TDF_Label& aComponentLab = aCompIt.Value();
1992 // Take the referred assembly item (ultimately, a part for an instance)
1993 TDF_Label aComponentRefLab;
1994 GetReferredShape(aComponentLab, aComponentRefLab);
1996 // Shape comes with some placement transformation here
1997 TopoDS_Shape aComponentShape;
1998 GetShape(aComponentLab, aComponentShape);
1999 TopLoc_Location aComponentLoc = aComponentShape.Location();
2001 // If the component is a sub-assembly, then its associated compound
2002 // has to be processed in the same manner
2003 if ( IsAssembly(aComponentRefLab) )
2006 if ( updateComponent(aComponentRefLab, aComponentShape) )
2009 isModified = Standard_True;
2011 aComponentShape.Location(aComponentLoc); // Apply placement
2016 // Search for a part in the actual compound of the ultimate assembly.
2017 // If the part is there, then the compound is up-to-date, so it does
2018 // not require rebuilding
2019 Standard_Boolean isPartFound = Standard_False;
2020 for ( TopoDS_Iterator aTopoIt(aCurrentRootShape); aTopoIt.More(); aTopoIt.Next() )
2022 if ( aTopoIt.Value() == aComponentShape )
2024 isPartFound = Standard_True;
2029 if ( !isPartFound && !isModified )
2030 isModified = Standard_True; // Part has been modified somewhere, so the compound
2031 // has to be rebuilt
2034 // Fill the list of shapes composing a new compound for the assembly
2035 aComponentShapes.Append(aComponentShape);
2038 // If any component is modified, we update the currently stored shape
2041 TopoDS_Compound anUpdatedCompound;
2043 aBB.MakeCompound(anUpdatedCompound);
2045 // Compose new compound
2046 for ( TopTools_ListIteratorOfListOfShape aShapeIt(aComponentShapes); aShapeIt.More(); aShapeIt.Next() )
2048 aBB.Add( anUpdatedCompound, aShapeIt.Value() );
2051 // Store the updated shape as an output
2052 theUpdatedShape = anUpdatedCompound;
2054 // Use topological naming services to store the updated shape in XDE
2055 TNaming_Builder NB(theItemLabel);
2056 NB.Generated(theUpdatedShape);