0025076: Hidden overloaded virtual functions
[occt.git] / src / XCAFDoc / XCAFDoc_ShapeTool.cxx
1 // Created on: 2000-08-03
2 // Created by: data exchange team
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BRep_Builder.hxx>
18 #include <gp_Pnt.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 <XCAFDoc.hxx>
49 #include <XCAFDoc_GraphNode.hxx>
50 #include <XCAFDoc_Location.hxx>
51 #include <XCAFDoc_ShapeMapTool.hxx>
52 #include <XCAFDoc_ShapeTool.hxx>
53
54 IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_ShapeTool,TDF_Attribute)
55
56 static Standard_Boolean theAutoNaming = Standard_True;
57
58 // attribute methods //////////////////////////////////////////////////
59
60 //=======================================================================
61 //function : GetID
62 //purpose  : 
63 //=======================================================================
64
65 const Standard_GUID& XCAFDoc_ShapeTool::GetID() 
66 {
67   static Standard_GUID ShapeToolID ("efd212ee-6dfd-11d4-b9c8-0060b0ee281b");
68   return ShapeToolID; 
69 }
70
71
72 //=======================================================================
73 //function : Set
74 //purpose  : 
75 //=======================================================================
76
77 Handle(XCAFDoc_ShapeTool) XCAFDoc_ShapeTool::Set(const TDF_Label& L) 
78 {
79   Handle(XCAFDoc_ShapeTool) A;
80   if (!L.FindAttribute (XCAFDoc_ShapeTool::GetID(), A)) {
81     A = new XCAFDoc_ShapeTool ();
82     L.AddAttribute(A);
83   }
84   A->Init();
85   return A;
86 }
87
88
89 //=======================================================================
90 //function : Constructor
91 //purpose  : 
92 //=======================================================================
93
94 XCAFDoc_ShapeTool::XCAFDoc_ShapeTool()
95 {
96   hasSimpleShapes = Standard_False;
97 }
98
99
100 //=======================================================================
101 //function : ID
102 //purpose  : 
103 //=======================================================================
104
105 const Standard_GUID& XCAFDoc_ShapeTool::ID() const
106 {
107   return GetID();
108 }
109
110 //=======================================================================
111 //function : Restore
112 //purpose  : 
113 //=======================================================================
114
115 void XCAFDoc_ShapeTool::Restore(const Handle(TDF_Attribute)& /*with*/) 
116 {
117 }
118
119 //=======================================================================
120 //function : NewEmpty
121 //purpose  : 
122 //=======================================================================
123
124 Handle(TDF_Attribute) XCAFDoc_ShapeTool::NewEmpty() const
125 {
126   return new XCAFDoc_ShapeTool;
127 }
128
129 //=======================================================================
130 //function : Paste
131 //purpose  : 
132 //=======================================================================
133
134 void XCAFDoc_ShapeTool::Paste (const Handle(TDF_Attribute)& /*into*/,
135                                const Handle(TDF_RelocationTable)& /*RT*/) const
136 {
137 }
138
139 // Auxiliary methods //////////////////////////////////////////////////
140
141 //=======================================================================
142 //function : SetLabelNameByLink
143 //purpose  : 
144 //=======================================================================
145 static void SetLabelNameByLink(const TDF_Label L) 
146 {
147   Handle(TDataStd_TreeNode) Node;
148   if (! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
149       ! Node->HasFather()) {
150 #ifdef OCCT_DEBUG
151     cout<<"Error: XCAFDoc_ShapeTool, SetLabelNameByLink(): NO NODE"<<endl;
152 #endif
153     return;
154   }
155   TCollection_AsciiString Entry;
156   TDF_Tool::Entry ( Node->Father()->Label(), Entry );
157   Entry.Insert(1, "=>[");
158   Entry += "]";
159
160   TDataStd_Name::Set(L, TCollection_ExtendedString( Entry ));
161 }
162
163
164 //=======================================================================
165 //function : SetLabelNameByShape
166 //purpose  : 
167 //=======================================================================
168 static void SetLabelNameByShape(const TDF_Label L) 
169 {
170   TopoDS_Shape S;
171   if (XCAFDoc_ShapeTool::GetShape(L, S) &&
172       ! L.IsAttribute(TDataStd_Name::GetID()) ) {
173     Standard_SStream Stream;
174 //    TopAbs_ShapeEnum Type = S.ShapeType();
175 //    if (Type == TopAbs_COMPOUND) Stream<<"ASSEMBLY";
176 //    else 
177     TopAbs::Print(S.ShapeType(), Stream);
178     TCollection_AsciiString aName (Stream.str().c_str());
179     TDataStd_Name::Set(L, TCollection_ExtendedString(aName));
180   }
181 }
182
183
184 //=======================================================================
185 //function : SearchUsingMap
186 //purpose  : 
187 //=======================================================================
188
189 Standard_Boolean XCAFDoc_ShapeTool::SearchUsingMap(const TopoDS_Shape &S, TDF_Label &L,
190                                                    const Standard_Boolean findWithoutLoc,
191                                                    const Standard_Boolean findSubShape) const
192 {
193
194   if(myShapeLabels.IsBound(S)) {
195     L = myShapeLabels.Find(S);
196     return Standard_True;
197   }
198   TopoDS_Shape S0 = S;
199   TopLoc_Location loc;
200   S0.Location(loc);
201   if(myShapeLabels.IsBound(S0)) {
202     TDF_Label L1 = myShapeLabels.Find(S0);
203     TDF_LabelSequence Labels;
204     if(GetUsers(L1, Labels, Standard_True)) {
205       for(Standard_Integer i=1; i<=Labels.Length(); i++) {
206         TopoDS_Shape c = GetShape(Labels.Value(i));
207         if(c.IsSame(S)) {
208           L = Labels.Value(i);
209           return Standard_True;
210         }
211       }
212     }
213     if(findWithoutLoc) {
214       L = L1;
215       return Standard_True;
216     }
217   }
218
219   if(hasSimpleShapes) {
220     if(mySimpleShapes.IsBound(S)) {
221       L = mySimpleShapes.Find(S);
222       return Standard_True;
223     }
224     if(mySimpleShapes.IsBound(S0)) {
225       L = mySimpleShapes.Find(S0);
226       return Standard_True;
227     }
228   }
229   // search subshapes
230   if(!findSubShape) return Standard_False;
231   TDF_Label mainL = FindMainShapeUsingMap(S);
232   if(mainL.IsNull()) return Standard_False;
233   L = AddSubShape(mainL,S);
234   return !L.IsNull();//Standard_True;
235 }
236
237
238 //=======================================================================
239 //function : Search
240 //purpose  : 
241 //=======================================================================
242
243 Standard_Boolean XCAFDoc_ShapeTool::Search (const TopoDS_Shape &S, 
244                                          TDF_Label &L,
245                                          const Standard_Boolean findInstance,
246                                          const Standard_Boolean findComponent,
247                                          const Standard_Boolean findSubShape) const
248 {
249   // search among shapes
250   Standard_Boolean isLocated = ! S.Location().IsIdentity();
251   
252   if ( isLocated ) {
253     // try to find top-level instance
254     if ( findInstance && FindShape ( S, L, Standard_True ) )
255       return Standard_True;
256     // try to find component of assembly
257     if ( findComponent ) {
258       TDF_LabelSequence labels;
259       GetShapes ( labels );
260       for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
261         if ( ! IsAssembly ( labels.Value(i) ) ) continue;
262         TDF_LabelSequence comp;
263         GetComponents ( labels.Value(i), comp );
264         for ( Standard_Integer j=1; j <= comp.Length(); j++ ) {
265           TopoDS_Shape c = GetShape ( comp.Value(j) );
266           if ( c.IsSame ( S ) ) {
267             L = comp.Value(j);
268             return Standard_True;
269           }
270         }
271       }
272     }
273   }
274   // try to find top-level simple shape
275   if ( FindShape ( S, L, Standard_False ) ) return Standard_True;
276   
277   // search subshapes
278   if ( ! findSubShape ) return Standard_False;
279   TDF_Label mainL = FindMainShape ( S );
280   if ( mainL.IsNull() ) return Standard_False;
281   L = AddSubShape ( mainL, S );
282   return !L.IsNull();//Standard_True;
283 }
284
285 //=======================================================================
286 //function : FindShape
287 //purpose  : 
288 //=======================================================================
289
290 Standard_Boolean XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S, 
291                                                TDF_Label& L,
292                                                const Standard_Boolean findInstance) const
293 {
294   // search for null-located shape
295   TopoDS_Shape S0 = S;
296   if ( ! findInstance ) {
297     TopLoc_Location loc;
298     S0.Location ( loc );
299   }
300
301   // this code is used instead of the following for performance reasons
302   if (TNaming_Tool::HasLabel(Label(), S0)) {
303     int TransDef = 0;
304     L = TNaming_Tool::Label(Label(), S0, TransDef);
305     return Standard_True;
306   }
307 /*
308   TDF_ChildIDIterator it(myLabel,TNaming_NamedShape::GetID());
309   for (; it.More(); it.Next()) {
310     TDF_Label aLabel = it.Value()->Label();
311     Handle(TNaming_NamedShape) NS;
312     if ( aLabel.FindAttribute(TNaming_NamedShape::GetID(), NS) &&
313          S0.IsSame ( TNaming_Tool::GetShape(NS) ) ) {
314       L = aLabel;
315       return Standard_True;
316     }
317   }
318 */
319   return Standard_False;
320 }
321
322 //=======================================================================
323 //function : FindShape
324 //purpose  : 
325 //=======================================================================
326
327 TDF_Label XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S,
328                                      const Standard_Boolean findInstance) const
329 {
330   TDF_Label L;
331   FindShape ( S, L, findInstance );
332   return L;
333 }
334
335 //=======================================================================
336 //function : GetShape
337 //purpose  : 
338 //=======================================================================
339
340 Standard_Boolean XCAFDoc_ShapeTool::GetShape (const TDF_Label& L, TopoDS_Shape& S) 
341 {
342   Handle(XCAFDoc_Location) LocationAttribute;
343
344   if(IsExternRef(L)) {
345     TopoDS_Compound EmptyComp;
346     BRep_Builder B;
347     B.MakeCompound(EmptyComp);
348     S = EmptyComp;
349   }
350
351   // for instance, get referred shape
352   Handle(TDataStd_TreeNode) Node;
353   if ( L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather() && 
354        L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute)) {
355     if ( ! GetShape(Node->Father()->Label(), S) ) return Standard_False;
356     S.Move ( LocationAttribute->Get() );
357     return Standard_True;
358   }
359
360   // else just return shape on this label
361   Handle(TNaming_NamedShape) NS;
362   if ( ! L.FindAttribute(TNaming_NamedShape::GetID(), NS) ) return Standard_False;
363   S = TNaming_Tool::GetShape(NS);
364   return Standard_True;
365 }
366
367 //=======================================================================
368 //function : GetShape
369 //purpose  : 
370 //=======================================================================
371
372 TopoDS_Shape XCAFDoc_ShapeTool::GetShape(const TDF_Label& L) 
373 {
374   TopoDS_Shape aShape;
375   GetShape(L,aShape);
376   return aShape;
377 }
378
379 //=======================================================================
380 //function : NewShape
381 //purpose  : 
382 //=======================================================================
383
384 TDF_Label XCAFDoc_ShapeTool::NewShape() const
385 {
386   TopoDS_Compound aShape;
387   BRep_Builder tdsB;
388   tdsB.MakeCompound ( aShape );
389
390   TDF_TagSource aTag;
391   TDF_Label aLabel = aTag.NewChild(Label());
392   
393   TNaming_Builder tnBuild(aLabel);
394   tnBuild.Generated(aShape);
395   
396   return aLabel;
397 }
398
399 //=======================================================================
400 //function : SetShape
401 //purpose  : 
402 //=======================================================================
403
404 void XCAFDoc_ShapeTool::SetShape (const TDF_Label& L, const TopoDS_Shape& S)
405
406   if(IsReference(L) || !IsTopLevel(L) || /*IsAssembly(L) ||*/ !S.Location().IsIdentity())
407     return;
408
409   TDF_LabelSequence aSubShapes;
410   GetSubShapes(L, aSubShapes);
411
412   TNaming_Builder tnBuild(L);
413   tnBuild.Generated(S);
414   Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(L);
415   A->SetShape(S);
416
417   for(Standard_Integer i = 1; i<=aSubShapes.Length(); i++)
418   {
419     TDF_Label aSubLabel = aSubShapes(i);
420     if (!IsSubShape(L, GetShape(aSubLabel)))
421     {
422       aSubLabel.ForgetAllAttributes();
423     }
424   }
425
426   if(!myShapeLabels.IsBound(S)) {
427     myShapeLabels.Bind(S,L);
428   }
429
430   UpdateAssociatedAssembly(L);
431 }
432
433 //=======================================================================
434 //function : MakeReference
435 //purpose  : 
436 //=======================================================================
437
438 void XCAFDoc_ShapeTool::MakeReference (const TDF_Label &L, 
439                                     const TDF_Label &refL,
440                                     const TopLoc_Location &loc)
441 {
442   // store location
443   XCAFDoc_Location::Set(L, loc);
444     
445     // set reference
446   Handle(TDataStd_TreeNode) refNode, mainNode;
447   mainNode = TDataStd_TreeNode::Set ( refL, XCAFDoc::ShapeRefGUID() );
448   refNode  = TDataStd_TreeNode::Set ( L,    XCAFDoc::ShapeRefGUID() );
449   refNode->Remove(); // abv: fix against bug in TreeNode::Append()
450   mainNode->Append(refNode);
451
452   if (theAutoNaming)
453     SetLabelNameByLink(L);
454 }
455
456 //=======================================================================
457 //function : addShape
458 //purpose  : private
459 //=======================================================================
460
461 TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly)
462 {
463   TDF_Label ShapeLabel;
464   TDF_TagSource aTag;
465
466   // search if the shape already exists (with the same location)
467   if ( S.IsNull() || FindShape ( S, ShapeLabel, Standard_True ) ) return ShapeLabel;
468   
469   // else add a new label
470   ShapeLabel = aTag.NewChild(Label());
471   
472   // if shape has location, make a reference to the same shape without location
473   if ( ! S.Location().IsIdentity() /*&& FindShape ( S, L )*/ ) {
474     TopoDS_Shape S0 = S;
475     TopLoc_Location loc;
476     S0.Location ( loc );
477     TDF_Label L = addShape ( S0, makeAssembly );
478     MakeReference ( ShapeLabel, L, S.Location() );
479     return ShapeLabel;
480   }
481   
482   // else add a shape to a label
483   TNaming_Builder tnBuild(ShapeLabel);
484   tnBuild.Generated(S);
485   
486   Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
487 //  if ( ! ShapeLabel.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
488 //    A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
489 //    ShapeLabel.AddAttribute(A);
490 //  }
491   A->SetShape(S);
492   
493   if (theAutoNaming)
494     SetLabelNameByShape(ShapeLabel);
495
496   // if shape is Compound and flag is set, create assembly
497   if ( makeAssembly && S.ShapeType() == TopAbs_COMPOUND ) {
498     // mark assembly by assigning UAttribute
499     Handle(TDataStd_UAttribute) Uattr;
500     Uattr = TDataStd_UAttribute::Set ( ShapeLabel, XCAFDoc::AssemblyGUID() );
501     if (theAutoNaming)
502       TDataStd_Name::Set(ShapeLabel, TCollection_ExtendedString("ASSEMBLY"));
503
504     // iterate on components
505     TopoDS_Iterator Iterator(S);
506     for (; Iterator.More(); Iterator.Next()) {
507       // get label for component`s shape
508       TopoDS_Shape Scomp = Iterator.Value(), S0 = Scomp;
509       TopLoc_Location loc;
510       S0.Location ( loc );
511       TDF_Label compL = addShape ( S0, makeAssembly );
512       
513       // add a component as reference
514       TDF_Label RefLabel = aTag.NewChild(ShapeLabel);
515       MakeReference ( RefLabel, compL, Scomp.Location() );
516     }
517   }
518   
519   if(!IsAssembly(ShapeLabel)) {
520     //const TopTools_IndexedMapOfShape tmpMap = A->GetMap();
521     //for(Standard_Integer i=1; i<=tmpMap.Extent(); i++)
522     //mySubShapes.Bind(tmpMap.FindKey(i),ShapeLabel);
523     for(Standard_Integer i=1; i<=A->GetMap().Extent(); i++)
524     {
525       TopoDS_Shape aSh = A->GetMap().FindKey(i);
526       mySubShapes.Bind(aSh,ShapeLabel);
527     }
528     //mySubShapes.Bind(ShapeLabel,A->GetMap());
529   }
530
531   return ShapeLabel;
532 }
533
534
535 //=======================================================================
536 //function : prepareAssembly
537 //purpose  : auxilary
538 //=======================================================================
539 static Standard_Boolean prepareAssembly (const TopoDS_Shape& theShape,
540                                          TopoDS_Shape& theOUTShape)
541 {
542   // iterate on components
543   theOUTShape = theShape;
544   if (theShape.ShapeType() == TopAbs_COMPOUND) {
545     BRep_Builder B;
546     // check if shape if frosen
547     if (!theOUTShape.Free())
548       theOUTShape.Free(Standard_True);
549     
550     TopTools_SequenceOfShape aSubShapeSeq;
551     TopoDS_Iterator Iterator(theShape);
552     for (; Iterator.More(); Iterator.Next())
553       aSubShapeSeq.Append(Iterator.Value());
554     for (Standard_Integer i = 1; i <= aSubShapeSeq.Length(); i++) {
555       TopoDS_Shape Scomp = aSubShapeSeq.Value(i);
556       TopoDS_Shape aNewScomp;
557       B.Remove(theOUTShape, Scomp);
558       prepareAssembly( Scomp, aNewScomp );
559       TopLoc_Location aLoc;
560       aLoc = aNewScomp.Location();
561       if ( aLoc.IsIdentity() ) {
562         // create an "empty" location
563         gp_Trsf aTrsf;
564         aTrsf.SetScale(gp_Pnt(0,0,0), 1);
565         aLoc = TopLoc_Location( aTrsf );
566         aNewScomp.Location( aLoc );
567       }
568       B.Add(theOUTShape, aNewScomp);
569     }
570   }
571   return Standard_True;
572 }
573
574
575 //=======================================================================
576 //function : AddShape
577 //purpose  : 
578 //=======================================================================
579
580 TDF_Label XCAFDoc_ShapeTool::AddShape (const TopoDS_Shape& theShape,
581                                        const Standard_Boolean makeAssembly,
582                                        const Standard_Boolean makePrepare)
583 {
584   // PTV 17.02.2003 to avoid components without location.
585   TopoDS_Shape S = theShape;
586   if ( makePrepare && makeAssembly && S.ShapeType() == TopAbs_COMPOUND )
587     prepareAssembly( theShape, S ); // OCC1669
588   
589   TDF_Label L = addShape(S,makeAssembly);
590
591   if(!myShapeLabels.IsBound(S)) {
592     myShapeLabels.Bind(S,L);
593   }
594
595   return L;
596
597   //return addShape( S, makeAssembly );
598 }
599
600 //=======================================================================
601 //function : RemoveShape
602 //purpose  : 
603 //=======================================================================
604
605 Standard_Boolean XCAFDoc_ShapeTool::RemoveShape (const TDF_Label& L,
606                                                  const Standard_Boolean removeCompletely) const
607 {
608   if ( ! IsTopLevel ( L ) || ! IsFree ( L ) ) return Standard_False;
609
610   Handle(TDataStd_TreeNode) aNode;
611   TDF_Label aLabel;
612   if (removeCompletely &&
613       L.FindAttribute (XCAFDoc::ShapeRefGUID(), aNode) &&
614       aNode->HasFather() &&
615       L.IsAttribute (XCAFDoc_Location::GetID()))
616   {
617     aLabel = aNode->Father()->Label();
618   }
619
620   L.ForgetAllAttributes (Standard_True);
621
622   if (removeCompletely && !aLabel.IsNull())
623   {
624     return RemoveShape(aLabel);
625   }
626   return Standard_True;
627 }
628
629
630 //=======================================================================
631 //function : Init
632 //purpose  : 
633 //=======================================================================
634
635 void XCAFDoc_ShapeTool::Init()
636 {
637   hasSimpleShapes = Standard_False;
638 }
639
640
641 //=======================================================================
642 //function : SetAutoNaming
643 //purpose  : 
644 //=======================================================================
645
646 void XCAFDoc_ShapeTool::SetAutoNaming (const Standard_Boolean V)
647 {
648   theAutoNaming = V;
649 }
650
651
652 //=======================================================================
653 //function : AutoNaming
654 //purpose  : 
655 //=======================================================================
656
657 Standard_Boolean XCAFDoc_ShapeTool::AutoNaming()
658 {
659   return theAutoNaming;
660 }
661
662
663 //=======================================================================
664 //function : ComputeShapes
665 //purpose  : 
666 //=======================================================================
667
668 void XCAFDoc_ShapeTool::ComputeShapes(const TDF_Label& L)
669 {
670   TDF_ChildIterator it(L); 
671   for(; it.More(); it.Next()) {
672     TDF_Label L1 = it.Value();
673     TopoDS_Shape S;
674     if(GetShape(L1,S)) {
675       if(!myShapeLabels.IsBound(S)) {
676         mySimpleShapes.Bind(S,L1);
677       }
678     }
679     ComputeShapes(L1);
680   }
681 }
682
683
684 //=======================================================================
685 //function : ComputeSimpleShapes
686 //purpose  : 
687 //=======================================================================
688
689 void XCAFDoc_ShapeTool::ComputeSimpleShapes()
690 {
691   ComputeShapes(Label());
692   hasSimpleShapes = Standard_True;
693 }
694
695
696 //=======================================================================
697 //function : GetShapes
698 //purpose  : 
699 //=======================================================================
700
701 void XCAFDoc_ShapeTool::GetShapes(TDF_LabelSequence& Labels) const
702 {
703   Labels.Clear();
704
705   TDF_ChildIterator it(Label()); 
706   for (; it.More(); it.Next()) {
707     TDF_Label L = it.Value();
708     TopoDS_Shape S;
709     if ( GetShape ( L, S ) ) Labels.Append ( L );
710   }
711 }
712
713
714 //=======================================================================
715 //function : GetFreeShapes
716 //purpose  : 
717 //=======================================================================
718
719 void XCAFDoc_ShapeTool::GetFreeShapes (TDF_LabelSequence& FreeLabels) const
720 {
721   FreeLabels.Clear();
722
723   TDF_ChildIterator it(Label());
724   for (; it.More(); it.Next()) {
725     TDF_Label L = it.Value();
726     TopoDS_Shape S;
727     if ( GetShape ( L, S ) && IsFree ( L ) ) FreeLabels.Append ( L );
728   }
729 }
730
731 //=======================================================================
732 //function : IsTopLevel
733 //purpose  : 
734 //=======================================================================
735
736 Standard_Boolean XCAFDoc_ShapeTool::IsTopLevel (const TDF_Label& L) const
737 {
738   return L.Father() == Label();
739 }
740
741 //=======================================================================
742 //function : IsShape
743 //purpose  : 
744 //=======================================================================
745
746 Standard_Boolean XCAFDoc_ShapeTool::IsShape (const TDF_Label& L) 
747 {
748   return IsSimpleShape ( L ) || IsAssembly ( L ) || IsReference ( L );
749 }
750
751 //=======================================================================
752 //function : IsSimpleShape
753 //purpose  : 
754 //=======================================================================
755
756 Standard_Boolean XCAFDoc_ShapeTool::IsSimpleShape (const TDF_Label& L) 
757 {
758   Handle(TNaming_NamedShape) NS;
759   return L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) &&
760          ! IsAssembly ( L ) && ! IsReference ( L );
761 }
762
763 //=======================================================================
764 //function : IsReference
765 //purpose  : 
766 //=======================================================================
767
768 Standard_Boolean XCAFDoc_ShapeTool::IsReference (const TDF_Label& L)
769 {
770   Handle(TDataStd_TreeNode) Node;
771   return L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather();
772 }
773
774 //=======================================================================
775 //function : IsAssembly
776 //purpose  : 
777 //=======================================================================
778
779 Standard_Boolean XCAFDoc_ShapeTool::IsAssembly (const TDF_Label& L) 
780 {
781   Handle(TDataStd_UAttribute) Uattr;
782   return L.FindAttribute(XCAFDoc::AssemblyGUID(), Uattr);
783 }
784
785 //=======================================================================
786 //function : IsComponent
787 //purpose  : 
788 //=======================================================================
789
790 Standard_Boolean XCAFDoc_ShapeTool::IsComponent (const TDF_Label& L)
791 {
792   return IsReference ( L ) && IsAssembly ( L.Father() );
793 }
794
795 //=======================================================================
796 //function : IsCompound
797 //purpose  : 
798 //=======================================================================
799
800 Standard_Boolean XCAFDoc_ShapeTool::IsCompound (const TDF_Label& L) 
801 {
802   Handle(TDataStd_Name) Name;
803   if (L.FindAttribute(TDataStd_Name::GetID(),Name)) {
804     TCollection_ExtendedString estr1 = Name->Get();
805     TCollection_ExtendedString estr2("COMPOUND");
806     if(estr1==estr2) {
807       return Standard_True;
808     }
809   }
810   return Standard_False;
811 }
812
813 //=======================================================================
814 //function : IsSubShape
815 //purpose  : 
816 //=======================================================================
817
818 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label& L)
819 {
820   return IsSimpleShape ( L ) && IsShape ( L.Father() );
821 }
822
823 //=======================================================================
824 //function : IsFree
825 //purpose  : 
826 //=======================================================================
827
828 Standard_Boolean XCAFDoc_ShapeTool::IsFree (const TDF_Label& L) 
829 {
830   Handle(TDataStd_TreeNode) Node;
831   if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) || 
832        ! Node->HasFirst() ) return Standard_True;
833
834   return Standard_False;
835 }
836
837 //=======================================================================
838 //function : GetUsers
839 //purpose  : Returns number of users (0 if shape is free)
840 //=======================================================================
841
842 Standard_Integer XCAFDoc_ShapeTool::GetUsers (const TDF_Label& L, 
843                                               TDF_LabelSequence& Labels,
844                                               const Standard_Boolean getsubchilds)
845 {
846   Standard_Integer NbUsers=0;
847   Handle(TDataStd_TreeNode) Node  ;
848
849   if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ) return NbUsers;
850   
851   Node = Node->First();
852   while ( ! Node.IsNull() ) {
853     
854     if ( getsubchilds ) {
855       TDF_Label underL = Node->Label().Father();
856       NbUsers += GetUsers ( underL, Labels, getsubchilds );
857     }
858     
859     Labels.Append(Node->Label());
860     Node = Node->Next();
861     NbUsers++;
862   }
863   return NbUsers;
864 }
865   
866 //=======================================================================
867 //function : NbComponents
868 //purpose  : 
869 //=======================================================================
870
871 Standard_Integer XCAFDoc_ShapeTool::NbComponents (const TDF_Label& L,
872                                                   const Standard_Boolean getsubchilds) 
873 {
874   TDF_LabelSequence subLabels;
875   GetComponents (L, subLabels, getsubchilds);
876   return subLabels.Length();
877 }
878
879 //=======================================================================
880 //function : GetComponents
881 //purpose  : 
882 //=======================================================================
883
884 Standard_Boolean XCAFDoc_ShapeTool::GetComponents (const TDF_Label& L, TDF_LabelSequence& Labels,
885                                                    const Standard_Boolean getsubchilds) 
886 {
887   if ( ! IsAssembly(L) ) return Standard_False;
888   
889   TDF_ChildIterator It(L);
890   for (; It.More(); It.Next() ) {
891     TDF_Label comp = It.Value();
892     if ( IsComponent ( comp ) ) {
893       if ( getsubchilds ) {
894         TDF_Label underL;
895         if ( GetReferredShape ( comp, underL ) )
896           GetComponents ( underL, Labels, getsubchilds);
897       }
898       Labels.Append ( comp );
899     }
900   }
901   return Standard_True;
902 }
903
904 //=======================================================================
905 //function : GetLocation
906 //purpose  : 
907 //=======================================================================
908
909 TopLoc_Location XCAFDoc_ShapeTool::GetLocation (const TDF_Label& L)
910 {
911   Handle(XCAFDoc_Location) LocationAttribute;
912   if (L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute)) 
913     return LocationAttribute->Get();
914   
915   Handle(TNaming_NamedShape) NS;
916   TopoDS_Shape S;
917   if ( L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) ) {
918     S = TNaming_Tool::GetShape(NS);
919   }
920   return S.Location();
921 }
922
923 //=======================================================================
924 //function : GetReferredShape
925 //purpose  : 
926 //=======================================================================
927
928 Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L, 
929                                                       TDF_Label& Label)
930 {
931   if ( ! IsReference(L) ) return Standard_False;
932   
933   Handle (TDataStd_TreeNode) Node;
934   L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node);
935   Label = Node->Father()->Label();
936   return Standard_True;
937 }
938
939 //=======================================================================
940 //function : AddComponent
941 //purpose  : 
942 //=======================================================================
943
944 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, 
945                                            const TDF_Label& compL, 
946                                            const TopLoc_Location &Loc) const
947 {
948   TDF_Label L;
949   
950   // check that shape is assembly
951   if ( ! IsAssembly(assembly) ) {
952     // if it is simple shape, make it assembly
953     if ( IsSimpleShape(assembly) ) 
954       TDataStd_UAttribute::Set ( assembly, XCAFDoc::AssemblyGUID() );
955     else return L;
956   }
957   
958   // add a component as reference
959   TDF_TagSource aTag;
960   L = aTag.NewChild(assembly);
961   MakeReference ( L, compL, Loc );
962
963   // update assembly`s TopoDS_Shape
964   UpdateAssembly ( assembly );
965   return L;
966 }
967
968 //=======================================================================
969 //function : AddComponent
970 //purpose  : 
971 //=======================================================================
972
973 TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly, 
974                                            const TopoDS_Shape& comp,
975                                            const Standard_Boolean expand)
976 {
977   // get label for component`s shape
978   TopoDS_Shape S0 = comp;
979   TopLoc_Location loc;
980   S0.Location ( loc );
981   TDF_Label compL;
982   compL = AddShape ( S0, expand );
983   
984   // add component by its label
985   return AddComponent ( assembly, compL, comp.Location() );
986 }
987
988 //=======================================================================
989 //function : RemoveComponent
990 //purpose  : 
991 //=======================================================================
992
993 void XCAFDoc_ShapeTool::RemoveComponent (const TDF_Label& comp) const
994 {
995   if ( IsComponent(comp) ) {
996     comp.ForgetAllAttributes();
997     UpdateAssembly(comp.Father());
998   }
999 }
1000
1001 //=======================================================================
1002 //function : UpdateAssociatedAssembly
1003 //purpose  : 
1004 //=======================================================================
1005
1006 void XCAFDoc_ShapeTool::UpdateAssociatedAssembly (const TDF_Label& L) const
1007 {
1008   TDF_LabelSequence Labels;
1009   if ( GetUsers ( L, Labels ) ) {
1010     for ( Standard_Integer i=Labels.Length(); i >=1; i-- ) 
1011     {
1012       TDF_Label anAssemblyLabel = Labels(i).Father();
1013       if(!anAssemblyLabel.IsNull())
1014       {
1015         UpdateAssembly(anAssemblyLabel);
1016       }
1017     }
1018   }
1019 }
1020
1021 //=======================================================================
1022 //function : UpdateAssembly
1023 //purpose  : 
1024 //=======================================================================
1025
1026 void XCAFDoc_ShapeTool::UpdateAssembly (const TDF_Label& L) const
1027 {
1028   if ( ! IsAssembly(L) ) return;
1029
1030   BRep_Builder b;
1031   TopoDS_Shape aShape = GetShape(L);
1032   Standard_Boolean isFree = aShape.Free();
1033   if (!isFree)
1034     aShape.Free(Standard_True);
1035
1036   TopTools_SequenceOfShape aSubShapeSeq;
1037   TopoDS_Iterator Iterator(aShape);
1038   for (; Iterator.More(); Iterator.Next())
1039     aSubShapeSeq.Append(Iterator.Value());
1040
1041   for (Standard_Integer i = 1; i <= aSubShapeSeq.Length(); i++) 
1042     b.Remove(aShape, aSubShapeSeq.Value(i));
1043
1044   TDF_ChildIterator chldLabIt(L);
1045   for (; chldLabIt.More(); chldLabIt.Next() ) {
1046     TDF_Label subLabel = chldLabIt.Value();
1047     if ( IsComponent ( subLabel ) ) {
1048       b.Add(aShape, GetShape(subLabel));
1049     }
1050   }
1051
1052   if (!isFree)
1053     aShape.Free(Standard_False);
1054
1055   TNaming_Builder tnBuild(L);
1056   tnBuild.Generated(aShape);
1057
1058   Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(L);
1059   A->SetShape(aShape);
1060
1061   UpdateAssociatedAssembly(L);
1062 }
1063
1064 //=======================================================================
1065 //function : IsSubShape
1066 //purpose  : 
1067 //=======================================================================
1068
1069 //static Standard_Boolean CheckSubShape (const TopoDS_Shape &S, const TopoDS_Shape &sub)
1070 //{
1071 //  if ( S.IsSame ( sub ) ) return Standard_True;
1072 //  
1073 //  if ( S.ShapeType() >= sub.ShapeType() ) return Standard_False;
1074 //  
1075 //  for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
1076 //    if ( CheckSubShape ( it.Value(), sub ) ) return Standard_True;
1077 //  }
1078 //  return Standard_False;
1079 //}
1080
1081 //=======================================================================
1082 //function : IsSubShape
1083 //purpose  : 
1084 //=======================================================================
1085
1086 Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label &shapeL,
1087                                              const TopoDS_Shape &sub) const
1088 {
1089   Handle(XCAFDoc_ShapeMapTool) A;
1090   if ( ! shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) )
1091     return Standard_False;
1092   
1093   //TopoDS_Shape S = GetShape ( shapeL );
1094   //return ! S.IsNull() && CheckSubShape ( S, sub );
1095   
1096   return A->IsSubShape(sub);
1097 }
1098
1099 //=======================================================================
1100 //function : FindSubShape
1101 //purpose  : 
1102 //=======================================================================
1103
1104 Standard_Boolean XCAFDoc_ShapeTool::FindSubShape (const TDF_Label &shapeL,
1105                                                   const TopoDS_Shape &sub,
1106                                                   TDF_Label &L) const
1107 {
1108   // this code is used instead of the following for performance reasons
1109   if ( TNaming_Tool::HasLabel(Label(), sub) ) {
1110     int TransDef = 0;
1111     L = TNaming_Tool::Label(Label(), sub, TransDef);
1112     return ( ! L.IsNull() && L.Father() == shapeL );
1113   }
1114
1115 /*
1116   TDF_ChildIterator chldLabIt(shapeL);
1117   for (; chldLabIt.More(); chldLabIt.Next() ) {
1118     TDF_Label subLabel = chldLabIt.Value();
1119     TopoDS_Shape S;
1120     if ( GetShape ( subLabel, S ) && S.IsSame ( sub ) ) {
1121       L = subLabel;
1122       return Standard_True;
1123     }
1124   }
1125 */
1126   return Standard_False;
1127 }
1128
1129 //=======================================================================
1130 //function : AddSubShape
1131 //purpose  : 
1132 //=======================================================================
1133
1134 TDF_Label XCAFDoc_ShapeTool::AddSubShape (const TDF_Label &shapeL,
1135                                           const TopoDS_Shape &sub) const
1136 {
1137   TDF_Label L;
1138   if ( FindSubShape ( shapeL, sub, L ) ) return L;
1139   
1140   if ( ! IsSubShape ( shapeL, sub ) ) return L;
1141   
1142   TDF_TagSource aTag;
1143   L = aTag.NewChild(shapeL);
1144   
1145   TNaming_Builder tnBuild(L);
1146   tnBuild.Generated(sub);
1147
1148 //  if(!mySubShapes.IsBound(sub))
1149 //    mySubShapes.Bind(sub,L);
1150    
1151   return L;
1152 }
1153
1154
1155 //=======================================================================
1156 //function : FindMainShapeUsingMap
1157 //purpose  : 
1158 //=======================================================================
1159
1160 TDF_Label XCAFDoc_ShapeTool::FindMainShapeUsingMap(const TopoDS_Shape &sub) const
1161 {
1162   //for(Standard_Integer i=1; i<=myNotAssemblies.Length(); i++) {
1163   //  TDF_Label L = myNotAssemblies.Value(i);
1164   //  if(IsSubShape(L,sub)) return L;
1165   //}
1166   if(mySubShapes.IsBound(sub))
1167     return mySubShapes.Find(sub);
1168   TDF_Label L0;
1169   return L0;
1170 }
1171
1172
1173 //=======================================================================
1174 //function : FindMainShape
1175 //purpose  : 
1176 //=======================================================================
1177
1178 TDF_Label XCAFDoc_ShapeTool::FindMainShape (const TopoDS_Shape &sub) const
1179 {
1180   TDF_ChildIterator it(Label());
1181   for (; it.More(); it.Next()) {
1182     TDF_Label L = it.Value();
1183     if ( ! IsAssembly ( L ) && IsSubShape ( L, sub ) ) return L;
1184   }
1185   TDF_Label L0;
1186   return L0;
1187 }
1188
1189
1190 //=======================================================================
1191 //function : GetSubShapes
1192 //purpose  : 
1193 //=======================================================================
1194
1195 Standard_Boolean XCAFDoc_ShapeTool::GetSubShapes (const TDF_Label &L, 
1196                                                TDF_LabelSequence& Labels)
1197 {
1198   TDF_ChildIterator It(L);
1199   for (; It.More(); It.Next() ) {
1200     TDF_Label sub = It.Value();
1201     if ( IsSubShape ( sub ) ) Labels.Append ( sub );
1202   }
1203   return Labels.Length() >0;
1204 }
1205
1206 //=======================================================================
1207 //function : BaseLabel
1208 //purpose  : 
1209 //=======================================================================
1210
1211 TDF_Label XCAFDoc_ShapeTool::BaseLabel () const
1212 {
1213   return Label();
1214 }
1215
1216 //=======================================================================
1217 //function : DumpAssembly
1218 //purpose  : recursive part of Dump()
1219 //=======================================================================
1220
1221 static void DumpAssembly(Standard_OStream& theDumpLog,
1222                          const TDF_Label L,
1223                          const Standard_Integer level,
1224                          const Standard_Boolean deep)
1225 {
1226   TopoDS_Shape S;
1227   XCAFDoc_ShapeTool::GetShape(L, S);
1228   if(S.IsNull())
1229     return;
1230   for (Standard_Integer i=0; i<level; i++)
1231     theDumpLog<<"\t";
1232   
1233   TCollection_AsciiString Entry;
1234   TDF_Tool::Entry(L, Entry);
1235   
1236   if(XCAFDoc_ShapeTool::IsAssembly(L))
1237   {
1238     theDumpLog<<"ASSEMBLY ";
1239   }
1240   else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
1241   {
1242     if(L.Father().Father().Father().IsRoot())
1243       theDumpLog<<"PART ";
1244   }
1245   else
1246   {
1247     theDumpLog<<"INSTANCE ";
1248   }
1249   TopAbs::Print(S.ShapeType(), theDumpLog);
1250
1251   theDumpLog<<" "<<Entry;
1252   if(XCAFDoc_ShapeTool::IsReference(L))
1253   {
1254     Handle(TDataStd_TreeNode) aRef;
1255     L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
1256     TDF_Tool::Entry(aRef->Father()->Label(), Entry);
1257     theDumpLog<<" (refers to "<<Entry<<")";
1258   }
1259   Handle(TDataStd_Name) Name;
1260   if (L.FindAttribute(TDataStd_Name::GetID(), Name))
1261     theDumpLog<<" \""<<Name->Get()<<"\" ";
1262   
1263   if (deep) {
1264     theDumpLog<<"("<<*(void**)&S.TShape();
1265     if (! S.Location().IsIdentity())
1266       theDumpLog<<", "<< *(void**)&S.Location();
1267     theDumpLog<<") ";
1268   }
1269   theDumpLog<<endl;
1270   
1271   Handle(TDataStd_TreeNode) Node;
1272   TDF_ChildIterator NodeIterator(L);
1273   for (; NodeIterator.More(); NodeIterator.Next()) {
1274     DumpAssembly(theDumpLog, NodeIterator.Value(), level+1, deep);
1275   }
1276   if(level == 0)
1277     theDumpLog<<endl;
1278 }
1279
1280 //=======================================================================
1281 //function : Dump
1282 //purpose  : 
1283 //=======================================================================
1284
1285 Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog, const Standard_Boolean deep) const
1286 {
1287   Standard_Integer level = 0;
1288 //   TopTools_SequenceOfShape SeqShapes;
1289   TDF_LabelSequence SeqLabels;
1290   GetShapes( SeqLabels);
1291
1292   if (SeqLabels.Length()>0) theDumpLog<<endl;
1293   Standard_Integer i;
1294   for (i=1; i<=SeqLabels.Length(); i++) {
1295     DumpAssembly(theDumpLog, SeqLabels.Value(i), level, deep);
1296   }
1297
1298   SeqLabels.Clear();
1299   GetFreeShapes(SeqLabels);
1300   theDumpLog<<endl<<"Free Shapes: "<<SeqLabels.Length()<<endl;
1301   for (i = 1; i<=SeqLabels.Length(); i++) {
1302     DumpShape(theDumpLog, SeqLabels.Value(i), level, deep);
1303     theDumpLog<<endl;
1304   }
1305   return theDumpLog;
1306 }
1307
1308 //=======================================================================
1309 //function : Dump
1310 //purpose  : override
1311 //=======================================================================
1312
1313 Standard_OStream& XCAFDoc_ShapeTool::Dump(Standard_OStream& theDumpLog) const
1314 {
1315   TDF_Attribute::Dump (theDumpLog);
1316   Dump (theDumpLog, Standard_False);
1317   return theDumpLog;
1318 }
1319
1320 //=======================================================================
1321 //function : DumpShape
1322 //purpose  : 
1323 //=======================================================================
1324
1325 void XCAFDoc_ShapeTool::DumpShape(Standard_OStream& theDumpLog, const TDF_Label& L,const Standard_Integer level,const Standard_Boolean deep)
1326 {
1327   TopoDS_Shape S;
1328   if(! XCAFDoc_ShapeTool::GetShape(L, S) ) return;
1329   for (Standard_Integer i=0; i<level; i++)
1330     theDumpLog<<"\t";
1331   
1332   if(XCAFDoc_ShapeTool::IsAssembly(L))
1333   {
1334     theDumpLog<<"ASSEMBLY ";
1335   }
1336   else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
1337   {
1338     if(L.Father().Father().Father().IsRoot())
1339       theDumpLog<<"PART ";
1340   }
1341   else
1342   {
1343     theDumpLog<<"INSTANCE ";
1344   }  
1345   TopAbs::Print(S.ShapeType(), theDumpLog);
1346   
1347   TCollection_AsciiString Entry;
1348   TDF_Tool::Entry(L, Entry);
1349   theDumpLog<<"  "<<Entry;
1350   if(XCAFDoc_ShapeTool::IsReference(L))
1351   {
1352     Handle(TDataStd_TreeNode) aRef;
1353     L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
1354     TDF_Tool::Entry(aRef->Father()->Label(), Entry);
1355     theDumpLog<<" (refers to "<<Entry<<")";
1356   }
1357   //cout<<endl;
1358   Handle(TDataStd_Name) Name;
1359   if (L.FindAttribute(TDataStd_Name::GetID(),Name)) 
1360     theDumpLog<<" \""<<Name->Get()<<"\" ";
1361   
1362   if (deep) {
1363     theDumpLog<<"("<<*(void**)&S.TShape();
1364     if (! S.Location().IsIdentity())
1365       theDumpLog<<", "<< *(void**)&S.Location();
1366     theDumpLog<<") ";
1367   }
1368 }
1369
1370 //=======================================================================
1371 //function : IsExternRef
1372 //purpose  : 
1373 //=======================================================================
1374
1375 Standard_Boolean XCAFDoc_ShapeTool::IsExternRef(const TDF_Label& L) 
1376 {
1377   Handle(TDataStd_UAttribute) Uattr;
1378   return L.FindAttribute(XCAFDoc::ExternRefGUID(), Uattr);
1379 }
1380
1381 //=======================================================================
1382 //function : SetExternRefs
1383 //purpose  : 
1384 //=======================================================================
1385
1386 void XCAFDoc_ShapeTool::SetExternRefs(const TDF_Label& L,
1387                                       const TColStd_SequenceOfHAsciiString& SHAS) const
1388 {
1389   TDF_Label ShapeLabel = L.NewChild();
1390   TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1391   for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1392     TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1393     Handle(TCollection_HAsciiString) str = SHAS(i);
1394     TCollection_ExtendedString extstr(str->String());
1395     TDataStd_Name::Set(tmplbl,extstr);
1396   }
1397 }
1398
1399 //=======================================================================
1400 //function : SetExternRefs
1401 //purpose  : 
1402 //=======================================================================
1403
1404 TDF_Label XCAFDoc_ShapeTool::SetExternRefs(const TColStd_SequenceOfHAsciiString& SHAS) const
1405 {
1406   TDF_Label ShapeLabel;
1407   TDF_TagSource aTag;
1408   // add a new label
1409   ShapeLabel = aTag.NewChild(Label());
1410   TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1411   for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1412     TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1413     Handle(TCollection_HAsciiString) str = SHAS(i);
1414     TCollection_ExtendedString extstr(str->String());
1415     TDataStd_Name::Set(tmplbl,extstr);
1416   }
1417   return ShapeLabel;
1418 }
1419
1420 //=======================================================================
1421 //function : GetExternRefs
1422 //purpose  : 
1423 //=======================================================================
1424
1425 void XCAFDoc_ShapeTool::GetExternRefs(const TDF_Label& L,
1426                                       TColStd_SequenceOfHAsciiString& SHAS)
1427 {
1428   Handle(TDataStd_Name) TDN;
1429   TDF_Label tmplbl;
1430   for(Standard_Integer i=1; i<=L.NbChildren(); i++) {
1431     tmplbl = L.FindChild(i);
1432     if(tmplbl.FindAttribute(TDataStd_Name::GetID(),TDN)) {
1433       TCollection_ExtendedString extstr = TDN->Get();
1434       Handle(TCollection_HAsciiString) str = 
1435         new TCollection_HAsciiString(TCollection_AsciiString(extstr, '?')); 
1436       SHAS.Append(str);
1437     }
1438   }
1439 }
1440
1441 // API: API work with SHUO (Specified Higher Usage Occurrance) structure
1442
1443 //=======================================================================
1444 //function : GetSHUO
1445 //purpose  : 
1446 //=======================================================================
1447
1448 Standard_Boolean XCAFDoc_ShapeTool::GetSHUO (const TDF_Label& SHUOLabel,
1449                                       Handle(XCAFDoc_GraphNode)& aSHUOAttr)
1450 {
1451   if ( !SHUOLabel.FindAttribute( XCAFDoc::SHUORefGUID(), aSHUOAttr ) )
1452     return Standard_False;
1453   return Standard_True;
1454 }
1455
1456 //=======================================================================
1457 //function : GetAllComponentSHUO
1458 //purpose  : 
1459 //=======================================================================
1460
1461 Standard_Boolean XCAFDoc_ShapeTool::GetAllComponentSHUO (const TDF_Label& theCompLabel,
1462                                                          TDF_AttributeSequence& theSHUOAttrs)
1463 {
1464   TDF_ChildIterator it(theCompLabel); 
1465   for (; it.More(); it.Next()) {
1466     TDF_Label L = it.Value();
1467     Handle(XCAFDoc_GraphNode) aSHUOAttr;
1468     if ( GetSHUO( L, aSHUOAttr ) )
1469       theSHUOAttrs.Append( aSHUOAttr );
1470   }
1471   return (theSHUOAttrs.Length() > 0);
1472 }
1473
1474 //=======================================================================
1475 //function : SetSHUO
1476 //purpose  : 
1477 //=======================================================================
1478
1479 Standard_Boolean XCAFDoc_ShapeTool::SetSHUO (const TDF_LabelSequence& labels,
1480                                              Handle(XCAFDoc_GraphNode)& MainSHUOAttr) const
1481 {
1482   MainSHUOAttr.Nullify();
1483   // check number of labels
1484   if (labels.Length() < 2)
1485     return Standard_False;
1486   // check is all labels contains components of any assemblyies 
1487   Standard_Integer i;
1488   for (i = 1; i <= labels.Length(); i++)
1489     if ( !IsComponent(labels.Value(i)) )
1490       return Standard_False;
1491   
1492   TDF_TagSource aTag;
1493   TDF_Label UpperSubL = aTag.NewChild( labels( 1 ) );
1494   if (theAutoNaming) {
1495     TCollection_ExtendedString Entry("SHUO");
1496     TDataStd_Name::Set(UpperSubL, TCollection_ExtendedString( Entry ));
1497   }
1498   Handle(XCAFDoc_GraphNode) aUpperSHUO;
1499   aUpperSHUO = XCAFDoc_GraphNode::Set( UpperSubL, XCAFDoc::SHUORefGUID() );
1500   // init out argument by main upper usage SHUO
1501   MainSHUOAttr = aUpperSHUO;
1502   // add other next_usage occurrences.
1503   for (i = 2; i <= labels.Length(); i++) {
1504     TDF_Label NextSubL = aTag.NewChild( labels( i ) );
1505     if (theAutoNaming) {
1506       TCollection_ExtendedString EntrySub("SHUO-");
1507       EntrySub += i;
1508       TDataStd_Name::Set(NextSubL, TCollection_ExtendedString( EntrySub ));
1509     }
1510     Handle(XCAFDoc_GraphNode) aNextSHUO;
1511     aNextSHUO = XCAFDoc_GraphNode::Set( NextSubL, XCAFDoc::SHUORefGUID() );
1512     // set references
1513     aUpperSHUO->SetChild( aNextSHUO );
1514     aNextSHUO->SetFather( aUpperSHUO );
1515     // now lets next_usage become upper_usage for next level of SHUO
1516     aUpperSHUO = aNextSHUO;
1517     UpperSubL = NextSubL;
1518   }
1519   
1520   return Standard_True;
1521 }
1522
1523 //=======================================================================
1524 //function : GetSHUOUpperUsage
1525 //purpose  : 
1526 //=======================================================================
1527
1528 Standard_Boolean XCAFDoc_ShapeTool::GetSHUOUpperUsage (const TDF_Label& NextUsageL,
1529                                                        TDF_LabelSequence& aLabels)
1530 {
1531   Handle(XCAFDoc_GraphNode) aNextSHUO;
1532   if( !GetSHUO( NextUsageL, aNextSHUO ) || aNextSHUO->NbFathers()<1 )
1533     return Standard_False;
1534   
1535   // get upper_usage SHAO
1536   for (Standard_Integer i = 1; i <= aNextSHUO->NbFathers(); i++)
1537     aLabels.Append( aNextSHUO->GetFather(i)->Label() );
1538   return Standard_True;
1539 }
1540
1541 //=======================================================================
1542 //function : GetSHUONextUsage
1543 //purpose  : 
1544 //=======================================================================
1545
1546 Standard_Boolean XCAFDoc_ShapeTool::GetSHUONextUsage (const TDF_Label& UpperUsageL,
1547                                                       TDF_LabelSequence& aLabels)
1548 {
1549   Handle(XCAFDoc_GraphNode) aUpperSHUO;
1550   if ( !GetSHUO( UpperUsageL, aUpperSHUO ) || aUpperSHUO->NbChildren()<1 )
1551     return Standard_False;
1552   // get upper_usage SHAO
1553   for (Standard_Integer i = 1; i <= aUpperSHUO->NbChildren(); i++)
1554     aLabels.Append( aUpperSHUO->GetChild(i)->Label() );
1555   return Standard_True;
1556 }
1557
1558 //=======================================================================
1559 //function : RemoveSHUO
1560 //purpose  : 
1561 //=======================================================================
1562
1563 Standard_Boolean XCAFDoc_ShapeTool::RemoveSHUO (const TDF_Label& L) const
1564 {
1565   L.ForgetAllAttributes (Standard_True);
1566   return Standard_True;
1567 }
1568
1569 //=======================================================================
1570 //function : checkForShape
1571 //purpose  : auxilary
1572 //=======================================================================
1573
1574 static Standard_Boolean checkForShape (const TopoDS_Shape& theShape,
1575                                        const TopoDS_Shape& theCurSh,
1576                                        const TDF_Label& theUserL,
1577                                        TDF_LabelSequence& theLabels)
1578 {
1579   // the label of an assembly which contains this component
1580   TDF_Label aSuperUserL = theUserL.Father();
1581   TopLoc_Location aSupLoc, aCompLoc;
1582   aSupLoc = ::XCAFDoc_ShapeTool::GetLocation ( aSuperUserL );
1583   aCompLoc = ::XCAFDoc_ShapeTool::GetLocation ( theUserL );
1584   TopoDS_Shape aCopySh = theCurSh;
1585   aCompLoc = aCompLoc.Multiplied( theCurSh.Location() );
1586   aSupLoc = aSupLoc.Multiplied( aCompLoc );
1587   aCopySh.Location( aSupLoc );
1588   if ( aCopySh.IsSame( theShape ) ) {
1589     theLabels.Prepend( theUserL );
1590     return Standard_True;
1591   }
1592   // try to search deeply (upper by assmebly structure)
1593   TDF_LabelSequence aNewLabels;
1594   for (Standard_Integer j = 1; j <= theLabels.Length(); j++)
1595     aNewLabels.Append( theLabels.Value( j ) );
1596   aNewLabels.Prepend( theUserL );
1597   TDF_LabelSequence aUsers;
1598   ::XCAFDoc_ShapeTool::GetUsers( aSuperUserL, aUsers );
1599   for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1600     if ( checkForShape( theShape, aCopySh, aUsers.Value( i ), aNewLabels ) ) {
1601       // get solution
1602       theLabels = aNewLabels;
1603       return Standard_True;
1604     }
1605   return Standard_False;
1606 }
1607
1608 //=======================================================================
1609 //function : FindComponent
1610 //purpose  : 
1611 //=======================================================================
1612
1613 Standard_Boolean XCAFDoc_ShapeTool::FindComponent (const TopoDS_Shape& theShape,
1614                                                   TDF_LabelSequence& theLabels) const
1615 {
1616   theLabels.Clear();
1617   // search for a top-level shape that corresponds to this component
1618   TopoDS_Shape S0 = theShape;
1619   TopLoc_Location loc;
1620   S0.Location ( loc );
1621   TDF_Label aRefL = FindShape( S0 );
1622   if (aRefL.IsNull())
1623     return Standard_False; // cannot find top-level shape.
1624   
1625   TDF_LabelSequence aUsers;
1626   ::XCAFDoc_ShapeTool::GetUsers( aRefL, aUsers );
1627   for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1628     if ( checkForShape( theShape, S0, aUsers.Value( i ), theLabels ) )
1629       break;
1630   
1631   return (theLabels.Length() > 0);
1632 }
1633
1634 //=======================================================================
1635 //function : getShapesOfSHUO
1636 //purpose  : auxilary
1637 //=======================================================================
1638
1639 static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLocMap,
1640                                          const Handle(XCAFDoc_ShapeTool)& theSTool,
1641                                          const TDF_Label& theSHUOlab,
1642                                          TopoDS_Shape& theShape)
1643 {
1644   Handle(XCAFDoc_GraphNode) SHUO;
1645   TDF_LabelSequence aLabSeq;
1646   theSTool->GetSHUONextUsage( theSHUOlab, aLabSeq );
1647   if (aLabSeq.Length() >= 1)
1648     for (Standard_Integer i = 1; i <= aLabSeq.Length(); i++) {
1649       TDF_Label aSubCompL = aLabSeq.Value( i );
1650       TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSubCompL.Father() );
1651       // create new map of laocation (to not merge locations from different shapes)
1652       TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1653       for (Standard_Integer m = 1; m <= theaPrevLocMap.Extent(); m++)
1654         aNewPrevLocMap.Add( theaPrevLocMap.FindKey( m ) );
1655       aNewPrevLocMap.Add( compLoc );
1656       // got for the new sublocations and corresponding shape
1657       getShapesOfSHUO( aNewPrevLocMap, theSTool, aSubCompL, theShape );
1658     }
1659   else {
1660     TopoDS_Shape aSHUO_NUSh = theSTool->GetShape ( theSHUOlab.Father() );
1661     if ( aSHUO_NUSh.IsNull() ) return Standard_False;
1662     // cause got shape with location already.
1663     TopLoc_Location nullLoc;
1664     aSHUO_NUSh.Location ( nullLoc );
1665     // multiply the locations
1666     Standard_Integer intMapLenght = theaPrevLocMap.Extent();
1667     if ( intMapLenght < 1 )
1668       return Standard_False; // should not be, but to avoid exception...?
1669     TopLoc_Location SupcompLoc;
1670     SupcompLoc = theaPrevLocMap.FindKey( intMapLenght );
1671     if (intMapLenght > 1) {
1672       Standard_Integer l = intMapLenght - 1;
1673       while (l >= 1) {
1674         SupcompLoc = theaPrevLocMap.FindKey( l ).Multiplied( SupcompLoc );
1675         l--;
1676       }
1677     }
1678     aSHUO_NUSh.Location( SupcompLoc );
1679     theShape = aSHUO_NUSh;
1680   }
1681   return (!theShape.IsNull());
1682 }
1683
1684 //=======================================================================
1685 //function : GetSHUOInstance
1686 //purpose  : 
1687 //=======================================================================
1688
1689 TopoDS_Shape XCAFDoc_ShapeTool::GetSHUOInstance (const Handle(XCAFDoc_GraphNode)& theSHUO) const
1690 {
1691   TopoDS_Shape aShape;
1692   if (theSHUO.IsNull())
1693     return aShape;
1694   
1695   TDF_Label aSHUOlab = theSHUO->Label();
1696   // get location of the assembly
1697   TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1698   // get location of the component
1699   TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1700   TopLoc_IndexedMapOfLocation aPrevLocMap;
1701   // get previous setted location 
1702   if ( !loc.IsIdentity() )
1703     aPrevLocMap.Add( loc );
1704   aPrevLocMap.Add( compLoc );
1705   // get shape by recurse method
1706   const Handle(XCAFDoc_ShapeTool)& STool = this;
1707   getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1708   
1709   return aShape;
1710 }
1711
1712 //=======================================================================
1713 //function : getUsersShapesOfSHUO
1714 //purpose  : auxilary
1715 //=======================================================================
1716
1717 static Standard_Boolean getUsersShapesOfSHUO (TopLoc_IndexedMapOfLocation& aPrevLocMap,
1718                                               const Handle(XCAFDoc_ShapeTool)& STool,
1719                                               const TDF_Label& aSHUOlab,
1720                                               const TDF_Label& theUserL,
1721                                               TopTools_SequenceOfShape& theSHUOShapeSeq)
1722 {
1723   TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1724   // get location of the assembly
1725   TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( theUserL.Father() );
1726   // get location of the component
1727   TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( theUserL );
1728   // get previous setted location 
1729   aNewPrevLocMap.Add( loc );
1730   aNewPrevLocMap.Add( compLoc );
1731   Standard_Integer i;
1732   for (i = 1; i <= aPrevLocMap.Extent(); i++)
1733     aNewPrevLocMap.Add( aPrevLocMap.FindKey(i) );
1734   TDF_Label L = theUserL.Father();
1735   TDF_LabelSequence usersLab;
1736   ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1737   if (usersLab.Length() == 0) {
1738     TopoDS_Shape aShape;
1739     getShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aShape );
1740     if (!aShape.IsNull()) {
1741       theSHUOShapeSeq.Append(aShape);
1742       return Standard_True;
1743     }
1744   }
1745   // now iterates on users of this assembly as component
1746   for ( i = 1; i <= usersLab.Length(); i++ ) {
1747     TDF_Label aNewUserL = usersLab.Value(i);
1748     getUsersShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aNewUserL, theSHUOShapeSeq );
1749   }
1750   
1751   return (theSHUOShapeSeq.Length() > 1);
1752 }
1753
1754 //=======================================================================
1755 //function : GetAllSHUOInstances
1756 //purpose  : auxilary
1757 //=======================================================================
1758
1759 Standard_Boolean XCAFDoc_ShapeTool::GetAllSHUOInstances (const Handle(XCAFDoc_GraphNode)& theSHUO,
1760                                                          TopTools_SequenceOfShape& theSHUOShapeSeq) const
1761 {
1762   if (theSHUO.IsNull())
1763     return Standard_False;
1764
1765   TDF_Label aSHUOlab = theSHUO->Label();
1766   TopLoc_IndexedMapOfLocation aPrevLocMap;
1767   // get location of the assembly
1768   TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1769   // get location of the component
1770   TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1771   // get previous setted location 
1772   if ( !loc.IsIdentity() )
1773     aPrevLocMap.Add( loc );
1774   aPrevLocMap.Add( compLoc );
1775   // get label of assembly
1776   TDF_Label L = aSHUOlab.Father().Father();
1777   TDF_LabelSequence usersLab;
1778   ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1779   TopoDS_Shape aShape;
1780   const Handle(XCAFDoc_ShapeTool)& STool = this;
1781   if (usersLab.Length() == 0) {
1782     getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1783     if (!aShape.IsNull()) {
1784       theSHUOShapeSeq.Append(aShape);
1785       return Standard_True;
1786     }
1787   }
1788   // now iterates on users of this assembly as component
1789   for (Standard_Integer i = 1; i <= usersLab.Length(); i++) {
1790     TDF_Label aUserL = usersLab.Value(i);
1791     getUsersShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aUserL, theSHUOShapeSeq );
1792   }
1793   
1794   return (theSHUOShapeSeq.Length() > 1);
1795 }
1796
1797 //=======================================================================
1798 //function : SetInstanceSHUO
1799 //purpose  : 
1800 //=======================================================================
1801
1802 Handle(XCAFDoc_GraphNode) XCAFDoc_ShapeTool::SetInstanceSHUO (const TopoDS_Shape& theShape) const
1803 {
1804   Handle(XCAFDoc_GraphNode) SHUO;
1805   TDF_LabelSequence aLabels;
1806   if ( FindComponent( theShape, aLabels ) )
1807     // set shuo structure on labels of component-assembly structure
1808     SetSHUO( aLabels, SHUO );
1809   return SHUO;
1810 }
1811
1812 //=======================================================================
1813 //function : FindSHUO
1814 //purpose  : 
1815 //=======================================================================
1816
1817 Standard_Boolean XCAFDoc_ShapeTool::FindSHUO (const TDF_LabelSequence& theLabels,
1818                                               Handle(XCAFDoc_GraphNode)& theSHUOAttr)
1819 {
1820   TDF_AttributeSequence SHUOAttrs;
1821   TDF_Label aCompLabel = theLabels.Value(1);
1822   if (! ::XCAFDoc_ShapeTool::GetAllComponentSHUO( aCompLabel, SHUOAttrs ) )
1823     return Standard_False;
1824   // WARNING: manage that each SHUO upper_usage have only one SHUO next_usage
1825   for (Standard_Integer i = 1; i <= SHUOAttrs.Length(); i++) {
1826     TDF_LabelSequence aCondidate;
1827     Handle(XCAFDoc_GraphNode) anSHUO = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1828     aCondidate.Append( anSHUO->Label().Father() );
1829     while (anSHUO->NbChildren()) {
1830       anSHUO = anSHUO->GetChild( 1 );
1831       aCondidate.Append( anSHUO->Label().Father() );
1832     }
1833     // check the label sequences
1834     Standard_Boolean isEqual = Standard_True;
1835     if (theLabels.Length() != aCondidate.Length())
1836       isEqual = Standard_False;
1837     else
1838       for (Standard_Integer li = 1; li <= theLabels.Length(); li++)
1839         if ( theLabels.Value(li) != aCondidate.Value(li) ) {
1840           isEqual = Standard_False;
1841           break;
1842         }
1843     if (!isEqual)
1844       continue;
1845       
1846     theSHUOAttr = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1847     break;
1848   }
1849   return ( !theSHUOAttr.IsNull() );
1850 }
1851
1852 //=======================================================================
1853 //function : Expand
1854 //purpose  : 
1855 //=======================================================================
1856
1857 Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& Shape)
1858 {
1859   if(Shape.IsNull())
1860     return Standard_False;
1861
1862   TopoDS_Shape aShape = GetShape(Shape);
1863   if(!aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND && !IsAssembly(Shape))
1864   {
1865     //set assembly attribute
1866     TDataStd_UAttribute::Set ( Shape, XCAFDoc::AssemblyGUID() );
1867
1868     TopoDS_Iterator anIter(aShape);
1869     for(; anIter.More(); anIter.Next())
1870     {
1871       TopoDS_Shape aChildShape = anIter.Value();
1872       TDF_Label aChild = FindShape(aChildShape, Standard_True);
1873       
1874       TDF_TagSource aTag;
1875       Handle(TDataStd_Name) anAttr;
1876       //make part for child
1877       TDF_Label aPart = aTag.NewChild(Label());
1878       //make child (if color isn't set or if it is compound)
1879       if(aChild.IsNull())
1880       {
1881         TopLoc_Location nulloc;
1882         aChild = aTag.NewChild(Shape);
1883         SetShape(aChild, aChildShape);
1884         SetShape(aPart, aChildShape.Located(nulloc));
1885       }
1886       else
1887       {
1888         //get name
1889         aChild.FindAttribute(TDataStd_Name::GetID(), anAttr);
1890         TopLoc_Location nulloc;
1891         SetShape(aPart, aChildShape.Located(nulloc));
1892
1893       }
1894       //set name to part
1895       if(!anAttr.IsNull())
1896       {
1897         TDataStd_Name::Set(aPart, anAttr->Get());
1898       }
1899       else
1900       {
1901         Standard_SStream Stream;
1902         TopAbs::Print(aChildShape.ShapeType(), Stream);
1903         TCollection_AsciiString aName (Stream.str().c_str());
1904         TDataStd_Name::Set(aPart, TCollection_ExtendedString(aName));
1905       }
1906
1907       MakeReference(aChild, aPart, aChildShape.Location());
1908       
1909       makeSubShape(aPart, aChildShape);
1910     }
1911     return Standard_True;
1912   }
1913   return Standard_False;
1914 }
1915
1916 //=======================================================================
1917 //function : makeSubShape
1918 //purpose  : 
1919 //=======================================================================
1920
1921 void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& Part, const TopoDS_Shape& Shape)
1922 {
1923   TDF_TagSource aTag;
1924   TopoDS_Iterator anIter(Shape);
1925   for(; anIter.More(); anIter.Next())
1926   {
1927     TopoDS_Shape aChildShape = anIter.Value();
1928     TDF_Label aChildLabel = FindShape(aChildShape,Standard_True);
1929     if(!aChildLabel.IsNull())
1930     { 
1931       //get name
1932       Handle(TDataStd_Name) anAttr;
1933       aChildLabel.FindAttribute(TDataStd_Name::GetID(), anAttr);
1934       TopLoc_Location nulloc;
1935       //make subshape
1936       TDF_Label aSubLabel = aTag.NewChild(Part);
1937       SetShape(aSubLabel, aChildShape.Located(nulloc));
1938       //set name to sub shape
1939       if(!anAttr.IsNull())
1940       {
1941         TDataStd_Name::Set(aSubLabel, anAttr->Get());
1942       }
1943       else
1944       {
1945         Standard_SStream Stream;
1946         TopAbs::Print(aChildShape.ShapeType(), Stream);
1947         TCollection_AsciiString aName (Stream.str().c_str());
1948         TDataStd_Name::Set(aSubLabel, TCollection_ExtendedString(aName));
1949       }
1950       MakeReference(aChildLabel, aSubLabel, aChildShape.Location());
1951     }
1952     makeSubShape(Part, aChildShape);
1953   }
1954 }