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