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