0032725: Visualization - Graphic3d_Structure::SetDisplayPriority() should use public...
[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 <Quantity_Color.hxx>
29
30 #include <Standard_Dump.hxx>
31
32 #include <stdio.h>
33
34 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Structure,Standard_Transient)
35
36 //=============================================================================
37 //function : Graphic3d_Structure
38 //purpose  :
39 //=============================================================================
40 Graphic3d_Structure::Graphic3d_Structure (const Handle(Graphic3d_StructureManager)& theManager,
41                                           const Handle(Graphic3d_Structure)&        theLinkPrs)
42 : myStructureManager(theManager.get()),
43   myOwner           (NULL),
44   myVisual          (Graphic3d_TOS_ALL),
45   myComputeVisual   (Graphic3d_TOS_ALL)
46 {
47   if (!theLinkPrs.IsNull())
48   {
49     myOwner = theLinkPrs->myOwner;
50     if (theLinkPrs->myVisual != Graphic3d_TOS_COMPUTED)
51     {
52       myVisual = theLinkPrs->myVisual;
53     }
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->SetGroupTransformPersistence (false);
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->Identification();
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 Graphic3d_DisplayPriority thePriority)
166 {
167   if (IsDeleted()
168    || thePriority == myCStructure->Priority())
169   {
170     return;
171   }
172
173   Graphic3d_PriorityDefinitionError_Raise_if ((thePriority > Graphic3d_DisplayPriority_Topmost)
174                                            || (thePriority < Graphic3d_DisplayPriority_Bottom),
175                                               "Bad value for StructurePriority");
176
177   myCStructure->SetPreviousPriority (myCStructure->Priority());
178   myCStructure->SetPriority (thePriority);
179   if (myCStructure->Priority() != myCStructure->PreviousPriority())
180   {
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 Graphic3d_DisplayPriority aPriority = myCStructure->Priority();
201   myCStructure->SetPriority (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 (Graphic3d_DisplayPriority_Highlight);
239   myCStructure->GraphicHighlight (theStyle);
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 : IsEmpty
294 //purpose  :
295 //=============================================================================
296 Standard_Boolean Graphic3d_Structure::IsEmpty() const
297 {
298   if (IsDeleted())
299   {
300     return Standard_True;
301   }
302
303   // structure is empty:
304   // - if all these groups are empty
305   // - or if all groups are empty and all their descendants are empty
306   // - or if all its descendants are empty
307   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
308   {
309     if (!aGroupIter.Value()->IsEmpty())
310     {
311       return Standard_False;
312     }
313   }
314
315   // stop at the first non-empty descendant
316   for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
317   {
318     if (!anIter.Value()->IsEmpty())
319     {
320       return Standard_False;
321     }
322   }
323   return Standard_True;
324 }
325
326 //=============================================================================
327 //function : ReCompute
328 //purpose  :
329 //=============================================================================
330 void Graphic3d_Structure::ReCompute()
331 {
332   myStructureManager->ReCompute (this);
333 }
334
335 //=============================================================================
336 //function : ReCompute
337 //purpose  :
338 //=============================================================================
339 void Graphic3d_Structure::ReCompute (const Handle(Graphic3d_DataStructureManager)& theProjector)
340 {
341   myStructureManager->ReCompute (this, theProjector);
342 }
343
344 //=============================================================================
345 //function : GraphicClear
346 //purpose  :
347 //=============================================================================
348 void Graphic3d_Structure::GraphicClear (const Standard_Boolean theWithDestruction)
349 {
350   if (myCStructure.IsNull())
351   {
352     return;
353   }
354
355   // clean and empty each group
356   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
357   {
358     aGroupIter.ChangeValue()->Clear();
359   }
360   if (!theWithDestruction)
361   {
362     return;
363   }
364
365   while (!myCStructure->Groups().IsEmpty())
366   {
367     Handle(Graphic3d_Group) aGroup = myCStructure->Groups().First();
368     aGroup->Remove();
369   }
370   myCStructure->Clear();
371 }
372
373 //=============================================================================
374 //function : SetVisual
375 //purpose  :
376 //=============================================================================
377 void Graphic3d_Structure::SetVisual (const Graphic3d_TypeOfStructure theVisual)
378 {
379   if (IsDeleted()
380    || myVisual == theVisual)
381   {
382     return;
383   }
384
385   if (!myCStructure->stick)
386   {
387     myVisual = theVisual;
388     SetComputeVisual (theVisual);
389   }
390   else
391   {
392     erase();
393     myVisual = theVisual;
394     SetComputeVisual (theVisual);
395     Display();
396   }
397 }
398
399 //=============================================================================
400 //function : SetZoomLimit
401 //purpose  :
402 //=============================================================================
403 void Graphic3d_Structure::SetZoomLimit (const Standard_Real theLimitInf,
404                                         const Standard_Real theLimitSup)
405 {
406   (void )theLimitInf;
407   (void )theLimitSup;
408   Graphic3d_StructureDefinitionError_Raise_if (theLimitInf <= 0.0,
409                                                "Bad value for ZoomLimit inf");
410   Graphic3d_StructureDefinitionError_Raise_if (theLimitSup <= 0.0,
411                                                "Bad value for ZoomLimit sup");
412   Graphic3d_StructureDefinitionError_Raise_if (theLimitSup < theLimitInf,
413                                                "ZoomLimit sup < ZoomLimit inf");
414 }
415
416 //=============================================================================
417 //function : AcceptConnection
418 //purpose  :
419 //=============================================================================
420 Standard_Boolean Graphic3d_Structure::AcceptConnection (Graphic3d_Structure* theStructure1,
421                                                         Graphic3d_Structure* theStructure2,
422                                                         Graphic3d_TypeOfConnection theType)
423 {
424   // cycle detection
425   NCollection_Map<Graphic3d_Structure*> aSet;
426   Graphic3d_Structure::Network (theStructure2, theType, aSet);
427   return !aSet.Contains (theStructure1);
428 }
429
430 //=============================================================================
431 //function : Ancestors
432 //purpose  :
433 //=============================================================================
434 void Graphic3d_Structure::Ancestors (Graphic3d_MapOfStructure& theSet) const
435 {
436   for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myAncestors); anIter.More(); anIter.Next())
437   {
438     theSet.Add (anIter.Value());
439   }
440 }
441
442 //=============================================================================
443 //function : Descendants
444 //purpose  :
445 //=============================================================================
446 void Graphic3d_Structure::Descendants (Graphic3d_MapOfStructure& theSet) const
447 {
448   for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
449   {
450     theSet.Add (anIter.Value());
451   }
452 }
453
454 //=============================================================================
455 //function : AppendAncestor
456 //purpose  :
457 //=============================================================================
458 Standard_Boolean Graphic3d_Structure::AppendAncestor (Graphic3d_Structure* theAncestor)
459 {
460   const Standard_Integer aSize = myAncestors.Size();
461
462   return myAncestors.Add (theAncestor) > aSize; // new object
463 }
464
465 //=============================================================================
466 //function : AppendDescendant
467 //purpose  :
468 //=============================================================================
469 Standard_Boolean Graphic3d_Structure::AppendDescendant (Graphic3d_Structure* theDescendant)
470 {
471   const Standard_Integer aSize = myDescendants.Size();
472
473   return myDescendants.Add (theDescendant) > aSize; // new object
474 }
475
476 //=============================================================================
477 //function : RemoveAncestor
478 //purpose  :
479 //=============================================================================
480 Standard_Boolean Graphic3d_Structure::RemoveAncestor (Graphic3d_Structure* theAncestor)
481 {
482   const Standard_Integer anIndex = myAncestors.FindIndex (theAncestor);
483
484   if (anIndex != 0)
485   {
486     myAncestors.Swap (anIndex, myAncestors.Size());
487     myAncestors.RemoveLast();
488   }
489
490   return anIndex != 0; // object was found
491 }
492
493 //=============================================================================
494 //function : RemoveDescendant
495 //purpose  :
496 //=============================================================================
497 Standard_Boolean Graphic3d_Structure::RemoveDescendant (Graphic3d_Structure* theDescendant)
498 {
499   const Standard_Integer anIndex = myDescendants.FindIndex (theDescendant);
500
501   if (anIndex != 0)
502   {
503     myDescendants.Swap (anIndex, myDescendants.Size());
504     myDescendants.RemoveLast();
505   }
506
507   return anIndex != 0; // object was found
508 }
509
510 //=============================================================================
511 //function : Connect
512 //purpose  :
513 //=============================================================================
514 void Graphic3d_Structure::Connect (Graphic3d_Structure* theStructure,
515                                    Graphic3d_TypeOfConnection theType,
516                                    Standard_Boolean theWithCheck)
517 {
518   if (IsDeleted())
519   {
520     return;
521   }
522
523   // cycle detection
524   if (theWithCheck
525    && !Graphic3d_Structure::AcceptConnection (this, theStructure, theType))
526   {
527     return;
528   }
529
530   if (theType == Graphic3d_TOC_DESCENDANT)
531   {
532     if (!AppendDescendant (theStructure))
533     {
534       return;
535     }
536
537     CalculateBoundBox();
538     theStructure->Connect (this, Graphic3d_TOC_ANCESTOR);
539
540     GraphicConnect (theStructure);
541     myStructureManager->Connect (this, theStructure);
542
543     Update (true);
544   }
545   else // Graphic3d_TOC_ANCESTOR
546   {
547     if (!AppendAncestor (theStructure))
548     {
549       return;
550     }
551
552     CalculateBoundBox();
553     theStructure->Connect (this, Graphic3d_TOC_DESCENDANT);
554
555     // myStructureManager->Connect is called in case if connection between parent and child
556   }
557 }
558
559 //=============================================================================
560 //function : Disconnect
561 //purpose  :
562 //=============================================================================
563 void Graphic3d_Structure::Disconnect (Graphic3d_Structure* theStructure)
564 {
565   if (IsDeleted())
566   {
567     return;
568   }
569
570   if (RemoveDescendant (theStructure))
571   {
572     theStructure->Disconnect (this);
573
574     GraphicDisconnect (theStructure);
575     myStructureManager->Disconnect (this, theStructure);
576
577     CalculateBoundBox();
578     Update (true);
579   }
580   else if (RemoveAncestor (theStructure))
581   {
582     theStructure->Disconnect (this);
583     CalculateBoundBox();
584
585     // no call of myStructureManager->Disconnect in case of an ancestor
586   }
587 }
588
589 //=============================================================================
590 //function : DisconnectAll
591 //purpose  :
592 //=============================================================================
593 void Graphic3d_Structure::DisconnectAll (const Graphic3d_TypeOfConnection theType)
594 {
595   if (IsDeleted()) return;
596
597   switch (theType)
598   {
599     case Graphic3d_TOC_DESCENDANT:
600     {
601       for (Standard_Integer anIdx = 1, aLength = myDescendants.Size(); anIdx <= aLength; ++anIdx)
602       {
603         // Value (1) instead of Value (i) as myDescendants
604         // is modified by :
605         // Graphic3d_Structure::Disconnect (AStructure)
606         // that takes AStructure from myDescendants
607         myDescendants.FindKey (1)->Disconnect (this);
608       }
609       break;
610     }
611     case Graphic3d_TOC_ANCESTOR:
612     {
613       for (Standard_Integer anIdx = 1, aLength = myAncestors.Size(); anIdx <= aLength; ++anIdx)
614       {
615         // Value (1) instead of Value (i) as myAncestors
616         // is modified by :
617         // Graphic3d_Structure::Disconnect (AStructure)
618         // that takes AStructure from myAncestors
619         myAncestors.FindKey (1)->Disconnect (this);
620       }
621       break;
622     }
623   }
624 }
625
626 //=============================================================================
627 //function : SetTransform
628 //purpose  :
629 //=============================================================================
630 void Graphic3d_Structure::SetTransformation (const Handle(TopLoc_Datum3D)& theTrsf)
631 {
632   if (IsDeleted()) return;
633
634   const Standard_Boolean wasTransformed = IsTransformed();
635
636   if (!theTrsf.IsNull()
637     && theTrsf->Trsf().Form() == gp_Identity)
638   {
639     myCStructure->SetTransformation (Handle(TopLoc_Datum3D)());
640   }
641   else
642   {
643     myCStructure->SetTransformation (theTrsf);
644   }
645
646   // If transformation, no validation of hidden already calculated parts
647   if (IsTransformed() || (!IsTransformed() && wasTransformed))
648   {
649     ReCompute();
650   }
651
652   myStructureManager->SetTransform (this, theTrsf);
653
654   Update (true);
655 }
656
657 //=============================================================================
658 //function : MinMaxValues
659 //purpose  :
660 //=============================================================================
661 Bnd_Box Graphic3d_Structure::MinMaxValues (const Standard_Boolean theToIgnoreInfiniteFlag) const
662 {
663   Graphic3d_BndBox3d aBox;
664   addTransformed (aBox, theToIgnoreInfiniteFlag);
665   if (!aBox.IsValid())
666   {
667     return Bnd_Box();
668   }
669
670   Bnd_Box aResult;
671   aResult.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
672                   aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
673
674   Standard_Real aLimMin = ShortRealFirst() + 1.0;
675   Standard_Real aLimMax = ShortRealLast()  - 1.0;
676   gp_Pnt aMin = aResult.CornerMin();
677   gp_Pnt aMax = aResult.CornerMax();
678   if (aMin.X() < aLimMin && aMin.Y() < aLimMin && aMin.Z() < aLimMin
679    && aMax.X() > aLimMax && aMax.Y() > aLimMax && aMax.Z() > aLimMax)
680   {
681     //For structure which infinite in all three dimensions the Whole bounding box will be returned
682     aResult.SetWhole();
683   }
684   return aResult;
685 }
686
687 //=============================================================================
688 //function : SetTransformPersistence
689 //purpose  :
690 //=============================================================================
691 void Graphic3d_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
692 {
693   if (IsDeleted())
694   {
695     return;
696   }
697
698   myCStructure->SetTransformPersistence (theTrsfPers);
699 }
700
701 //=============================================================================
702 //function : Remove
703 //purpose  :
704 //=============================================================================
705 void Graphic3d_Structure::Remove (Graphic3d_Structure* thePtr,
706                                   const Graphic3d_TypeOfConnection theType)
707 {
708   if (theType == Graphic3d_TOC_DESCENDANT)
709   {
710     RemoveDescendant (thePtr);
711   }
712   else
713   {
714     RemoveAncestor (thePtr);
715   }
716 }
717
718 //=============================================================================
719 //function : NewGroup
720 //purpose  :
721 //=============================================================================
722 Handle(Graphic3d_Group) Graphic3d_Structure::NewGroup()
723 {
724   return myCStructure->NewGroup (this);
725 }
726
727 //=============================================================================
728 //function : Remove
729 //purpose  :
730 //=============================================================================
731 void Graphic3d_Structure::Remove (const Handle(Graphic3d_Group)& theGroup)
732 {
733   if (theGroup.IsNull()
734    || theGroup->myStructure != this)
735   {
736     return;
737   }
738
739   myCStructure->RemoveGroup (theGroup);
740   theGroup->myStructure = NULL;
741 }
742
743 //=============================================================================
744 //function : StructureManager
745 //purpose  :
746 //=============================================================================
747 Handle(Graphic3d_StructureManager) Graphic3d_Structure::StructureManager() const
748 {
749   return myStructureManager;
750 }
751
752 //=============================================================================
753 //function : minMaxCoord
754 //purpose  :
755 //=============================================================================
756 Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord() const
757 {
758   Graphic3d_BndBox4f aBnd;
759   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
760   {
761     if (!aGroupIter.Value()->TransformPersistence().IsNull())
762     {
763       continue; // should be translated to current view orientation to make sense
764     }
765
766     aBnd.Combine (aGroupIter.Value()->BoundingBox());
767   }
768   return aBnd;
769 }
770
771 //=============================================================================
772 //function : addTransformed
773 //purpose  :
774 //=============================================================================
775 void Graphic3d_Structure::getBox (Graphic3d_BndBox3d&    theBox,
776                                   const Standard_Boolean theToIgnoreInfiniteFlag) const
777 {
778   Graphic3d_BndBox4f aBoxF = minMaxCoord();
779   if (aBoxF.IsValid())
780   {
781     theBox = Graphic3d_BndBox3d (Graphic3d_Vec3d ((Standard_Real )aBoxF.CornerMin().x(),
782                                                   (Standard_Real )aBoxF.CornerMin().y(),
783                                                   (Standard_Real )aBoxF.CornerMin().z()),
784                                  Graphic3d_Vec3d ((Standard_Real )aBoxF.CornerMax().x(),
785                                                   (Standard_Real )aBoxF.CornerMax().y(),
786                                                   (Standard_Real )aBoxF.CornerMax().z()));
787     if (IsInfinite()
788     && !theToIgnoreInfiniteFlag)
789     {
790       const Graphic3d_Vec3d aDiagVec = theBox.CornerMax() - theBox.CornerMin();
791       if (aDiagVec.SquareModulus() >= 500000.0 * 500000.0)
792       {
793         // bounding borders of infinite line has been calculated as own point in center of this line
794         theBox = Graphic3d_BndBox3d ((theBox.CornerMin() + theBox.CornerMax()) * 0.5);
795       }
796       else
797       {
798         theBox = Graphic3d_BndBox3d (Graphic3d_Vec3d (RealFirst(), RealFirst(), RealFirst()),
799                                      Graphic3d_Vec3d (RealLast(),  RealLast(),  RealLast()));
800         return;
801       }
802     }
803   }
804 }
805
806 //=============================================================================
807 //function : addTransformed
808 //purpose  :
809 //=============================================================================
810 void Graphic3d_Structure::addTransformed (Graphic3d_BndBox3d&    theBox,
811                                           const Standard_Boolean theToIgnoreInfiniteFlag) const
812 {
813   Graphic3d_BndBox3d aCombinedBox, aBox;
814   getBox (aCombinedBox, theToIgnoreInfiniteFlag);
815
816   for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
817   {
818     const Graphic3d_Structure* aStruct = anIter.Value();
819     aStruct->getBox (aBox, theToIgnoreInfiniteFlag);
820     aCombinedBox.Combine (aBox);
821   }
822
823   aBox = aCombinedBox;
824   if (aBox.IsValid())
825   {
826     if (!myCStructure->Transformation().IsNull())
827     {
828       TransformBoundaries (myCStructure->Transformation()->Trsf(),
829                            aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
830                            aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
831     }
832
833     // if box is still valid after transformation
834     if (aBox.IsValid())
835     {
836       theBox.Combine (aBox);
837     }
838     else // it was infinite, return untransformed
839     {
840       theBox.Combine (aCombinedBox);
841     }
842   }
843 }
844
845 //=============================================================================
846 //function : Transforms
847 //purpose  :
848 //=============================================================================
849 void Graphic3d_Structure::Transforms (const gp_Trsf& theTrsf,
850                                       const Standard_Real theX,    const Standard_Real theY,    const Standard_Real theZ,
851                                       Standard_Real&      theNewX, Standard_Real&      theNewY, Standard_Real&      theNewZ)
852 {
853   const Standard_Real aRL = RealLast();
854   const Standard_Real aRF = RealFirst();
855   theNewX = theX;
856   theNewY = theY;
857   theNewZ = theZ;
858   if ((theX == aRF) || (theY == aRF) || (theZ == aRF)
859    || (theX == aRL) || (theY == aRL) || (theZ == aRL))
860   {
861     return;
862   }
863
864   theTrsf.Transforms (theNewX, theNewY, theNewZ);
865 }
866
867 //=============================================================================
868 //function : Transforms
869 //purpose  :
870 //=============================================================================
871 void Graphic3d_Structure::TransformBoundaries (const gp_Trsf& theTrsf,
872                                                Standard_Real& theXMin,
873                                                Standard_Real& theYMin,
874                                                Standard_Real& theZMin,
875                                                Standard_Real& theXMax,
876                                                Standard_Real& theYMax,
877                                                Standard_Real& theZMax)
878 {
879   Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax, anU, aV, aW;
880
881   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMin, aXMin, aYMin, aZMin);
882   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMax, aXMax, aYMax, aZMax);
883
884   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMax, anU, aV, aW);
885   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
886   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
887   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
888
889   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMax, anU, aV, aW);
890   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
891   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
892   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
893
894   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMin, anU, aV, aW);
895   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
896   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
897   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
898
899   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMin, anU, aV, aW);
900   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
901   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
902   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
903
904   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMax, anU, aV, aW);
905   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
906   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
907   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
908
909   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMin, anU, aV, aW);
910   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
911   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
912   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
913
914   theXMin = aXMin;
915   theYMin = aYMin;
916   theZMin = aZMin;
917   theXMax = aXMax;
918   theYMax = aYMax;
919   theZMax = aZMax;
920 }
921
922 //=============================================================================
923 //function : Network
924 //purpose  :
925 //=============================================================================
926 void Graphic3d_Structure::Network (Graphic3d_Structure* theStructure,
927                                    const Graphic3d_TypeOfConnection theType,
928                                    NCollection_Map<Graphic3d_Structure*>& theSet)
929 {
930   theSet.Add (theStructure);
931   switch (theType)
932   {
933     case Graphic3d_TOC_DESCENDANT:
934     {
935       for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (theStructure->myDescendants); anIter.More(); anIter.Next())
936       {
937         Graphic3d_Structure::Network (anIter.Value(), theType, theSet);
938       }
939       break;
940     }
941     case Graphic3d_TOC_ANCESTOR:
942     {
943       for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (theStructure->myAncestors); anIter.More(); anIter.Next())
944       {
945         Graphic3d_Structure::Network (anIter.Value(), theType, theSet);
946       }
947       break;
948     }
949   }
950 }
951
952 //=============================================================================
953 //function : PrintNetwork
954 //purpose  :
955 //=============================================================================
956 void Graphic3d_Structure::PrintNetwork (const Handle(Graphic3d_Structure)& theStructure,
957                                         const Graphic3d_TypeOfConnection   theType)
958 {
959   NCollection_Map<Graphic3d_Structure*> aSet;
960   Graphic3d_Structure::Network (theStructure.get(), theType, aSet);
961   for (NCollection_Map<Graphic3d_Structure*>::Iterator anIter (aSet); anIter.More(); anIter.Next())
962   {
963     std::cout << "\tIdent " << (anIter.Key())->Identification () << "\n";
964   }
965   std::cout << std::flush;
966 }
967
968 //=============================================================================
969 //function : Update
970 //purpose  :
971 //=============================================================================
972 void Graphic3d_Structure::Update (const bool theUpdateLayer) const
973 {
974   if (IsDeleted())
975   {
976     return;
977   }
978
979   myStructureManager->Update (theUpdateLayer ? myCStructure->ZLayer() : Graphic3d_ZLayerId_UNKNOWN);
980 }
981
982 //=======================================================================
983 //function : SetZLayer
984 //purpose  :
985 //=======================================================================
986 void Graphic3d_Structure::SetZLayer (const Graphic3d_ZLayerId theLayerId)
987 {
988   // if the structure is not displayed, unable to change its display layer
989   if (IsDeleted ())
990     return;
991
992   myStructureManager->ChangeZLayer (this, theLayerId);
993   myCStructure->SetZLayer (theLayerId);
994 }
995
996 //=======================================================================
997 //function : DumpJson
998 //purpose  : 
999 //=======================================================================
1000 void Graphic3d_Structure::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
1001 {
1002   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
1003
1004   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myStructureManager)
1005   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myCStructure.get())
1006
1007   for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myAncestors); anIter.More(); anIter.Next())
1008   {
1009     Graphic3d_Structure* anAncestor = anIter.Value();
1010     OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, anAncestor)
1011   }
1012
1013   for (NCollection_IndexedMap<Graphic3d_Structure*>::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
1014   {
1015     Graphic3d_Structure* aDescendant = anIter.Value();
1016     OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, aDescendant)
1017   }
1018
1019   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myOwner)
1020   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myVisual)
1021   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myComputeVisual)
1022 }