0023595: XCAFDoc_ShapeTool extended with two methods - SetAutoNaming() and AutoNaming()
[occt.git] / src / XCAFDoc / XCAFDoc_ShapeTool.cxx
CommitLineData
b311480e 1// Created on: 2000-08-03
2// Created by: data exchange team
3// Copyright (c) 2000-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21
22#include <XCAFDoc_ShapeTool.ixx>
23#include <XCAFDoc.hxx>
24
25#include <TDF_Tool.hxx>
26#include <TDF_Label.hxx>
27#include <TDF_LabelMap.hxx>
28#include <TDF_LabelSequence.hxx>
29#include <TDF_ChildIterator.hxx>
30#include <TDF_ChildIDIterator.hxx>
31#include <TDF_MapIteratorOfLabelMap.hxx>
32
33#include <TDataStd_Name.hxx>
34#include <TDataStd_TreeNode.hxx>
35#include <TDataStd_ChildNodeIterator.hxx>
36#include <TDataStd_UAttribute.hxx>
37
38#include <TDocStd_Document.hxx>
39
40#include <TNaming_Builder.hxx>
41#include <TNaming_NamedShape.hxx>
42#include <TNaming_Tool.hxx>
43
44#include <TopLoc_Location.hxx>
45#include <TopoDS_Iterator.hxx>
46#include <TopoDS_Shape.hxx>
47#include <TopoDS_Compound.hxx>
48#include <BRep_Builder.hxx>
49#include <XCAFDoc_Location.hxx>
50
51#include <TCollection_AsciiString.hxx>
52#include <TCollection_HAsciiString.hxx>
53#include <TCollection_ExtendedString.hxx>
54#include <TColStd_SequenceOfHAsciiString.hxx>
55#include <XCAFDoc_GraphNode.hxx>
56#include <TopLoc_IndexedMapOfLocation.hxx>
57#include <gp_Trsf.hxx>
58#include <gp_Pnt.hxx>
59#include <XCAFDoc_ShapeMapTool.hxx>
60
e6aad0ee 61static Standard_Boolean theAutoNaming = Standard_True;
7fd59977 62
63// attribute methods //////////////////////////////////////////////////
64
65//=======================================================================
66//function : GetID
67//purpose :
68//=======================================================================
69
70const Standard_GUID& XCAFDoc_ShapeTool::GetID()
71{
72 static Standard_GUID ShapeToolID ("efd212ee-6dfd-11d4-b9c8-0060b0ee281b");
73 return ShapeToolID;
74}
75
76
77//=======================================================================
78//function : Set
79//purpose :
80//=======================================================================
81
82Handle(XCAFDoc_ShapeTool) XCAFDoc_ShapeTool::Set(const TDF_Label& L)
83{
84 Handle(XCAFDoc_ShapeTool) A;
85 if (!L.FindAttribute (XCAFDoc_ShapeTool::GetID(), A)) {
86 A = new XCAFDoc_ShapeTool ();
87 L.AddAttribute(A);
88 }
89 A->Init();
90 return A;
91}
92
93
94//=======================================================================
95//function : Constructor
96//purpose :
97//=======================================================================
98
99XCAFDoc_ShapeTool::XCAFDoc_ShapeTool()
100{
101 hasSimpleShapes = Standard_False;
102}
103
104
105//=======================================================================
106//function : ID
107//purpose :
108//=======================================================================
109
110const Standard_GUID& XCAFDoc_ShapeTool::ID() const
111{
112 return GetID();
113}
114
115//=======================================================================
116//function : Restore
117//purpose :
118//=======================================================================
119
120void XCAFDoc_ShapeTool::Restore(const Handle(TDF_Attribute)& /*with*/)
121{
122}
123
124//=======================================================================
125//function : NewEmpty
126//purpose :
127//=======================================================================
128
129Handle(TDF_Attribute) XCAFDoc_ShapeTool::NewEmpty() const
130{
131 return new XCAFDoc_ShapeTool;
132}
133
134//=======================================================================
135//function : Paste
136//purpose :
137//=======================================================================
138
139void XCAFDoc_ShapeTool::Paste (const Handle(TDF_Attribute)& /*into*/,
140 const Handle(TDF_RelocationTable)& /*RT*/) const
141{
142}
143
7fd59977 144// Auxiliary methods //////////////////////////////////////////////////
145
146//=======================================================================
147//function : SetLabelNameByLink
148//purpose :
149//=======================================================================
150static void SetLabelNameByLink(const TDF_Label L)
151{
152 Handle(TDataStd_TreeNode) Node;
153 if (! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
154 ! Node->HasFather()) {
155 cout<<"Error: XCAFDoc_ShapeTool, SetLabelNameByLink(): NO NODE"<<endl;
156 return;
157 }
158 TCollection_AsciiString Entry;
159 TDF_Tool::Entry ( Node->Father()->Label(), Entry );
160 Entry.Insert(1, "=>[");
161 Entry += "]";
162
163 TDataStd_Name::Set(L, TCollection_ExtendedString( Entry ));
164}
165
166
167//=======================================================================
168//function : SetLabelNameByShape
169//purpose :
170//=======================================================================
171static void SetLabelNameByShape(const TDF_Label L)
172{
173 TopoDS_Shape S;
174 if (XCAFDoc_ShapeTool::GetShape(L, S) &&
175 ! L.IsAttribute(TDataStd_Name::GetID()) ) {
176 Standard_SStream Stream;
177// TopAbs_ShapeEnum Type = S.ShapeType();
178// if (Type == TopAbs_COMPOUND) Stream<<"ASSEMBLY";
179// else
180 TopAbs::Print(S.ShapeType(), Stream);
181
182#ifdef USE_STL_STREAM
183 TCollection_AsciiString aName (Stream.str().c_str());
184#else
185 Stream << ends;
186 TCollection_AsciiString aName (Stream.str());
187#endif
188 TDataStd_Name::Set(L, TCollection_ExtendedString(aName));
189 }
190}
7fd59977 191
192
193//=======================================================================
194//function : SearchUsingMap
195//purpose :
196//=======================================================================
197
198Standard_Boolean XCAFDoc_ShapeTool::SearchUsingMap(const TopoDS_Shape &S, TDF_Label &L,
199 const Standard_Boolean findWithoutLoc,
200 const Standard_Boolean findSubShape) const
201{
202
203 if(myShapeLabels.IsBound(S)) {
204 L = myShapeLabels.Find(S);
205 return Standard_True;
206 }
207 TopoDS_Shape S0 = S;
208 TopLoc_Location loc;
209 S0.Location(loc);
210 if(myShapeLabels.IsBound(S0)) {
211 TDF_Label L1 = myShapeLabels.Find(S0);
212 TDF_LabelSequence Labels;
213 if(GetUsers(L1, Labels, Standard_True)) {
214 for(Standard_Integer i=1; i<=Labels.Length(); i++) {
215 TopoDS_Shape c = GetShape(Labels.Value(i));
216 if(c.IsSame(S)) {
217 L = Labels.Value(i);
218 return Standard_True;
219 }
220 }
221 }
222 if(findWithoutLoc) {
223 L = L1;
224 return Standard_True;
225 }
226 }
227
228 if(hasSimpleShapes) {
229 if(mySimpleShapes.IsBound(S)) {
230 L = mySimpleShapes.Find(S);
231 return Standard_True;
232 }
233 if(mySimpleShapes.IsBound(S0)) {
234 L = mySimpleShapes.Find(S0);
235 return Standard_True;
236 }
237 }
238 // search subshapes
239 if(!findSubShape) return Standard_False;
240 TDF_Label mainL = FindMainShapeUsingMap(S);
241 if(mainL.IsNull()) return Standard_False;
242 L = AddSubShape(mainL,S);
243 return !L.IsNull();//Standard_True;
244}
245
246
247//=======================================================================
248//function : Search
249//purpose :
250//=======================================================================
251
252Standard_Boolean XCAFDoc_ShapeTool::Search (const TopoDS_Shape &S,
253 TDF_Label &L,
254 const Standard_Boolean findInstance,
255 const Standard_Boolean findComponent,
256 const Standard_Boolean findSubShape) const
257{
258 // search among shapes
259 Standard_Boolean isLocated = ! S.Location().IsIdentity();
260
261 if ( isLocated ) {
262 // try to find top-level instance
263 if ( findInstance && FindShape ( S, L, Standard_True ) )
264 return Standard_True;
265 // try to find component of assembly
266 if ( findComponent ) {
267 TDF_LabelSequence labels;
268 GetShapes ( labels );
269 for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
270 if ( ! IsAssembly ( labels.Value(i) ) ) continue;
271 TDF_LabelSequence comp;
272 GetComponents ( labels.Value(i), comp );
273 for ( Standard_Integer j=1; j <= comp.Length(); j++ ) {
274 TopoDS_Shape c = GetShape ( comp.Value(j) );
275 if ( c.IsSame ( S ) ) {
276 L = comp.Value(j);
277 return Standard_True;
278 }
279 }
280 }
281 }
282 }
283 // try to find top-level simple shape
284 if ( FindShape ( S, L, Standard_False ) ) return Standard_True;
285
286 // search subshapes
287 if ( ! findSubShape ) return Standard_False;
288 TDF_Label mainL = FindMainShape ( S );
289 if ( mainL.IsNull() ) return Standard_False;
290 L = AddSubShape ( mainL, S );
291 return !L.IsNull();//Standard_True;
292}
293
294//=======================================================================
295//function : FindShape
296//purpose :
297//=======================================================================
298
299Standard_Boolean XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S,
300 TDF_Label& L,
301 const Standard_Boolean findInstance) const
302{
303 // search for null-located shape
304 TopoDS_Shape S0 = S;
305 if ( ! findInstance ) {
306 TopLoc_Location loc;
307 S0.Location ( loc );
308 }
309
310 // this code is used instead of the following for performance reasons
311 if (TNaming_Tool::HasLabel(Label(), S0)) {
312 int TransDef = 0;
313 L = TNaming_Tool::Label(Label(), S0, TransDef);
314 return Standard_True;
315 }
316/*
317 TDF_ChildIDIterator it(myLabel,TNaming_NamedShape::GetID());
318 for (; it.More(); it.Next()) {
319 TDF_Label aLabel = it.Value()->Label();
320 Handle(TNaming_NamedShape) NS;
321 if ( aLabel.FindAttribute(TNaming_NamedShape::GetID(), NS) &&
322 S0.IsSame ( TNaming_Tool::GetShape(NS) ) ) {
323 L = aLabel;
324 return Standard_True;
325 }
326 }
327*/
328 return Standard_False;
329}
330
331//=======================================================================
332//function : FindShape
333//purpose :
334//=======================================================================
335
336TDF_Label XCAFDoc_ShapeTool::FindShape (const TopoDS_Shape& S,
337 const Standard_Boolean findInstance) const
338{
339 TDF_Label L;
340 FindShape ( S, L, findInstance );
341 return L;
342}
343
344//=======================================================================
345//function : GetShape
346//purpose :
347//=======================================================================
348
349Standard_Boolean XCAFDoc_ShapeTool::GetShape (const TDF_Label& L, TopoDS_Shape& S)
350{
351 Handle(XCAFDoc_Location) LocationAttribute;
352
353 if(IsExternRef(L)) {
354 TopoDS_Compound EmptyComp;
355 BRep_Builder B;
356 B.MakeCompound(EmptyComp);
357 S = EmptyComp;
358 }
359
360 // for instance, get referred shape
361 Handle(TDataStd_TreeNode) Node;
362 if ( L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather() &&
363 L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute)) {
364 if ( ! GetShape(Node->Father()->Label(), S) ) return Standard_False;
365 S.Move ( LocationAttribute->Get() );
366 return Standard_True;
367 }
368
369 // else just return shape on this label
370 Handle(TNaming_NamedShape) NS;
371 if ( ! L.FindAttribute(TNaming_NamedShape::GetID(), NS) ) return Standard_False;
372 S = TNaming_Tool::GetShape(NS);
373 return Standard_True;
374}
375
376//=======================================================================
377//function : GetShape
378//purpose :
379//=======================================================================
380
381TopoDS_Shape XCAFDoc_ShapeTool::GetShape(const TDF_Label& L)
382{
383 TopoDS_Shape aShape;
384 GetShape(L,aShape);
385 return aShape;
386}
387
388//=======================================================================
389//function : NewShape
390//purpose :
391//=======================================================================
392
393TDF_Label XCAFDoc_ShapeTool::NewShape() const
394{
395 TopoDS_Compound aShape;
396 BRep_Builder tdsB;
397 tdsB.MakeCompound ( aShape );
398
399 TDF_TagSource aTag;
400 TDF_Label aLabel = aTag.NewChild(Label());
401
402 TNaming_Builder tnBuild(aLabel);
403 tnBuild.Generated(aShape);
404
405 return aLabel;
406}
407
408//=======================================================================
409//function : SetShape
410//purpose :
411//=======================================================================
412
413void XCAFDoc_ShapeTool::SetShape (const TDF_Label& L, const TopoDS_Shape& S)
414{
415 TNaming_Builder tnBuild(L);
416 tnBuild.Generated(S);
417 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(L);
418// if ( ! L.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
419// A = XCAFDoc_ShapeMapTool::Set(L);
420// L.AddAttribute(A);
421// }
422 A->SetShape(S);
423
424 if(!myShapeLabels.IsBound(S)) {
425 myShapeLabels.Bind(S,L);
426 }
427
428 //:abv 31.10.01: update assemblies that refer a shape
429 TDF_LabelSequence Labels;
430 if ( GetUsers ( L, Labels, Standard_True ) ) {
431 for ( Standard_Integer i=Labels.Length(); i >=1; i-- )
432 UpdateAssembly ( Labels(i) );
433 }
434}
435
436//=======================================================================
437//function : MakeReference
438//purpose :
439//=======================================================================
440
441void XCAFDoc_ShapeTool::MakeReference (const TDF_Label &L,
442 const TDF_Label &refL,
443 const TopLoc_Location &loc)
444{
445 // store location
446 XCAFDoc_Location::Set(L, loc);
447
448 // set reference
449 Handle(TDataStd_TreeNode) refNode, mainNode;
450 mainNode = TDataStd_TreeNode::Set ( refL, XCAFDoc::ShapeRefGUID() );
451 refNode = TDataStd_TreeNode::Set ( L, XCAFDoc::ShapeRefGUID() );
452 refNode->Remove(); // abv: fix against bug in TreeNode::Append()
453 mainNode->Append(refNode);
454
e6aad0ee
RL
455 if (theAutoNaming)
456 SetLabelNameByLink(L);
7fd59977 457}
458
459//=======================================================================
460//function : addShape
461//purpose : private
462//=======================================================================
463
464TDF_Label XCAFDoc_ShapeTool::addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly)
465{
466 TDF_Label ShapeLabel;
467 TDF_TagSource aTag;
468
469 // search if the shape already exists (with the same location)
470 if ( S.IsNull() || FindShape ( S, ShapeLabel, Standard_True ) ) return ShapeLabel;
471
472 // else add a new label
473 ShapeLabel = aTag.NewChild(Label());
474
475 // if shape has location, make a reference to the same shape without location
476 if ( ! S.Location().IsIdentity() /*&& FindShape ( S, L )*/ ) {
477 TopoDS_Shape S0 = S;
478 TopLoc_Location loc;
479 S0.Location ( loc );
480 TDF_Label L = addShape ( S0, makeAssembly );
481 MakeReference ( ShapeLabel, L, S.Location() );
482 return ShapeLabel;
483 }
484
485 // else add a shape to a label
486 TNaming_Builder tnBuild(ShapeLabel);
487 tnBuild.Generated(S);
488
489 Handle(XCAFDoc_ShapeMapTool) A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
490// if ( ! ShapeLabel.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) ) {
491// A = XCAFDoc_ShapeMapTool::Set(ShapeLabel);
492// ShapeLabel.AddAttribute(A);
493// }
494 A->SetShape(S);
495
e6aad0ee
RL
496 if (theAutoNaming)
497 SetLabelNameByShape(ShapeLabel);
7fd59977 498
499 // if shape is Compound and flag is set, create assembly
500 if ( makeAssembly && S.ShapeType() == TopAbs_COMPOUND ) {
501 // mark assembly by assigning UAttribute
502 Handle(TDataStd_UAttribute) Uattr;
503 Uattr = TDataStd_UAttribute::Set ( ShapeLabel, XCAFDoc::AssemblyGUID() );
e6aad0ee
RL
504 if (theAutoNaming)
505 TDataStd_Name::Set(ShapeLabel, TCollection_ExtendedString("ASSEMBLY"));
7fd59977 506
507 // iterate on components
508 TopoDS_Iterator Iterator(S);
509 for (; Iterator.More(); Iterator.Next()) {
510 // get label for component`s shape
511 TopoDS_Shape Scomp = Iterator.Value(), S0 = Scomp;
512 TopLoc_Location loc;
513 S0.Location ( loc );
514 TDF_Label compL = addShape ( S0, makeAssembly );
515
516 // add a component as reference
517 TDF_Label RefLabel = aTag.NewChild(ShapeLabel);
518 MakeReference ( RefLabel, compL, Scomp.Location() );
519 }
520 }
521
522 if(!IsAssembly(ShapeLabel)) {
523 //const TopTools_IndexedMapOfShape tmpMap = A->GetMap();
524 //for(Standard_Integer i=1; i<=tmpMap.Extent(); i++)
525 //mySubShapes.Bind(tmpMap.FindKey(i),ShapeLabel);
526 for(Standard_Integer i=1; i<=A->GetMap().Extent(); i++)
527 mySubShapes.Bind(A->GetMap().FindKey(i),ShapeLabel);
528 //mySubShapes.Bind(ShapeLabel,A->GetMap());
529 }
530
531 return ShapeLabel;
532}
533
534
535//=======================================================================
536//function : prepareAssembly
537//purpose : auxilary
538//=======================================================================
539static 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
580TDF_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
a7aa1465 605Standard_Boolean XCAFDoc_ShapeTool::RemoveShape (const TDF_Label& L,
606 const Standard_Boolean removeCompletely) const
7fd59977 607{
608 if ( ! IsTopLevel ( L ) || ! IsFree ( L ) ) return Standard_False;
a7aa1465 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
7fd59977 620 L.ForgetAllAttributes (Standard_True);
a7aa1465 621
622 if (removeCompletely && !aLabel.IsNull())
623 {
624 return RemoveShape(aLabel);
625 }
7fd59977 626 return Standard_True;
627}
628
629
630//=======================================================================
631//function : Init
632//purpose :
633//=======================================================================
634
635void XCAFDoc_ShapeTool::Init()
636{
637 hasSimpleShapes = Standard_False;
638}
639
640
e6aad0ee
RL
641//=======================================================================
642//function : SetAutoNaming
643//purpose :
644//=======================================================================
645
646void XCAFDoc_ShapeTool::SetAutoNaming (const Standard_Boolean V)
647{
648 theAutoNaming = V;
649}
650
651
652//=======================================================================
653//function : AutoNaming
654//purpose :
655//=======================================================================
656
657Standard_Boolean XCAFDoc_ShapeTool::AutoNaming()
658{
659 return theAutoNaming;
660}
661
662
7fd59977 663//=======================================================================
664//function : ComputeShapes
665//purpose :
666//=======================================================================
667
668void 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
689void XCAFDoc_ShapeTool::ComputeSimpleShapes()
690{
691 ComputeShapes(Label());
692 hasSimpleShapes = Standard_True;
693}
694
695
696//=======================================================================
697//function : GetShapes
698//purpose :
699//=======================================================================
700
701void 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
719void 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
736Standard_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
746Standard_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
756Standard_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
768Standard_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
779Standard_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
790Standard_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
800Standard_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
818Standard_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
828Standard_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
842Standard_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
871Standard_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
884Standard_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
909TopLoc_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
928Standard_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
944TDF_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
973TDF_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
993void 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 : UpdateAssembly
1003//purpose :
1004//=======================================================================
1005
1006void XCAFDoc_ShapeTool::UpdateAssembly (const TDF_Label& L) const
1007{
1008 if ( ! IsAssembly(L) ) return;
1009
1010 TopoDS_Compound newassembly;
1011 BRep_Builder b;
1012 b.MakeCompound(newassembly);
1013
1014 TDF_ChildIterator chldLabIt(L);
1015 for (; chldLabIt.More(); chldLabIt.Next() ) {
1016 TDF_Label subLabel = chldLabIt.Value();
1017 if ( IsComponent ( subLabel ) ) {
1018 b.Add(newassembly, GetShape(subLabel));
1019 }
1020 }
1021 TNaming_Builder tnBuild(L);
1022 tnBuild.Generated(newassembly);
1023}
1024
1025//=======================================================================
1026//function : IsSubShape
1027//purpose :
1028//=======================================================================
1029
1d07572c
E
1030//static Standard_Boolean CheckSubShape (const TopoDS_Shape &S, const TopoDS_Shape &sub)
1031//{
1032// if ( S.IsSame ( sub ) ) return Standard_True;
1033//
1034// if ( S.ShapeType() >= sub.ShapeType() ) return Standard_False;
1035//
1036// for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
1037// if ( CheckSubShape ( it.Value(), sub ) ) return Standard_True;
1038// }
1039// return Standard_False;
1040//}
7fd59977 1041
1042//=======================================================================
1043//function : IsSubShape
1044//purpose :
1045//=======================================================================
1046
1047Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label &shapeL,
1048 const TopoDS_Shape &sub) const
1049{
1050 Handle(XCAFDoc_ShapeMapTool) A;
1051 if ( ! shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) )
1052 return Standard_False;
1053
1054 //TopoDS_Shape S = GetShape ( shapeL );
1055 //return ! S.IsNull() && CheckSubShape ( S, sub );
1056
1057 return A->IsSubShape(sub);
1058}
1059
1060//=======================================================================
1061//function : FindSubShape
1062//purpose :
1063//=======================================================================
1064
1065Standard_Boolean XCAFDoc_ShapeTool::FindSubShape (const TDF_Label &shapeL,
1066 const TopoDS_Shape &sub,
1067 TDF_Label &L) const
1068{
1069 // this code is used instead of the following for performance reasons
1070 if ( TNaming_Tool::HasLabel(Label(), sub) ) {
1071 int TransDef = 0;
1072 L = TNaming_Tool::Label(Label(), sub, TransDef);
1073 return ( ! L.IsNull() && L.Father() == shapeL );
1074 }
1075
1076/*
1077 TDF_ChildIterator chldLabIt(shapeL);
1078 for (; chldLabIt.More(); chldLabIt.Next() ) {
1079 TDF_Label subLabel = chldLabIt.Value();
1080 TopoDS_Shape S;
1081 if ( GetShape ( subLabel, S ) && S.IsSame ( sub ) ) {
1082 L = subLabel;
1083 return Standard_True;
1084 }
1085 }
1086*/
1087 return Standard_False;
1088}
1089
1090//=======================================================================
1091//function : AddSubShape
1092//purpose :
1093//=======================================================================
1094
1095TDF_Label XCAFDoc_ShapeTool::AddSubShape (const TDF_Label &shapeL,
1096 const TopoDS_Shape &sub) const
1097{
1098 TDF_Label L;
1099 if ( FindSubShape ( shapeL, sub, L ) ) return L;
1100
1101 if ( ! IsSubShape ( shapeL, sub ) ) return L;
1102
1103 TDF_TagSource aTag;
1104 L = aTag.NewChild(shapeL);
1105
1106 TNaming_Builder tnBuild(L);
1107 tnBuild.Generated(sub);
1108
1109// if(!mySubShapes.IsBound(sub))
1110// mySubShapes.Bind(sub,L);
1111
1112 return L;
1113}
1114
1115
1116//=======================================================================
1117//function : FindMainShapeUsingMap
1118//purpose :
1119//=======================================================================
1120
1121TDF_Label XCAFDoc_ShapeTool::FindMainShapeUsingMap(const TopoDS_Shape &sub) const
1122{
1123 //for(Standard_Integer i=1; i<=myNotAssemblies.Length(); i++) {
1124 // TDF_Label L = myNotAssemblies.Value(i);
1125 // if(IsSubShape(L,sub)) return L;
1126 //}
1127 if(mySubShapes.IsBound(sub))
1128 return mySubShapes.Find(sub);
1129 TDF_Label L0;
1130 return L0;
1131}
1132
1133
1134//=======================================================================
1135//function : FindMainShape
1136//purpose :
1137//=======================================================================
1138
1139TDF_Label XCAFDoc_ShapeTool::FindMainShape (const TopoDS_Shape &sub) const
1140{
1141 TDF_ChildIterator it(Label());
1142 for (; it.More(); it.Next()) {
1143 TDF_Label L = it.Value();
1144 if ( ! IsAssembly ( L ) && IsSubShape ( L, sub ) ) return L;
1145 }
1146 TDF_Label L0;
1147 return L0;
1148}
1149
1150
1151//=======================================================================
1152//function : GetSubShapes
1153//purpose :
1154//=======================================================================
1155
1156Standard_Boolean XCAFDoc_ShapeTool::GetSubShapes (const TDF_Label &L,
1157 TDF_LabelSequence& Labels)
1158{
1159 TDF_ChildIterator It(L);
1160 for (; It.More(); It.Next() ) {
1161 TDF_Label sub = It.Value();
1162 if ( IsSubShape ( sub ) ) Labels.Append ( sub );
1163 }
1164 return Labels.Length() >0;
1165}
1166
1167//=======================================================================
1168//function : BaseLabel
1169//purpose :
1170//=======================================================================
1171
1172TDF_Label XCAFDoc_ShapeTool::BaseLabel () const
1173{
1174 return Label();
1175}
1176
1177//=======================================================================
1178//function : DumpAssembly
1179//purpose : recursive part of Dump()
1180//=======================================================================
1181
1182static void DumpAssembly(const TDF_Label L,
1183 const Standard_Integer level,
1184 const Standard_Boolean deep)
1185{
1186 for (Standard_Integer i=0; i<level; i++)
1187 cout<<"\t";
1188
1189 TCollection_AsciiString Entry;
1190 TDF_Tool::Entry(L, Entry);
1191
1192 cout<<"ASSEMBLY "<<Entry;
1193 Handle(TDataStd_Name) Name;
1194 if (L.FindAttribute(TDataStd_Name::GetID(), Name))
1195 cout<<" "<<Name->Get();
1196
1197 if (deep) {
1198 TopoDS_Shape S;
1199 XCAFDoc_ShapeTool::GetShape(L, S);
1200 cout<<"("<<*(void**)&S.TShape();
1201 if (! S.Location().IsIdentity())
1202 cout<<", "<< *(void**)&S.Location();
1203 cout<<") ";
1204 }
1205 cout<<endl;
1206
1207 Handle(TDataStd_TreeNode) Node;
1208 TDF_ChildIDIterator NodeIterator(L, XCAFDoc::ShapeRefGUID());
1209 for (; NodeIterator.More(); NodeIterator.Next()) {
1210 Node = Handle(TDataStd_TreeNode)::DownCast(NodeIterator.Value());
1211 if (Node->HasFather()) {
1212 if (Node->Father()->Label().HasChild())
1213 DumpAssembly(Node->Father()->Label(), level+1, deep);
1214 else {
1215 XCAFDoc_ShapeTool::DumpShape(Node->Father()->Label(), level+1, deep);
1216 cout<<endl;
1217 }
1218 }
1219 }
1220}
1221
1222//=======================================================================
1223//function : Dump
1224//purpose :
1225//=======================================================================
1226
1227void XCAFDoc_ShapeTool::Dump(const Standard_Boolean deep) const
1228{
1229 Standard_Integer level = 0;
1230// TopTools_SequenceOfShape SeqShapes;
1231 TDF_LabelSequence SeqLabels;
1232 GetShapes( SeqLabels);
1233
1234 if (SeqLabels.Length()>0) cout<<endl;
1235 Standard_Integer i;
1236 for (i=1; i<=SeqLabels.Length(); i++) {
1237 DumpAssembly(SeqLabels.Value(i), level, deep);
1238 }
1239
1240 SeqLabels.Clear();
1241 GetFreeShapes(SeqLabels);
1242 cout<<endl<<"Free Shapes: "<<SeqLabels.Length()<<endl;
1243 for (i = 1; i<=SeqLabels.Length(); i++) {
1244 DumpShape(SeqLabels.Value(i), level, deep);
1245 cout<<endl;
1246 }
1247}
1248
1249//=======================================================================
1250//function : DumpShape
1251//purpose :
1252//=======================================================================
1253
1254void XCAFDoc_ShapeTool::DumpShape(const TDF_Label& L,const Standard_Integer level,const Standard_Boolean deep)
1255{
1256 TopoDS_Shape S;
1257 if(! XCAFDoc_ShapeTool::GetShape(L, S) ) return;
1258 for (Standard_Integer i=0; i<level; i++)
1259 cout<<"\t";
1260
1261 if (S.ShapeType() == TopAbs_COMPOUND) cout<<"ASSEMBLY";
1262 else TopAbs::Print(S.ShapeType(), cout);
1263
1264 TCollection_AsciiString Entry;
1265 TDF_Tool::Entry(L, Entry);
1266 cout<<" "<<Entry;
1267 //cout<<endl;
1268 Handle(TDataStd_Name) Name;
1269 if (L.FindAttribute(TDataStd_Name::GetID(),Name))
1270 cout<<" "<<Name->Get();
1271
1272 if (deep) {
1273 cout<<"("<<*(void**)&S.TShape();
1274 if (! S.Location().IsIdentity())
1275 cout<<", "<< *(void**)&S.Location();
1276 cout<<") ";
1277 }
1278}
1279
1280//=======================================================================
1281//function : IsExternRef
1282//purpose :
1283//=======================================================================
1284
1285Standard_Boolean XCAFDoc_ShapeTool::IsExternRef(const TDF_Label& L)
1286{
1287 Handle(TDataStd_UAttribute) Uattr;
1288 return L.FindAttribute(XCAFDoc::ExternRefGUID(), Uattr);
1289}
1290
1291//=======================================================================
1292//function : SetExternRefs
1293//purpose :
1294//=======================================================================
1295
1296void XCAFDoc_ShapeTool::SetExternRefs(const TDF_Label& L,
1297 const TColStd_SequenceOfHAsciiString& SHAS) const
1298{
1299 TDF_Label ShapeLabel = L.NewChild();
1300 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1301 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1302 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1303 Handle(TCollection_HAsciiString) str = SHAS(i);
1304 TCollection_ExtendedString extstr(str->String());
1305 TDataStd_Name::Set(tmplbl,extstr);
1306 }
1307}
1308
1309//=======================================================================
1310//function : SetExternRefs
1311//purpose :
1312//=======================================================================
1313
1314TDF_Label XCAFDoc_ShapeTool::SetExternRefs(const TColStd_SequenceOfHAsciiString& SHAS) const
1315{
1316 TDF_Label ShapeLabel;
1317 TDF_TagSource aTag;
1318 // add a new label
1319 ShapeLabel = aTag.NewChild(Label());
1320 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1321 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1322 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1323 Handle(TCollection_HAsciiString) str = SHAS(i);
1324 TCollection_ExtendedString extstr(str->String());
1325 TDataStd_Name::Set(tmplbl,extstr);
1326 }
1327 return ShapeLabel;
1328}
1329
1330//=======================================================================
1331//function : GetExternRefs
1332//purpose :
1333//=======================================================================
1334
1335void XCAFDoc_ShapeTool::GetExternRefs(const TDF_Label& L,
1336 TColStd_SequenceOfHAsciiString& SHAS)
1337{
1338 Handle(TDataStd_Name) TDN;
1339 TDF_Label tmplbl;
1340 for(Standard_Integer i=1; i<=L.NbChildren(); i++) {
1341 tmplbl = L.FindChild(i);
1342 if(tmplbl.FindAttribute(TDataStd_Name::GetID(),TDN)) {
1343 TCollection_ExtendedString extstr = TDN->Get();
1344 Handle(TCollection_HAsciiString) str =
1345 new TCollection_HAsciiString(TCollection_AsciiString(extstr, '?'));
1346 SHAS.Append(str);
1347 }
1348 }
1349}
1350
1351// API: API work with SHUO (Specified Higher Usage Occurrance) structure
1352
1353//=======================================================================
1354//function : GetSHUO
1355//purpose :
1356//=======================================================================
1357
1358Standard_Boolean XCAFDoc_ShapeTool::GetSHUO (const TDF_Label& SHUOLabel,
1359 Handle(XCAFDoc_GraphNode)& aSHUOAttr)
1360{
1361 if ( !SHUOLabel.FindAttribute( XCAFDoc::SHUORefGUID(), aSHUOAttr ) )
1362 return Standard_False;
1363 return Standard_True;
1364}
1365
1366//=======================================================================
1367//function : GetAllComponentSHUO
1368//purpose :
1369//=======================================================================
1370
1371Standard_Boolean XCAFDoc_ShapeTool::GetAllComponentSHUO (const TDF_Label& theCompLabel,
1372 TDF_AttributeSequence& theSHUOAttrs)
1373{
1374 TDF_ChildIterator it(theCompLabel);
1375 for (; it.More(); it.Next()) {
1376 TDF_Label L = it.Value();
1377 Handle(XCAFDoc_GraphNode) aSHUOAttr;
1378 if ( GetSHUO( L, aSHUOAttr ) )
1379 theSHUOAttrs.Append( aSHUOAttr );
1380 }
1381 return (theSHUOAttrs.Length() > 0);
1382}
1383
1384//=======================================================================
1385//function : SetSHUO
1386//purpose :
1387//=======================================================================
1388
1389Standard_Boolean XCAFDoc_ShapeTool::SetSHUO (const TDF_LabelSequence& labels,
1390 Handle(XCAFDoc_GraphNode)& MainSHUOAttr) const
1391{
1392 MainSHUOAttr.Nullify();
1393 // check number of labels
1394 if (labels.Length() < 2)
1395 return Standard_False;
1396 // check is all labels contains components of any assemblyies
1397 Standard_Integer i;
1398 for (i = 1; i <= labels.Length(); i++)
1399 if ( !IsComponent(labels.Value(i)) )
1400 return Standard_False;
1401
1402 TDF_TagSource aTag;
1403 TDF_Label UpperSubL = aTag.NewChild( labels( 1 ) );
e6aad0ee
RL
1404 if (theAutoNaming) {
1405 TCollection_ExtendedString Entry("SHUO");
1406 TDataStd_Name::Set(UpperSubL, TCollection_ExtendedString( Entry ));
1407 }
7fd59977 1408 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1409 aUpperSHUO = XCAFDoc_GraphNode::Set( UpperSubL, XCAFDoc::SHUORefGUID() );
1410 // init out argument by main upper usage SHUO
1411 MainSHUOAttr = aUpperSHUO;
1412 // add other next_usage occurrences.
1413 for (i = 2; i <= labels.Length(); i++) {
1414 TDF_Label NextSubL = aTag.NewChild( labels( i ) );
e6aad0ee
RL
1415 if (theAutoNaming) {
1416 TCollection_ExtendedString EntrySub("SHUO-");
1417 EntrySub += i;
1418 TDataStd_Name::Set(NextSubL, TCollection_ExtendedString( EntrySub ));
1419 }
7fd59977 1420 Handle(XCAFDoc_GraphNode) aNextSHUO;
1421 aNextSHUO = XCAFDoc_GraphNode::Set( NextSubL, XCAFDoc::SHUORefGUID() );
1422 // set references
1423 aUpperSHUO->SetChild( aNextSHUO );
1424 aNextSHUO->SetFather( aUpperSHUO );
1425 // now lets next_usage become upper_usage for next level of SHUO
1426 aUpperSHUO = aNextSHUO;
1427 UpperSubL = NextSubL;
1428 }
1429
1430 return Standard_True;
1431}
1432
1433//=======================================================================
1434//function : GetSHUOUpperUsage
1435//purpose :
1436//=======================================================================
1437
1438Standard_Boolean XCAFDoc_ShapeTool::GetSHUOUpperUsage (const TDF_Label& NextUsageL,
1439 TDF_LabelSequence& aLabels)
1440{
1441 Handle(XCAFDoc_GraphNode) aNextSHUO;
1442 if( !GetSHUO( NextUsageL, aNextSHUO ) || aNextSHUO->NbFathers()<1 )
1443 return Standard_False;
1444
1445 // get upper_usage SHAO
1446 for (Standard_Integer i = 1; i <= aNextSHUO->NbFathers(); i++)
1447 aLabels.Append( aNextSHUO->GetFather(i)->Label() );
1448 return Standard_True;
1449}
1450
1451//=======================================================================
1452//function : GetSHUONextUsage
1453//purpose :
1454//=======================================================================
1455
1456Standard_Boolean XCAFDoc_ShapeTool::GetSHUONextUsage (const TDF_Label& UpperUsageL,
1457 TDF_LabelSequence& aLabels)
1458{
1459 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1460 if ( !GetSHUO( UpperUsageL, aUpperSHUO ) || aUpperSHUO->NbChildren()<1 )
1461 return Standard_False;
1462 // get upper_usage SHAO
1463 for (Standard_Integer i = 1; i <= aUpperSHUO->NbChildren(); i++)
1464 aLabels.Append( aUpperSHUO->GetChild(i)->Label() );
1465 return Standard_True;
1466}
1467
1468//=======================================================================
1469//function : RemoveSHUO
1470//purpose :
1471//=======================================================================
1472
1473Standard_Boolean XCAFDoc_ShapeTool::RemoveSHUO (const TDF_Label& L) const
1474{
1475 L.ForgetAllAttributes (Standard_True);
1476 return Standard_True;
1477}
1478
1479//=======================================================================
1480//function : checkForShape
1481//purpose : auxilary
1482//=======================================================================
1483
1484static Standard_Boolean checkForShape (const TopoDS_Shape& theShape,
1485 const TopoDS_Shape& theCurSh,
1486 const TDF_Label& theUserL,
1487 TDF_LabelSequence& theLabels)
1488{
1489 // the label of an assembly which contains this component
1490 TDF_Label aSuperUserL = theUserL.Father();
1491 TopLoc_Location aSupLoc, aCompLoc;
1492 aSupLoc = ::XCAFDoc_ShapeTool::GetLocation ( aSuperUserL );
1493 aCompLoc = ::XCAFDoc_ShapeTool::GetLocation ( theUserL );
1494 TopoDS_Shape aCopySh = theCurSh;
1495 aCompLoc = aCompLoc.Multiplied( theCurSh.Location() );
1496 aSupLoc = aSupLoc.Multiplied( aCompLoc );
1497 aCopySh.Location( aSupLoc );
1498 if ( aCopySh.IsSame( theShape ) ) {
1499 theLabels.Prepend( theUserL );
1500 return Standard_True;
1501 }
1502 // try to search deeply (upper by assmebly structure)
1503 TDF_LabelSequence aNewLabels;
1504 for (Standard_Integer j = 1; j <= theLabels.Length(); j++)
1505 aNewLabels.Append( theLabels.Value( j ) );
1506 aNewLabels.Prepend( theUserL );
1507 TDF_LabelSequence aUsers;
1508 ::XCAFDoc_ShapeTool::GetUsers( aSuperUserL, aUsers );
1509 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1510 if ( checkForShape( theShape, aCopySh, aUsers.Value( i ), aNewLabels ) ) {
1511 // get solution
1512 theLabels = aNewLabels;
1513 return Standard_True;
1514 }
1515 return Standard_False;
1516}
1517
1518//=======================================================================
1519//function : FindComponent
1520//purpose :
1521//=======================================================================
1522
1523Standard_Boolean XCAFDoc_ShapeTool::FindComponent (const TopoDS_Shape& theShape,
1524 TDF_LabelSequence& theLabels) const
1525{
1526 theLabels.Clear();
1527 // search for a top-level shape that corresponds to this component
1528 TopoDS_Shape S0 = theShape;
1529 TopLoc_Location loc;
1530 S0.Location ( loc );
1531 TDF_Label aRefL = FindShape( S0 );
1532 if (aRefL.IsNull())
1533 return Standard_False; // cannot find top-level shape.
1534
1535 TDF_LabelSequence aUsers;
1536 ::XCAFDoc_ShapeTool::GetUsers( aRefL, aUsers );
1537 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1538 if ( checkForShape( theShape, S0, aUsers.Value( i ), theLabels ) )
1539 break;
1540
1541 return (theLabels.Length() > 0);
1542}
1543
1544//=======================================================================
1545//function : getShapesOfSHUO
1546//purpose : auxilary
1547//=======================================================================
1548
1549static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLocMap,
1550 const Handle(XCAFDoc_ShapeTool)& theSTool,
1551 const TDF_Label& theSHUOlab,
1552 TopoDS_Shape& theShape)
1553{
1554 Handle(XCAFDoc_GraphNode) SHUO;
1555 TDF_LabelSequence aLabSeq;
1556 theSTool->GetSHUONextUsage( theSHUOlab, aLabSeq );
1557 if (aLabSeq.Length() >= 1)
1558 for (Standard_Integer i = 1; i <= aLabSeq.Length(); i++) {
1559 TDF_Label aSubCompL = aLabSeq.Value( i );
1560 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSubCompL.Father() );
1561 // create new map of laocation (to not merge locations from different shapes)
1562 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1563 for (Standard_Integer m = 1; m <= theaPrevLocMap.Extent(); m++)
1564 aNewPrevLocMap.Add( theaPrevLocMap.FindKey( m ) );
1565 aNewPrevLocMap.Add( compLoc );
1566 // got for the new sublocations and corresponding shape
1567 getShapesOfSHUO( aNewPrevLocMap, theSTool, aSubCompL, theShape );
1568 }
1569 else {
1570 TopoDS_Shape aSHUO_NUSh = theSTool->GetShape ( theSHUOlab.Father() );
1571 if ( aSHUO_NUSh.IsNull() ) return Standard_False;
1572 // cause got shape with location already.
1573 TopLoc_Location nullLoc;
1574 aSHUO_NUSh.Location ( nullLoc );
1575 // multiply the locations
1576 Standard_Integer intMapLenght = theaPrevLocMap.Extent();
1577 if ( intMapLenght < 1 )
1578 return Standard_False; // should not be, but to avoid exception...?
1579 TopLoc_Location SupcompLoc;
1580 SupcompLoc = theaPrevLocMap.FindKey( intMapLenght );
1581 if (intMapLenght > 1) {
1582 Standard_Integer l = intMapLenght - 1;
1583 while (l >= 1) {
1584 SupcompLoc = theaPrevLocMap.FindKey( l ).Multiplied( SupcompLoc );
1585 l--;
1586 }
1587 }
1588 aSHUO_NUSh.Location( SupcompLoc );
1589 theShape = aSHUO_NUSh;
1590 }
1591 return (!theShape.IsNull());
1592}
1593
1594//=======================================================================
1595//function : GetSHUOInstance
1596//purpose :
1597//=======================================================================
1598
1599TopoDS_Shape XCAFDoc_ShapeTool::GetSHUOInstance (const Handle(XCAFDoc_GraphNode)& theSHUO) const
1600{
1601 TopoDS_Shape aShape;
1602 if (theSHUO.IsNull())
1603 return aShape;
1604
1605 TDF_Label aSHUOlab = theSHUO->Label();
1606 // get location of the assembly
1607 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1608 // get location of the component
1609 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1610 TopLoc_IndexedMapOfLocation aPrevLocMap;
1611 // get previous setted location
1612 if ( !loc.IsIdentity() )
1613 aPrevLocMap.Add( loc );
1614 aPrevLocMap.Add( compLoc );
1615 // get shape by recurse method
1616 const Handle(XCAFDoc_ShapeTool)& STool = this;
1617 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1618
1619 return aShape;
1620}
1621
1622//=======================================================================
1623//function : getUsersShapesOfSHUO
1624//purpose : auxilary
1625//=======================================================================
1626
1627static Standard_Boolean getUsersShapesOfSHUO (TopLoc_IndexedMapOfLocation& aPrevLocMap,
1628 const Handle(XCAFDoc_ShapeTool)& STool,
1629 const TDF_Label& aSHUOlab,
1630 const TDF_Label& theUserL,
1631 TopTools_SequenceOfShape& theSHUOShapeSeq)
1632{
1633 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1634 // get location of the assembly
1635 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( theUserL.Father() );
1636 // get location of the component
1637 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( theUserL );
1638 // get previous setted location
1639 aNewPrevLocMap.Add( loc );
1640 aNewPrevLocMap.Add( compLoc );
1641 Standard_Integer i;
1642 for (i = 1; i <= aPrevLocMap.Extent(); i++)
1643 aNewPrevLocMap.Add( aPrevLocMap.FindKey(i) );
1644 TDF_Label L = theUserL.Father();
1645 TDF_LabelSequence usersLab;
1646 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1647 if (usersLab.Length() == 0) {
1648 TopoDS_Shape aShape;
1649 getShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aShape );
1650 if (!aShape.IsNull()) {
1651 theSHUOShapeSeq.Append(aShape);
1652 return Standard_True;
1653 }
1654 }
1655 // now iterates on users of this assembly as component
1656 for ( i = 1; i <= usersLab.Length(); i++ ) {
1657 TDF_Label aNewUserL = usersLab.Value(i);
1658 getUsersShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aNewUserL, theSHUOShapeSeq );
1659 }
1660
1661 return (theSHUOShapeSeq.Length() > 1);
1662}
1663
1664//=======================================================================
1665//function : GetAllSHUOInstances
1666//purpose : auxilary
1667//=======================================================================
1668
1669Standard_Boolean XCAFDoc_ShapeTool::GetAllSHUOInstances (const Handle(XCAFDoc_GraphNode)& theSHUO,
1670 TopTools_SequenceOfShape& theSHUOShapeSeq) const
1671{
1672 if (theSHUO.IsNull())
1673 return Standard_False;
1674
1675 TDF_Label aSHUOlab = theSHUO->Label();
1676 TopLoc_IndexedMapOfLocation aPrevLocMap;
1677 // get location of the assembly
1678 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1679 // get location of the component
1680 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1681 // get previous setted location
1682 if ( !loc.IsIdentity() )
1683 aPrevLocMap.Add( loc );
1684 aPrevLocMap.Add( compLoc );
1685 // get label of assembly
1686 TDF_Label L = aSHUOlab.Father().Father();
1687 TDF_LabelSequence usersLab;
1688 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1689 TopoDS_Shape aShape;
1690 const Handle(XCAFDoc_ShapeTool)& STool = this;
1691 if (usersLab.Length() == 0) {
1692 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1693 if (!aShape.IsNull()) {
1694 theSHUOShapeSeq.Append(aShape);
1695 return Standard_True;
1696 }
1697 }
1698 // now iterates on users of this assembly as component
1699 for (Standard_Integer i = 1; i <= usersLab.Length(); i++) {
1700 TDF_Label aUserL = usersLab.Value(i);
1701 getUsersShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aUserL, theSHUOShapeSeq );
1702 }
1703
1704 return (theSHUOShapeSeq.Length() > 1);
1705}
1706
1707//=======================================================================
1708//function : SetInstanceSHUO
1709//purpose :
1710//=======================================================================
1711
1712Handle(XCAFDoc_GraphNode) XCAFDoc_ShapeTool::SetInstanceSHUO (const TopoDS_Shape& theShape) const
1713{
1714 Handle(XCAFDoc_GraphNode) SHUO;
1715 TDF_LabelSequence aLabels;
1716 if ( FindComponent( theShape, aLabels ) )
1717 // set shuo structure on labels of component-assembly structure
1718 SetSHUO( aLabels, SHUO );
1719 return SHUO;
1720}
1721
1722//=======================================================================
1723//function : FindSHUO
1724//purpose :
1725//=======================================================================
1726
1727Standard_Boolean XCAFDoc_ShapeTool::FindSHUO (const TDF_LabelSequence& theLabels,
1728 Handle(XCAFDoc_GraphNode)& theSHUOAttr)
1729{
1730 TDF_AttributeSequence SHUOAttrs;
1731 TDF_Label aCompLabel = theLabels.Value(1);
1732 if (! ::XCAFDoc_ShapeTool::GetAllComponentSHUO( aCompLabel, SHUOAttrs ) )
1733 return Standard_False;
1734 // WARNING: manage that each SHUO upper_usage have only one SHUO next_usage
1735 for (Standard_Integer i = 1; i <= SHUOAttrs.Length(); i++) {
1736 TDF_LabelSequence aCondidate;
1737 Handle(XCAFDoc_GraphNode) anSHUO = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1738 aCondidate.Append( anSHUO->Label().Father() );
1739 while (anSHUO->NbChildren()) {
1740 anSHUO = anSHUO->GetChild( 1 );
1741 aCondidate.Append( anSHUO->Label().Father() );
1742 }
1743 // check the label sequences
1744 Standard_Boolean isEqual = Standard_True;
1745 if (theLabels.Length() != aCondidate.Length())
1746 isEqual = Standard_False;
1747 else
1748 for (Standard_Integer li = 1; li <= theLabels.Length(); li++)
1749 if ( theLabels.Value(li) != aCondidate.Value(li) ) {
1750 isEqual = Standard_False;
1751 break;
1752 }
1753 if (!isEqual)
1754 continue;
1755
1756 theSHUOAttr = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1757 break;
1758 }
1759 return ( !theSHUOAttr.IsNull() );
1760}