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