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