3a1d416befcbd9d56500f97382fdebab570bdf7c
[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 void 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 }
1306
1307 //=======================================================================
1308 //function : DumpShape
1309 //purpose  : 
1310 //=======================================================================
1311
1312 void XCAFDoc_ShapeTool::DumpShape(Standard_OStream& theDumpLog, const TDF_Label& L,const Standard_Integer level,const Standard_Boolean deep)
1313 {
1314   TopoDS_Shape S;
1315   if(! XCAFDoc_ShapeTool::GetShape(L, S) ) return;
1316   for (Standard_Integer i=0; i<level; i++)
1317     theDumpLog<<"\t";
1318   
1319   if(XCAFDoc_ShapeTool::IsAssembly(L))
1320   {
1321     theDumpLog<<"ASSEMBLY ";
1322   }
1323   else if (XCAFDoc_ShapeTool::IsSimpleShape(L))
1324   {
1325     if(L.Father().Father().Father().IsRoot())
1326       theDumpLog<<"PART ";
1327   }
1328   else
1329   {
1330     theDumpLog<<"INSTANCE ";
1331   }  
1332   TopAbs::Print(S.ShapeType(), theDumpLog);
1333   
1334   TCollection_AsciiString Entry;
1335   TDF_Tool::Entry(L, Entry);
1336   theDumpLog<<"  "<<Entry;
1337   if(XCAFDoc_ShapeTool::IsReference(L))
1338   {
1339     Handle(TDataStd_TreeNode) aRef;
1340     L.FindAttribute(XCAFDoc::ShapeRefGUID(), aRef);
1341     TDF_Tool::Entry(aRef->Father()->Label(), Entry);
1342     theDumpLog<<" (refers to "<<Entry<<")";
1343   }
1344   //cout<<endl;
1345   Handle(TDataStd_Name) Name;
1346   if (L.FindAttribute(TDataStd_Name::GetID(),Name)) 
1347     theDumpLog<<" \""<<Name->Get()<<"\" ";
1348   
1349   if (deep) {
1350     theDumpLog<<"("<<*(void**)&S.TShape();
1351     if (! S.Location().IsIdentity())
1352       theDumpLog<<", "<< *(void**)&S.Location();
1353     theDumpLog<<") ";
1354   }
1355 }
1356
1357 //=======================================================================
1358 //function : IsExternRef
1359 //purpose  : 
1360 //=======================================================================
1361
1362 Standard_Boolean XCAFDoc_ShapeTool::IsExternRef(const TDF_Label& L) 
1363 {
1364   Handle(TDataStd_UAttribute) Uattr;
1365   return L.FindAttribute(XCAFDoc::ExternRefGUID(), Uattr);
1366 }
1367
1368 //=======================================================================
1369 //function : SetExternRefs
1370 //purpose  : 
1371 //=======================================================================
1372
1373 void XCAFDoc_ShapeTool::SetExternRefs(const TDF_Label& L,
1374                                       const TColStd_SequenceOfHAsciiString& SHAS) const
1375 {
1376   TDF_Label ShapeLabel = L.NewChild();
1377   TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1378   for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1379     TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1380     Handle(TCollection_HAsciiString) str = SHAS(i);
1381     TCollection_ExtendedString extstr(str->String());
1382     TDataStd_Name::Set(tmplbl,extstr);
1383   }
1384 }
1385
1386 //=======================================================================
1387 //function : SetExternRefs
1388 //purpose  : 
1389 //=======================================================================
1390
1391 TDF_Label XCAFDoc_ShapeTool::SetExternRefs(const TColStd_SequenceOfHAsciiString& SHAS) const
1392 {
1393   TDF_Label ShapeLabel;
1394   TDF_TagSource aTag;
1395   // add a new label
1396   ShapeLabel = aTag.NewChild(Label());
1397   TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1398   for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1399     TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1400     Handle(TCollection_HAsciiString) str = SHAS(i);
1401     TCollection_ExtendedString extstr(str->String());
1402     TDataStd_Name::Set(tmplbl,extstr);
1403   }
1404   return ShapeLabel;
1405 }
1406
1407 //=======================================================================
1408 //function : GetExternRefs
1409 //purpose  : 
1410 //=======================================================================
1411
1412 void XCAFDoc_ShapeTool::GetExternRefs(const TDF_Label& L,
1413                                       TColStd_SequenceOfHAsciiString& SHAS)
1414 {
1415   Handle(TDataStd_Name) TDN;
1416   TDF_Label tmplbl;
1417   for(Standard_Integer i=1; i<=L.NbChildren(); i++) {
1418     tmplbl = L.FindChild(i);
1419     if(tmplbl.FindAttribute(TDataStd_Name::GetID(),TDN)) {
1420       TCollection_ExtendedString extstr = TDN->Get();
1421       Handle(TCollection_HAsciiString) str = 
1422         new TCollection_HAsciiString(TCollection_AsciiString(extstr, '?')); 
1423       SHAS.Append(str);
1424     }
1425   }
1426 }
1427
1428 // API: API work with SHUO (Specified Higher Usage Occurrance) structure
1429
1430 //=======================================================================
1431 //function : GetSHUO
1432 //purpose  : 
1433 //=======================================================================
1434
1435 Standard_Boolean XCAFDoc_ShapeTool::GetSHUO (const TDF_Label& SHUOLabel,
1436                                       Handle(XCAFDoc_GraphNode)& aSHUOAttr)
1437 {
1438   if ( !SHUOLabel.FindAttribute( XCAFDoc::SHUORefGUID(), aSHUOAttr ) )
1439     return Standard_False;
1440   return Standard_True;
1441 }
1442
1443 //=======================================================================
1444 //function : GetAllComponentSHUO
1445 //purpose  : 
1446 //=======================================================================
1447
1448 Standard_Boolean XCAFDoc_ShapeTool::GetAllComponentSHUO (const TDF_Label& theCompLabel,
1449                                                          TDF_AttributeSequence& theSHUOAttrs)
1450 {
1451   TDF_ChildIterator it(theCompLabel); 
1452   for (; it.More(); it.Next()) {
1453     TDF_Label L = it.Value();
1454     Handle(XCAFDoc_GraphNode) aSHUOAttr;
1455     if ( GetSHUO( L, aSHUOAttr ) )
1456       theSHUOAttrs.Append( aSHUOAttr );
1457   }
1458   return (theSHUOAttrs.Length() > 0);
1459 }
1460
1461 //=======================================================================
1462 //function : SetSHUO
1463 //purpose  : 
1464 //=======================================================================
1465
1466 Standard_Boolean XCAFDoc_ShapeTool::SetSHUO (const TDF_LabelSequence& labels,
1467                                              Handle(XCAFDoc_GraphNode)& MainSHUOAttr) const
1468 {
1469   MainSHUOAttr.Nullify();
1470   // check number of labels
1471   if (labels.Length() < 2)
1472     return Standard_False;
1473   // check is all labels contains components of any assemblyies 
1474   Standard_Integer i;
1475   for (i = 1; i <= labels.Length(); i++)
1476     if ( !IsComponent(labels.Value(i)) )
1477       return Standard_False;
1478   
1479   TDF_TagSource aTag;
1480   TDF_Label UpperSubL = aTag.NewChild( labels( 1 ) );
1481   if (theAutoNaming) {
1482     TCollection_ExtendedString Entry("SHUO");
1483     TDataStd_Name::Set(UpperSubL, TCollection_ExtendedString( Entry ));
1484   }
1485   Handle(XCAFDoc_GraphNode) aUpperSHUO;
1486   aUpperSHUO = XCAFDoc_GraphNode::Set( UpperSubL, XCAFDoc::SHUORefGUID() );
1487   // init out argument by main upper usage SHUO
1488   MainSHUOAttr = aUpperSHUO;
1489   // add other next_usage occurrences.
1490   for (i = 2; i <= labels.Length(); i++) {
1491     TDF_Label NextSubL = aTag.NewChild( labels( i ) );
1492     if (theAutoNaming) {
1493       TCollection_ExtendedString EntrySub("SHUO-");
1494       EntrySub += i;
1495       TDataStd_Name::Set(NextSubL, TCollection_ExtendedString( EntrySub ));
1496     }
1497     Handle(XCAFDoc_GraphNode) aNextSHUO;
1498     aNextSHUO = XCAFDoc_GraphNode::Set( NextSubL, XCAFDoc::SHUORefGUID() );
1499     // set references
1500     aUpperSHUO->SetChild( aNextSHUO );
1501     aNextSHUO->SetFather( aUpperSHUO );
1502     // now lets next_usage become upper_usage for next level of SHUO
1503     aUpperSHUO = aNextSHUO;
1504     UpperSubL = NextSubL;
1505   }
1506   
1507   return Standard_True;
1508 }
1509
1510 //=======================================================================
1511 //function : GetSHUOUpperUsage
1512 //purpose  : 
1513 //=======================================================================
1514
1515 Standard_Boolean XCAFDoc_ShapeTool::GetSHUOUpperUsage (const TDF_Label& NextUsageL,
1516                                                        TDF_LabelSequence& aLabels)
1517 {
1518   Handle(XCAFDoc_GraphNode) aNextSHUO;
1519   if( !GetSHUO( NextUsageL, aNextSHUO ) || aNextSHUO->NbFathers()<1 )
1520     return Standard_False;
1521   
1522   // get upper_usage SHAO
1523   for (Standard_Integer i = 1; i <= aNextSHUO->NbFathers(); i++)
1524     aLabels.Append( aNextSHUO->GetFather(i)->Label() );
1525   return Standard_True;
1526 }
1527
1528 //=======================================================================
1529 //function : GetSHUONextUsage
1530 //purpose  : 
1531 //=======================================================================
1532
1533 Standard_Boolean XCAFDoc_ShapeTool::GetSHUONextUsage (const TDF_Label& UpperUsageL,
1534                                                       TDF_LabelSequence& aLabels)
1535 {
1536   Handle(XCAFDoc_GraphNode) aUpperSHUO;
1537   if ( !GetSHUO( UpperUsageL, aUpperSHUO ) || aUpperSHUO->NbChildren()<1 )
1538     return Standard_False;
1539   // get upper_usage SHAO
1540   for (Standard_Integer i = 1; i <= aUpperSHUO->NbChildren(); i++)
1541     aLabels.Append( aUpperSHUO->GetChild(i)->Label() );
1542   return Standard_True;
1543 }
1544
1545 //=======================================================================
1546 //function : RemoveSHUO
1547 //purpose  : 
1548 //=======================================================================
1549
1550 Standard_Boolean XCAFDoc_ShapeTool::RemoveSHUO (const TDF_Label& L) const
1551 {
1552   L.ForgetAllAttributes (Standard_True);
1553   return Standard_True;
1554 }
1555
1556 //=======================================================================
1557 //function : checkForShape
1558 //purpose  : auxilary
1559 //=======================================================================
1560
1561 static Standard_Boolean checkForShape (const TopoDS_Shape& theShape,
1562                                        const TopoDS_Shape& theCurSh,
1563                                        const TDF_Label& theUserL,
1564                                        TDF_LabelSequence& theLabels)
1565 {
1566   // the label of an assembly which contains this component
1567   TDF_Label aSuperUserL = theUserL.Father();
1568   TopLoc_Location aSupLoc, aCompLoc;
1569   aSupLoc = ::XCAFDoc_ShapeTool::GetLocation ( aSuperUserL );
1570   aCompLoc = ::XCAFDoc_ShapeTool::GetLocation ( theUserL );
1571   TopoDS_Shape aCopySh = theCurSh;
1572   aCompLoc = aCompLoc.Multiplied( theCurSh.Location() );
1573   aSupLoc = aSupLoc.Multiplied( aCompLoc );
1574   aCopySh.Location( aSupLoc );
1575   if ( aCopySh.IsSame( theShape ) ) {
1576     theLabels.Prepend( theUserL );
1577     return Standard_True;
1578   }
1579   // try to search deeply (upper by assmebly structure)
1580   TDF_LabelSequence aNewLabels;
1581   for (Standard_Integer j = 1; j <= theLabels.Length(); j++)
1582     aNewLabels.Append( theLabels.Value( j ) );
1583   aNewLabels.Prepend( theUserL );
1584   TDF_LabelSequence aUsers;
1585   ::XCAFDoc_ShapeTool::GetUsers( aSuperUserL, aUsers );
1586   for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1587     if ( checkForShape( theShape, aCopySh, aUsers.Value( i ), aNewLabels ) ) {
1588       // get solution
1589       theLabels = aNewLabels;
1590       return Standard_True;
1591     }
1592   return Standard_False;
1593 }
1594
1595 //=======================================================================
1596 //function : FindComponent
1597 //purpose  : 
1598 //=======================================================================
1599
1600 Standard_Boolean XCAFDoc_ShapeTool::FindComponent (const TopoDS_Shape& theShape,
1601                                                   TDF_LabelSequence& theLabels) const
1602 {
1603   theLabels.Clear();
1604   // search for a top-level shape that corresponds to this component
1605   TopoDS_Shape S0 = theShape;
1606   TopLoc_Location loc;
1607   S0.Location ( loc );
1608   TDF_Label aRefL = FindShape( S0 );
1609   if (aRefL.IsNull())
1610     return Standard_False; // cannot find top-level shape.
1611   
1612   TDF_LabelSequence aUsers;
1613   ::XCAFDoc_ShapeTool::GetUsers( aRefL, aUsers );
1614   for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1615     if ( checkForShape( theShape, S0, aUsers.Value( i ), theLabels ) )
1616       break;
1617   
1618   return (theLabels.Length() > 0);
1619 }
1620
1621 //=======================================================================
1622 //function : getShapesOfSHUO
1623 //purpose  : auxilary
1624 //=======================================================================
1625
1626 static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLocMap,
1627                                          const Handle(XCAFDoc_ShapeTool)& theSTool,
1628                                          const TDF_Label& theSHUOlab,
1629                                          TopoDS_Shape& theShape)
1630 {
1631   Handle(XCAFDoc_GraphNode) SHUO;
1632   TDF_LabelSequence aLabSeq;
1633   theSTool->GetSHUONextUsage( theSHUOlab, aLabSeq );
1634   if (aLabSeq.Length() >= 1)
1635     for (Standard_Integer i = 1; i <= aLabSeq.Length(); i++) {
1636       TDF_Label aSubCompL = aLabSeq.Value( i );
1637       TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSubCompL.Father() );
1638       // create new map of laocation (to not merge locations from different shapes)
1639       TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1640       for (Standard_Integer m = 1; m <= theaPrevLocMap.Extent(); m++)
1641         aNewPrevLocMap.Add( theaPrevLocMap.FindKey( m ) );
1642       aNewPrevLocMap.Add( compLoc );
1643       // got for the new sublocations and corresponding shape
1644       getShapesOfSHUO( aNewPrevLocMap, theSTool, aSubCompL, theShape );
1645     }
1646   else {
1647     TopoDS_Shape aSHUO_NUSh = theSTool->GetShape ( theSHUOlab.Father() );
1648     if ( aSHUO_NUSh.IsNull() ) return Standard_False;
1649     // cause got shape with location already.
1650     TopLoc_Location nullLoc;
1651     aSHUO_NUSh.Location ( nullLoc );
1652     // multiply the locations
1653     Standard_Integer intMapLenght = theaPrevLocMap.Extent();
1654     if ( intMapLenght < 1 )
1655       return Standard_False; // should not be, but to avoid exception...?
1656     TopLoc_Location SupcompLoc;
1657     SupcompLoc = theaPrevLocMap.FindKey( intMapLenght );
1658     if (intMapLenght > 1) {
1659       Standard_Integer l = intMapLenght - 1;
1660       while (l >= 1) {
1661         SupcompLoc = theaPrevLocMap.FindKey( l ).Multiplied( SupcompLoc );
1662         l--;
1663       }
1664     }
1665     aSHUO_NUSh.Location( SupcompLoc );
1666     theShape = aSHUO_NUSh;
1667   }
1668   return (!theShape.IsNull());
1669 }
1670
1671 //=======================================================================
1672 //function : GetSHUOInstance
1673 //purpose  : 
1674 //=======================================================================
1675
1676 TopoDS_Shape XCAFDoc_ShapeTool::GetSHUOInstance (const Handle(XCAFDoc_GraphNode)& theSHUO) const
1677 {
1678   TopoDS_Shape aShape;
1679   if (theSHUO.IsNull())
1680     return aShape;
1681   
1682   TDF_Label aSHUOlab = theSHUO->Label();
1683   // get location of the assembly
1684   TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1685   // get location of the component
1686   TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1687   TopLoc_IndexedMapOfLocation aPrevLocMap;
1688   // get previous setted location 
1689   if ( !loc.IsIdentity() )
1690     aPrevLocMap.Add( loc );
1691   aPrevLocMap.Add( compLoc );
1692   // get shape by recurse method
1693   const Handle(XCAFDoc_ShapeTool)& STool = this;
1694   getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1695   
1696   return aShape;
1697 }
1698
1699 //=======================================================================
1700 //function : getUsersShapesOfSHUO
1701 //purpose  : auxilary
1702 //=======================================================================
1703
1704 static Standard_Boolean getUsersShapesOfSHUO (TopLoc_IndexedMapOfLocation& aPrevLocMap,
1705                                               const Handle(XCAFDoc_ShapeTool)& STool,
1706                                               const TDF_Label& aSHUOlab,
1707                                               const TDF_Label& theUserL,
1708                                               TopTools_SequenceOfShape& theSHUOShapeSeq)
1709 {
1710   TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1711   // get location of the assembly
1712   TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( theUserL.Father() );
1713   // get location of the component
1714   TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( theUserL );
1715   // get previous setted location 
1716   aNewPrevLocMap.Add( loc );
1717   aNewPrevLocMap.Add( compLoc );
1718   Standard_Integer i;
1719   for (i = 1; i <= aPrevLocMap.Extent(); i++)
1720     aNewPrevLocMap.Add( aPrevLocMap.FindKey(i) );
1721   TDF_Label L = theUserL.Father();
1722   TDF_LabelSequence usersLab;
1723   ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1724   if (usersLab.Length() == 0) {
1725     TopoDS_Shape aShape;
1726     getShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aShape );
1727     if (!aShape.IsNull()) {
1728       theSHUOShapeSeq.Append(aShape);
1729       return Standard_True;
1730     }
1731   }
1732   // now iterates on users of this assembly as component
1733   for ( i = 1; i <= usersLab.Length(); i++ ) {
1734     TDF_Label aNewUserL = usersLab.Value(i);
1735     getUsersShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aNewUserL, theSHUOShapeSeq );
1736   }
1737   
1738   return (theSHUOShapeSeq.Length() > 1);
1739 }
1740
1741 //=======================================================================
1742 //function : GetAllSHUOInstances
1743 //purpose  : auxilary
1744 //=======================================================================
1745
1746 Standard_Boolean XCAFDoc_ShapeTool::GetAllSHUOInstances (const Handle(XCAFDoc_GraphNode)& theSHUO,
1747                                                          TopTools_SequenceOfShape& theSHUOShapeSeq) const
1748 {
1749   if (theSHUO.IsNull())
1750     return Standard_False;
1751
1752   TDF_Label aSHUOlab = theSHUO->Label();
1753   TopLoc_IndexedMapOfLocation aPrevLocMap;
1754   // get location of the assembly
1755   TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1756   // get location of the component
1757   TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1758   // get previous setted location 
1759   if ( !loc.IsIdentity() )
1760     aPrevLocMap.Add( loc );
1761   aPrevLocMap.Add( compLoc );
1762   // get label of assembly
1763   TDF_Label L = aSHUOlab.Father().Father();
1764   TDF_LabelSequence usersLab;
1765   ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1766   TopoDS_Shape aShape;
1767   const Handle(XCAFDoc_ShapeTool)& STool = this;
1768   if (usersLab.Length() == 0) {
1769     getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1770     if (!aShape.IsNull()) {
1771       theSHUOShapeSeq.Append(aShape);
1772       return Standard_True;
1773     }
1774   }
1775   // now iterates on users of this assembly as component
1776   for (Standard_Integer i = 1; i <= usersLab.Length(); i++) {
1777     TDF_Label aUserL = usersLab.Value(i);
1778     getUsersShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aUserL, theSHUOShapeSeq );
1779   }
1780   
1781   return (theSHUOShapeSeq.Length() > 1);
1782 }
1783
1784 //=======================================================================
1785 //function : SetInstanceSHUO
1786 //purpose  : 
1787 //=======================================================================
1788
1789 Handle(XCAFDoc_GraphNode) XCAFDoc_ShapeTool::SetInstanceSHUO (const TopoDS_Shape& theShape) const
1790 {
1791   Handle(XCAFDoc_GraphNode) SHUO;
1792   TDF_LabelSequence aLabels;
1793   if ( FindComponent( theShape, aLabels ) )
1794     // set shuo structure on labels of component-assembly structure
1795     SetSHUO( aLabels, SHUO );
1796   return SHUO;
1797 }
1798
1799 //=======================================================================
1800 //function : FindSHUO
1801 //purpose  : 
1802 //=======================================================================
1803
1804 Standard_Boolean XCAFDoc_ShapeTool::FindSHUO (const TDF_LabelSequence& theLabels,
1805                                               Handle(XCAFDoc_GraphNode)& theSHUOAttr)
1806 {
1807   TDF_AttributeSequence SHUOAttrs;
1808   TDF_Label aCompLabel = theLabels.Value(1);
1809   if (! ::XCAFDoc_ShapeTool::GetAllComponentSHUO( aCompLabel, SHUOAttrs ) )
1810     return Standard_False;
1811   // WARNING: manage that each SHUO upper_usage have only one SHUO next_usage
1812   for (Standard_Integer i = 1; i <= SHUOAttrs.Length(); i++) {
1813     TDF_LabelSequence aCondidate;
1814     Handle(XCAFDoc_GraphNode) anSHUO = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1815     aCondidate.Append( anSHUO->Label().Father() );
1816     while (anSHUO->NbChildren()) {
1817       anSHUO = anSHUO->GetChild( 1 );
1818       aCondidate.Append( anSHUO->Label().Father() );
1819     }
1820     // check the label sequences
1821     Standard_Boolean isEqual = Standard_True;
1822     if (theLabels.Length() != aCondidate.Length())
1823       isEqual = Standard_False;
1824     else
1825       for (Standard_Integer li = 1; li <= theLabels.Length(); li++)
1826         if ( theLabels.Value(li) != aCondidate.Value(li) ) {
1827           isEqual = Standard_False;
1828           break;
1829         }
1830     if (!isEqual)
1831       continue;
1832       
1833     theSHUOAttr = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1834     break;
1835   }
1836   return ( !theSHUOAttr.IsNull() );
1837 }
1838
1839 //=======================================================================
1840 //function : Expand
1841 //purpose  : 
1842 //=======================================================================
1843
1844 Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& Shape)
1845 {
1846   if(Shape.IsNull())
1847     return Standard_False;
1848
1849   TopoDS_Shape aShape = GetShape(Shape);
1850   if(!aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND && !IsAssembly(Shape))
1851   {
1852     //set assembly attribute
1853     TDataStd_UAttribute::Set ( Shape, XCAFDoc::AssemblyGUID() );
1854
1855     TopoDS_Iterator anIter(aShape);
1856     for(; anIter.More(); anIter.Next())
1857     {
1858       TopoDS_Shape aChildShape = anIter.Value();
1859       TDF_Label aChild = FindShape(aChildShape, Standard_True);
1860       
1861       TDF_TagSource aTag;
1862       Handle(TDataStd_Name) anAttr;
1863       //make part for child
1864       TDF_Label aPart = aTag.NewChild(Label());
1865       //make child (if color isn't set or if it is compound)
1866       if(aChild.IsNull())
1867       {
1868         TopLoc_Location nulloc;
1869         aChild = aTag.NewChild(Shape);
1870         SetShape(aChild, aChildShape);
1871         SetShape(aPart, aChildShape.Located(nulloc));
1872       }
1873       else
1874       {
1875         //get name
1876         aChild.FindAttribute(TDataStd_Name::GetID(), anAttr);
1877         TopLoc_Location nulloc;
1878         SetShape(aPart, aChildShape.Located(nulloc));
1879
1880       }
1881       //set name to part
1882       if(!anAttr.IsNull())
1883       {
1884         TDataStd_Name::Set(aPart, anAttr->Get());
1885       }
1886       else
1887       {
1888         Standard_SStream Stream;
1889         TopAbs::Print(aChildShape.ShapeType(), Stream);
1890         TCollection_AsciiString aName (Stream.str().c_str());
1891         TDataStd_Name::Set(aPart, TCollection_ExtendedString(aName));
1892       }
1893
1894       MakeReference(aChild, aPart, aChildShape.Location());
1895       
1896       makeSubShape(aPart, aChildShape);
1897     }
1898     return Standard_True;
1899   }
1900   return Standard_False;
1901 }
1902
1903 //=======================================================================
1904 //function : makeSubShape
1905 //purpose  : 
1906 //=======================================================================
1907
1908 void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& Part, const TopoDS_Shape& Shape)
1909 {
1910   TDF_TagSource aTag;
1911   TopoDS_Iterator anIter(Shape);
1912   for(; anIter.More(); anIter.Next())
1913   {
1914     TopoDS_Shape aChildShape = anIter.Value();
1915     TDF_Label aChildLabel = FindShape(aChildShape,Standard_True);
1916     if(!aChildLabel.IsNull())
1917     { 
1918       //get name
1919       Handle(TDataStd_Name) anAttr;
1920       aChildLabel.FindAttribute(TDataStd_Name::GetID(), anAttr);
1921       TopLoc_Location nulloc;
1922       //make subshape
1923       TDF_Label aSubLabel = aTag.NewChild(Part);
1924       SetShape(aSubLabel, aChildShape.Located(nulloc));
1925       //set name to sub shape
1926       if(!anAttr.IsNull())
1927       {
1928         TDataStd_Name::Set(aSubLabel, anAttr->Get());
1929       }
1930       else
1931       {
1932         Standard_SStream Stream;
1933         TopAbs::Print(aChildShape.ShapeType(), Stream);
1934         TCollection_AsciiString aName (Stream.str().c_str());
1935         TDataStd_Name::Set(aSubLabel, TCollection_ExtendedString(aName));
1936       }
1937       MakeReference(aChildLabel, aSubLabel, aChildShape.Location());
1938     }
1939     makeSubShape(Part, aChildShape);
1940   }
1941 }