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 FindShape ( S, L, findInstance );
336 //=======================================================================
337 //function : GetShape
339 //=======================================================================
341 Standard_Boolean XCAFDoc_ShapeTool::GetShape (const TDF_Label& L, TopoDS_Shape& S)
343 Handle(XCAFDoc_Location) LocationAttribute;
346 TopoDS_Compound EmptyComp;
348 B.MakeCompound(EmptyComp);
352 // for instance, get referred shape
353 Handle(TDataStd_TreeNode) Node;
354 if ( L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather() &&
355 L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute)) {
356 if ( ! GetShape(Node->Father()->Label(), S) ) return Standard_False;
357 S.Move ( LocationAttribute->Get() );
358 return Standard_True;
361 // else just return shape on this label
362 Handle(TNaming_NamedShape) NS;
363 if ( ! L.FindAttribute(TNaming_NamedShape::GetID(), NS) ) return Standard_False;
364 S = TNaming_Tool::GetShape(NS);
365 return Standard_True;
368 //=======================================================================
369 //function : GetShape
371 //=======================================================================
373 TopoDS_Shape XCAFDoc_ShapeTool::GetShape(const TDF_Label& L)
380 //=======================================================================
381 //function : NewShape
383 //=======================================================================
385 TDF_Label XCAFDoc_ShapeTool::NewShape() const
387 TopoDS_Compound aShape;
389 tdsB.MakeCompound ( aShape );
392 TDF_Label aLabel = aTag.NewChild(Label());
394 TNaming_Builder tnBuild(aLabel);
395 tnBuild.Generated(aShape);
400 //=======================================================================
401 //function : SetShape
403 //=======================================================================
405 void XCAFDoc_ShapeTool::SetShape (const TDF_Label& L, const TopoDS_Shape& S)
407 TNaming_Builder tnBuild(L);
408 tnBuild.Generated(S);
409 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(L);
410 // if ( ! L.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
411 // A = XCAFDoc_ShapeMapTool::Set(L);
412 // L.AddAttribute(A);
416 if(!myShapeLabels.IsBound(S)) {
417 myShapeLabels.Bind(S,L);
421 //=======================================================================
422 //function : MakeReference
424 //=======================================================================
426 void XCAFDoc_ShapeTool::MakeReference (const TDF_Label &L,
427 const TDF_Label &refL,
428 const TopLoc_Location &loc)
431 XCAFDoc_Location::Set(L, loc);
434 Handle(TDataStd_TreeNode) refNode, mainNode;
435 mainNode = TDataStd_TreeNode::Set ( refL, XCAFDoc::ShapeRefGUID() );
436 refNode = TDataStd_TreeNode::Set ( L, XCAFDoc::ShapeRefGUID() );
437 refNode->Remove(); // abv: fix against bug in TreeNode::Append()
438 mainNode->Append(refNode);
441 SetLabelNameByLink(L);
444 //=======================================================================
445 //function : addShape
447 //=======================================================================
449 TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly)
451 TDF_Label ShapeLabel;
454 // search if the shape already exists (with the same location)
455 if ( S.IsNull() || FindShape ( S, ShapeLabel, Standard_True ) ) return ShapeLabel;
457 // else add a new label
458 ShapeLabel = aTag.NewChild(Label());
460 // if shape has location, make a reference to the same shape without location
461 if ( ! S.Location().IsIdentity() /*&& FindShape ( S, L )*/ ) {
465 TDF_Label L = addShape ( S0, makeAssembly );
466 MakeReference ( ShapeLabel, L, S.Location() );
470 // else add a shape to a label
471 TNaming_Builder tnBuild(ShapeLabel);
472 tnBuild.Generated(S);
474 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
475 // if ( ! ShapeLabel.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
476 // A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
477 // ShapeLabel.AddAttribute(A);
482 SetLabelNameByShape(ShapeLabel);
484 // if shape is Compound and flag is set, create assembly
485 if ( makeAssembly && S.ShapeType() == TopAbs_COMPOUND ) {
486 // mark assembly by assigning UAttribute
487 Handle(TDataStd_UAttribute) Uattr;
488 Uattr = TDataStd_UAttribute::Set ( ShapeLabel, XCAFDoc::AssemblyGUID() );
490 TDataStd_Name::Set(ShapeLabel, TCollection_ExtendedString("ASSEMBLY"));
492 // iterate on components
493 TopoDS_Iterator Iterator(S);
494 for (; Iterator.More(); Iterator.Next()) {
495 // get label for component`s shape
496 TopoDS_Shape Scomp = Iterator.Value(), S0 = Scomp;
499 TDF_Label compL = addShape ( S0, makeAssembly );
501 // add a component as reference
502 TDF_Label RefLabel = aTag.NewChild(ShapeLabel);
503 MakeReference ( RefLabel, compL, Scomp.Location() );
507 if(!IsAssembly(ShapeLabel)) {
508 //const TopTools_IndexedMapOfShape tmpMap = A->GetMap();
509 //for(Standard_Integer i=1; i<=tmpMap.Extent(); i++)
510 //mySubShapes.Bind(tmpMap.FindKey(i),ShapeLabel);
511 for(Standard_Integer i=1; i<=A->GetMap().Extent(); i++)
513 TopoDS_Shape aSh = A->GetMap().FindKey(i);
514 mySubShapes.Bind(aSh,ShapeLabel);
516 //mySubShapes.Bind(ShapeLabel,A->GetMap());
523 //=======================================================================
524 //function : prepareAssembly
526 //=======================================================================
527 static Standard_Boolean prepareAssembly (const TopoDS_Shape& theShape,
528 TopoDS_Shape& theOUTShape)
530 // iterate on components
531 theOUTShape = theShape;
532 if (theShape.ShapeType() == TopAbs_COMPOUND) {
534 // check if shape if frosen
535 if (!theOUTShape.Free())
536 theOUTShape.Free(Standard_True);
538 TopTools_SequenceOfShape aSubShapeSeq;
539 TopoDS_Iterator Iterator(theShape);
540 for (; Iterator.More(); Iterator.Next())
541 aSubShapeSeq.Append(Iterator.Value());
542 for (Standard_Integer i = 1; i <= aSubShapeSeq.Length(); i++) {
543 TopoDS_Shape Scomp = aSubShapeSeq.Value(i);
544 TopoDS_Shape aNewScomp;
545 B.Remove(theOUTShape, Scomp);
546 prepareAssembly( Scomp, aNewScomp );
547 TopLoc_Location aLoc;
548 aLoc = aNewScomp.Location();
549 if ( aLoc.IsIdentity() ) {
550 // create an "empty" location
552 aTrsf.SetScale(gp_Pnt(0,0,0), 1);
553 aLoc = TopLoc_Location( aTrsf );
554 aNewScomp.Location( aLoc );
556 B.Add(theOUTShape, aNewScomp);
559 return Standard_True;
563 //=======================================================================
564 //function : AddShape
566 //=======================================================================
568 TDF_Label XCAFDoc_ShapeTool::AddShape (const TopoDS_Shape& theShape,
569 const Standard_Boolean makeAssembly,
570 const Standard_Boolean makePrepare)
572 // PTV 17.02.2003 to avoid components without location.
573 TopoDS_Shape S = theShape;
574 if ( makePrepare && makeAssembly && S.ShapeType() == TopAbs_COMPOUND )
575 prepareAssembly( theShape, S ); // OCC1669
577 TDF_Label L = addShape(S,makeAssembly);
579 if(!myShapeLabels.IsBound(S)) {
580 myShapeLabels.Bind(S,L);
585 //return addShape( S, makeAssembly );
588 //=======================================================================
589 //function : RemoveShape
591 //=======================================================================
593 Standard_Boolean XCAFDoc_ShapeTool::RemoveShape (const TDF_Label& L,
594 const Standard_Boolean removeCompletely) const
596 if ( ! IsTopLevel ( L ) || ! IsFree ( L ) ) return Standard_False;
598 Handle(TDataStd_TreeNode) aNode;
600 if (removeCompletely &&
601 L.FindAttribute (XCAFDoc::ShapeRefGUID(), aNode) &&
602 aNode->HasFather() &&
603 L.IsAttribute (XCAFDoc_Location::GetID()))
605 aLabel = aNode->Father()->Label();
608 L.ForgetAllAttributes (Standard_True);
610 if (removeCompletely && !aLabel.IsNull())
612 return RemoveShape(aLabel);
614 return Standard_True;
618 //=======================================================================
621 //=======================================================================
623 void XCAFDoc_ShapeTool::Init()
625 hasSimpleShapes = Standard_False;
629 //=======================================================================
630 //function : SetAutoNaming
632 //=======================================================================
634 void XCAFDoc_ShapeTool::SetAutoNaming (const Standard_Boolean V)
640 //=======================================================================
641 //function : AutoNaming
643 //=======================================================================
645 Standard_Boolean XCAFDoc_ShapeTool::AutoNaming()
647 return theAutoNaming;
651 //=======================================================================
652 //function : ComputeShapes
654 //=======================================================================
656 void XCAFDoc_ShapeTool::ComputeShapes(const TDF_Label& L)
658 TDF_ChildIterator it(L);
659 for(; it.More(); it.Next()) {
660 TDF_Label L1 = it.Value();
663 if(!myShapeLabels.IsBound(S)) {
664 mySimpleShapes.Bind(S,L1);
672 //=======================================================================
673 //function : ComputeSimpleShapes
675 //=======================================================================
677 void XCAFDoc_ShapeTool::ComputeSimpleShapes()
679 ComputeShapes(Label());
680 hasSimpleShapes = Standard_True;
684 //=======================================================================
685 //function : GetShapes
687 //=======================================================================
689 void XCAFDoc_ShapeTool::GetShapes(TDF_LabelSequence& Labels) const
693 TDF_ChildIterator it(Label());
694 for (; it.More(); it.Next()) {
695 TDF_Label L = it.Value();
697 if ( GetShape ( L, S ) ) Labels.Append ( L );
702 //=======================================================================
703 //function : GetFreeShapes
705 //=======================================================================
707 void XCAFDoc_ShapeTool::GetFreeShapes (TDF_LabelSequence& FreeLabels) const
711 TDF_ChildIterator it(Label());
712 for (; it.More(); it.Next()) {
713 TDF_Label L = it.Value();
715 if ( GetShape ( L, S ) && IsFree ( L ) ) FreeLabels.Append ( L );
719 //=======================================================================
720 //function : IsTopLevel
722 //=======================================================================
724 Standard_Boolean XCAFDoc_ShapeTool::IsTopLevel (const TDF_Label& L) const
726 return L.Father() == Label();
729 //=======================================================================
732 //=======================================================================
734 Standard_Boolean XCAFDoc_ShapeTool::IsShape (const TDF_Label& L)
736 return IsSimpleShape ( L ) || IsAssembly ( L ) || IsReference ( L );
739 //=======================================================================
740 //function : IsSimpleShape
742 //=======================================================================
744 Standard_Boolean XCAFDoc_ShapeTool::IsSimpleShape (const TDF_Label& L)
746 Handle(TNaming_NamedShape) NS;
747 return L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) &&
748 ! IsAssembly ( L ) && ! IsReference ( L );
751 //=======================================================================
752 //function : IsReference
754 //=======================================================================
756 Standard_Boolean XCAFDoc_ShapeTool::IsReference (const TDF_Label& L)
758 Handle(TDataStd_TreeNode) Node;
759 return L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather();
762 //=======================================================================
763 //function : IsAssembly
765 //=======================================================================
767 Standard_Boolean XCAFDoc_ShapeTool::IsAssembly (const TDF_Label& L)
769 Handle(TDataStd_UAttribute) Uattr;
770 return L.FindAttribute(XCAFDoc::AssemblyGUID(), Uattr);
773 //=======================================================================
774 //function : IsComponent
776 //=======================================================================
778 Standard_Boolean XCAFDoc_ShapeTool::IsComponent (const TDF_Label& L)
780 return IsReference ( L ) && IsAssembly ( L.Father() );
783 //=======================================================================
784 //function : IsCompound
786 //=======================================================================
788 Standard_Boolean XCAFDoc_ShapeTool::IsCompound (const TDF_Label& L)
790 Handle(TDataStd_Name) Name;
791 if (L.FindAttribute(TDataStd_Name::GetID(),Name)) {
792 TCollection_ExtendedString estr1 = Name->Get();
793 TCollection_ExtendedString estr2("COMPOUND");
795 return Standard_True;
798 return Standard_False;
801 //=======================================================================
802 //function : IsSubShape
804 //=======================================================================
806 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label& L)
808 return IsSimpleShape ( L ) && IsShape ( L.Father() );
811 //=======================================================================
814 //=======================================================================
816 Standard_Boolean XCAFDoc_ShapeTool::IsFree (const TDF_Label& L)
818 Handle(TDataStd_TreeNode) Node;
819 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
820 ! Node->HasFirst() ) return Standard_True;
822 return Standard_False;
825 //=======================================================================
826 //function : GetUsers
827 //purpose : Returns number of users (0 if shape is free)
828 //=======================================================================
830 Standard_Integer XCAFDoc_ShapeTool::GetUsers (const TDF_Label& L,
831 TDF_LabelSequence& Labels,
832 const Standard_Boolean getsubchilds)
834 Standard_Integer NbUsers=0;
835 Handle(TDataStd_TreeNode) Node ;
837 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ) return NbUsers;
839 Node = Node->First();
840 while ( ! Node.IsNull() ) {
842 if ( getsubchilds ) {
843 TDF_Label underL = Node->Label().Father();
844 NbUsers += GetUsers ( underL, Labels, getsubchilds );
847 Labels.Append(Node->Label());
854 //=======================================================================
855 //function : NbComponents
857 //=======================================================================
859 Standard_Integer XCAFDoc_ShapeTool::NbComponents (const TDF_Label& L,
860 const Standard_Boolean getsubchilds)
862 TDF_LabelSequence subLabels;
863 GetComponents (L, subLabels, getsubchilds);
864 return subLabels.Length();
867 //=======================================================================
868 //function : GetComponents
870 //=======================================================================
872 Standard_Boolean XCAFDoc_ShapeTool::GetComponents (const TDF_Label& L, TDF_LabelSequence& Labels,
873 const Standard_Boolean getsubchilds)
875 if ( ! IsAssembly(L) ) return Standard_False;
877 TDF_ChildIterator It(L);
878 for (; It.More(); It.Next() ) {
879 TDF_Label comp = It.Value();
880 if ( IsComponent ( comp ) ) {
881 if ( getsubchilds ) {
883 if ( GetReferredShape ( comp, underL ) )
884 GetComponents ( underL, Labels, getsubchilds);
886 Labels.Append ( comp );
889 return Standard_True;
892 //=======================================================================
893 //function : GetLocation
895 //=======================================================================
897 TopLoc_Location XCAFDoc_ShapeTool::GetLocation (const TDF_Label& L)
899 Handle(XCAFDoc_Location) LocationAttribute;
900 if (L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute))
901 return LocationAttribute->Get();
903 Handle(TNaming_NamedShape) NS;
905 if ( L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) ) {
906 S = TNaming_Tool::GetShape(NS);
911 //=======================================================================
912 //function : GetReferredShape
914 //=======================================================================
916 Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L,
919 if ( ! IsReference(L) ) return Standard_False;
921 Handle (TDataStd_TreeNode) Node;
922 L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node);
923 Label = Node->Father()->Label();
924 return Standard_True;
927 //=======================================================================
928 //function : AddComponent
930 //=======================================================================
932 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
933 const TDF_Label& compL,
934 const TopLoc_Location &Loc) const
938 // check that shape is assembly
939 if ( ! IsAssembly(assembly) ) {
940 // if it is simple shape, make it assembly
941 if ( IsSimpleShape(assembly) )
942 TDataStd_UAttribute::Set ( assembly, XCAFDoc::AssemblyGUID() );
946 // add a component as reference
948 L = aTag.NewChild(assembly);
949 MakeReference ( L, compL, Loc );
954 //=======================================================================
955 //function : AddComponent
957 //=======================================================================
959 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
960 const TopoDS_Shape& comp,
961 const Standard_Boolean expand)
963 // get label for component`s shape
964 TopoDS_Shape S0 = comp;
968 compL = AddShape ( S0, expand );
970 // add component by its label
971 return AddComponent ( assembly, compL, comp.Location() );
974 //=======================================================================
975 //function : RemoveComponent
977 //=======================================================================
979 void XCAFDoc_ShapeTool::RemoveComponent (const TDF_Label& comp) const
981 if ( IsComponent(comp) )
983 comp.ForgetAllAttributes();
987 //=======================================================================
988 //function : UpdateAssemblies
990 //=======================================================================
992 void XCAFDoc_ShapeTool::UpdateAssemblies()
994 // We start from the free shapes (roots in the assembly structure)
995 TDF_LabelSequence aRootLabels;
996 GetFreeShapes(aRootLabels);
998 // Iterate over the free shapes
999 for ( TDF_LabelSequence::Iterator anIt(aRootLabels); anIt.More(); anIt.Next() )
1001 TDF_Label aRefLabel = anIt.Value();
1002 if (IsReference(aRefLabel))
1004 GetReferredShape(aRefLabel, aRefLabel);
1006 const TDF_Label& aRootLab = aRefLabel;
1007 TopoDS_Shape anAssemblyShape;
1008 updateComponent(aRootLab, anAssemblyShape);
1012 //=======================================================================
1013 //function : IsSubShape
1015 //=======================================================================
1017 //static Standard_Boolean CheckSubShape (const TopoDS_Shape &S, const TopoDS_Shape &sub)
1019 // if ( S.IsSame ( sub ) ) return Standard_True;
1021 // if ( S.ShapeType() >= sub.ShapeType() ) return Standard_False;
1023 // for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
1024 // if ( CheckSubShape ( it.Value(), sub ) ) return Standard_True;
1026 // return Standard_False;
1029 //=======================================================================
1030 //function : IsSubShape
1032 //=======================================================================
1034 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label &shapeL,
1035 const TopoDS_Shape &sub) const
1037 Handle(XCAFDoc_ShapeMapTool) A;
1038 if ( ! shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) )
1039 return Standard_False;
1041 //TopoDS_Shape S = GetShape ( shapeL );
1042 //return ! S.IsNull() && CheckSubShape ( S, sub );
1044 return A->IsSubShape(sub);
1047 //=======================================================================
1048 //function : FindSubShape
1050 //=======================================================================
1052 Standard_Boolean XCAFDoc_ShapeTool::FindSubShape (const TDF_Label &shapeL,
1053 const TopoDS_Shape &sub,
1056 // this code is used instead of the following for performance reasons
1057 if ( TNaming_Tool::HasLabel(Label(), sub) ) {
1059 L = TNaming_Tool::Label(Label(), sub, TransDef);
1060 return ( ! L.IsNull() && L.Father() == shapeL );
1064 TDF_ChildIterator chldLabIt(shapeL);
1065 for (; chldLabIt.More(); chldLabIt.Next() ) {
1066 TDF_Label subLabel = chldLabIt.Value();
1068 if ( GetShape ( subLabel, S ) && S.IsSame ( sub ) ) {
1070 return Standard_True;
1074 return Standard_False;
1077 //=======================================================================
1078 //function : AddSubShape
1080 //=======================================================================
1082 TDF_Label XCAFDoc_ShapeTool::AddSubShape (const TDF_Label &shapeL,
1083 const TopoDS_Shape &sub) const
1086 if ( FindSubShape ( shapeL, sub, L ) ) return L;
1088 if ( ! IsSubShape ( shapeL, sub ) ) return L;
1091 L = aTag.NewChild(shapeL);
1093 TNaming_Builder tnBuild(L);
1094 tnBuild.Generated(sub);
1096 // if(!mySubShapes.IsBound(sub))
1097 // mySubShapes.Bind(sub,L);
1103 //=======================================================================
1104 //function : FindMainShapeUsingMap
1106 //=======================================================================
1108 TDF_Label XCAFDoc_ShapeTool::FindMainShapeUsingMap(const TopoDS_Shape &sub) const
1110 //for(Standard_Integer i=1; i<=myNotAssemblies.Length(); i++) {
1111 // TDF_Label L = myNotAssemblies.Value(i);
1112 // if(IsSubShape(L,sub)) return L;
1114 if(mySubShapes.IsBound(sub))
1115 return mySubShapes.Find(sub);
1121 //=======================================================================
1122 //function : FindMainShape
1124 //=======================================================================
1126 TDF_Label XCAFDoc_ShapeTool::FindMainShape (const TopoDS_Shape &sub) const
1128 TDF_ChildIterator it(Label());
1129 for (; it.More(); it.Next()) {
1130 TDF_Label L = it.Value();
1131 if ( ! IsAssembly ( L ) && IsSubShape ( L, sub ) ) return L;
1138 //=======================================================================
1139 //function : GetSubShapes
1141 //=======================================================================
1143 Standard_Boolean XCAFDoc_ShapeTool::GetSubShapes (const TDF_Label &L,
1144 TDF_LabelSequence& Labels)
1146 TDF_ChildIterator It(L);
1147 for (; It.More(); It.Next() ) {
1148 TDF_Label sub = It.Value();
1149 if ( IsSubShape ( sub ) ) Labels.Append ( sub );
1151 return Labels.Length() >0;
1154 //=======================================================================
1155 //function : BaseLabel
1157 //=======================================================================
1159 TDF_Label XCAFDoc_ShapeTool::BaseLabel () const
1164 //=======================================================================
1165 //function : DumpAssembly
1166 //purpose : recursive part of Dump()
1167 //=======================================================================
1169 static void DumpAssembly(Standard_OStream& theDumpLog,
1171 const Standard_Integer level,
1172 const Standard_Boolean deep)
1175 XCAFDoc_ShapeTool::GetShape(L, S);
1178 for (Standard_Integer i=0; i<level; i++)
1181 TCollection_AsciiString Entry;
1182 TDF_Tool::Entry(L, Entry);
1184 if(XCAFDoc_ShapeTool::IsAssembly(L))
1186 theDumpLog<<"ASSEMBLY ";
1188 else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
1190 if(L.Father().Father().Father().IsRoot())
1191 theDumpLog<<"PART ";
1195 theDumpLog<<"INSTANCE ";
1197 TopAbs::Print(S.ShapeType(), theDumpLog);
1199 theDumpLog<<" "<<Entry;
1200 if(XCAFDoc_ShapeTool::IsReference(L))
1202 Handle(TDataStd_TreeNode) aRef;
1203 L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
1204 TDF_Tool::Entry(aRef->Father()->Label(), Entry);
1205 theDumpLog<<" (refers to "<<Entry<<")";
1207 Handle(TDataStd_Name) Name;
1208 if (L.FindAttribute(TDataStd_Name::GetID(), Name))
1209 theDumpLog<<" \""<<Name->Get()<<"\" ";
1212 theDumpLog<<"("<<*(void**)&S.TShape();
1213 if (! S.Location().IsIdentity())
1214 theDumpLog<<", "<< *(void**)&S.Location();
1219 Handle(TDataStd_TreeNode) Node;
1220 TDF_ChildIterator NodeIterator(L);
1221 for (; NodeIterator.More(); NodeIterator.Next()) {
1222 DumpAssembly(theDumpLog, NodeIterator.Value(), level+1, deep);
1228 //=======================================================================
1231 //=======================================================================
1233 Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog, const Standard_Boolean deep) const
1235 Standard_Integer level = 0;
1236 // TopTools_SequenceOfShape SeqShapes;
1237 TDF_LabelSequence SeqLabels;
1238 GetShapes( SeqLabels);
1240 if (SeqLabels.Length()>0) theDumpLog<<endl;
1242 for (i=1; i<=SeqLabels.Length(); i++) {
1243 DumpAssembly(theDumpLog, SeqLabels.Value(i), level, deep);
1247 GetFreeShapes(SeqLabels);
1248 theDumpLog<<endl<<"Free Shapes: "<<SeqLabels.Length()<<endl;
1249 for (i = 1; i<=SeqLabels.Length(); i++) {
1250 DumpShape(theDumpLog, SeqLabels.Value(i), level, deep);
1256 //=======================================================================
1258 //purpose : override
1259 //=======================================================================
1261 Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog) const
1263 TDF_Attribute::Dump (theDumpLog);
1264 Dump (theDumpLog, Standard_False);
1268 //=======================================================================
1269 //function : DumpShape
1271 //=======================================================================
1273 void XCAFDoc_ShapeTool::DumpShape(Standard_OStream& theDumpLog, const TDF_Label& L,const Standard_Integer level,const Standard_Boolean deep)
1276 if(! XCAFDoc_ShapeTool::GetShape(L, S) ) return;
1277 for (Standard_Integer i=0; i<level; i++)
1280 if(XCAFDoc_ShapeTool::IsAssembly(L))
1282 theDumpLog<<"ASSEMBLY ";
1284 else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
1286 if(L.Father().Father().Father().IsRoot())
1287 theDumpLog<<"PART ";
1291 theDumpLog<<"INSTANCE ";
1293 TopAbs::Print(S.ShapeType(), theDumpLog);
1295 TCollection_AsciiString Entry;
1296 TDF_Tool::Entry(L, Entry);
1297 theDumpLog<<" "<<Entry;
1298 if(XCAFDoc_ShapeTool::IsReference(L))
1300 Handle(TDataStd_TreeNode) aRef;
1301 L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
1302 TDF_Tool::Entry(aRef->Father()->Label(), Entry);
1303 theDumpLog<<" (refers to "<<Entry<<")";
1306 Handle(TDataStd_Name) Name;
1307 if (L.FindAttribute(TDataStd_Name::GetID(),Name))
1308 theDumpLog<<" \""<<Name->Get()<<"\" ";
1311 theDumpLog<<"("<<*(void**)&S.TShape();
1312 if (! S.Location().IsIdentity())
1313 theDumpLog<<", "<< *(void**)&S.Location();
1318 //=======================================================================
1319 //function : IsExternRef
1321 //=======================================================================
1323 Standard_Boolean XCAFDoc_ShapeTool::IsExternRef(const TDF_Label& L)
1325 Handle(TDataStd_UAttribute) Uattr;
1326 return L.FindAttribute(XCAFDoc::ExternRefGUID(), Uattr);
1329 //=======================================================================
1330 //function : SetExternRefs
1332 //=======================================================================
1334 void XCAFDoc_ShapeTool::SetExternRefs(const TDF_Label& L,
1335 const TColStd_SequenceOfHAsciiString& SHAS) const
1337 TDF_Label ShapeLabel = L.NewChild();
1338 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1339 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1340 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1341 Handle(TCollection_HAsciiString) str = SHAS(i);
1342 TCollection_ExtendedString extstr(str->String());
1343 TDataStd_Name::Set(tmplbl,extstr);
1347 //=======================================================================
1348 //function : SetExternRefs
1350 //=======================================================================
1352 TDF_Label XCAFDoc_ShapeTool::SetExternRefs(const TColStd_SequenceOfHAsciiString& SHAS) const
1354 TDF_Label ShapeLabel;
1357 ShapeLabel = aTag.NewChild(Label());
1358 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1359 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1360 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1361 Handle(TCollection_HAsciiString) str = SHAS(i);
1362 TCollection_ExtendedString extstr(str->String());
1363 TDataStd_Name::Set(tmplbl,extstr);
1368 //=======================================================================
1369 //function : GetExternRefs
1371 //=======================================================================
1373 void XCAFDoc_ShapeTool::GetExternRefs(const TDF_Label& L,
1374 TColStd_SequenceOfHAsciiString& SHAS)
1376 Handle(TDataStd_Name) TDN;
1378 for(Standard_Integer i=1; i<=L.NbChildren(); i++) {
1379 tmplbl = L.FindChild(i);
1380 if(tmplbl.FindAttribute(TDataStd_Name::GetID(),TDN)) {
1381 TCollection_ExtendedString extstr = TDN->Get();
1382 Handle(TCollection_HAsciiString) str =
1383 new TCollection_HAsciiString(TCollection_AsciiString(extstr, '?'));
1389 // API: API work with SHUO (Specified Higher Usage Occurrance) structure
1391 //=======================================================================
1392 //function : GetSHUO
1394 //=======================================================================
1396 Standard_Boolean XCAFDoc_ShapeTool::GetSHUO (const TDF_Label& SHUOLabel,
1397 Handle(XCAFDoc_GraphNode)& aSHUOAttr)
1399 if ( !SHUOLabel.FindAttribute( XCAFDoc::SHUORefGUID(), aSHUOAttr ) )
1400 return Standard_False;
1401 return Standard_True;
1404 //=======================================================================
1405 //function : GetAllComponentSHUO
1407 //=======================================================================
1409 Standard_Boolean XCAFDoc_ShapeTool::GetAllComponentSHUO (const TDF_Label& theCompLabel,
1410 TDF_AttributeSequence& theSHUOAttrs)
1412 TDF_ChildIterator it(theCompLabel);
1413 for (; it.More(); it.Next()) {
1414 TDF_Label L = it.Value();
1415 Handle(XCAFDoc_GraphNode) aSHUOAttr;
1416 if ( GetSHUO( L, aSHUOAttr ) )
1417 theSHUOAttrs.Append( aSHUOAttr );
1419 return (theSHUOAttrs.Length() > 0);
1422 //=======================================================================
1423 //function : SetSHUO
1425 //=======================================================================
1427 Standard_Boolean XCAFDoc_ShapeTool::SetSHUO (const TDF_LabelSequence& labels,
1428 Handle(XCAFDoc_GraphNode)& MainSHUOAttr) const
1430 MainSHUOAttr.Nullify();
1431 // check number of labels
1432 if (labels.Length() < 2)
1433 return Standard_False;
1434 // check is all labels contains components of any assemblyies
1436 for (i = 1; i <= labels.Length(); i++)
1437 if ( !IsComponent(labels.Value(i)) )
1438 return Standard_False;
1441 TDF_Label UpperSubL = aTag.NewChild( labels( 1 ) );
1442 if (theAutoNaming) {
1443 TCollection_ExtendedString Entry("SHUO");
1444 TDataStd_Name::Set(UpperSubL, TCollection_ExtendedString( Entry ));
1446 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1447 aUpperSHUO = XCAFDoc_GraphNode::Set( UpperSubL, XCAFDoc::SHUORefGUID() );
1448 // init out argument by main upper usage SHUO
1449 MainSHUOAttr = aUpperSHUO;
1450 // add other next_usage occurrences.
1451 for (i = 2; i <= labels.Length(); i++) {
1452 TDF_Label NextSubL = aTag.NewChild( labels( i ) );
1453 if (theAutoNaming) {
1454 TCollection_ExtendedString EntrySub("SHUO-");
1456 TDataStd_Name::Set(NextSubL, TCollection_ExtendedString( EntrySub ));
1458 Handle(XCAFDoc_GraphNode) aNextSHUO;
1459 aNextSHUO = XCAFDoc_GraphNode::Set( NextSubL, XCAFDoc::SHUORefGUID() );
1461 aUpperSHUO->SetChild( aNextSHUO );
1462 aNextSHUO->SetFather( aUpperSHUO );
1463 // now lets next_usage become upper_usage for next level of SHUO
1464 aUpperSHUO = aNextSHUO;
1465 UpperSubL = NextSubL;
1468 return Standard_True;
1471 //=======================================================================
1472 //function : GetSHUOUpperUsage
1474 //=======================================================================
1476 Standard_Boolean XCAFDoc_ShapeTool::GetSHUOUpperUsage (const TDF_Label& NextUsageL,
1477 TDF_LabelSequence& aLabels)
1479 Handle(XCAFDoc_GraphNode) aNextSHUO;
1480 if( !GetSHUO( NextUsageL, aNextSHUO ) || aNextSHUO->NbFathers()<1 )
1481 return Standard_False;
1483 // get upper_usage SHAO
1484 for (Standard_Integer i = 1; i <= aNextSHUO->NbFathers(); i++)
1485 aLabels.Append( aNextSHUO->GetFather(i)->Label() );
1486 return Standard_True;
1489 //=======================================================================
1490 //function : GetSHUONextUsage
1492 //=======================================================================
1494 Standard_Boolean XCAFDoc_ShapeTool::GetSHUONextUsage (const TDF_Label& UpperUsageL,
1495 TDF_LabelSequence& aLabels)
1497 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1498 if ( !GetSHUO( UpperUsageL, aUpperSHUO ) || aUpperSHUO->NbChildren()<1 )
1499 return Standard_False;
1500 // get upper_usage SHAO
1501 for (Standard_Integer i = 1; i <= aUpperSHUO->NbChildren(); i++)
1502 aLabels.Append( aUpperSHUO->GetChild(i)->Label() );
1503 return Standard_True;
1506 //=======================================================================
1507 //function : RemoveSHUO
1509 //=======================================================================
1511 Standard_Boolean XCAFDoc_ShapeTool::RemoveSHUO (const TDF_Label& L) const
1513 L.ForgetAllAttributes (Standard_True);
1514 return Standard_True;
1517 //=======================================================================
1518 //function : checkForShape
1519 //purpose : auxilary
1520 //=======================================================================
1522 static Standard_Boolean checkForShape (const TopoDS_Shape& theShape,
1523 const TopoDS_Shape& theCurSh,
1524 const TDF_Label& theUserL,
1525 TDF_LabelSequence& theLabels)
1527 // the label of an assembly which contains this component
1528 TDF_Label aSuperUserL = theUserL.Father();
1529 TopLoc_Location aSupLoc, aCompLoc;
1530 aSupLoc = ::XCAFDoc_ShapeTool::GetLocation ( aSuperUserL );
1531 aCompLoc = ::XCAFDoc_ShapeTool::GetLocation ( theUserL );
1532 TopoDS_Shape aCopySh = theCurSh;
1533 aCompLoc = aCompLoc.Multiplied( theCurSh.Location() );
1534 aSupLoc = aSupLoc.Multiplied( aCompLoc );
1535 aCopySh.Location( aSupLoc );
1536 if ( aCopySh.IsSame( theShape ) ) {
1537 theLabels.Prepend( theUserL );
1538 return Standard_True;
1540 // try to search deeply (upper by assmebly structure)
1541 TDF_LabelSequence aNewLabels;
1542 for (Standard_Integer j = 1; j <= theLabels.Length(); j++)
1543 aNewLabels.Append( theLabels.Value( j ) );
1544 aNewLabels.Prepend( theUserL );
1545 TDF_LabelSequence aUsers;
1546 ::XCAFDoc_ShapeTool::GetUsers( aSuperUserL, aUsers );
1547 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1548 if ( checkForShape( theShape, aCopySh, aUsers.Value( i ), aNewLabels ) ) {
1550 theLabels = aNewLabels;
1551 return Standard_True;
1553 return Standard_False;
1556 //=======================================================================
1557 //function : FindComponent
1559 //=======================================================================
1561 Standard_Boolean XCAFDoc_ShapeTool::FindComponent (const TopoDS_Shape& theShape,
1562 TDF_LabelSequence& theLabels) const
1565 // search for a top-level shape that corresponds to this component
1566 TopoDS_Shape S0 = theShape;
1567 TopLoc_Location loc;
1568 S0.Location ( loc );
1569 TDF_Label aRefL = FindShape( S0 );
1571 return Standard_False; // cannot find top-level shape.
1573 TDF_LabelSequence aUsers;
1574 ::XCAFDoc_ShapeTool::GetUsers( aRefL, aUsers );
1575 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1576 if ( checkForShape( theShape, S0, aUsers.Value( i ), theLabels ) )
1579 return (theLabels.Length() > 0);
1582 //=======================================================================
1583 //function : getShapesOfSHUO
1584 //purpose : auxilary
1585 //=======================================================================
1587 static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLocMap,
1588 const Handle(XCAFDoc_ShapeTool)& theSTool,
1589 const TDF_Label& theSHUOlab,
1590 TopoDS_Shape& theShape)
1592 Handle(XCAFDoc_GraphNode) SHUO;
1593 TDF_LabelSequence aLabSeq;
1594 theSTool->GetSHUONextUsage( theSHUOlab, aLabSeq );
1595 if (aLabSeq.Length() >= 1)
1596 for (Standard_Integer i = 1; i <= aLabSeq.Length(); i++) {
1597 TDF_Label aSubCompL = aLabSeq.Value( i );
1598 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSubCompL.Father() );
1599 // create new map of laocation (to not merge locations from different shapes)
1600 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1601 for (Standard_Integer m = 1; m <= theaPrevLocMap.Extent(); m++)
1602 aNewPrevLocMap.Add( theaPrevLocMap.FindKey( m ) );
1603 aNewPrevLocMap.Add( compLoc );
1604 // got for the new sublocations and corresponding shape
1605 getShapesOfSHUO( aNewPrevLocMap, theSTool, aSubCompL, theShape );
1608 TopoDS_Shape aSHUO_NUSh = theSTool->GetShape ( theSHUOlab.Father() );
1609 if ( aSHUO_NUSh.IsNull() ) return Standard_False;
1610 // cause got shape with location already.
1611 TopLoc_Location nullLoc;
1612 aSHUO_NUSh.Location ( nullLoc );
1613 // multiply the locations
1614 Standard_Integer intMapLenght = theaPrevLocMap.Extent();
1615 if ( intMapLenght < 1 )
1616 return Standard_False; // should not be, but to avoid exception...?
1617 TopLoc_Location SupcompLoc;
1618 SupcompLoc = theaPrevLocMap.FindKey( intMapLenght );
1619 if (intMapLenght > 1) {
1620 Standard_Integer l = intMapLenght - 1;
1622 SupcompLoc = theaPrevLocMap.FindKey( l ).Multiplied( SupcompLoc );
1626 aSHUO_NUSh.Location( SupcompLoc );
1627 theShape = aSHUO_NUSh;
1629 return (!theShape.IsNull());
1632 //=======================================================================
1633 //function : GetSHUOInstance
1635 //=======================================================================
1637 TopoDS_Shape XCAFDoc_ShapeTool::GetSHUOInstance (const Handle(XCAFDoc_GraphNode)& theSHUO) const
1639 TopoDS_Shape aShape;
1640 if (theSHUO.IsNull())
1643 TDF_Label aSHUOlab = theSHUO->Label();
1644 // get location of the assembly
1645 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1646 // get location of the component
1647 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1648 TopLoc_IndexedMapOfLocation aPrevLocMap;
1649 // get previous setted location
1650 if ( !loc.IsIdentity() )
1651 aPrevLocMap.Add( loc );
1652 aPrevLocMap.Add( compLoc );
1653 // get shape by recurse method
1654 const Handle(XCAFDoc_ShapeTool)& STool = this;
1655 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1660 //=======================================================================
1661 //function : getUsersShapesOfSHUO
1662 //purpose : auxilary
1663 //=======================================================================
1665 static Standard_Boolean getUsersShapesOfSHUO (TopLoc_IndexedMapOfLocation& aPrevLocMap,
1666 const Handle(XCAFDoc_ShapeTool)& STool,
1667 const TDF_Label& aSHUOlab,
1668 const TDF_Label& theUserL,
1669 TopTools_SequenceOfShape& theSHUOShapeSeq)
1671 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1672 // get location of the assembly
1673 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( theUserL.Father() );
1674 // get location of the component
1675 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( theUserL );
1676 // get previous setted location
1677 aNewPrevLocMap.Add( loc );
1678 aNewPrevLocMap.Add( compLoc );
1680 for (i = 1; i <= aPrevLocMap.Extent(); i++)
1681 aNewPrevLocMap.Add( aPrevLocMap.FindKey(i) );
1682 TDF_Label L = theUserL.Father();
1683 TDF_LabelSequence usersLab;
1684 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1685 if (usersLab.Length() == 0) {
1686 TopoDS_Shape aShape;
1687 getShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aShape );
1688 if (!aShape.IsNull()) {
1689 theSHUOShapeSeq.Append(aShape);
1690 return Standard_True;
1693 // now iterates on users of this assembly as component
1694 for ( i = 1; i <= usersLab.Length(); i++ ) {
1695 TDF_Label aNewUserL = usersLab.Value(i);
1696 getUsersShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aNewUserL, theSHUOShapeSeq );
1699 return (theSHUOShapeSeq.Length() > 1);
1702 //=======================================================================
1703 //function : GetAllSHUOInstances
1704 //purpose : auxilary
1705 //=======================================================================
1707 Standard_Boolean XCAFDoc_ShapeTool::GetAllSHUOInstances (const Handle(XCAFDoc_GraphNode)& theSHUO,
1708 TopTools_SequenceOfShape& theSHUOShapeSeq) const
1710 if (theSHUO.IsNull())
1711 return Standard_False;
1713 TDF_Label aSHUOlab = theSHUO->Label();
1714 TopLoc_IndexedMapOfLocation aPrevLocMap;
1715 // get location of the assembly
1716 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1717 // get location of the component
1718 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1719 // get previous setted location
1720 if ( !loc.IsIdentity() )
1721 aPrevLocMap.Add( loc );
1722 aPrevLocMap.Add( compLoc );
1723 // get label of assembly
1724 TDF_Label L = aSHUOlab.Father().Father();
1725 TDF_LabelSequence usersLab;
1726 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1727 TopoDS_Shape aShape;
1728 const Handle(XCAFDoc_ShapeTool)& STool = this;
1729 if (usersLab.Length() == 0) {
1730 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1731 if (!aShape.IsNull()) {
1732 theSHUOShapeSeq.Append(aShape);
1733 return Standard_True;
1736 // now iterates on users of this assembly as component
1737 for (Standard_Integer i = 1; i <= usersLab.Length(); i++) {
1738 TDF_Label aUserL = usersLab.Value(i);
1739 getUsersShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aUserL, theSHUOShapeSeq );
1742 return (theSHUOShapeSeq.Length() > 1);
1745 //=======================================================================
1746 //function : SetInstanceSHUO
1748 //=======================================================================
1750 Handle(XCAFDoc_GraphNode) XCAFDoc_ShapeTool::SetInstanceSHUO (const TopoDS_Shape& theShape) const
1752 Handle(XCAFDoc_GraphNode) SHUO;
1753 TDF_LabelSequence aLabels;
1754 if ( FindComponent( theShape, aLabels ) )
1755 // set shuo structure on labels of component-assembly structure
1756 SetSHUO( aLabels, SHUO );
1760 //=======================================================================
1761 //function : FindSHUO
1763 //=======================================================================
1765 Standard_Boolean XCAFDoc_ShapeTool::FindSHUO (const TDF_LabelSequence& theLabels,
1766 Handle(XCAFDoc_GraphNode)& theSHUOAttr)
1768 TDF_AttributeSequence SHUOAttrs;
1769 TDF_Label aCompLabel = theLabels.Value(1);
1770 if (! ::XCAFDoc_ShapeTool::GetAllComponentSHUO( aCompLabel, SHUOAttrs ) )
1771 return Standard_False;
1772 // WARNING: manage that each SHUO upper_usage have only one SHUO next_usage
1773 for (Standard_Integer i = 1; i <= SHUOAttrs.Length(); i++) {
1774 TDF_LabelSequence aCondidate;
1775 Handle(XCAFDoc_GraphNode) anSHUO = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1776 aCondidate.Append( anSHUO->Label().Father() );
1777 while (anSHUO->NbChildren()) {
1778 anSHUO = anSHUO->GetChild( 1 );
1779 aCondidate.Append( anSHUO->Label().Father() );
1781 // check the label sequences
1782 Standard_Boolean isEqual = Standard_True;
1783 if (theLabels.Length() != aCondidate.Length())
1784 isEqual = Standard_False;
1786 for (Standard_Integer li = 1; li <= theLabels.Length(); li++)
1787 if ( theLabels.Value(li) != aCondidate.Value(li) ) {
1788 isEqual = Standard_False;
1794 theSHUOAttr = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1797 return ( !theSHUOAttr.IsNull() );
1800 //=======================================================================
1803 //=======================================================================
1805 Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& Shape)
1808 return Standard_False;
1810 TopoDS_Shape aShape = GetShape(Shape);
1811 if(!aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND && !IsAssembly(Shape))
1813 //set assembly attribute
1814 TDataStd_UAttribute::Set ( Shape, XCAFDoc::AssemblyGUID() );
1816 TopoDS_Iterator anIter(aShape);
1817 for(; anIter.More(); anIter.Next())
1819 TopoDS_Shape aChildShape = anIter.Value();
1820 TDF_Label aChild = FindShape(aChildShape, Standard_True);
1823 Handle(TDataStd_Name) anAttr;
1824 //make part for child
1825 TDF_Label aPart = aTag.NewChild(Label());
1826 //make child (if color isn't set or if it is compound)
1829 TopLoc_Location nulloc;
1830 aChild = aTag.NewChild(Shape);
1831 SetShape(aChild, aChildShape);
1832 SetShape(aPart, aChildShape.Located(nulloc));
1837 aChild.FindAttribute(TDataStd_Name::GetID(), anAttr);
1838 TopLoc_Location nulloc;
1839 SetShape(aPart, aChildShape.Located(nulloc));
1843 if(!anAttr.IsNull())
1845 TDataStd_Name::Set(aPart, anAttr->Get());
1849 Standard_SStream Stream;
1850 TopAbs::Print(aChildShape.ShapeType(), Stream);
1851 TCollection_AsciiString aName (Stream.str().c_str());
1852 TDataStd_Name::Set(aPart, TCollection_ExtendedString(aName));
1855 MakeReference(aChild, aPart, aChildShape.Location());
1857 makeSubShape(aPart, aChildShape);
1859 return Standard_True;
1861 return Standard_False;
1864 //=======================================================================
1865 //function : makeSubShape
1867 //=======================================================================
1869 void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& Part, const TopoDS_Shape& Shape)
1872 TopoDS_Iterator anIter(Shape);
1873 for(; anIter.More(); anIter.Next())
1875 TopoDS_Shape aChildShape = anIter.Value();
1876 TDF_Label aChildLabel = FindShape(aChildShape,Standard_True);
1877 if(!aChildLabel.IsNull())
1880 Handle(TDataStd_Name) anAttr;
1881 aChildLabel.FindAttribute(TDataStd_Name::GetID(), anAttr);
1882 TopLoc_Location nulloc;
1884 TDF_Label aSubLabel = aTag.NewChild(Part);
1885 SetShape(aSubLabel, aChildShape.Located(nulloc));
1886 //set name to sub shape
1887 if(!anAttr.IsNull())
1889 TDataStd_Name::Set(aSubLabel, anAttr->Get());
1893 Standard_SStream Stream;
1894 TopAbs::Print(aChildShape.ShapeType(), Stream);
1895 TCollection_AsciiString aName (Stream.str().c_str());
1896 TDataStd_Name::Set(aSubLabel, TCollection_ExtendedString(aName));
1898 MakeReference(aChildLabel, aSubLabel, aChildShape.Location());
1900 makeSubShape(Part, aChildShape);
1904 //=======================================================================
1905 //function : updateComponent
1907 //=======================================================================
1909 Standard_Boolean XCAFDoc_ShapeTool::updateComponent(const TDF_Label& theItemLabel,
1910 TopoDS_Shape& theUpdatedShape) const
1912 if ( !IsAssembly(theItemLabel) )
1913 return Standard_False; // Do nothing for non-assemblies
1915 // Get the currently stored compound for the assembly
1916 TopoDS_Shape aCurrentRootShape;
1917 GetShape(theItemLabel, aCurrentRootShape);
1919 // Get components of the assembly
1920 TDF_LabelSequence aComponentLabs;
1921 GetComponents(theItemLabel, aComponentLabs);
1923 // This flag indicates whether to update the compound of the assembly
1924 Standard_Boolean isModified = Standard_False;
1926 // Compare the number of components in XDE structure with the number of
1927 // components in topological structure. A component may happen to be removed,
1928 // so we have to update the assembly compound
1929 Standard_Integer aNumTopoComponents = 0;
1930 for ( TopoDS_Iterator aTopIt(aCurrentRootShape); aTopIt.More(); aTopIt.Next() )
1931 aNumTopoComponents++;
1933 if ( aNumTopoComponents != aComponentLabs.Length() )
1934 isModified = Standard_True;
1936 // Iterate over the assembly components. If at least one component is
1937 // modified (this is the recursive check), then the actually stored
1938 // compound has to be updated
1939 TopTools_ListOfShape aComponentShapes;
1941 for ( TDF_LabelSequence::Iterator aCompIt(aComponentLabs); aCompIt.More(); aCompIt.Next() )
1943 const TDF_Label& aComponentLab = aCompIt.Value();
1945 // Take the referred assembly item (ultimately, a part for an instance)
1946 TDF_Label aComponentRefLab;
1947 GetReferredShape(aComponentLab, aComponentRefLab);
1949 // Shape comes with some placement transformation here
1950 TopoDS_Shape aComponentShape;
1951 GetShape(aComponentLab, aComponentShape);
1952 TopLoc_Location aComponentLoc = aComponentShape.Location();
1954 // If the component is a sub-assembly, then its associated compound
1955 // has to be processed in the same manner
1956 if ( IsAssembly(aComponentRefLab) )
1959 if ( updateComponent(aComponentRefLab, aComponentShape) )
1962 isModified = Standard_True;
1964 aComponentShape.Location(aComponentLoc); // Apply placement
1969 // Search for a part in the actual compound of the ultimate assembly.
1970 // If the part is there, then the compound is up-to-date, so it does
1971 // not require rebuilding
1972 Standard_Boolean isPartFound = Standard_False;
1973 for ( TopoDS_Iterator aTopoIt(aCurrentRootShape); aTopoIt.More(); aTopoIt.Next() )
1975 if ( aTopoIt.Value() == aComponentShape )
1977 isPartFound = Standard_True;
1982 if ( !isPartFound && !isModified )
1983 isModified = Standard_True; // Part has been modified somewhere, so the compound
1984 // has to be rebuilt
1987 // Fill the list of shapes composing a new compound for the assembly
1988 aComponentShapes.Append(aComponentShape);
1991 // If any component is modified, we update the currently stored shape
1994 TopoDS_Compound anUpdatedCompound;
1996 aBB.MakeCompound(anUpdatedCompound);
1998 // Compose new compound
1999 for ( TopTools_ListIteratorOfListOfShape aShapeIt(aComponentShapes); aShapeIt.More(); aShapeIt.Next() )
2001 aBB.Add( anUpdatedCompound, aShapeIt.Value() );
2004 // Store the updated shape as an output
2005 theUpdatedShape = anUpdatedCompound;
2007 // Use topological naming services to store the updated shape in XDE
2008 TNaming_Builder NB(theItemLabel);
2009 NB.Generated(theUpdatedShape);