Correction of compilation error
[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
610Standard_Boolean XCAFDoc_ShapeTool::RemoveShape (const TDF_Label& L) const
611{
612 if ( ! IsTopLevel ( L ) || ! IsFree ( L ) ) return Standard_False;
613 L.ForgetAllAttributes (Standard_True);
614 return Standard_True;
615}
616
617
618//=======================================================================
619//function : Init
620//purpose :
621//=======================================================================
622
623void XCAFDoc_ShapeTool::Init()
624{
625 hasSimpleShapes = Standard_False;
626}
627
628
629//=======================================================================
630//function : ComputeShapes
631//purpose :
632//=======================================================================
633
634void XCAFDoc_ShapeTool::ComputeShapes(const TDF_Label& L)
635{
636 TDF_ChildIterator it(L);
637 for(; it.More(); it.Next()) {
638 TDF_Label L1 = it.Value();
639 TopoDS_Shape S;
640 if(GetShape(L1,S)) {
641 if(!myShapeLabels.IsBound(S)) {
642 mySimpleShapes.Bind(S,L1);
643 }
644 }
645 ComputeShapes(L1);
646 }
647}
648
649
650//=======================================================================
651//function : ComputeSimpleShapes
652//purpose :
653//=======================================================================
654
655void XCAFDoc_ShapeTool::ComputeSimpleShapes()
656{
657 ComputeShapes(Label());
658 hasSimpleShapes = Standard_True;
659}
660
661
662//=======================================================================
663//function : GetShapes
664//purpose :
665//=======================================================================
666
667void XCAFDoc_ShapeTool::GetShapes(TDF_LabelSequence& Labels) const
668{
669 Labels.Clear();
670
671 TDF_ChildIterator it(Label());
672 for (; it.More(); it.Next()) {
673 TDF_Label L = it.Value();
674 TopoDS_Shape S;
675 if ( GetShape ( L, S ) ) Labels.Append ( L );
676 }
677}
678
679
680//=======================================================================
681//function : GetFreeShapes
682//purpose :
683//=======================================================================
684
685void XCAFDoc_ShapeTool::GetFreeShapes (TDF_LabelSequence& FreeLabels) const
686{
687 FreeLabels.Clear();
688
689 TDF_ChildIterator it(Label());
690 for (; it.More(); it.Next()) {
691 TDF_Label L = it.Value();
692 TopoDS_Shape S;
693 if ( GetShape ( L, S ) && IsFree ( L ) ) FreeLabels.Append ( L );
694 }
695}
696
697//=======================================================================
698//function : IsTopLevel
699//purpose :
700//=======================================================================
701
702Standard_Boolean XCAFDoc_ShapeTool::IsTopLevel (const TDF_Label& L) const
703{
704 return L.Father() == Label();
705}
706
707//=======================================================================
708//function : IsShape
709//purpose :
710//=======================================================================
711
712Standard_Boolean XCAFDoc_ShapeTool::IsShape (const TDF_Label& L)
713{
714 return IsSimpleShape ( L ) || IsAssembly ( L ) || IsReference ( L );
715}
716
717//=======================================================================
718//function : IsSimpleShape
719//purpose :
720//=======================================================================
721
722Standard_Boolean XCAFDoc_ShapeTool::IsSimpleShape (const TDF_Label& L)
723{
724 Handle(TNaming_NamedShape) NS;
725 return L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) &&
726 ! IsAssembly ( L ) && ! IsReference ( L );
727}
728
729//=======================================================================
730//function : IsReference
731//purpose :
732//=======================================================================
733
734Standard_Boolean XCAFDoc_ShapeTool::IsReference (const TDF_Label& L)
735{
736 Handle(TDataStd_TreeNode) Node;
737 return L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) && Node->HasFather();
738}
739
740//=======================================================================
741//function : IsAssembly
742//purpose :
743//=======================================================================
744
745Standard_Boolean XCAFDoc_ShapeTool::IsAssembly (const TDF_Label& L)
746{
747 Handle(TDataStd_UAttribute) Uattr;
748 return L.FindAttribute(XCAFDoc::AssemblyGUID(), Uattr);
749}
750
751//=======================================================================
752//function : IsComponent
753//purpose :
754//=======================================================================
755
756Standard_Boolean XCAFDoc_ShapeTool::IsComponent (const TDF_Label& L)
757{
758 return IsReference ( L ) && IsAssembly ( L.Father() );
759}
760
761//=======================================================================
762//function : IsCompound
763//purpose :
764//=======================================================================
765
766Standard_Boolean XCAFDoc_ShapeTool::IsCompound (const TDF_Label& L)
767{
768 Handle(TDataStd_Name) Name;
769 if (L.FindAttribute(TDataStd_Name::GetID(),Name)) {
770 TCollection_ExtendedString estr1 = Name->Get();
771 TCollection_ExtendedString estr2("COMPOUND");
772 if(estr1==estr2) {
773 return Standard_True;
774 }
775 }
776 return Standard_False;
777}
778
779//=======================================================================
780//function : IsSubShape
781//purpose :
782//=======================================================================
783
784Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label& L)
785{
786 return IsSimpleShape ( L ) && IsShape ( L.Father() );
787}
788
789//=======================================================================
790//function : IsFree
791//purpose :
792//=======================================================================
793
794Standard_Boolean XCAFDoc_ShapeTool::IsFree (const TDF_Label& L)
795{
796 Handle(TDataStd_TreeNode) Node;
797 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ||
798 ! Node->HasFirst() ) return Standard_True;
799
800 return Standard_False;
801}
802
803//=======================================================================
804//function : GetUsers
805//purpose : Returns number of users (0 if shape is free)
806//=======================================================================
807
808Standard_Integer XCAFDoc_ShapeTool::GetUsers (const TDF_Label& L,
809 TDF_LabelSequence& Labels,
810 const Standard_Boolean getsubchilds)
811{
812 Standard_Integer NbUsers=0;
813 Handle(TDataStd_TreeNode) Node ;
814
815 if ( ! L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node) ) return NbUsers;
816
817 Node = Node->First();
818 while ( ! Node.IsNull() ) {
819
820 if ( getsubchilds ) {
821 TDF_Label underL = Node->Label().Father();
822 NbUsers += GetUsers ( underL, Labels, getsubchilds );
823 }
824
825 Labels.Append(Node->Label());
826 Node = Node->Next();
827 NbUsers++;
828 }
829 return NbUsers;
830}
831
832//=======================================================================
833//function : NbComponents
834//purpose :
835//=======================================================================
836
837Standard_Integer XCAFDoc_ShapeTool::NbComponents (const TDF_Label& L,
838 const Standard_Boolean getsubchilds)
839{
840 TDF_LabelSequence subLabels;
841 GetComponents (L, subLabels, getsubchilds);
842 return subLabels.Length();
843}
844
845//=======================================================================
846//function : GetComponents
847//purpose :
848//=======================================================================
849
850Standard_Boolean XCAFDoc_ShapeTool::GetComponents (const TDF_Label& L, TDF_LabelSequence& Labels,
851 const Standard_Boolean getsubchilds)
852{
853 if ( ! IsAssembly(L) ) return Standard_False;
854
855 TDF_ChildIterator It(L);
856 for (; It.More(); It.Next() ) {
857 TDF_Label comp = It.Value();
858 if ( IsComponent ( comp ) ) {
859 if ( getsubchilds ) {
860 TDF_Label underL;
861 if ( GetReferredShape ( comp, underL ) )
862 GetComponents ( underL, Labels, getsubchilds);
863 }
864 Labels.Append ( comp );
865 }
866 }
867 return Standard_True;
868}
869
870//=======================================================================
871//function : GetLocation
872//purpose :
873//=======================================================================
874
875TopLoc_Location XCAFDoc_ShapeTool::GetLocation (const TDF_Label& L)
876{
877 Handle(XCAFDoc_Location) LocationAttribute;
878 if (L.FindAttribute(XCAFDoc_Location::GetID(), LocationAttribute))
879 return LocationAttribute->Get();
880
881 Handle(TNaming_NamedShape) NS;
882 TopoDS_Shape S;
883 if ( L.FindAttribute ( TNaming_NamedShape::GetID(), NS ) ) {
884 S = TNaming_Tool::GetShape(NS);
885 }
886 return S.Location();
887}
888
889//=======================================================================
890//function : GetReferredShape
891//purpose :
892//=======================================================================
893
894Standard_Boolean XCAFDoc_ShapeTool::GetReferredShape (const TDF_Label& L,
895 TDF_Label& Label)
896{
897 if ( ! IsReference(L) ) return Standard_False;
898
899 Handle (TDataStd_TreeNode) Node;
900 L.FindAttribute(XCAFDoc::ShapeRefGUID(), Node);
901 Label = Node->Father()->Label();
902 return Standard_True;
903}
904
905//=======================================================================
906//function : AddComponent
907//purpose :
908//=======================================================================
909
910TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
911 const TDF_Label& compL,
912 const TopLoc_Location &Loc) const
913{
914 TDF_Label L;
915
916 // check that shape is assembly
917 if ( ! IsAssembly(assembly) ) {
918 // if it is simple shape, make it assembly
919 if ( IsSimpleShape(assembly) )
920 TDataStd_UAttribute::Set ( assembly, XCAFDoc::AssemblyGUID() );
921 else return L;
922 }
923
924 // add a component as reference
925 TDF_TagSource aTag;
926 L = aTag.NewChild(assembly);
927 MakeReference ( L, compL, Loc );
928
929 // update assembly`s TopoDS_Shape
930 UpdateAssembly ( assembly );
931 return L;
932}
933
934//=======================================================================
935//function : AddComponent
936//purpose :
937//=======================================================================
938
939TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
940 const TopoDS_Shape& comp,
941 const Standard_Boolean expand)
942{
943 // get label for component`s shape
944 TopoDS_Shape S0 = comp;
945 TopLoc_Location loc;
946 S0.Location ( loc );
947 TDF_Label compL;
948 compL = AddShape ( S0, expand );
949
950 // add component by its label
951 return AddComponent ( assembly, compL, comp.Location() );
952}
953
954//=======================================================================
955//function : RemoveComponent
956//purpose :
957//=======================================================================
958
959void XCAFDoc_ShapeTool::RemoveComponent (const TDF_Label& comp) const
960{
961 if ( IsComponent(comp) ) {
962 comp.ForgetAllAttributes();
963 UpdateAssembly(comp.Father());
964 }
965}
966
967//=======================================================================
968//function : UpdateAssembly
969//purpose :
970//=======================================================================
971
972void XCAFDoc_ShapeTool::UpdateAssembly (const TDF_Label& L) const
973{
974 if ( ! IsAssembly(L) ) return;
975
976 TopoDS_Compound newassembly;
977 BRep_Builder b;
978 b.MakeCompound(newassembly);
979
980 TDF_ChildIterator chldLabIt(L);
981 for (; chldLabIt.More(); chldLabIt.Next() ) {
982 TDF_Label subLabel = chldLabIt.Value();
983 if ( IsComponent ( subLabel ) ) {
984 b.Add(newassembly, GetShape(subLabel));
985 }
986 }
987 TNaming_Builder tnBuild(L);
988 tnBuild.Generated(newassembly);
989}
990
991//=======================================================================
992//function : IsSubShape
993//purpose :
994//=======================================================================
995
1d07572c
E
996//static Standard_Boolean CheckSubShape (const TopoDS_Shape &S, const TopoDS_Shape &sub)
997//{
998// if ( S.IsSame ( sub ) ) return Standard_True;
999//
1000// if ( S.ShapeType() >= sub.ShapeType() ) return Standard_False;
1001//
1002// for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
1003// if ( CheckSubShape ( it.Value(), sub ) ) return Standard_True;
1004// }
1005// return Standard_False;
1006//}
7fd59977 1007
1008//=======================================================================
1009//function : IsSubShape
1010//purpose :
1011//=======================================================================
1012
1013Standard_Boolean XCAFDoc_ShapeTool::IsSubShape (const TDF_Label &shapeL,
1014 const TopoDS_Shape &sub) const
1015{
1016 Handle(XCAFDoc_ShapeMapTool) A;
1017 if ( ! shapeL.FindAttribute(XCAFDoc_ShapeMapTool::GetID(), A) )
1018 return Standard_False;
1019
1020 //TopoDS_Shape S = GetShape ( shapeL );
1021 //return ! S.IsNull() && CheckSubShape ( S, sub );
1022
1023 return A->IsSubShape(sub);
1024}
1025
1026//=======================================================================
1027//function : FindSubShape
1028//purpose :
1029//=======================================================================
1030
1031Standard_Boolean XCAFDoc_ShapeTool::FindSubShape (const TDF_Label &shapeL,
1032 const TopoDS_Shape &sub,
1033 TDF_Label &L) const
1034{
1035 // this code is used instead of the following for performance reasons
1036 if ( TNaming_Tool::HasLabel(Label(), sub) ) {
1037 int TransDef = 0;
1038 L = TNaming_Tool::Label(Label(), sub, TransDef);
1039 return ( ! L.IsNull() && L.Father() == shapeL );
1040 }
1041
1042/*
1043 TDF_ChildIterator chldLabIt(shapeL);
1044 for (; chldLabIt.More(); chldLabIt.Next() ) {
1045 TDF_Label subLabel = chldLabIt.Value();
1046 TopoDS_Shape S;
1047 if ( GetShape ( subLabel, S ) && S.IsSame ( sub ) ) {
1048 L = subLabel;
1049 return Standard_True;
1050 }
1051 }
1052*/
1053 return Standard_False;
1054}
1055
1056//=======================================================================
1057//function : AddSubShape
1058//purpose :
1059//=======================================================================
1060
1061TDF_Label XCAFDoc_ShapeTool::AddSubShape (const TDF_Label &shapeL,
1062 const TopoDS_Shape &sub) const
1063{
1064 TDF_Label L;
1065 if ( FindSubShape ( shapeL, sub, L ) ) return L;
1066
1067 if ( ! IsSubShape ( shapeL, sub ) ) return L;
1068
1069 TDF_TagSource aTag;
1070 L = aTag.NewChild(shapeL);
1071
1072 TNaming_Builder tnBuild(L);
1073 tnBuild.Generated(sub);
1074
1075// if(!mySubShapes.IsBound(sub))
1076// mySubShapes.Bind(sub,L);
1077
1078 return L;
1079}
1080
1081
1082//=======================================================================
1083//function : FindMainShapeUsingMap
1084//purpose :
1085//=======================================================================
1086
1087TDF_Label XCAFDoc_ShapeTool::FindMainShapeUsingMap(const TopoDS_Shape &sub) const
1088{
1089 //for(Standard_Integer i=1; i<=myNotAssemblies.Length(); i++) {
1090 // TDF_Label L = myNotAssemblies.Value(i);
1091 // if(IsSubShape(L,sub)) return L;
1092 //}
1093 if(mySubShapes.IsBound(sub))
1094 return mySubShapes.Find(sub);
1095 TDF_Label L0;
1096 return L0;
1097}
1098
1099
1100//=======================================================================
1101//function : FindMainShape
1102//purpose :
1103//=======================================================================
1104
1105TDF_Label XCAFDoc_ShapeTool::FindMainShape (const TopoDS_Shape &sub) const
1106{
1107 TDF_ChildIterator it(Label());
1108 for (; it.More(); it.Next()) {
1109 TDF_Label L = it.Value();
1110 if ( ! IsAssembly ( L ) && IsSubShape ( L, sub ) ) return L;
1111 }
1112 TDF_Label L0;
1113 return L0;
1114}
1115
1116
1117//=======================================================================
1118//function : GetSubShapes
1119//purpose :
1120//=======================================================================
1121
1122Standard_Boolean XCAFDoc_ShapeTool::GetSubShapes (const TDF_Label &L,
1123 TDF_LabelSequence& Labels)
1124{
1125 TDF_ChildIterator It(L);
1126 for (; It.More(); It.Next() ) {
1127 TDF_Label sub = It.Value();
1128 if ( IsSubShape ( sub ) ) Labels.Append ( sub );
1129 }
1130 return Labels.Length() >0;
1131}
1132
1133//=======================================================================
1134//function : BaseLabel
1135//purpose :
1136//=======================================================================
1137
1138TDF_Label XCAFDoc_ShapeTool::BaseLabel () const
1139{
1140 return Label();
1141}
1142
1143//=======================================================================
1144//function : DumpAssembly
1145//purpose : recursive part of Dump()
1146//=======================================================================
1147
1148static void DumpAssembly(const TDF_Label L,
1149 const Standard_Integer level,
1150 const Standard_Boolean deep)
1151{
1152 for (Standard_Integer i=0; i<level; i++)
1153 cout<<"\t";
1154
1155 TCollection_AsciiString Entry;
1156 TDF_Tool::Entry(L, Entry);
1157
1158 cout<<"ASSEMBLY "<<Entry;
1159 Handle(TDataStd_Name) Name;
1160 if (L.FindAttribute(TDataStd_Name::GetID(), Name))
1161 cout<<" "<<Name->Get();
1162
1163 if (deep) {
1164 TopoDS_Shape S;
1165 XCAFDoc_ShapeTool::GetShape(L, S);
1166 cout<<"("<<*(void**)&S.TShape();
1167 if (! S.Location().IsIdentity())
1168 cout<<", "<< *(void**)&S.Location();
1169 cout<<") ";
1170 }
1171 cout<<endl;
1172
1173 Handle(TDataStd_TreeNode) Node;
1174 TDF_ChildIDIterator NodeIterator(L, XCAFDoc::ShapeRefGUID());
1175 for (; NodeIterator.More(); NodeIterator.Next()) {
1176 Node = Handle(TDataStd_TreeNode)::DownCast(NodeIterator.Value());
1177 if (Node->HasFather()) {
1178 if (Node->Father()->Label().HasChild())
1179 DumpAssembly(Node->Father()->Label(), level+1, deep);
1180 else {
1181 XCAFDoc_ShapeTool::DumpShape(Node->Father()->Label(), level+1, deep);
1182 cout<<endl;
1183 }
1184 }
1185 }
1186}
1187
1188//=======================================================================
1189//function : Dump
1190//purpose :
1191//=======================================================================
1192
1193void XCAFDoc_ShapeTool::Dump(const Standard_Boolean deep) const
1194{
1195 Standard_Integer level = 0;
1196// TopTools_SequenceOfShape SeqShapes;
1197 TDF_LabelSequence SeqLabels;
1198 GetShapes( SeqLabels);
1199
1200 if (SeqLabels.Length()>0) cout<<endl;
1201 Standard_Integer i;
1202 for (i=1; i<=SeqLabels.Length(); i++) {
1203 DumpAssembly(SeqLabels.Value(i), level, deep);
1204 }
1205
1206 SeqLabels.Clear();
1207 GetFreeShapes(SeqLabels);
1208 cout<<endl<<"Free Shapes: "<<SeqLabels.Length()<<endl;
1209 for (i = 1; i<=SeqLabels.Length(); i++) {
1210 DumpShape(SeqLabels.Value(i), level, deep);
1211 cout<<endl;
1212 }
1213}
1214
1215//=======================================================================
1216//function : DumpShape
1217//purpose :
1218//=======================================================================
1219
1220void XCAFDoc_ShapeTool::DumpShape(const TDF_Label& L,const Standard_Integer level,const Standard_Boolean deep)
1221{
1222 TopoDS_Shape S;
1223 if(! XCAFDoc_ShapeTool::GetShape(L, S) ) return;
1224 for (Standard_Integer i=0; i<level; i++)
1225 cout<<"\t";
1226
1227 if (S.ShapeType() == TopAbs_COMPOUND) cout<<"ASSEMBLY";
1228 else TopAbs::Print(S.ShapeType(), cout);
1229
1230 TCollection_AsciiString Entry;
1231 TDF_Tool::Entry(L, Entry);
1232 cout<<" "<<Entry;
1233 //cout<<endl;
1234 Handle(TDataStd_Name) Name;
1235 if (L.FindAttribute(TDataStd_Name::GetID(),Name))
1236 cout<<" "<<Name->Get();
1237
1238 if (deep) {
1239 cout<<"("<<*(void**)&S.TShape();
1240 if (! S.Location().IsIdentity())
1241 cout<<", "<< *(void**)&S.Location();
1242 cout<<") ";
1243 }
1244}
1245
1246//=======================================================================
1247//function : IsExternRef
1248//purpose :
1249//=======================================================================
1250
1251Standard_Boolean XCAFDoc_ShapeTool::IsExternRef(const TDF_Label& L)
1252{
1253 Handle(TDataStd_UAttribute) Uattr;
1254 return L.FindAttribute(XCAFDoc::ExternRefGUID(), Uattr);
1255}
1256
1257//=======================================================================
1258//function : SetExternRefs
1259//purpose :
1260//=======================================================================
1261
1262void XCAFDoc_ShapeTool::SetExternRefs(const TDF_Label& L,
1263 const TColStd_SequenceOfHAsciiString& SHAS) const
1264{
1265 TDF_Label ShapeLabel = L.NewChild();
1266 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1267 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1268 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1269 Handle(TCollection_HAsciiString) str = SHAS(i);
1270 TCollection_ExtendedString extstr(str->String());
1271 TDataStd_Name::Set(tmplbl,extstr);
1272 }
1273}
1274
1275//=======================================================================
1276//function : SetExternRefs
1277//purpose :
1278//=======================================================================
1279
1280TDF_Label XCAFDoc_ShapeTool::SetExternRefs(const TColStd_SequenceOfHAsciiString& SHAS) const
1281{
1282 TDF_Label ShapeLabel;
1283 TDF_TagSource aTag;
1284 // add a new label
1285 ShapeLabel = aTag.NewChild(Label());
1286 TDataStd_UAttribute::Set(ShapeLabel,XCAFDoc::ExternRefGUID());
1287 for(Standard_Integer i=1; i<=SHAS.Length(); i++) {
1288 TDF_Label tmplbl = ShapeLabel.FindChild(i,Standard_True);
1289 Handle(TCollection_HAsciiString) str = SHAS(i);
1290 TCollection_ExtendedString extstr(str->String());
1291 TDataStd_Name::Set(tmplbl,extstr);
1292 }
1293 return ShapeLabel;
1294}
1295
1296//=======================================================================
1297//function : GetExternRefs
1298//purpose :
1299//=======================================================================
1300
1301void XCAFDoc_ShapeTool::GetExternRefs(const TDF_Label& L,
1302 TColStd_SequenceOfHAsciiString& SHAS)
1303{
1304 Handle(TDataStd_Name) TDN;
1305 TDF_Label tmplbl;
1306 for(Standard_Integer i=1; i<=L.NbChildren(); i++) {
1307 tmplbl = L.FindChild(i);
1308 if(tmplbl.FindAttribute(TDataStd_Name::GetID(),TDN)) {
1309 TCollection_ExtendedString extstr = TDN->Get();
1310 Handle(TCollection_HAsciiString) str =
1311 new TCollection_HAsciiString(TCollection_AsciiString(extstr, '?'));
1312 SHAS.Append(str);
1313 }
1314 }
1315}
1316
1317// API: API work with SHUO (Specified Higher Usage Occurrance) structure
1318
1319//=======================================================================
1320//function : GetSHUO
1321//purpose :
1322//=======================================================================
1323
1324Standard_Boolean XCAFDoc_ShapeTool::GetSHUO (const TDF_Label& SHUOLabel,
1325 Handle(XCAFDoc_GraphNode)& aSHUOAttr)
1326{
1327 if ( !SHUOLabel.FindAttribute( XCAFDoc::SHUORefGUID(), aSHUOAttr ) )
1328 return Standard_False;
1329 return Standard_True;
1330}
1331
1332//=======================================================================
1333//function : GetAllComponentSHUO
1334//purpose :
1335//=======================================================================
1336
1337Standard_Boolean XCAFDoc_ShapeTool::GetAllComponentSHUO (const TDF_Label& theCompLabel,
1338 TDF_AttributeSequence& theSHUOAttrs)
1339{
1340 TDF_ChildIterator it(theCompLabel);
1341 for (; it.More(); it.Next()) {
1342 TDF_Label L = it.Value();
1343 Handle(XCAFDoc_GraphNode) aSHUOAttr;
1344 if ( GetSHUO( L, aSHUOAttr ) )
1345 theSHUOAttrs.Append( aSHUOAttr );
1346 }
1347 return (theSHUOAttrs.Length() > 0);
1348}
1349
1350//=======================================================================
1351//function : SetSHUO
1352//purpose :
1353//=======================================================================
1354
1355Standard_Boolean XCAFDoc_ShapeTool::SetSHUO (const TDF_LabelSequence& labels,
1356 Handle(XCAFDoc_GraphNode)& MainSHUOAttr) const
1357{
1358 MainSHUOAttr.Nullify();
1359 // check number of labels
1360 if (labels.Length() < 2)
1361 return Standard_False;
1362 // check is all labels contains components of any assemblyies
1363 Standard_Integer i;
1364 for (i = 1; i <= labels.Length(); i++)
1365 if ( !IsComponent(labels.Value(i)) )
1366 return Standard_False;
1367
1368 TDF_TagSource aTag;
1369 TDF_Label UpperSubL = aTag.NewChild( labels( 1 ) );
1370#ifdef AUTONAMING
1371 TCollection_ExtendedString Entry("SHUO");
1372 TDataStd_Name::Set(UpperSubL, TCollection_ExtendedString( Entry ));
1373#endif
1374 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1375 aUpperSHUO = XCAFDoc_GraphNode::Set( UpperSubL, XCAFDoc::SHUORefGUID() );
1376 // init out argument by main upper usage SHUO
1377 MainSHUOAttr = aUpperSHUO;
1378 // add other next_usage occurrences.
1379 for (i = 2; i <= labels.Length(); i++) {
1380 TDF_Label NextSubL = aTag.NewChild( labels( i ) );
1381#ifdef AUTONAMING
1382 TCollection_ExtendedString EntrySub("SHUO-");
1383 EntrySub += i;
1384 TDataStd_Name::Set(NextSubL, TCollection_ExtendedString( EntrySub ));
1385#endif
1386 Handle(XCAFDoc_GraphNode) aNextSHUO;
1387 aNextSHUO = XCAFDoc_GraphNode::Set( NextSubL, XCAFDoc::SHUORefGUID() );
1388 // set references
1389 aUpperSHUO->SetChild( aNextSHUO );
1390 aNextSHUO->SetFather( aUpperSHUO );
1391 // now lets next_usage become upper_usage for next level of SHUO
1392 aUpperSHUO = aNextSHUO;
1393 UpperSubL = NextSubL;
1394 }
1395
1396 return Standard_True;
1397}
1398
1399//=======================================================================
1400//function : GetSHUOUpperUsage
1401//purpose :
1402//=======================================================================
1403
1404Standard_Boolean XCAFDoc_ShapeTool::GetSHUOUpperUsage (const TDF_Label& NextUsageL,
1405 TDF_LabelSequence& aLabels)
1406{
1407 Handle(XCAFDoc_GraphNode) aNextSHUO;
1408 if( !GetSHUO( NextUsageL, aNextSHUO ) || aNextSHUO->NbFathers()<1 )
1409 return Standard_False;
1410
1411 // get upper_usage SHAO
1412 for (Standard_Integer i = 1; i <= aNextSHUO->NbFathers(); i++)
1413 aLabels.Append( aNextSHUO->GetFather(i)->Label() );
1414 return Standard_True;
1415}
1416
1417//=======================================================================
1418//function : GetSHUONextUsage
1419//purpose :
1420//=======================================================================
1421
1422Standard_Boolean XCAFDoc_ShapeTool::GetSHUONextUsage (const TDF_Label& UpperUsageL,
1423 TDF_LabelSequence& aLabels)
1424{
1425 Handle(XCAFDoc_GraphNode) aUpperSHUO;
1426 if ( !GetSHUO( UpperUsageL, aUpperSHUO ) || aUpperSHUO->NbChildren()<1 )
1427 return Standard_False;
1428 // get upper_usage SHAO
1429 for (Standard_Integer i = 1; i <= aUpperSHUO->NbChildren(); i++)
1430 aLabels.Append( aUpperSHUO->GetChild(i)->Label() );
1431 return Standard_True;
1432}
1433
1434//=======================================================================
1435//function : RemoveSHUO
1436//purpose :
1437//=======================================================================
1438
1439Standard_Boolean XCAFDoc_ShapeTool::RemoveSHUO (const TDF_Label& L) const
1440{
1441 L.ForgetAllAttributes (Standard_True);
1442 return Standard_True;
1443}
1444
1445//=======================================================================
1446//function : checkForShape
1447//purpose : auxilary
1448//=======================================================================
1449
1450static Standard_Boolean checkForShape (const TopoDS_Shape& theShape,
1451 const TopoDS_Shape& theCurSh,
1452 const TDF_Label& theUserL,
1453 TDF_LabelSequence& theLabels)
1454{
1455 // the label of an assembly which contains this component
1456 TDF_Label aSuperUserL = theUserL.Father();
1457 TopLoc_Location aSupLoc, aCompLoc;
1458 aSupLoc = ::XCAFDoc_ShapeTool::GetLocation ( aSuperUserL );
1459 aCompLoc = ::XCAFDoc_ShapeTool::GetLocation ( theUserL );
1460 TopoDS_Shape aCopySh = theCurSh;
1461 aCompLoc = aCompLoc.Multiplied( theCurSh.Location() );
1462 aSupLoc = aSupLoc.Multiplied( aCompLoc );
1463 aCopySh.Location( aSupLoc );
1464 if ( aCopySh.IsSame( theShape ) ) {
1465 theLabels.Prepend( theUserL );
1466 return Standard_True;
1467 }
1468 // try to search deeply (upper by assmebly structure)
1469 TDF_LabelSequence aNewLabels;
1470 for (Standard_Integer j = 1; j <= theLabels.Length(); j++)
1471 aNewLabels.Append( theLabels.Value( j ) );
1472 aNewLabels.Prepend( theUserL );
1473 TDF_LabelSequence aUsers;
1474 ::XCAFDoc_ShapeTool::GetUsers( aSuperUserL, aUsers );
1475 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1476 if ( checkForShape( theShape, aCopySh, aUsers.Value( i ), aNewLabels ) ) {
1477 // get solution
1478 theLabels = aNewLabels;
1479 return Standard_True;
1480 }
1481 return Standard_False;
1482}
1483
1484//=======================================================================
1485//function : FindComponent
1486//purpose :
1487//=======================================================================
1488
1489Standard_Boolean XCAFDoc_ShapeTool::FindComponent (const TopoDS_Shape& theShape,
1490 TDF_LabelSequence& theLabels) const
1491{
1492 theLabels.Clear();
1493 // search for a top-level shape that corresponds to this component
1494 TopoDS_Shape S0 = theShape;
1495 TopLoc_Location loc;
1496 S0.Location ( loc );
1497 TDF_Label aRefL = FindShape( S0 );
1498 if (aRefL.IsNull())
1499 return Standard_False; // cannot find top-level shape.
1500
1501 TDF_LabelSequence aUsers;
1502 ::XCAFDoc_ShapeTool::GetUsers( aRefL, aUsers );
1503 for (Standard_Integer i = 1; i <= aUsers.Length(); i++)
1504 if ( checkForShape( theShape, S0, aUsers.Value( i ), theLabels ) )
1505 break;
1506
1507 return (theLabels.Length() > 0);
1508}
1509
1510//=======================================================================
1511//function : getShapesOfSHUO
1512//purpose : auxilary
1513//=======================================================================
1514
1515static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLocMap,
1516 const Handle(XCAFDoc_ShapeTool)& theSTool,
1517 const TDF_Label& theSHUOlab,
1518 TopoDS_Shape& theShape)
1519{
1520 Handle(XCAFDoc_GraphNode) SHUO;
1521 TDF_LabelSequence aLabSeq;
1522 theSTool->GetSHUONextUsage( theSHUOlab, aLabSeq );
1523 if (aLabSeq.Length() >= 1)
1524 for (Standard_Integer i = 1; i <= aLabSeq.Length(); i++) {
1525 TDF_Label aSubCompL = aLabSeq.Value( i );
1526 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSubCompL.Father() );
1527 // create new map of laocation (to not merge locations from different shapes)
1528 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1529 for (Standard_Integer m = 1; m <= theaPrevLocMap.Extent(); m++)
1530 aNewPrevLocMap.Add( theaPrevLocMap.FindKey( m ) );
1531 aNewPrevLocMap.Add( compLoc );
1532 // got for the new sublocations and corresponding shape
1533 getShapesOfSHUO( aNewPrevLocMap, theSTool, aSubCompL, theShape );
1534 }
1535 else {
1536 TopoDS_Shape aSHUO_NUSh = theSTool->GetShape ( theSHUOlab.Father() );
1537 if ( aSHUO_NUSh.IsNull() ) return Standard_False;
1538 // cause got shape with location already.
1539 TopLoc_Location nullLoc;
1540 aSHUO_NUSh.Location ( nullLoc );
1541 // multiply the locations
1542 Standard_Integer intMapLenght = theaPrevLocMap.Extent();
1543 if ( intMapLenght < 1 )
1544 return Standard_False; // should not be, but to avoid exception...?
1545 TopLoc_Location SupcompLoc;
1546 SupcompLoc = theaPrevLocMap.FindKey( intMapLenght );
1547 if (intMapLenght > 1) {
1548 Standard_Integer l = intMapLenght - 1;
1549 while (l >= 1) {
1550 SupcompLoc = theaPrevLocMap.FindKey( l ).Multiplied( SupcompLoc );
1551 l--;
1552 }
1553 }
1554 aSHUO_NUSh.Location( SupcompLoc );
1555 theShape = aSHUO_NUSh;
1556 }
1557 return (!theShape.IsNull());
1558}
1559
1560//=======================================================================
1561//function : GetSHUOInstance
1562//purpose :
1563//=======================================================================
1564
1565TopoDS_Shape XCAFDoc_ShapeTool::GetSHUOInstance (const Handle(XCAFDoc_GraphNode)& theSHUO) const
1566{
1567 TopoDS_Shape aShape;
1568 if (theSHUO.IsNull())
1569 return aShape;
1570
1571 TDF_Label aSHUOlab = theSHUO->Label();
1572 // get location of the assembly
1573 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1574 // get location of the component
1575 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1576 TopLoc_IndexedMapOfLocation aPrevLocMap;
1577 // get previous setted location
1578 if ( !loc.IsIdentity() )
1579 aPrevLocMap.Add( loc );
1580 aPrevLocMap.Add( compLoc );
1581 // get shape by recurse method
1582 const Handle(XCAFDoc_ShapeTool)& STool = this;
1583 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1584
1585 return aShape;
1586}
1587
1588//=======================================================================
1589//function : getUsersShapesOfSHUO
1590//purpose : auxilary
1591//=======================================================================
1592
1593static Standard_Boolean getUsersShapesOfSHUO (TopLoc_IndexedMapOfLocation& aPrevLocMap,
1594 const Handle(XCAFDoc_ShapeTool)& STool,
1595 const TDF_Label& aSHUOlab,
1596 const TDF_Label& theUserL,
1597 TopTools_SequenceOfShape& theSHUOShapeSeq)
1598{
1599 TopLoc_IndexedMapOfLocation aNewPrevLocMap;
1600 // get location of the assembly
1601 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( theUserL.Father() );
1602 // get location of the component
1603 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( theUserL );
1604 // get previous setted location
1605 aNewPrevLocMap.Add( loc );
1606 aNewPrevLocMap.Add( compLoc );
1607 Standard_Integer i;
1608 for (i = 1; i <= aPrevLocMap.Extent(); i++)
1609 aNewPrevLocMap.Add( aPrevLocMap.FindKey(i) );
1610 TDF_Label L = theUserL.Father();
1611 TDF_LabelSequence usersLab;
1612 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1613 if (usersLab.Length() == 0) {
1614 TopoDS_Shape aShape;
1615 getShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aShape );
1616 if (!aShape.IsNull()) {
1617 theSHUOShapeSeq.Append(aShape);
1618 return Standard_True;
1619 }
1620 }
1621 // now iterates on users of this assembly as component
1622 for ( i = 1; i <= usersLab.Length(); i++ ) {
1623 TDF_Label aNewUserL = usersLab.Value(i);
1624 getUsersShapesOfSHUO( aNewPrevLocMap, STool, aSHUOlab, aNewUserL, theSHUOShapeSeq );
1625 }
1626
1627 return (theSHUOShapeSeq.Length() > 1);
1628}
1629
1630//=======================================================================
1631//function : GetAllSHUOInstances
1632//purpose : auxilary
1633//=======================================================================
1634
1635Standard_Boolean XCAFDoc_ShapeTool::GetAllSHUOInstances (const Handle(XCAFDoc_GraphNode)& theSHUO,
1636 TopTools_SequenceOfShape& theSHUOShapeSeq) const
1637{
1638 if (theSHUO.IsNull())
1639 return Standard_False;
1640
1641 TDF_Label aSHUOlab = theSHUO->Label();
1642 TopLoc_IndexedMapOfLocation aPrevLocMap;
1643 // get location of the assembly
1644 TopLoc_Location loc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father().Father() );
1645 // get location of the component
1646 TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation ( aSHUOlab.Father() );
1647 // get previous setted location
1648 if ( !loc.IsIdentity() )
1649 aPrevLocMap.Add( loc );
1650 aPrevLocMap.Add( compLoc );
1651 // get label of assembly
1652 TDF_Label L = aSHUOlab.Father().Father();
1653 TDF_LabelSequence usersLab;
1654 ::XCAFDoc_ShapeTool::GetUsers( L, usersLab );
1655 TopoDS_Shape aShape;
1656 const Handle(XCAFDoc_ShapeTool)& STool = this;
1657 if (usersLab.Length() == 0) {
1658 getShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aShape );
1659 if (!aShape.IsNull()) {
1660 theSHUOShapeSeq.Append(aShape);
1661 return Standard_True;
1662 }
1663 }
1664 // now iterates on users of this assembly as component
1665 for (Standard_Integer i = 1; i <= usersLab.Length(); i++) {
1666 TDF_Label aUserL = usersLab.Value(i);
1667 getUsersShapesOfSHUO( aPrevLocMap, STool, aSHUOlab, aUserL, theSHUOShapeSeq );
1668 }
1669
1670 return (theSHUOShapeSeq.Length() > 1);
1671}
1672
1673//=======================================================================
1674//function : SetInstanceSHUO
1675//purpose :
1676//=======================================================================
1677
1678Handle(XCAFDoc_GraphNode) XCAFDoc_ShapeTool::SetInstanceSHUO (const TopoDS_Shape& theShape) const
1679{
1680 Handle(XCAFDoc_GraphNode) SHUO;
1681 TDF_LabelSequence aLabels;
1682 if ( FindComponent( theShape, aLabels ) )
1683 // set shuo structure on labels of component-assembly structure
1684 SetSHUO( aLabels, SHUO );
1685 return SHUO;
1686}
1687
1688//=======================================================================
1689//function : FindSHUO
1690//purpose :
1691//=======================================================================
1692
1693Standard_Boolean XCAFDoc_ShapeTool::FindSHUO (const TDF_LabelSequence& theLabels,
1694 Handle(XCAFDoc_GraphNode)& theSHUOAttr)
1695{
1696 TDF_AttributeSequence SHUOAttrs;
1697 TDF_Label aCompLabel = theLabels.Value(1);
1698 if (! ::XCAFDoc_ShapeTool::GetAllComponentSHUO( aCompLabel, SHUOAttrs ) )
1699 return Standard_False;
1700 // WARNING: manage that each SHUO upper_usage have only one SHUO next_usage
1701 for (Standard_Integer i = 1; i <= SHUOAttrs.Length(); i++) {
1702 TDF_LabelSequence aCondidate;
1703 Handle(XCAFDoc_GraphNode) anSHUO = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1704 aCondidate.Append( anSHUO->Label().Father() );
1705 while (anSHUO->NbChildren()) {
1706 anSHUO = anSHUO->GetChild( 1 );
1707 aCondidate.Append( anSHUO->Label().Father() );
1708 }
1709 // check the label sequences
1710 Standard_Boolean isEqual = Standard_True;
1711 if (theLabels.Length() != aCondidate.Length())
1712 isEqual = Standard_False;
1713 else
1714 for (Standard_Integer li = 1; li <= theLabels.Length(); li++)
1715 if ( theLabels.Value(li) != aCondidate.Value(li) ) {
1716 isEqual = Standard_False;
1717 break;
1718 }
1719 if (!isEqual)
1720 continue;
1721
1722 theSHUOAttr = Handle(XCAFDoc_GraphNode)::DownCast(SHUOAttrs.Value(i));
1723 break;
1724 }
1725 return ( !theSHUOAttr.IsNull() );
1726}