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);
308 return Standard_False;
311 return Standard_True;
313 // Try to find shape manually
314 TDF_ChildIDIterator it(Label(), TNaming_NamedShape::GetID());
315 for (; it.More(); it.Next()) {
316 TDF_Label aLabel = it.Value()->Label();
317 Handle(TNaming_NamedShape) NS;
318 if ( aLabel.FindAttribute(TNaming_NamedShape::GetID(), NS) &&
319 S0.IsSame ( TNaming_Tool::GetShape(NS) ) ) {
321 return Standard_True;
326 return Standard_False;
329 //=======================================================================
330 //function : FindShape
332 //=======================================================================
334 TDF_Label XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S,
335 const Standard_Boolean findInstance) const
338 if (FindShape(S, L, findInstance))
343 //=======================================================================
344 //function : GetShape
346 //=======================================================================
348 Standard_Boolean XCAFDoc_ShapeTool::GetShape (const TDF_Label& L, TopoDS_Shape& S)
350 Handle(XCAFDoc_Location) LocationAttribute;
353 TopoDS_Compound EmptyComp;
355 B.MakeCompound(EmptyComp);
359 // for instance, get referred shape
360 Handle(TDataStd_TreeNode) Node;
361 if ( L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather() &&
362 L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute)) {
363 if ( ! GetShape(Node->Father()->Label(), S) ) return Standard_False;
364 S.Move ( LocationAttribute->Get() );
365 return Standard_True;
368 // else just return shape on this label
369 Handle(TNaming_NamedShape) NS;
370 if ( ! L.FindAttribute(TNaming_NamedShape::GetID(), NS) ) return Standard_False;
371 S = TNaming_Tool::GetShape(NS);
372 return Standard_True;
375 //=======================================================================
376 //function : GetShape
378 //=======================================================================
380 TopoDS_Shape XCAFDoc_ShapeTool::GetShape(const TDF_Label& L)
387 //=======================================================================
388 //function : NewShape
390 //=======================================================================
392 TDF_Label XCAFDoc_ShapeTool::NewShape() const
394 TopoDS_Compound aShape;
396 tdsB.MakeCompound ( aShape );
399 TDF_Label aLabel = aTag.NewChild(Label());
401 TNaming_Builder tnBuild(aLabel);
402 tnBuild.Generated(aShape);
407 //=======================================================================
408 //function : SetShape
410 //=======================================================================
412 void XCAFDoc_ShapeTool::SetShape (const TDF_Label& L, const TopoDS_Shape& S)
414 TNaming_Builder tnBuild(L);
415 tnBuild.Generated(S);
416 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(L);
417 // if ( ! L.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
418 // A = XCAFDoc_ShapeMapTool::Set(L);
419 // L.AddAttribute(A);
423 if(!myShapeLabels.IsBound(S)) {
424 myShapeLabels.Bind(S,L);
428 //=======================================================================
429 //function : MakeReference
431 //=======================================================================
433 void XCAFDoc_ShapeTool::MakeReference (const TDF_Label &L,
434 const TDF_Label &refL,
435 const TopLoc_Location &loc)
438 XCAFDoc_Location::Set(L, loc);
441 Handle(TDataStd_TreeNode) refNode, mainNode;
442 mainNode = TDataStd_TreeNode::Set ( refL, XCAFDoc::ShapeRefGUID() );
443 refNode = TDataStd_TreeNode::Set ( L, XCAFDoc::ShapeRefGUID() );
444 refNode->Remove(); // abv: fix against bug in TreeNode::Append()
445 mainNode->Append(refNode);
448 SetLabelNameByLink(L);
451 //=======================================================================
452 //function : addShape
454 //=======================================================================
456 TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly)
458 TDF_Label ShapeLabel;
461 // search if the shape already exists (with the same location)
462 if ( S.IsNull() || FindShape ( S, ShapeLabel, Standard_True ) ) return ShapeLabel;
464 // else add a new label
465 ShapeLabel = aTag.NewChild(Label());
467 // if shape has location, make a reference to the same shape without location
468 if ( ! S.Location().IsIdentity() /*&& FindShape ( S, L )*/ ) {
472 TDF_Label L = addShape ( S0, makeAssembly );
473 MakeReference ( ShapeLabel, L, S.Location() );
477 // else add a shape to a label
478 TNaming_Builder tnBuild(ShapeLabel);
479 tnBuild.Generated(S);
481 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
482 // if ( ! ShapeLabel.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
483 // A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
484 // ShapeLabel.AddAttribute(A);
489 SetLabelNameByShape(ShapeLabel);
491 // if shape is Compound and flag is set, create assembly
492 if ( makeAssembly && S.ShapeType() == TopAbs_COMPOUND ) {
493 // mark assembly by assigning UAttribute
494 Handle(TDataStd_UAttribute) Uattr;
495 Uattr = TDataStd_UAttribute::Set ( ShapeLabel, XCAFDoc::AssemblyGUID() );
497 TDataStd_Name::Set(ShapeLabel, TCollection_ExtendedString("ASSEMBLY"));
499 // iterate on components
500 TopoDS_Iterator Iterator(S);
501 for (; Iterator.More(); Iterator.Next()) {
502 // get label for component`s shape
503 TopoDS_Shape Scomp = Iterator.Value(), S0 = Scomp;
506 TDF_Label compL = addShape ( S0, makeAssembly );
508 // add a component as reference
509 TDF_Label RefLabel = aTag.NewChild(ShapeLabel);
510 MakeReference ( RefLabel, compL, Scomp.Location() );
514 if(!IsAssembly(ShapeLabel)) {
515 //const TopTools_IndexedMapOfShape tmpMap = A->GetMap();
516 //for(Standard_Integer i=1; i<=tmpMap.Extent(); i++)
517 //mySubShapes.Bind(tmpMap.FindKey(i),ShapeLabel);
518 for(Standard_Integer i=1; i<=A->GetMap().Extent(); i++)
520 TopoDS_Shape aSh = A->GetMap().FindKey(i);
521 mySubShapes.Bind(aSh,ShapeLabel);
523 //mySubShapes.Bind(ShapeLabel,A->GetMap());
530 //=======================================================================
531 //function : prepareAssembly
533 //=======================================================================
534 static Standard_Boolean prepareAssembly (const TopoDS_Shape& theShape,
535 TopoDS_Shape& theOUTShape)
537 // iterate on components
538 theOUTShape = theShape;
539 if (theShape.ShapeType() == TopAbs_COMPOUND) {
541 // check if shape if frosen
542 if (!theOUTShape.Free())
543 theOUTShape.Free(Standard_True);
545 TopTools_SequenceOfShape aSubShapeSeq;
546 TopoDS_Iterator Iterator(theShape);
547 for (; Iterator.More(); Iterator.Next())
548 aSubShapeSeq.Append(Iterator.Value());
549 for (Standard_Integer i = 1; i <= aSubShapeSeq.Length(); i++) {
550 TopoDS_Shape Scomp = aSubShapeSeq.Value(i);
551 TopoDS_Shape aNewScomp;
552 B.Remove(theOUTShape, Scomp);
553 prepareAssembly( Scomp, aNewScomp );
554 TopLoc_Location aLoc;
555 aLoc = aNewScomp.Location();
556 if ( aLoc.IsIdentity() ) {
557 // create an "empty" location
559 aTrsf.SetScale(gp_Pnt(0,0,0), 1);
560 aLoc = TopLoc_Location( aTrsf );
561 aNewScomp.Location( aLoc );
563 B.Add(theOUTShape, aNewScomp);
566 return Standard_True;
570 //=======================================================================
571 //function : AddShape
573 //=======================================================================
575 TDF_Label XCAFDoc_ShapeTool::AddShape (const TopoDS_Shape& theShape,
576 const Standard_Boolean makeAssembly,
577 const Standard_Boolean makePrepare)
579 // PTV 17.02.2003 to avoid components without location.
580 TopoDS_Shape S = theShape;
581 if ( makePrepare && makeAssembly && S.ShapeType() == TopAbs_COMPOUND )
582 prepareAssembly( theShape, S ); // OCC1669
584 TDF_Label L = addShape(S,makeAssembly);
586 if(!myShapeLabels.IsBound(S)) {
587 myShapeLabels.Bind(S,L);
592 //return addShape( S, makeAssembly );
595 //=======================================================================
596 //function : RemoveShape
598 //=======================================================================
600 Standard_Boolean XCAFDoc_ShapeTool::RemoveShape (const TDF_Label& L,
601 const Standard_Boolean removeCompletely) const
603 if ( ! IsTopLevel ( L ) || ! IsFree ( L ) ) return Standard_False;
605 Handle(TDataStd_TreeNode) aNode;
607 if (removeCompletely &&
608 L.FindAttribute (XCAFDoc::ShapeRefGUID(), aNode) &&
609 aNode->HasFather() &&
610 L.IsAttribute (XCAFDoc_Location::GetID()))
612 aLabel = aNode->Father()->Label();
615 L.ForgetAllAttributes (Standard_True);
617 if (removeCompletely && !aLabel.IsNull())
619 return RemoveShape(aLabel);
621 return Standard_True;
625 //=======================================================================
628 //=======================================================================
630 void XCAFDoc_ShapeTool::Init()
632 hasSimpleShapes = Standard_False;
636 //=======================================================================
637 //function : SetAutoNaming
639 //=======================================================================
641 void XCAFDoc_ShapeTool::SetAutoNaming (const Standard_Boolean V)
647 //=======================================================================
648 //function : AutoNaming
650 //=======================================================================
652 Standard_Boolean XCAFDoc_ShapeTool::AutoNaming()
654 return theAutoNaming;
658 //=======================================================================
659 //function : ComputeShapes
661 //=======================================================================
663 void XCAFDoc_ShapeTool::ComputeShapes(const TDF_Label& L)
665 TDF_ChildIterator it(L);
666 for(; it.More(); it.Next()) {
667 TDF_Label L1 = it.Value();
670 if(!myShapeLabels.IsBound(S)) {
671 mySimpleShapes.Bind(S,L1);
679 //=======================================================================
680 //function : ComputeSimpleShapes
682 //=======================================================================
684 void XCAFDoc_ShapeTool::ComputeSimpleShapes()
686 ComputeShapes(Label());
687 hasSimpleShapes = Standard_True;
691 //=======================================================================
692 //function : GetShapes
694 //=======================================================================
696 void XCAFDoc_ShapeTool::GetShapes(TDF_LabelSequence& Labels) const
700 TDF_ChildIterator it(Label());
701 for (; it.More(); it.Next()) {
702 TDF_Label L = it.Value();
704 if ( GetShape ( L, S ) ) Labels.Append ( L );
709 //=======================================================================
710 //function : GetFreeShapes
712 //=======================================================================
714 void XCAFDoc_ShapeTool::GetFreeShapes (TDF_LabelSequence& FreeLabels) const
718 TDF_ChildIterator it(Label());
719 for (; it.More(); it.Next()) {
720 TDF_Label L = it.Value();
722 if ( GetShape ( L, S ) && IsFree ( L ) ) FreeLabels.Append ( L );
726 //=======================================================================
727 //function : IsTopLevel
729 //=======================================================================
731 Standard_Boolean XCAFDoc_ShapeTool::IsTopLevel (const TDF_Label& L) const
733 return L.Father() == Label();
736 //=======================================================================
739 //=======================================================================
741 Standard_Boolean XCAFDoc_ShapeTool::IsShape (const TDF_Label& L)
743 return IsSimpleShape ( L ) || IsAssembly ( L ) || IsReference ( L );
746 //=======================================================================
747 //function : IsSimpleShape
749 //=======================================================================
751 Standard_Boolean XCAFDoc_ShapeTool::IsSimpleShape (const TDF_Label& L)
753 Handle(TNaming_NamedShape) NS;
754 return L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) &&
755 ! IsAssembly ( L ) && ! IsReference ( L );
758 //=======================================================================
759 //function : IsReference
761 //=======================================================================
763 Standard_Boolean XCAFDoc_ShapeTool::IsReference (const TDF_Label& L)
765 Handle(TDataStd_TreeNode) Node;
766 return L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather();
769 //=======================================================================
770 //function : IsAssembly
772 //=======================================================================
774 Standard_Boolean XCAFDoc_ShapeTool::IsAssembly (const TDF_Label& L)
776 Handle(TDataStd_UAttribute) Uattr;
777 return L.FindAttribute(XCAFDoc::AssemblyGUID(), Uattr);
780 //=======================================================================
781 //function : IsComponent
783 //=======================================================================
785 Standard_Boolean XCAFDoc_ShapeTool::IsComponent (const TDF_Label& L)
787 return IsReference ( L ) && IsAssembly ( L.Father() );
790 //=======================================================================
791 //function : IsCompound
793 //=======================================================================
795 Standard_Boolean XCAFDoc_ShapeTool::IsCompound (const TDF_Label& L)
797 Handle(TDataStd_Name) Name;
798 if (L.FindAttribute(TDataStd_Name::GetID(),Name)) {
799 TCollection_ExtendedString estr1 = Name->Get();
800 TCollection_ExtendedString estr2("COMPOUND");
802 return Standard_True;
805 return Standard_False;
808 //=======================================================================
809 //function : IsSubShape
811 //=======================================================================
813 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label& L)
815 return IsSimpleShape ( L ) && IsShape ( L.Father() );
818 //=======================================================================
821 //=======================================================================
823 Standard_Boolean XCAFDoc_ShapeTool::IsFree (const TDF_Label& L)
825 Handle(TDataStd_TreeNode) Node;
826 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
827 ! Node->HasFirst() ) return Standard_True;
829 return Standard_False;
832 //=======================================================================
833 //function : GetUsers
834 //purpose : Returns number of users (0 if shape is free)
835 //=======================================================================
837 Standard_Integer XCAFDoc_ShapeTool::GetUsers (const TDF_Label& L,
838 TDF_LabelSequence& Labels,
839 const Standard_Boolean getsubchilds)
841 Standard_Integer NbUsers=0;
842 Handle(TDataStd_TreeNode) Node ;
844 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ) return NbUsers;
846 Node = Node->First();
847 while ( ! Node.IsNull() ) {
849 if ( getsubchilds ) {
850 TDF_Label underL = Node->Label().Father();
851 NbUsers += GetUsers ( underL, Labels, getsubchilds );
854 Labels.Append(Node->Label());
861 //=======================================================================
862 //function : NbComponents
864 //=======================================================================
866 Standard_Integer XCAFDoc_ShapeTool::NbComponents (const TDF_Label& L,
867 const Standard_Boolean getsubchilds)
869 TDF_LabelSequence subLabels;
870 GetComponents (L, subLabels, getsubchilds);
871 return subLabels.Length();
874 //=======================================================================
875 //function : GetComponents
877 //=======================================================================
879 Standard_Boolean XCAFDoc_ShapeTool::GetComponents (const TDF_Label& L, TDF_LabelSequence& Labels,
880 const Standard_Boolean getsubchilds)
882 if ( ! IsAssembly(L) ) return Standard_False;
884 TDF_ChildIterator It(L);
885 for (; It.More(); It.Next() ) {
886 TDF_Label comp = It.Value();
887 if ( IsComponent ( comp ) ) {
888 if ( getsubchilds ) {
890 if ( GetReferredShape ( comp, underL ) )
891 GetComponents ( underL, Labels, getsubchilds);
893 Labels.Append ( comp );
896 return Standard_True;
899 //=======================================================================
900 //function : GetLocation
902 //=======================================================================
904 TopLoc_Location XCAFDoc_ShapeTool::GetLocation (const TDF_Label& L)
906 Handle(XCAFDoc_Location) LocationAttribute;
907 if (L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute))
908 return LocationAttribute->Get();
910 Handle(TNaming_NamedShape) NS;
912 if ( L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) ) {
913 S = TNaming_Tool::GetShape(NS);
918 //=======================================================================
919 //function : GetReferredShape
921 //=======================================================================
923 Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L,
926 if ( ! IsReference(L) ) return Standard_False;
928 Handle (TDataStd_TreeNode) Node;
929 L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node);
930 Label = Node->Father()->Label();
931 return Standard_True;
934 //=======================================================================
935 //function : AddComponent
937 //=======================================================================
939 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
940 const TDF_Label& compL,
941 const TopLoc_Location &Loc)
945 // check that shape is assembly
946 if ( ! IsAssembly(assembly) ) {
947 // if it is simple shape, make it assembly
948 if ( IsSimpleShape(assembly) )
949 TDataStd_UAttribute::Set ( assembly, XCAFDoc::AssemblyGUID() );
953 // add a component as reference
955 L = aTag.NewChild(assembly);
956 MakeReference ( L, compL, Loc );
958 // map shape to label
960 if (GetShape(L, aShape))
962 if (!myShapeLabels.IsBound(aShape))
963 myShapeLabels.Bind(aShape, L);
969 //=======================================================================
970 //function : AddComponent
972 //=======================================================================
974 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
975 const TopoDS_Shape& comp,
976 const Standard_Boolean expand)
978 // get label for component`s shape
979 TopoDS_Shape S0 = comp;
983 compL = AddShape ( S0, expand );
985 // add component by its label
986 return AddComponent ( assembly, compL, comp.Location() );
989 //=======================================================================
990 //function : RemoveComponent
992 //=======================================================================
994 void XCAFDoc_ShapeTool::RemoveComponent (const TDF_Label& comp) const
996 if ( IsComponent(comp) )
998 comp.ForgetAllAttributes();
1002 //=======================================================================
1003 //function : UpdateAssemblies
1005 //=======================================================================
1007 void XCAFDoc_ShapeTool::UpdateAssemblies()
1009 // We start from the free shapes (roots in the assembly structure)
1010 TDF_LabelSequence aRootLabels;
1011 GetFreeShapes(aRootLabels);
1013 // Iterate over the free shapes
1014 for ( TDF_LabelSequence::Iterator anIt(aRootLabels); anIt.More(); anIt.Next() )
1016 TDF_Label aRefLabel = anIt.Value();
1017 if (IsReference(aRefLabel))
1019 GetReferredShape(aRefLabel, aRefLabel);
1021 const TDF_Label& aRootLab = aRefLabel;
1022 TopoDS_Shape anAssemblyShape;
1023 updateComponent(aRootLab, anAssemblyShape);
1027 //=======================================================================
1028 //function : IsSubShape
1030 //=======================================================================
1032 //static Standard_Boolean CheckSubShape (const TopoDS_Shape &S, const TopoDS_Shape &sub)
1034 // if ( S.IsSame ( sub ) ) return Standard_True;
1036 // if ( S.ShapeType() >= sub.ShapeType() ) return Standard_False;
1038 // for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
1039 // if ( CheckSubShape ( it.Value(), sub ) ) return Standard_True;
1041 // return Standard_False;
1044 //=======================================================================
1045 //function : IsSubShape
1047 //=======================================================================
1049 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label &shapeL,
1050 const TopoDS_Shape &sub) const
1052 Handle(XCAFDoc_ShapeMapTool) A;
1053 if (!shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A))
1055 TopoDS_Shape aShape = GetShape(shapeL);
1056 if (aShape.IsNull())
1057 return Standard_False;
1058 A = XCAFDoc_ShapeMapTool::Set(shapeL);
1059 A->SetShape(aShape);
1062 return A->IsSubShape(sub);
1065 //=======================================================================
1066 //function : FindSubShape
1068 //=======================================================================
1070 Standard_Boolean XCAFDoc_ShapeTool::FindSubShape (const TDF_Label &shapeL,
1071 const TopoDS_Shape &sub,
1075 return Standard_False;
1077 if (TNaming_Tool::HasLabel(Label(), sub)) {
1079 L = TNaming_Tool::Label(Label(), sub, TransDef);
1081 return Standard_False;
1082 if (L.Father() == shapeL)
1083 return Standard_True;
1087 return Standard_False;
1090 // if subshape was found wrong, try to do it manually
1091 // it can be possible if several part shapes has the same subshapes
1093 TDF_ChildIterator aChldLabIt(shapeL);
1094 for (; aChldLabIt.More(); aChldLabIt.Next() ) {
1095 TDF_Label aSubLabel = aChldLabIt.Value();
1096 TopoDS_Shape aSubShape;
1097 if (GetShape(aSubLabel, aSubShape) && aSubShape.IsSame(sub)) {
1099 return Standard_True;
1102 return Standard_False;
1105 //=======================================================================
1106 //function : AddSubShape
1108 //=======================================================================
1110 TDF_Label XCAFDoc_ShapeTool::AddSubShape (const TDF_Label &shapeL,
1111 const TopoDS_Shape &sub) const
1114 if (!IsSimpleShape(shapeL) || !IsTopLevel(shapeL))
1117 if ( FindSubShape ( shapeL, sub, L ) ) return L;
1119 if (!IsSubShape(shapeL, sub))
1123 L = aTag.NewChild(shapeL);
1125 TNaming_Builder tnBuild(L);
1126 tnBuild.Generated(sub);
1128 // if(!mySubShapes.IsBound(sub))
1129 // mySubShapes.Bind(sub,L);
1135 //=======================================================================
1136 //function : FindMainShapeUsingMap
1138 //=======================================================================
1140 TDF_Label XCAFDoc_ShapeTool::FindMainShapeUsingMap(const TopoDS_Shape &sub) const
1142 //for(Standard_Integer i=1; i<=myNotAssemblies.Length(); i++) {
1143 // TDF_Label L = myNotAssemblies.Value(i);
1144 // if(IsSubShape(L,sub)) return L;
1146 if(mySubShapes.IsBound(sub))
1147 return mySubShapes.Find(sub);
1153 //=======================================================================
1154 //function : FindMainShape
1156 //=======================================================================
1158 TDF_Label XCAFDoc_ShapeTool::FindMainShape (const TopoDS_Shape &sub) const
1160 TDF_ChildIterator it(Label());
1161 for (; it.More(); it.Next()) {
1162 TDF_Label L = it.Value();
1164 if ( IsSimpleShape( L ) && IsSubShape ( L, sub ) ) return L;
1171 //=======================================================================
1172 //function : GetSubShapes
1174 //=======================================================================
1176 Standard_Boolean XCAFDoc_ShapeTool::GetSubShapes (const TDF_Label &L,
1177 TDF_LabelSequence& Labels)
1179 TDF_ChildIterator It(L);
1180 for (; It.More(); It.Next() ) {
1181 TDF_Label sub = It.Value();
1182 if ( IsSubShape ( sub ) ) Labels.Append ( sub );
1184 return Labels.Length() >0;
1187 //=======================================================================
1188 //function : BaseLabel
1190 //=======================================================================
1192 TDF_Label XCAFDoc_ShapeTool::BaseLabel () const
1197 //=======================================================================
1198 //function : DumpAssembly
1199 //purpose : recursive part of Dump()
1200 //=======================================================================
1202 static void DumpAssembly(Standard_OStream& theDumpLog,
1204 const Standard_Integer level,
1205 const Standard_Boolean deep)
1208 XCAFDoc_ShapeTool::GetShape(L, S);
1211 for (Standard_Integer i=0; i<level; i++)
1214 TCollection_AsciiString Entry;
1215 TDF_Tool::Entry(L, Entry);
1217 if(XCAFDoc_ShapeTool::IsAssembly(L))
1219 theDumpLog<<"ASSEMBLY ";
1221 else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
1223 if(L.Father().Father().Father().IsRoot())
1224 theDumpLog<<"PART ";
1228 theDumpLog<<"INSTANCE ";
1230 TopAbs::Print(S.ShapeType(), theDumpLog);
1232 theDumpLog<<" "<<Entry;
1233 if(XCAFDoc_ShapeTool::IsReference(L))
1235 Handle(TDataStd_TreeNode) aRef;
1236 L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
1237 TDF_Tool::Entry(aRef->Father()->Label(), Entry);
1238 theDumpLog<<" (refers to "<<Entry<<")";
1240 Handle(TDataStd_Name) Name;
1241 if (L.FindAttribute(TDataStd_Name::GetID(), Name))
1242 theDumpLog<<" \""<<Name->Get()<<"\" ";
1245 theDumpLog<<"("<<*(void**)&S.TShape();
1246 if (! S.Location().IsIdentity())
1247 theDumpLog<<", "<< *(void**)&S.Location();
1252 Handle(TDataStd_TreeNode) Node;
1253 TDF_ChildIterator NodeIterator(L);
1254 for (; NodeIterator.More(); NodeIterator.Next()) {
1255 DumpAssembly(theDumpLog, NodeIterator.Value(), level+1, deep);
1261 //=======================================================================
1264 //=======================================================================
1266 Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog, const Standard_Boolean deep) const
1268 Standard_Integer level = 0;
1269 // TopTools_SequenceOfShape SeqShapes;
1270 TDF_LabelSequence SeqLabels;
1271 GetShapes( SeqLabels);
1273 if (SeqLabels.Length()>0) theDumpLog<<endl;
1275 for (i=1; i<=SeqLabels.Length(); i++) {
1276 DumpAssembly(theDumpLog, SeqLabels.Value(i), level, deep);
1280 GetFreeShapes(SeqLabels);
1281 theDumpLog<<endl<<"Free Shapes: "<<SeqLabels.Length()<<endl;
1282 for (i = 1; i<=SeqLabels.Length(); i++) {
1283 DumpShape(theDumpLog, SeqLabels.Value(i), level, deep);
1289 //=======================================================================
1291 //purpose : override
1292 //=======================================================================
1294 Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog) const
1296 TDF_Attribute::Dump (theDumpLog);
1297 Dump (theDumpLog, Standard_False);
1301 //=======================================================================
1302 //function : DumpShape
1304 //=======================================================================
1306 void XCAFDoc_ShapeTool::DumpShape(Standard_OStream& theDumpLog, const TDF_Label& L,const Standard_Integer level,const Standard_Boolean deep)
1309 if(! XCAFDoc_ShapeTool::GetShape(L, S) ) return;
1310 for (Standard_Integer i=0; i<level; i++)
1313 if(XCAFDoc_ShapeTool::IsAssembly(L))
1315 theDumpLog<<"ASSEMBLY ";
1317 else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
1319 if(L.Father().Father().Father().IsRoot())
1320 theDumpLog<<"PART ";
1324 theDumpLog<<"INSTANCE ";
1326 TopAbs::Print(S.ShapeType(), theDumpLog);
1328 TCollection_AsciiString Entry;
1329 TDF_Tool::Entry(L, Entry);
1330 theDumpLog<<" "<<Entry;
1331 if(XCAFDoc_ShapeTool::IsReference(L))
1333 Handle(TDataStd_TreeNode) aRef;
1334 L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
1335 TDF_Tool::Entry(aRef->Father()->Label(), Entry);
1336 theDumpLog<<" (refers to "<<Entry<<")";
1339 Handle(TDataStd_Name) Name;
1340 if (L.FindAttribute(TDataStd_Name::GetID(),Name))
1341 theDumpLog<<" \""<<Name->Get()<<"\" ";
1344 theDumpLog<<"("<<*(void**)&S.TShape();
1345 if (! S.Location().IsIdentity())
1346 theDumpLog<<", "<< *(void**)&S.Location();
1351 //=======================================================================
1352 //function : IsExternRef
1354 //=======================================================================
1356 Standard_Boolean XCAFDoc_ShapeTool::IsExternRef(const TDF_Label& L)
1358 Handle(TDataStd_UAttribute) Uattr;
1359 return L.FindAttribute(XCAFDoc::ExternRefGUID(), Uattr);
1362 //=======================================================================
1363 //function : SetExternRefs
1365 //=======================================================================
1367 void XCAFDoc_ShapeTool::SetExternRefs(const TDF_Label& L,
1368 const TColStd_SequenceOfHAsciiString& SHAS) const
1370 TDF_Label ShapeLabel = L.NewChild();
1371 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1372 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1373 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1374 Handle(TCollection_HAsciiString) str = SHAS(i);
1375 TCollection_ExtendedString extstr(str->String());
1376 TDataStd_Name::Set(tmplbl,extstr);
1380 //=======================================================================
1381 //function : SetExternRefs
1383 //=======================================================================
1385 TDF_Label XCAFDoc_ShapeTool::SetExternRefs(const TColStd_SequenceOfHAsciiString& SHAS) const
1387 TDF_Label ShapeLabel;
1390 ShapeLabel = aTag.NewChild(Label());
1391 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1392 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1393 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1394 Handle(TCollection_HAsciiString) str = SHAS(i);
1395 TCollection_ExtendedString extstr(str->String());
1396 TDataStd_Name::Set(tmplbl,extstr);
1401 //=======================================================================
1402 //function : GetExternRefs
1404 //=======================================================================
1406 void XCAFDoc_ShapeTool::GetExternRefs(const TDF_Label& L,
1407 TColStd_SequenceOfHAsciiString& SHAS)
1409 Handle(TDataStd_Name) TDN;
1411 for(Standard_Integer i=1; i<=L.NbChildren(); i++) {
1412 tmplbl = L.FindChild(i);
1413 if(tmplbl.FindAttribute(TDataStd_Name::GetID(),TDN)) {
1414 TCollection_ExtendedString extstr = TDN->Get();
1415 Handle(TCollection_HAsciiString) str =
1416 new TCollection_HAsciiString(TCollection_AsciiString(extstr, '?'));
1422 // API: API work with SHUO (Specified Higher Usage Occurrance) structure
1424 //=======================================================================
1425 //function : GetSHUO
1427 //=======================================================================
1429 Standard_Boolean XCAFDoc_ShapeTool::GetSHUO (const TDF_Label& SHUOLabel,
1430 Handle(XCAFDoc_GraphNode)& aSHUOAttr)
1432 if ( !SHUOLabel.FindAttribute( XCAFDoc::SHUORefGUID(), aSHUOAttr ) )
1433 return Standard_False;
1434 return Standard_True;
1437 //=======================================================================
1438 //function : GetAllComponentSHUO
1440 //=======================================================================
1442 Standard_Boolean XCAFDoc_ShapeTool::GetAllComponentSHUO (const TDF_Label& theCompLabel,
1443 TDF_AttributeSequence& theSHUOAttrs)
1445 TDF_ChildIterator it(theCompLabel);
1446 for (; it.More(); it.Next()) {
1447 TDF_Label L = it.Value();
1448 Handle(XCAFDoc_GraphNode) aSHUOAttr;
1449 if ( GetSHUO( L, aSHUOAttr ) )
1450 theSHUOAttrs.Append( aSHUOAttr );
1452 return (theSHUOAttrs.Length() > 0);
1455 //=======================================================================
1456 //function : SetSHUO
1458 //=======================================================================
1460 Standard_Boolean XCAFDoc_ShapeTool::SetSHUO (const TDF_LabelSequence& labels,
1461 Handle(XCAFDoc_GraphNode)& MainSHUOAttr) const
1463 MainSHUOAttr.Nullify();
1464 // check number of labels
1465 if (labels.Length() < 2)
1466 return Standard_False;
1467 // check is all labels contains components of any assemblyies
1469 for (i = 1; i <= labels.Length(); i++)
1470 if ( !IsComponent(labels.Value(i)) )
1471 return Standard_False;
1474 TDF_Label UpperSubL = aTag.NewChild( labels( 1 ) );
1475 if (theAutoNaming) {
1476 TCollection_ExtendedString Entry("SHUO");
1477 TDataStd_Name::Set(UpperSubL, TCollection_ExtendedString( Entry ));
1479 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1480 aUpperSHUO = XCAFDoc_GraphNode::Set( UpperSubL, XCAFDoc::SHUORefGUID() );
1481 // init out argument by main upper usage SHUO
1482 MainSHUOAttr = aUpperSHUO;
1483 // add other next_usage occurrences.
1484 for (i = 2; i <= labels.Length(); i++) {
1485 TDF_Label NextSubL = aTag.NewChild( labels( i ) );
1486 if (theAutoNaming) {
1487 TCollection_ExtendedString EntrySub("SHUO-");
1489 TDataStd_Name::Set(NextSubL, TCollection_ExtendedString( EntrySub ));
1491 Handle(XCAFDoc_GraphNode) aNextSHUO;
1492 aNextSHUO = XCAFDoc_GraphNode::Set( NextSubL, XCAFDoc::SHUORefGUID() );
1494 aUpperSHUO->SetChild( aNextSHUO );
1495 aNextSHUO->SetFather( aUpperSHUO );
1496 // now lets next_usage become upper_usage for next level of SHUO
1497 aUpperSHUO = aNextSHUO;
1498 UpperSubL = NextSubL;
1501 return Standard_True;
1504 //=======================================================================
1505 //function : GetSHUOUpperUsage
1507 //=======================================================================
1509 Standard_Boolean XCAFDoc_ShapeTool::GetSHUOUpperUsage (const TDF_Label& NextUsageL,
1510 TDF_LabelSequence& aLabels)
1512 Handle(XCAFDoc_GraphNode) aNextSHUO;
1513 if( !GetSHUO( NextUsageL, aNextSHUO ) || aNextSHUO->NbFathers()<1 )
1514 return Standard_False;
1516 // get upper_usage SHAO
1517 for (Standard_Integer i = 1; i <= aNextSHUO->NbFathers(); i++)
1518 aLabels.Append( aNextSHUO->GetFather(i)->Label() );
1519 return Standard_True;
1522 //=======================================================================
1523 //function : GetSHUONextUsage
1525 //=======================================================================
1527 Standard_Boolean XCAFDoc_ShapeTool::GetSHUONextUsage (const TDF_Label& UpperUsageL,
1528 TDF_LabelSequence& aLabels)
1530 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1531 if ( !GetSHUO( UpperUsageL, aUpperSHUO ) || aUpperSHUO->NbChildren()<1 )
1532 return Standard_False;
1533 // get upper_usage SHAO
1534 for (Standard_Integer i = 1; i <= aUpperSHUO->NbChildren(); i++)
1535 aLabels.Append( aUpperSHUO->GetChild(i)->Label() );
1536 return Standard_True;
1539 //=======================================================================
1540 //function : RemoveSHUO
1542 //=======================================================================
1544 Standard_Boolean XCAFDoc_ShapeTool::RemoveSHUO (const TDF_Label& L) const
1546 L.ForgetAllAttributes (Standard_True);
1547 return Standard_True;
1550 //=======================================================================
1551 //function : checkForShape
1552 //purpose : auxilary
1553 //=======================================================================
1555 static Standard_Boolean checkForShape (const TopoDS_Shape& theShape,
1556 const TopoDS_Shape& theCurSh,
1557 const TDF_Label& theUserL,
1558 TDF_LabelSequence& theLabels)
1560 // the label of an assembly which contains this component
1561 TDF_Label aSuperUserL = theUserL.Father();
1562 TopLoc_Location aSupLoc, aCompLoc;
1563 aSupLoc = ::XCAFDoc_ShapeTool::GetLocation ( aSuperUserL );
1564 aCompLoc = ::XCAFDoc_ShapeTool::GetLocation ( theUserL );
1565 TopoDS_Shape aCopySh = theCurSh;
1566 aCompLoc = aCompLoc.Multiplied( theCurSh.Location() );
1567 aSupLoc = aSupLoc.Multiplied( aCompLoc );
1568 aCopySh.Location( aSupLoc );
1569 if ( aCopySh.IsSame( theShape ) ) {
1570 theLabels.Prepend( theUserL );
1571 return Standard_True;
1573 // try to search deeply (upper by assmebly structure)
1574 TDF_LabelSequence aNewLabels;
1575 for (Standard_Integer j = 1; j <= theLabels.Length(); j++)
1576 aNewLabels.Append( theLabels.Value( j ) );
1577 aNewLabels.Prepend( theUserL );
1578 TDF_LabelSequence aUsers;
1579 ::XCAFDoc_ShapeTool::GetUsers( aSuperUserL, aUsers );
1580 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1581 if ( checkForShape( theShape, aCopySh, aUsers.Value( i ), aNewLabels ) ) {
1583 theLabels = aNewLabels;
1584 return Standard_True;
1586 return Standard_False;
1589 //=======================================================================
1590 //function : FindComponent
1592 //=======================================================================
1594 Standard_Boolean XCAFDoc_ShapeTool::FindComponent (const TopoDS_Shape& theShape,
1595 TDF_LabelSequence& theLabels) const
1598 // search for a top-level shape that corresponds to this component
1599 TopoDS_Shape S0 = theShape;
1600 TopLoc_Location loc;
1601 S0.Location ( loc );
1602 TDF_Label aRefL = FindShape( S0 );
1604 return Standard_False; // cannot find top-level shape.
1606 TDF_LabelSequence aUsers;
1607 ::XCAFDoc_ShapeTool::GetUsers( aRefL, aUsers );
1608 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1609 if ( checkForShape( theShape, S0, aUsers.Value( i ), theLabels ) )
1612 return (theLabels.Length() > 0);
1615 //=======================================================================
1616 //function : getShapesOfSHUO
1617 //purpose : auxilary
1618 //=======================================================================
1620 static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLocMap,
1621 const Handle(XCAFDoc_ShapeTool)& theSTool,
1622 const TDF_Label& theSHUOlab,
1623 TopoDS_Shape& theShape)
1625 Handle(XCAFDoc_GraphNode) SHUO;
1626 TDF_LabelSequence aLabSeq;
1627 theSTool->GetSHUONextUsage( theSHUOlab, aLabSeq );
1628 if (aLabSeq.Length() >= 1)
1629 for (Standard_Integer i = 1; i <= aLabSeq.Length(); i++) {
1630 TDF_Label aSubCompL = aLabSeq.Value( i );
1631 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSubCompL.Father() );
1632 // create new map of laocation (to not merge locations from different shapes)
1633 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1634 for (Standard_Integer m = 1; m <= theaPrevLocMap.Extent(); m++)
1635 aNewPrevLocMap.Add( theaPrevLocMap.FindKey( m ) );
1636 aNewPrevLocMap.Add( compLoc );
1637 // got for the new sublocations and corresponding shape
1638 getShapesOfSHUO( aNewPrevLocMap, theSTool, aSubCompL, theShape );
1641 TopoDS_Shape aSHUO_NUSh = theSTool->GetShape ( theSHUOlab.Father() );
1642 if ( aSHUO_NUSh.IsNull() ) return Standard_False;
1643 // cause got shape with location already.
1644 TopLoc_Location nullLoc;
1645 aSHUO_NUSh.Location ( nullLoc );
1646 // multiply the locations
1647 Standard_Integer intMapLenght = theaPrevLocMap.Extent();
1648 if ( intMapLenght < 1 )
1649 return Standard_False; // should not be, but to avoid exception...?
1650 TopLoc_Location SupcompLoc;
1651 SupcompLoc = theaPrevLocMap.FindKey( intMapLenght );
1652 if (intMapLenght > 1) {
1653 Standard_Integer l = intMapLenght - 1;
1655 SupcompLoc = theaPrevLocMap.FindKey( l ).Multiplied( SupcompLoc );
1659 aSHUO_NUSh.Location( SupcompLoc );
1660 theShape = aSHUO_NUSh;
1662 return (!theShape.IsNull());
1665 //=======================================================================
1666 //function : GetSHUOInstance
1668 //=======================================================================
1670 TopoDS_Shape XCAFDoc_ShapeTool::GetSHUOInstance (const Handle(XCAFDoc_GraphNode)& theSHUO) const
1672 TopoDS_Shape aShape;
1673 if (theSHUO.IsNull())
1676 TDF_Label aSHUOlab = theSHUO->Label();
1677 // get location of the assembly
1678 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1679 // get location of the component
1680 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1681 TopLoc_IndexedMapOfLocation aPrevLocMap;
1682 // get previous setted location
1683 if ( !loc.IsIdentity() )
1684 aPrevLocMap.Add( loc );
1685 aPrevLocMap.Add( compLoc );
1686 // get shape by recurse method
1687 const Handle(XCAFDoc_ShapeTool)& STool = this;
1688 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1693 //=======================================================================
1694 //function : getUsersShapesOfSHUO
1695 //purpose : auxilary
1696 //=======================================================================
1698 static Standard_Boolean getUsersShapesOfSHUO (TopLoc_IndexedMapOfLocation& aPrevLocMap,
1699 const Handle(XCAFDoc_ShapeTool)& STool,
1700 const TDF_Label& aSHUOlab,
1701 const TDF_Label& theUserL,
1702 TopTools_SequenceOfShape& theSHUOShapeSeq)
1704 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1705 // get location of the assembly
1706 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( theUserL.Father() );
1707 // get location of the component
1708 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( theUserL );
1709 // get previous setted location
1710 aNewPrevLocMap.Add( loc );
1711 aNewPrevLocMap.Add( compLoc );
1713 for (i = 1; i <= aPrevLocMap.Extent(); i++)
1714 aNewPrevLocMap.Add( aPrevLocMap.FindKey(i) );
1715 TDF_Label L = theUserL.Father();
1716 TDF_LabelSequence usersLab;
1717 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1718 if (usersLab.Length() == 0) {
1719 TopoDS_Shape aShape;
1720 getShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aShape );
1721 if (!aShape.IsNull()) {
1722 theSHUOShapeSeq.Append(aShape);
1723 return Standard_True;
1726 // now iterates on users of this assembly as component
1727 for ( i = 1; i <= usersLab.Length(); i++ ) {
1728 TDF_Label aNewUserL = usersLab.Value(i);
1729 getUsersShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aNewUserL, theSHUOShapeSeq );
1732 return (theSHUOShapeSeq.Length() > 1);
1735 //=======================================================================
1736 //function : GetAllSHUOInstances
1737 //purpose : auxilary
1738 //=======================================================================
1740 Standard_Boolean XCAFDoc_ShapeTool::GetAllSHUOInstances (const Handle(XCAFDoc_GraphNode)& theSHUO,
1741 TopTools_SequenceOfShape& theSHUOShapeSeq) const
1743 if (theSHUO.IsNull())
1744 return Standard_False;
1746 TDF_Label aSHUOlab = theSHUO->Label();
1747 TopLoc_IndexedMapOfLocation aPrevLocMap;
1748 // get location of the assembly
1749 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1750 // get location of the component
1751 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1752 // get previous setted location
1753 if ( !loc.IsIdentity() )
1754 aPrevLocMap.Add( loc );
1755 aPrevLocMap.Add( compLoc );
1756 // get label of assembly
1757 TDF_Label L = aSHUOlab.Father().Father();
1758 TDF_LabelSequence usersLab;
1759 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1760 TopoDS_Shape aShape;
1761 const Handle(XCAFDoc_ShapeTool)& STool = this;
1762 if (usersLab.Length() == 0) {
1763 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1764 if (!aShape.IsNull()) {
1765 theSHUOShapeSeq.Append(aShape);
1766 return Standard_True;
1769 // now iterates on users of this assembly as component
1770 for (Standard_Integer i = 1; i <= usersLab.Length(); i++) {
1771 TDF_Label aUserL = usersLab.Value(i);
1772 getUsersShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aUserL, theSHUOShapeSeq );
1775 return (theSHUOShapeSeq.Length() > 1);
1778 //=======================================================================
1779 //function : SetInstanceSHUO
1781 //=======================================================================
1783 Handle(XCAFDoc_GraphNode) XCAFDoc_ShapeTool::SetInstanceSHUO (const TopoDS_Shape& theShape) const
1785 Handle(XCAFDoc_GraphNode) SHUO;
1786 TDF_LabelSequence aLabels;
1787 if ( FindComponent( theShape, aLabels ) )
1788 // set shuo structure on labels of component-assembly structure
1789 SetSHUO( aLabels, SHUO );
1793 //=======================================================================
1794 //function : FindSHUO
1796 //=======================================================================
1798 Standard_Boolean XCAFDoc_ShapeTool::FindSHUO (const TDF_LabelSequence& theLabels,
1799 Handle(XCAFDoc_GraphNode)& theSHUOAttr)
1801 TDF_AttributeSequence SHUOAttrs;
1802 TDF_Label aCompLabel = theLabels.Value(1);
1803 if (! ::XCAFDoc_ShapeTool::GetAllComponentSHUO( aCompLabel, SHUOAttrs ) )
1804 return Standard_False;
1805 // WARNING: manage that each SHUO upper_usage have only one SHUO next_usage
1806 for (Standard_Integer i = 1; i <= SHUOAttrs.Length(); i++) {
1807 TDF_LabelSequence aCondidate;
1808 Handle(XCAFDoc_GraphNode) anSHUO = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1809 aCondidate.Append( anSHUO->Label().Father() );
1810 while (anSHUO->NbChildren()) {
1811 anSHUO = anSHUO->GetChild( 1 );
1812 aCondidate.Append( anSHUO->Label().Father() );
1814 // check the label sequences
1815 Standard_Boolean isEqual = Standard_True;
1816 if (theLabels.Length() != aCondidate.Length())
1817 isEqual = Standard_False;
1819 for (Standard_Integer li = 1; li <= theLabels.Length(); li++)
1820 if ( theLabels.Value(li) != aCondidate.Value(li) ) {
1821 isEqual = Standard_False;
1827 theSHUOAttr = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1830 return ( !theSHUOAttr.IsNull() );
1833 //=======================================================================
1836 //=======================================================================
1837 Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& theShapeL)
1839 if (theShapeL.IsNull() || IsAssembly(theShapeL))
1840 return Standard_False;
1842 TopoDS_Shape aShape = GetShape(theShapeL);
1843 if (aShape.IsNull())
1844 return Standard_False;
1846 TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
1847 Standard_Boolean isExpandedType = aShapeType == TopAbs_COMPOUND || aShapeType == TopAbs_COMPSOLID ||
1848 aShapeType == TopAbs_SHELL || aShapeType == TopAbs_WIRE;
1851 TopoDS_Iterator anIter(aShape);
1852 for(; anIter.More(); anIter.Next())
1854 const TopoDS_Shape& aChildShape = anIter.Value();
1855 TDF_Label aChild, aPart;
1857 // Find child shape as subshape of expanded shape
1858 FindSubShape(theShapeL, aChildShape, aChild);
1859 Handle(TDataStd_Name) anAttr;
1860 //make child (if color isn't set or if it is compound)
1861 if (aChild.IsNull()) {
1862 aChild = AddSubShape(theShapeL, aChildShape);
1866 aChild.FindAttribute(TDataStd_Name::GetID(), anAttr);
1869 // Try to find child shape as already existed part
1870 aPart = FindShape(aChildShape.Located(TopLoc_Location()));
1871 if (aPart.IsNull()) {
1872 // Create new part to link child shape
1873 aPart = AddShape(aChildShape.Located(TopLoc_Location()), Standard_False, Standard_False);
1875 // Add shape manually, if already existed subshape found instead of creation of new part
1876 if (!aPart.IsNull() && !IsTopLevel(aPart)) {
1877 if (!GetReferredShape(aPart, aPart)) {
1879 aPart = aTag.NewChild(Label());
1880 SetShape(aPart, aChildShape.Located(TopLoc_Location()));
1885 if (!anAttr.IsNull()) {
1886 TDataStd_Name::Set(aPart, anAttr->Get());
1889 Standard_SStream Stream;
1890 TopAbs::Print(aChildShape.ShapeType(), Stream);
1891 TCollection_AsciiString aName(Stream.str().c_str());
1892 TDataStd_Name::Set(aPart, TCollection_ExtendedString(aName));
1894 MakeReference(aChild, aPart, aChildShape.Location());
1895 makeSubShape(theShapeL, aPart, aChildShape, aChildShape.Location());
1897 //set assembly attribute
1898 TDataStd_UAttribute::Set(theShapeL, XCAFDoc::AssemblyGUID());
1899 return Standard_True;
1901 return Standard_False;
1904 //=======================================================================
1905 //function : makeSubShape
1907 //=======================================================================
1909 void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& theMainShapeL,
1910 const TDF_Label& thePart,
1911 const TopoDS_Shape& theShape,
1912 const TopLoc_Location& theLoc)
1914 TopoDS_Iterator anIter(theShape);
1915 Standard_Boolean isCompoundPart = (GetShape(thePart).ShapeType() == TopAbs_COMPOUND);
1916 Standard_Boolean isAssembly = IsAssembly(thePart);
1917 for(; anIter.More(); anIter.Next()) {
1918 const TopoDS_Shape& aChildShape = anIter.Value();
1919 TDF_Label aChildLabel;
1920 FindSubShape(theMainShapeL, aChildShape, aChildLabel);
1921 if(!aChildLabel.IsNull()) {
1923 aChildLabel.ForgetAllAttributes();
1924 makeSubShape(theMainShapeL, thePart, aChildShape, theLoc);
1929 Handle(TDataStd_Name) anAttr;
1930 aChildLabel.FindAttribute(TDataStd_Name::GetID(), anAttr);
1931 TopLoc_Location aSubLoc;
1932 // Calculate location for subshapes of compound parts
1934 aSubLoc = theLoc.Inverted() * aChildShape.Location();
1936 TDF_Label aSubLabel;
1937 if (!FindSubShape(thePart, aChildShape.Located(aSubLoc), aSubLabel)) {
1938 aSubLabel = AddSubShape(thePart, aChildShape.Located(aSubLoc));
1939 //set name to sub shape
1940 if (!anAttr.IsNull()) {
1941 TDataStd_Name::Set(aSubLabel, anAttr->Get());
1944 Standard_SStream Stream;
1945 TopAbs::Print(aChildShape.ShapeType(), Stream);
1946 TCollection_AsciiString aName(Stream.str().c_str());
1947 TDataStd_Name::Set(aSubLabel, TCollection_ExtendedString(aName));
1949 // Create auxiliary link, it will be removed during moving attributes
1950 MakeReference(aSubLabel, aChildLabel, aChildShape.Location());
1953 aChildLabel.ForgetAllAttributes();
1956 makeSubShape(theMainShapeL, thePart, aChildShape, theLoc);
1960 //=======================================================================
1961 //function : updateComponent
1963 //=======================================================================
1965 Standard_Boolean XCAFDoc_ShapeTool::updateComponent(const TDF_Label& theItemLabel,
1966 TopoDS_Shape& theUpdatedShape) const
1968 if ( !IsAssembly(theItemLabel) )
1969 return Standard_False; // Do nothing for non-assemblies
1971 // Get the currently stored compound for the assembly
1972 TopoDS_Shape aCurrentRootShape;
1973 GetShape(theItemLabel, aCurrentRootShape);
1975 // Get components of the assembly
1976 TDF_LabelSequence aComponentLabs;
1977 GetComponents(theItemLabel, aComponentLabs);
1979 // This flag indicates whether to update the compound of the assembly
1980 Standard_Boolean isModified = Standard_False;
1982 // Compare the number of components in XDE structure with the number of
1983 // components in topological structure. A component may happen to be removed,
1984 // so we have to update the assembly compound
1985 Standard_Integer aNumTopoComponents = aCurrentRootShape.NbChildren();
1987 if ( aNumTopoComponents != aComponentLabs.Length() )
1988 isModified = Standard_True;
1990 // Iterate over the assembly components. If at least one component is
1991 // modified (this is the recursive check), then the actually stored
1992 // compound has to be updated
1993 TopTools_ListOfShape aComponentShapes;
1995 for ( TDF_LabelSequence::Iterator aCompIt(aComponentLabs); aCompIt.More(); aCompIt.Next() )
1997 const TDF_Label& aComponentLab = aCompIt.Value();
1999 // Take the referred assembly item (ultimately, a part for an instance)
2000 TDF_Label aComponentRefLab;
2001 GetReferredShape(aComponentLab, aComponentRefLab);
2003 // Shape comes with some placement transformation here
2004 TopoDS_Shape aComponentShape;
2005 GetShape(aComponentLab, aComponentShape);
2006 TopLoc_Location aComponentLoc = aComponentShape.Location();
2008 // If the component is a sub-assembly, then its associated compound
2009 // has to be processed in the same manner
2010 if ( IsAssembly(aComponentRefLab) )
2013 if ( updateComponent(aComponentRefLab, aComponentShape) )
2016 isModified = Standard_True;
2018 aComponentShape.Location(aComponentLoc); // Apply placement
2023 // Search for a part in the actual compound of the ultimate assembly.
2024 // If the part is there, then the compound is up-to-date, so it does
2025 // not require rebuilding
2026 Standard_Boolean isPartFound = Standard_False;
2027 for ( TopoDS_Iterator aTopoIt(aCurrentRootShape); aTopoIt.More(); aTopoIt.Next() )
2029 if ( aTopoIt.Value() == aComponentShape )
2031 isPartFound = Standard_True;
2036 if ( !isPartFound && !isModified )
2037 isModified = Standard_True; // Part has been modified somewhere, so the compound
2038 // has to be rebuilt
2041 // Fill the list of shapes composing a new compound for the assembly
2042 aComponentShapes.Append(aComponentShape);
2045 // If any component is modified, we update the currently stored shape
2048 TopoDS_Compound anUpdatedCompound;
2050 aBB.MakeCompound(anUpdatedCompound);
2052 // Compose new compound
2053 for ( TopTools_ListIteratorOfListOfShape aShapeIt(aComponentShapes); aShapeIt.More(); aShapeIt.Next() )
2055 aBB.Add( anUpdatedCompound, aShapeIt.Value() );
2058 // Store the updated shape as an output
2059 theUpdatedShape = anUpdatedCompound;
2061 // Use topological naming services to store the updated shape in XDE
2062 TNaming_Builder NB(theItemLabel);
2063 NB.Generated(theUpdatedShape);