0031652: Visualization - crash on highlighting HLR Computed presentation displayed...
[occt.git] / src / Graphic3d / Graphic3d_Structure.cxx
1 // Created by: NW,JPB,CAL
2 // Copyright (c) 1991-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <Graphic3d_Structure.hxx>
17
18 #include <Bnd_Box.hxx>
19 #include <gp_Pnt.hxx>
20 #include <Graphic3d_DataStructureManager.hxx>
21 #include <Graphic3d_GraphicDriver.hxx>
22 #include <Graphic3d_Group.hxx>
23 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
24 #include <Graphic3d_MapOfStructure.hxx>
25 #include <Graphic3d_PriorityDefinitionError.hxx>
26 #include <Graphic3d_StructureDefinitionError.hxx>
27 #include <Graphic3d_StructureManager.hxx>
28 #include <Graphic3d_TransformError.hxx>
29 #include <Quantity_Color.hxx>
30
31 #include "Graphic3d_Structure.pxx"
32
33 #include <Standard_Dump.hxx>
34
35 #include <stdio.h>
36
37 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Structure,Standard_Transient)
38
39 //=============================================================================
40 //function : Graphic3d_Structure
41 //purpose  :
42 //=============================================================================
43 Graphic3d_Structure::Graphic3d_Structure (const Handle(Graphic3d_StructureManager)& theManager,
44                                           const Handle(Graphic3d_Structure)&        theLinkPrs)
45 : myStructureManager(theManager.get()),
46   myOwner           (NULL),
47   myVisual          (Graphic3d_TOS_ALL),
48   myComputeVisual   (Graphic3d_TOS_ALL)
49 {
50   if (!theLinkPrs.IsNull())
51   {
52     myOwner = theLinkPrs->myOwner;
53     if (theLinkPrs->myVisual != Graphic3d_TOS_COMPUTED)
54     {
55       myVisual = theLinkPrs->myVisual;
56     }
57     myComputeVisual = theLinkPrs->myComputeVisual;
58     myCStructure = theLinkPrs->myCStructure->ShadowLink (theManager);
59   }
60   else
61   {
62     myCStructure = theManager->GraphicDriver()->CreateStructure (theManager);
63   }
64 }
65
66 //=============================================================================
67 //function : ~Graphic3d_Structure
68 //purpose  :
69 //=============================================================================
70 Graphic3d_Structure::~Graphic3d_Structure()
71 {
72   // as myStructureManager can be already destroyed,
73   // avoid attempts to access it
74   myStructureManager = NULL;
75   Remove();
76 }
77
78 //=============================================================================
79 //function : clear
80 //purpose  :
81 //=============================================================================
82 void Graphic3d_Structure::clear (const Standard_Boolean theWithDestruction)
83 {
84   if (IsDeleted()) return;
85
86   // clean groups in graphics driver at first
87   GraphicClear (theWithDestruction);
88
89   myCStructure->ContainsFacet = 0;
90   myStructureManager->Clear (this, theWithDestruction);
91
92   Update (true);
93 }
94
95 //=======================================================================
96 //function : CalculateBoundBox
97 //purpose  : Calculates AABB of a structure.
98 //=======================================================================
99 void Graphic3d_Structure::CalculateBoundBox()
100 {
101   Graphic3d_BndBox3d aBox;
102   addTransformed (aBox, Standard_True);
103   myCStructure->ChangeBoundingBox() = aBox;
104 }
105
106 //=============================================================================
107 //function : Remove
108 //purpose  :
109 //=============================================================================
110 void Graphic3d_Structure::Remove()
111 {
112   if (IsDeleted()) return;
113
114   // clean groups in graphics driver at first; this is also should be done
115   // to avoid unwanted group cleaning in group's destructor
116   // Pass Standard_False to Clear(..) method to avoid updating in
117   // structure manager, it isn't necessary, besides of it structure manager
118   // could be already destroyed and invalid pointers used in structure;
119   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
120   {
121     aGroupIter.ChangeValue()->Clear (Standard_False);
122   }
123
124   // It is necessary to remove the eventual pointer on the structure that can be destroyed, in the list of descendants
125   // of ancestors of this structure and in the list of ancestors of descendants of the same structure.
126   for (Standard_Integer aStructIdx = 1, aNbDesc = myDescendants.Size(); aStructIdx <= aNbDesc; ++aStructIdx)
127   {
128     myDescendants.FindKey (aStructIdx)->Remove (this, Graphic3d_TOC_ANCESTOR);
129   }
130
131   for (Standard_Integer aStructIdx = 1, aNbAnces = myAncestors.Size(); aStructIdx <= aNbAnces; ++aStructIdx)
132   {
133     myAncestors.FindKey (aStructIdx)->Remove (this, Graphic3d_TOC_DESCENDANT);
134   }
135
136   // Destruction of me in the graphic library
137   const Standard_Integer aStructId = myCStructure->Id;
138   myCStructure->GraphicDriver()->RemoveIdentification(aStructId);
139   myCStructure->GraphicDriver()->RemoveStructure (myCStructure);
140   myCStructure.Nullify();
141 }
142
143 //=============================================================================
144 //function : Display
145 //purpose  :
146 //=============================================================================
147 void Graphic3d_Structure::Display()
148 {
149   if (IsDeleted()) return;
150
151   if (!myCStructure->stick)
152   {
153     myCStructure->stick = 1;
154     myStructureManager->Display (this);
155   }
156
157   if (myCStructure->visible != 1)
158   {
159     myCStructure->visible = 1;
160     myCStructure->OnVisibilityChanged();
161   }
162 }
163
164 //=============================================================================
165 //function : SetDisplayPriority
166 //purpose  :
167 //=============================================================================
168 void Graphic3d_Structure::SetDisplayPriority (const Standard_Integer thePriority)
169 {
170   if (IsDeleted()
171    || thePriority == myCStructure->Priority)
172   {
173     return;
174   }
175
176   myCStructure->PreviousPriority = myCStructure->Priority;
177   myCStructure->Priority         = thePriority;
178
179   if (myCStructure->Priority != myCStructure->PreviousPriority)
180   {
181     Graphic3d_PriorityDefinitionError_Raise_if ((myCStructure->Priority > Structure_MAX_PRIORITY)
182                                              || (myCStructure->Priority < Structure_MIN_PRIORITY),
183                                                 "Bad value for StructurePriority");
184     if (myCStructure->stick)
185     {
186       myStructureManager->ChangeDisplayPriority (this, myCStructure->PreviousPriority, myCStructure->Priority);
187     }
188   }
189 }
190
191 //=============================================================================
192 //function : ResetDisplayPriority
193 //purpose  :
194 //=============================================================================
195 void Graphic3d_Structure::ResetDisplayPriority()
196 {
197   if (IsDeleted()
198    || myCStructure->Priority == myCStructure->PreviousPriority)
199   {
200     return;
201   }
202
203   const Standard_Integer aPriority = myCStructure->Priority;
204   myCStructure->Priority = myCStructure->PreviousPriority;
205   if (myCStructure->stick)
206   {
207     myStructureManager->ChangeDisplayPriority (this, aPriority, myCStructure->Priority);
208   }
209 }
210
211 //=============================================================================
212 //function : erase
213 //purpose  :
214 //=============================================================================
215 void Graphic3d_Structure::erase()
216 {
217   if (IsDeleted())
218   {
219     return;
220   }
221
222   if (myCStructure->stick)
223   {
224     myCStructure->stick = 0;
225     myStructureManager->Erase (this);
226   }
227 }
228
229 //=============================================================================
230 //function : Highlight
231 //purpose  :
232 //=============================================================================
233 void Graphic3d_Structure::Highlight (const Handle(Graphic3d_PresentationAttributes)& theStyle,
234                                      const Standard_Boolean theToUpdateMgr)
235 {
236   if (IsDeleted())
237   {
238     return;
239   }
240
241   SetDisplayPriority (Structure_MAX_PRIORITY - 1);
242
243   myCStructure->GraphicHighlight (theStyle);
244
245   if (!theToUpdateMgr)
246   {
247     return;
248   }
249
250   if (myCStructure->stick)
251   {
252     myStructureManager->Highlight (this);
253   }
254
255   Update();
256 }
257
258 //=============================================================================
259 //function : SetVisible
260 //purpose  :
261 //=============================================================================
262 void Graphic3d_Structure::SetVisible (const Standard_Boolean theValue)
263 {
264   if (IsDeleted()) return;
265
266   const unsigned isVisible = theValue ? 1 : 0;
267   if (myCStructure->visible == isVisible)
268   {
269     return;
270   }
271
272   myCStructure->visible = isVisible;
273   myCStructure->OnVisibilityChanged();
274   Update (true);
275 }
276
277 //=============================================================================
278 //function : UnHighlight
279 //purpose  :
280 //=============================================================================
281 void Graphic3d_Structure::UnHighlight()
282 {
283   if (IsDeleted()) return;
284
285   if (myCStructure->highlight)
286   {
287     myCStructure->highlight = 0;
288
289     myCStructure->GraphicUnhighlight();
290     myStructureManager->UnHighlight (this);
291
292     ResetDisplayPriority();
293     Update();
294   }
295 }
296
297 //=============================================================================
298 //function : ContainsFacet
299 //purpose  :
300 //=============================================================================
301 Standard_Boolean Graphic3d_Structure::ContainsFacet() const
302 {
303   if (IsDeleted())
304   {
305     return Standard_False;
306   }
307   else if (myCStructure->ContainsFacet > 0)
308   {
309     // if one of groups contains at least one facet, the structure contains it too
310     return Standard_True;
311   }
312
313   // stop at the first descendant containing at least one facet
314   for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
315   {
316     if (anIter.Value()->ContainsFacet())
317     {
318       return Standard_True;
319     }
320   }
321   return Standard_False;
322 }
323
324 //=============================================================================
325 //function : IsEmpty
326 //purpose  :
327 //=============================================================================
328 Standard_Boolean Graphic3d_Structure::IsEmpty() const
329 {
330   if (IsDeleted())
331   {
332     return Standard_True;
333   }
334
335   // structure is empty:
336   // - if all these groups are empty
337   // - or if all groups are empty and all their descendants are empty
338   // - or if all its descendants are empty
339   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
340   {
341     if (!aGroupIter.Value()->IsEmpty())
342     {
343       return Standard_False;
344     }
345   }
346
347   // stop at the first non-empty descendant
348   for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
349   {
350     if (!anIter.Value()->IsEmpty())
351     {
352       return Standard_False;
353     }
354   }
355   return Standard_True;
356 }
357
358 //=============================================================================
359 //function : GroupsWithFacet
360 //purpose  :
361 //=============================================================================
362 void Graphic3d_Structure::GroupsWithFacet (const Standard_Integer theDelta)
363 {
364   myCStructure->ContainsFacet = myCStructure->ContainsFacet + theDelta;
365   if (myCStructure->ContainsFacet < 0)
366   {
367     myCStructure->ContainsFacet = 0;
368   }
369 }
370
371 //=============================================================================
372 //function : ReCompute
373 //purpose  :
374 //=============================================================================
375 void Graphic3d_Structure::ReCompute()
376 {
377   myStructureManager->ReCompute (this);
378 }
379
380 //=============================================================================
381 //function : ReCompute
382 //purpose  :
383 //=============================================================================
384 void Graphic3d_Structure::ReCompute (const Handle(Graphic3d_DataStructureManager)& theProjector)
385 {
386   myStructureManager->ReCompute (this, theProjector);
387 }
388
389 //=============================================================================
390 //function : GraphicClear
391 //purpose  :
392 //=============================================================================
393 void Graphic3d_Structure::GraphicClear (const Standard_Boolean theWithDestruction)
394 {
395   if (myCStructure.IsNull())
396   {
397     return;
398   }
399
400   // clean and empty each group
401   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
402   {
403     aGroupIter.ChangeValue()->Clear();
404   }
405   if (!theWithDestruction)
406   {
407     return;
408   }
409
410   while (!myCStructure->Groups().IsEmpty())
411   {
412     Handle(Graphic3d_Group) aGroup = myCStructure->Groups().First();
413     aGroup->Remove();
414   }
415   myCStructure->Clear();
416 }
417
418 //=============================================================================
419 //function : SetVisual
420 //purpose  :
421 //=============================================================================
422 void Graphic3d_Structure::SetVisual (const Graphic3d_TypeOfStructure theVisual)
423 {
424   if (IsDeleted()
425    || myVisual == theVisual)
426   {
427     return;
428   }
429
430   if (!myCStructure->stick)
431   {
432     myVisual = theVisual;
433     SetComputeVisual (theVisual);
434   }
435   else
436   {
437     erase();
438     myVisual = theVisual;
439     SetComputeVisual (theVisual);
440     Display();
441   }
442 }
443
444 //=============================================================================
445 //function : SetZoomLimit
446 //purpose  :
447 //=============================================================================
448 void Graphic3d_Structure::SetZoomLimit (const Standard_Real theLimitInf,
449                                         const Standard_Real theLimitSup)
450 {
451   (void )theLimitInf;
452   (void )theLimitSup;
453   Graphic3d_StructureDefinitionError_Raise_if (theLimitInf <= 0.0,
454                                                "Bad value for ZoomLimit inf");
455   Graphic3d_StructureDefinitionError_Raise_if (theLimitSup <= 0.0,
456                                                "Bad value for ZoomLimit sup");
457   Graphic3d_StructureDefinitionError_Raise_if (theLimitSup < theLimitInf,
458                                                "ZoomLimit sup < ZoomLimit inf");
459 }
460
461 //=============================================================================
462 //function : AcceptConnection
463 //purpose  :
464 //=============================================================================
465 Standard_Boolean Graphic3d_Structure::AcceptConnection (Graphic3d_Structure* theStructure1,
466                                                         Graphic3d_Structure* theStructure2,
467                                                         Graphic3d_TypeOfConnection theType)
468 {
469   // cycle detection
470   NCollection_Map<Graphic3d_Structure*> aSet;
471   Graphic3d_Structure::Network (theStructure2, theType, aSet);
472   return !aSet.Contains (theStructure1);
473 }
474
475 //=============================================================================
476 //function : Ancestors
477 //purpose  :
478 //=============================================================================
479 void Graphic3d_Structure::Ancestors (Graphic3d_MapOfStructure& theSet) const
480 {
481   for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myAncestors); anIter.More(); anIter.Next())
482   {
483     theSet.Add (anIter.Value());
484   }
485 }
486
487 //=============================================================================
488 //function : Descendants
489 //purpose  :
490 //=============================================================================
491 void Graphic3d_Structure::Descendants (Graphic3d_MapOfStructure& theSet) const
492 {
493   for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
494   {
495     theSet.Add (anIter.Value());
496   }
497 }
498
499 //=============================================================================
500 //function : AppendAncestor
501 //purpose  :
502 //=============================================================================
503 Standard_Boolean Graphic3d_Structure::AppendAncestor (Graphic3d_Structure* theAncestor)
504 {
505   const Standard_Integer aSize = myAncestors.Size();
506
507   return myAncestors.Add (theAncestor) > aSize; // new object
508 }
509
510 //=============================================================================
511 //function : AppendDescendant
512 //purpose  :
513 //=============================================================================
514 Standard_Boolean Graphic3d_Structure::AppendDescendant (Graphic3d_Structure* theDescendant)
515 {
516   const Standard_Integer aSize = myDescendants.Size();
517
518   return myDescendants.Add (theDescendant) > aSize; // new object
519 }
520
521 //=============================================================================
522 //function : RemoveAncestor
523 //purpose  :
524 //=============================================================================
525 Standard_Boolean Graphic3d_Structure::RemoveAncestor (Graphic3d_Structure* theAncestor)
526 {
527   const Standard_Integer anIndex = myAncestors.FindIndex (theAncestor);
528
529   if (anIndex != 0)
530   {
531     myAncestors.Swap (anIndex, myAncestors.Size());
532     myAncestors.RemoveLast();
533   }
534
535   return anIndex != 0; // object was found
536 }
537
538 //=============================================================================
539 //function : RemoveDescendant
540 //purpose  :
541 //=============================================================================
542 Standard_Boolean Graphic3d_Structure::RemoveDescendant (Graphic3d_Structure* theDescendant)
543 {
544   const Standard_Integer anIndex = myDescendants.FindIndex (theDescendant);
545
546   if (anIndex != 0)
547   {
548     myDescendants.Swap (anIndex, myDescendants.Size());
549     myDescendants.RemoveLast();
550   }
551
552   return anIndex != 0; // object was found
553 }
554
555 //=============================================================================
556 //function : Connect
557 //purpose  :
558 //=============================================================================
559 void Graphic3d_Structure::Connect (Graphic3d_Structure* theStructure,
560                                    Graphic3d_TypeOfConnection theType,
561                                    Standard_Boolean theWithCheck)
562 {
563   if (IsDeleted())
564   {
565     return;
566   }
567
568   // cycle detection
569   if (theWithCheck
570    && !Graphic3d_Structure::AcceptConnection (this, theStructure, theType))
571   {
572     return;
573   }
574
575   if (theType == Graphic3d_TOC_DESCENDANT)
576   {
577     if (!AppendDescendant (theStructure))
578     {
579       return;
580     }
581
582     CalculateBoundBox();
583     theStructure->Connect (this, Graphic3d_TOC_ANCESTOR);
584
585     GraphicConnect (theStructure);
586     myStructureManager->Connect (this, theStructure);
587
588     Update (true);
589   }
590   else // Graphic3d_TOC_ANCESTOR
591   {
592     if (!AppendAncestor (theStructure))
593     {
594       return;
595     }
596
597     CalculateBoundBox();
598     theStructure->Connect (this, Graphic3d_TOC_DESCENDANT);
599
600     // myStructureManager->Connect is called in case if connection between parent and child
601   }
602 }
603
604 //=============================================================================
605 //function : Disconnect
606 //purpose  :
607 //=============================================================================
608 void Graphic3d_Structure::Disconnect (Graphic3d_Structure* theStructure)
609 {
610   if (IsDeleted())
611   {
612     return;
613   }
614
615   if (RemoveDescendant (theStructure))
616   {
617     theStructure->Disconnect (this);
618
619     GraphicDisconnect (theStructure);
620     myStructureManager->Disconnect (this, theStructure);
621
622     CalculateBoundBox();
623     Update (true);
624   }
625   else if (RemoveAncestor (theStructure))
626   {
627     theStructure->Disconnect (this);
628     CalculateBoundBox();
629
630     // no call of myStructureManager->Disconnect in case of an ancestor
631   }
632 }
633
634 //=============================================================================
635 //function : DisconnectAll
636 //purpose  :
637 //=============================================================================
638 void Graphic3d_Structure::DisconnectAll (const Graphic3d_TypeOfConnection theType)
639 {
640   if (IsDeleted()) return;
641
642   switch (theType)
643   {
644     case Graphic3d_TOC_DESCENDANT:
645     {
646       for (Standard_Integer anIdx = 1, aLength = myDescendants.Size(); anIdx <= aLength; ++anIdx)
647       {
648         // Value (1) instead of Value (i) as myDescendants
649         // is modified by :
650         // Graphic3d_Structure::Disconnect (AStructure)
651         // that takes AStructure from myDescendants
652         myDescendants.FindKey (1)->Disconnect (this);
653       }
654       break;
655     }
656     case Graphic3d_TOC_ANCESTOR:
657     {
658       for (Standard_Integer anIdx = 1, aLength = myAncestors.Size(); anIdx <= aLength; ++anIdx)
659       {
660         // Value (1) instead of Value (i) as myAncestors
661         // is modified by :
662         // Graphic3d_Structure::Disconnect (AStructure)
663         // that takes AStructure from myAncestors
664         myAncestors.FindKey (1)->Disconnect (this);
665       }
666       break;
667     }
668   }
669 }
670
671 //=============================================================================
672 //function : SetTransform
673 //purpose  :
674 //=============================================================================
675 void Graphic3d_Structure::SetTransformation (const Handle(TopLoc_Datum3D)& theTrsf)
676 {
677   if (IsDeleted()) return;
678
679   const Standard_Boolean wasTransformed = IsTransformed();
680
681   if (!theTrsf.IsNull()
682     && theTrsf->Trsf().Form() == gp_Identity)
683   {
684     myCStructure->SetTransformation (Handle(TopLoc_Datum3D)());
685   }
686   else
687   {
688     myCStructure->SetTransformation (theTrsf);
689   }
690
691   // If transformation, no validation of hidden already calculated parts
692   if (IsTransformed() || (!IsTransformed() && wasTransformed))
693   {
694     ReCompute();
695   }
696
697   myStructureManager->SetTransform (this, theTrsf);
698
699   Update (true);
700 }
701
702 //=============================================================================
703 //function : MinMaxValues
704 //purpose  :
705 //=============================================================================
706 Bnd_Box Graphic3d_Structure::MinMaxValues (const Standard_Boolean theToIgnoreInfiniteFlag) const
707 {
708   Graphic3d_BndBox3d aBox;
709   addTransformed (aBox, theToIgnoreInfiniteFlag);
710   if (!aBox.IsValid())
711   {
712     return Bnd_Box();
713   }
714
715   Bnd_Box aResult;
716   aResult.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
717                   aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
718
719   Standard_Real aLimMin = ShortRealFirst() + 1.0;
720   Standard_Real aLimMax = ShortRealLast()  - 1.0;
721   gp_Pnt aMin = aResult.CornerMin();
722   gp_Pnt aMax = aResult.CornerMax();
723   if (aMin.X() < aLimMin && aMin.Y() < aLimMin && aMin.Z() < aLimMin
724    && aMax.X() > aLimMax && aMax.Y() > aLimMax && aMax.Z() > aLimMax)
725   {
726     //For structure which infinite in all three dimensions the Whole bounding box will be returned
727     aResult.SetWhole();
728   }
729   return aResult;
730 }
731
732 //=============================================================================
733 //function : SetTransformPersistence
734 //purpose  :
735 //=============================================================================
736 void Graphic3d_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
737 {
738   if (IsDeleted())
739   {
740     return;
741   }
742
743   myCStructure->SetTransformPersistence (theTrsfPers);
744 }
745
746 //=============================================================================
747 //function : Remove
748 //purpose  :
749 //=============================================================================
750 void Graphic3d_Structure::Remove (Graphic3d_Structure* thePtr,
751                                   const Graphic3d_TypeOfConnection theType)
752 {
753   if (theType == Graphic3d_TOC_DESCENDANT)
754   {
755     RemoveDescendant (thePtr);
756   }
757   else
758   {
759     RemoveAncestor (thePtr);
760   }
761 }
762
763 //=============================================================================
764 //function : NewGroup
765 //purpose  :
766 //=============================================================================
767 Handle(Graphic3d_Group) Graphic3d_Structure::NewGroup()
768 {
769   return myCStructure->NewGroup (this);
770 }
771
772 //=============================================================================
773 //function : Remove
774 //purpose  :
775 //=============================================================================
776 void Graphic3d_Structure::Remove (const Handle(Graphic3d_Group)& theGroup)
777 {
778   if (theGroup.IsNull()
779    || theGroup->myStructure != this)
780   {
781     return;
782   }
783
784   myCStructure->RemoveGroup (theGroup);
785   theGroup->myStructure = NULL;
786 }
787
788 //=============================================================================
789 //function : StructureManager
790 //purpose  :
791 //=============================================================================
792 Handle(Graphic3d_StructureManager) Graphic3d_Structure::StructureManager() const
793 {
794   return myStructureManager;
795 }
796
797 //=============================================================================
798 //function : minMaxCoord
799 //purpose  :
800 //=============================================================================
801 Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord() const
802 {
803   Graphic3d_BndBox4f aBnd;
804   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
805   {
806     aBnd.Combine (aGroupIter.Value()->BoundingBox());
807   }
808   return aBnd;
809 }
810
811 //=============================================================================
812 //function : addTransformed
813 //purpose  :
814 //=============================================================================
815 void Graphic3d_Structure::getBox (Graphic3d_BndBox3d&    theBox,
816                                   const Standard_Boolean theToIgnoreInfiniteFlag) const
817 {
818   Graphic3d_BndBox4f aBoxF = minMaxCoord();
819   if (aBoxF.IsValid())
820   {
821     theBox = Graphic3d_BndBox3d (Graphic3d_Vec3d ((Standard_Real )aBoxF.CornerMin().x(),
822                                                   (Standard_Real )aBoxF.CornerMin().y(),
823                                                   (Standard_Real )aBoxF.CornerMin().z()),
824                                  Graphic3d_Vec3d ((Standard_Real )aBoxF.CornerMax().x(),
825                                                   (Standard_Real )aBoxF.CornerMax().y(),
826                                                   (Standard_Real )aBoxF.CornerMax().z()));
827     if (IsInfinite()
828     && !theToIgnoreInfiniteFlag)
829     {
830       const Graphic3d_Vec3d aDiagVec = theBox.CornerMax() - theBox.CornerMin();
831       if (aDiagVec.SquareModulus() >= 500000.0 * 500000.0)
832       {
833         // bounding borders of infinite line has been calculated as own point in center of this line
834         theBox = Graphic3d_BndBox3d ((theBox.CornerMin() + theBox.CornerMax()) * 0.5);
835       }
836       else
837       {
838         theBox = Graphic3d_BndBox3d (Graphic3d_Vec3d (RealFirst(), RealFirst(), RealFirst()),
839                                      Graphic3d_Vec3d (RealLast(),  RealLast(),  RealLast()));
840         return;
841       }
842     }
843   }
844 }
845
846 //=============================================================================
847 //function : addTransformed
848 //purpose  :
849 //=============================================================================
850 void Graphic3d_Structure::addTransformed (Graphic3d_BndBox3d&    theBox,
851                                           const Standard_Boolean theToIgnoreInfiniteFlag) const
852 {
853   Graphic3d_BndBox3d aCombinedBox, aBox;
854   getBox (aCombinedBox, theToIgnoreInfiniteFlag);
855
856   for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
857   {
858     const Graphic3d_Structure* aStruct = anIter.Value();
859     aStruct->getBox (aBox, theToIgnoreInfiniteFlag);
860     aCombinedBox.Combine (aBox);
861   }
862
863   aBox = aCombinedBox;
864   if (aBox.IsValid())
865   {
866     if (!myCStructure->Transformation().IsNull())
867     {
868       TransformBoundaries (myCStructure->Transformation()->Trsf(),
869                            aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
870                            aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
871     }
872
873     // if box is still valid after transformation
874     if (aBox.IsValid())
875     {
876       theBox.Combine (aBox);
877     }
878     else // it was infinite, return untransformed
879     {
880       theBox.Combine (aCombinedBox);
881     }
882   }
883 }
884
885 //=============================================================================
886 //function : Transforms
887 //purpose  :
888 //=============================================================================
889 void Graphic3d_Structure::Transforms (const gp_Trsf& theTrsf,
890                                       const Standard_Real theX,    const Standard_Real theY,    const Standard_Real theZ,
891                                       Standard_Real&      theNewX, Standard_Real&      theNewY, Standard_Real&      theNewZ)
892 {
893   const Standard_Real aRL = RealLast();
894   const Standard_Real aRF = RealFirst();
895   theNewX = theX;
896   theNewY = theY;
897   theNewZ = theZ;
898   if ((theX == aRF) || (theY == aRF) || (theZ == aRF)
899    || (theX == aRL) || (theY == aRL) || (theZ == aRL))
900   {
901     return;
902   }
903
904   theTrsf.Transforms (theNewX, theNewY, theNewZ);
905 }
906
907 //=============================================================================
908 //function : Transforms
909 //purpose  :
910 //=============================================================================
911 void Graphic3d_Structure::TransformBoundaries (const gp_Trsf& theTrsf,
912                                                Standard_Real& theXMin,
913                                                Standard_Real& theYMin,
914                                                Standard_Real& theZMin,
915                                                Standard_Real& theXMax,
916                                                Standard_Real& theYMax,
917                                                Standard_Real& theZMax)
918 {
919   Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax, anU, aV, aW;
920
921   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMin, aXMin, aYMin, aZMin);
922   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMax, aXMax, aYMax, aZMax);
923
924   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMax, anU, aV, aW);
925   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
926   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
927   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
928
929   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMax, anU, aV, aW);
930   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
931   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
932   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
933
934   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMin, anU, aV, aW);
935   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
936   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
937   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
938
939   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMin, anU, aV, aW);
940   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
941   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
942   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
943
944   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMax, anU, aV, aW);
945   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
946   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
947   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
948
949   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMin, anU, aV, aW);
950   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
951   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
952   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
953
954   theXMin = aXMin;
955   theYMin = aYMin;
956   theZMin = aZMin;
957   theXMax = aXMax;
958   theYMax = aYMax;
959   theZMax = aZMax;
960 }
961
962 //=============================================================================
963 //function : Network
964 //purpose  :
965 //=============================================================================
966 void Graphic3d_Structure::Network (Graphic3d_Structure* theStructure,
967                                    const Graphic3d_TypeOfConnection theType,
968                                    NCollection_Map<Graphic3d_Structure*>& theSet)
969 {
970   theSet.Add (theStructure);
971   switch (theType)
972   {
973     case Graphic3d_TOC_DESCENDANT:
974     {
975       for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (theStructure->myDescendants); anIter.More(); anIter.Next())
976       {
977         Graphic3d_Structure::Network (anIter.Value(), theType, theSet);
978       }
979       break;
980     }
981     case Graphic3d_TOC_ANCESTOR:
982     {
983       for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (theStructure->myAncestors); anIter.More(); anIter.Next())
984       {
985         Graphic3d_Structure::Network (anIter.Value(), theType, theSet);
986       }
987       break;
988     }
989   }
990 }
991
992 //=============================================================================
993 //function : PrintNetwork
994 //purpose  :
995 //=============================================================================
996 void Graphic3d_Structure::PrintNetwork (const Handle(Graphic3d_Structure)& theStructure,
997                                         const Graphic3d_TypeOfConnection   theType)
998 {
999   NCollection_Map<Graphic3d_Structure*> aSet;
1000   Graphic3d_Structure::Network (theStructure.get(), theType, aSet);
1001   for (NCollection_Map<Graphic3d_Structure*>::Iterator anIter (aSet); anIter.More(); anIter.Next())
1002   {
1003     std::cout << "\tIdent " << (anIter.Key())->Identification () << "\n";
1004   }
1005   std::cout << std::flush;
1006 }
1007
1008 //=============================================================================
1009 //function : Update
1010 //purpose  :
1011 //=============================================================================
1012 void Graphic3d_Structure::Update (const bool theUpdateLayer) const
1013 {
1014   if (IsDeleted())
1015   {
1016     return;
1017   }
1018
1019   myStructureManager->Update (theUpdateLayer ? myCStructure->ZLayer() : Graphic3d_ZLayerId_UNKNOWN);
1020 }
1021
1022 //=======================================================================
1023 //function : SetZLayer
1024 //purpose  :
1025 //=======================================================================
1026 void Graphic3d_Structure::SetZLayer (const Graphic3d_ZLayerId theLayerId)
1027 {
1028   // if the structure is not displayed, unable to change its display layer
1029   if (IsDeleted ())
1030     return;
1031
1032   myStructureManager->ChangeZLayer (this, theLayerId);
1033   myCStructure->SetZLayer (theLayerId);
1034 }
1035
1036 //=======================================================================
1037 //function : DumpJson
1038 //purpose  : 
1039 //=======================================================================
1040 void Graphic3d_Structure::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
1041 {
1042   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
1043
1044   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myCStructure.get())
1045
1046   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myVisual)
1047   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myComputeVisual)
1048 }