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