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