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