0028927: Visualization - Graphic3d_StructureManager destructor should invalidate...
[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 <Graphic3d_Vector.hxx>
30 #include <Quantity_Color.hxx>
31 #include <Standard_Type.hxx>
32
33 #include "Graphic3d_Structure.pxx"
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 : myStructureManager(theManager.operator->()),
45   myComputeVisual   (Graphic3d_TOS_ALL),
46   myOwner           (NULL),
47   myVisual          (Graphic3d_TOS_ALL)
48 {
49   myCStructure = theManager->GraphicDriver()->CreateStructure (theManager);
50 }
51
52 //=============================================================================
53 //function : Graphic3d_Structure
54 //purpose  :
55 //=============================================================================
56 Graphic3d_Structure::Graphic3d_Structure (const Handle(Graphic3d_StructureManager)& theManager,
57                                           const Handle(Graphic3d_Structure)&        thePrs)
58 : myStructureManager(theManager.operator->()),
59   myComputeVisual   (thePrs->myComputeVisual),
60   myOwner           (thePrs->myOwner),
61   myVisual          (thePrs->myVisual)
62 {
63   myCStructure = thePrs->myCStructure->ShadowLink (theManager);
64 }
65
66 //=============================================================================
67 //function : ~Graphic3d_Structure
68 //purpose  :
69 //=============================================================================
70 Graphic3d_Structure::~Graphic3d_Structure()
71 {
72   // as myStructureManager can be already destroyed,
73   // avoid attempts to access it
74   myStructureManager = NULL;
75   Remove();
76 }
77
78 //=============================================================================
79 //function : Clear
80 //purpose  :
81 //=============================================================================
82 void Graphic3d_Structure::Clear (const Standard_Boolean theWithDestruction)
83 {
84   if (IsDeleted()) return;
85
86   // clean groups in graphics driver at first
87   GraphicClear (theWithDestruction);
88
89   myCStructure->ContainsFacet = 0;
90   myStructureManager->Clear (this, theWithDestruction);
91
92   Update (true);
93 }
94
95 //=======================================================================
96 //function : CalculateBoundBox
97 //purpose  : Calculates AABB of a structure.
98 //=======================================================================
99 void Graphic3d_Structure::CalculateBoundBox()
100 {
101   Graphic3d_BndBox3d aBox;
102   addTransformed (aBox, Standard_True);
103   myCStructure->ChangeBoundingBox() = aBox;
104 }
105
106 //=============================================================================
107 //function : Remove
108 //purpose  :
109 //=============================================================================
110 void Graphic3d_Structure::Remove()
111 {
112   if (IsDeleted()) return;
113
114   // clean groups in graphics driver at first; this is also should be done
115   // to avoid unwanted group cleaning in group's destructor
116   // Pass Standard_False to Clear(..) method to avoid updating in
117   // structure manager, it isn't necessary, besides of it structure manager
118   // could be already destroyed and invalid pointers used in structure;
119   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
120   {
121     aGroupIter.ChangeValue()->Clear (Standard_False);
122   }
123
124   Standard_Address APtr = (void *) this;
125   // It is necessary to remove the eventual pointer on the structure
126   // that can be destroyed, in the list of descendants
127   // of ancestors of this structure and in the list of ancestors
128   // of descendants of the same structure.
129
130   for (Standard_Integer aStructIdx = 1, aNbDesc = myDescendants.Size(); aStructIdx <= aNbDesc; ++aStructIdx)
131   {
132     ((Graphic3d_Structure *)myDescendants.FindKey (aStructIdx))->Remove (APtr, Graphic3d_TOC_ANCESTOR);
133   }
134
135   for (Standard_Integer aStructIdx = 1, aNbAnces = myAncestors.Size(); aStructIdx <= aNbAnces; ++aStructIdx)
136   {
137     ((Graphic3d_Structure *)myAncestors.FindKey (aStructIdx))->Remove (APtr, Graphic3d_TOC_DESCENDANT);
138   }
139
140   // Destruction of me in the graphic library
141   const Standard_Integer aStructId = myCStructure->Id;
142   myCStructure->GraphicDriver()->RemoveIdentification(aStructId);
143   myCStructure->GraphicDriver()->RemoveStructure (myCStructure);
144   myCStructure.Nullify();
145 }
146
147 //=============================================================================
148 //function : Display
149 //purpose  :
150 //=============================================================================
151 void Graphic3d_Structure::Display()
152 {
153   if (IsDeleted()) return;
154
155   if (!myCStructure->stick)
156   {
157     myCStructure->stick = 1;
158     myStructureManager->Display (this);
159   }
160
161   if (myCStructure->visible != 1)
162   {
163     myCStructure->visible = 1;
164     myCStructure->OnVisibilityChanged();
165   }
166 }
167
168 //=============================================================================
169 //function : SetIsForHighlight
170 //purpose  :
171 //=============================================================================
172 void Graphic3d_Structure::SetIsForHighlight (const Standard_Boolean isForHighlight)
173 {
174   myCStructure->IsForHighlight = isForHighlight;
175 }
176
177 //=============================================================================
178 //function : SetDisplayPriority
179 //purpose  :
180 //=============================================================================
181 void Graphic3d_Structure::SetDisplayPriority (const Standard_Integer thePriority)
182 {
183   if (IsDeleted()
184    || thePriority == myCStructure->Priority)
185   {
186     return;
187   }
188
189   myCStructure->PreviousPriority = myCStructure->Priority;
190   myCStructure->Priority         = thePriority;
191
192   if (myCStructure->Priority != myCStructure->PreviousPriority)
193   {
194     Graphic3d_PriorityDefinitionError_Raise_if ((myCStructure->Priority > Structure_MAX_PRIORITY)
195                                              || (myCStructure->Priority < Structure_MIN_PRIORITY),
196                                                 "Bad value for StructurePriority");
197     if (myCStructure->stick)
198     {
199       myStructureManager->ChangeDisplayPriority (this, myCStructure->PreviousPriority, myCStructure->Priority);
200     }
201   }
202 }
203
204 //=============================================================================
205 //function : ResetDisplayPriority
206 //purpose  :
207 //=============================================================================
208 void Graphic3d_Structure::ResetDisplayPriority()
209 {
210   if (IsDeleted()
211    || myCStructure->Priority == myCStructure->PreviousPriority)
212   {
213     return;
214   }
215
216   const Standard_Integer aPriority = myCStructure->Priority;
217   myCStructure->Priority = myCStructure->PreviousPriority;
218   if (myCStructure->stick)
219   {
220     myStructureManager->ChangeDisplayPriority (this, aPriority, myCStructure->Priority);
221   }
222 }
223
224 //=============================================================================
225 //function : DisplayPriority
226 //purpose  :
227 //=============================================================================
228 Standard_Integer Graphic3d_Structure::DisplayPriority() const
229 {
230   return myCStructure->Priority;
231 }
232
233 //=============================================================================
234 //function : Erase
235 //purpose  :
236 //=============================================================================
237 void Graphic3d_Structure::Erase()
238 {
239   if (IsDeleted())
240   {
241     return;
242   }
243
244   if (myCStructure->stick)
245   {
246     myCStructure->stick = 0;
247     myStructureManager->Erase (this);
248   }
249 }
250
251 //=============================================================================
252 //function : Highlight
253 //purpose  :
254 //=============================================================================
255 void Graphic3d_Structure::Highlight (const Handle(Graphic3d_PresentationAttributes)& theStyle,
256                                      const Standard_Boolean theToUpdateMgr)
257 {
258   if (IsDeleted())
259   {
260     return;
261   }
262
263   SetDisplayPriority (Structure_MAX_PRIORITY - 1);
264
265   myCStructure->GraphicHighlight (theStyle, this);
266
267   if (!theToUpdateMgr)
268   {
269     return;
270   }
271
272   if (myCStructure->stick)
273   {
274     myStructureManager->Highlight (this);
275   }
276
277   Update();
278 }
279
280 //=============================================================================
281 //function : SetVisible
282 //purpose  :
283 //=============================================================================
284 void Graphic3d_Structure::SetVisible (const Standard_Boolean theValue)
285 {
286   if (IsDeleted()) return;
287
288   const unsigned isVisible = theValue ? 1 : 0;
289   if (myCStructure->visible == isVisible)
290   {
291     return;
292   }
293
294   myCStructure->visible = isVisible;
295   myCStructure->OnVisibilityChanged();
296   Update (true);
297 }
298
299 //=============================================================================
300 //function : UnHighlight
301 //purpose  :
302 //=============================================================================
303 void Graphic3d_Structure::UnHighlight()
304 {
305   if (IsDeleted()) return;
306
307   if (myCStructure->highlight)
308   {
309     myCStructure->highlight = 0;
310
311     myCStructure->GraphicUnhighlight();
312     myStructureManager->UnHighlight (this);
313
314     ResetDisplayPriority();
315     Update();
316   }
317 }
318
319 //=============================================================================
320 //function : HighlightStyle
321 //purpose  :
322 //=============================================================================
323 const Handle(Graphic3d_PresentationAttributes)& Graphic3d_Structure::HighlightStyle() const
324 {
325   return myCStructure->HighlightStyle();
326 }
327
328 //=============================================================================
329 //function : IsDisplayed
330 //purpose  :
331 //=============================================================================
332 Standard_Boolean Graphic3d_Structure::IsDisplayed() const
333 {
334   return myCStructure->stick ? Standard_True : Standard_False;
335 }
336
337 //=============================================================================
338 //function : IsDeleted
339 //purpose  :
340 //=============================================================================
341 Standard_Boolean Graphic3d_Structure::IsDeleted() const
342 {
343   return myCStructure.IsNull();
344 }
345
346 //=============================================================================
347 //function : IsHighlighted
348 //purpose  :
349 //=============================================================================
350 Standard_Boolean Graphic3d_Structure::IsHighlighted() const
351 {
352   return myCStructure->highlight ? Standard_True : Standard_False;
353 }
354
355 //=============================================================================
356 //function : IsVisible
357 //purpose  :
358 //=============================================================================
359 Standard_Boolean Graphic3d_Structure::IsVisible() const
360 {
361   return myCStructure->visible ? Standard_True : Standard_False;
362 }
363
364 //=============================================================================
365 //function : IsTransformed
366 //purpose  :
367 //=============================================================================
368 Standard_Boolean Graphic3d_Structure::IsTransformed() const
369 {
370   return !myCStructure->Transformation().IsNull()
371        && myCStructure->Transformation()->Form() != gp_Identity;
372 }
373
374 //=============================================================================
375 //function : ContainsFacet
376 //purpose  :
377 //=============================================================================
378 Standard_Boolean Graphic3d_Structure::ContainsFacet() const
379 {
380   if (IsDeleted())
381   {
382     return Standard_False;
383   }
384   else if (myCStructure->ContainsFacet > 0)
385   {
386     // if one of groups contains at least one facet, the structure contains it too
387     return Standard_True;
388   }
389
390   // stop at the first descendant containing at least one facet
391   for (Graphic3d_IndexedMapOfAddress::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
392   {
393     if (((const Graphic3d_Structure *)anIter.Value())->ContainsFacet())
394     {
395       return Standard_True;
396     }
397   }
398   return Standard_False;
399 }
400
401 //=============================================================================
402 //function : IsEmpty
403 //purpose  :
404 //=============================================================================
405 Standard_Boolean Graphic3d_Structure::IsEmpty() const
406 {
407   if (IsDeleted())
408   {
409     return Standard_True;
410   }
411
412   // structure is empty:
413   // - if all these groups are empty
414   // - or if all groups are empty and all their descendants are empty
415   // - or if all its descendants are empty
416   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
417   {
418     if (!aGroupIter.Value()->IsEmpty())
419     {
420       return Standard_False;
421     }
422   }
423
424   // stop at the first non-empty descendant
425   for (Graphic3d_IndexedMapOfAddress::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
426   {
427     if (!((const Graphic3d_Structure* )anIter.Value())->IsEmpty())
428     {
429       return Standard_False;
430     }
431   }
432   return Standard_True;
433 }
434
435 //=============================================================================
436 //function : GroupsWithFacet
437 //purpose  :
438 //=============================================================================
439 void Graphic3d_Structure::GroupsWithFacet (const Standard_Integer theDelta)
440 {
441   myCStructure->ContainsFacet = myCStructure->ContainsFacet + theDelta;
442   if (myCStructure->ContainsFacet < 0)
443   {
444     myCStructure->ContainsFacet = 0;
445   }
446 }
447
448 //=============================================================================
449 //function : Compute
450 //purpose  :
451 //=============================================================================
452 void Graphic3d_Structure::Compute()
453 {
454   // Implemented by Presentation
455 }
456
457 //=============================================================================
458 //function : Compute
459 //purpose  :
460 //=============================================================================
461 Handle(Graphic3d_Structure) Graphic3d_Structure::Compute (const Handle(Graphic3d_DataStructureManager)& )
462 {
463   // Implemented by Presentation
464   return this;
465 }
466
467 //=============================================================================
468 //function : Compute
469 //purpose  :
470 //=============================================================================
471 Handle(Graphic3d_Structure) Graphic3d_Structure::Compute (const Handle(Graphic3d_DataStructureManager)& ,
472                                                           const Handle(Geom_Transformation)& )
473 {
474   // Implemented by Presentation
475   return this;
476 }
477
478 //=============================================================================
479 //function : Compute
480 //purpose  :
481 //=============================================================================
482 void Graphic3d_Structure::Compute (const Handle(Graphic3d_DataStructureManager)& ,
483                                    Handle(Graphic3d_Structure)& )
484 {
485   // Implemented by Presentation
486 }
487
488 //=============================================================================
489 //function : Compute
490 //purpose  :
491 //=============================================================================
492 void Graphic3d_Structure::Compute (const Handle(Graphic3d_DataStructureManager)& ,
493                                    const Handle(Geom_Transformation)& ,
494                                    Handle(Graphic3d_Structure)& )
495 {
496   // Implemented by Presentation
497 }
498
499 //=============================================================================
500 //function : ReCompute
501 //purpose  :
502 //=============================================================================
503 void Graphic3d_Structure::ReCompute()
504 {
505   myStructureManager->ReCompute (this);
506 }
507
508 //=============================================================================
509 //function : ReCompute
510 //purpose  :
511 //=============================================================================
512 void Graphic3d_Structure::ReCompute (const Handle(Graphic3d_DataStructureManager)& theProjector)
513 {
514   myStructureManager->ReCompute (this, theProjector);
515 }
516
517 //=============================================================================
518 //function : SetInfiniteState
519 //purpose  :
520 //=============================================================================
521 void Graphic3d_Structure::SetInfiniteState (const Standard_Boolean theToSet)
522 {
523   myCStructure->IsInfinite = theToSet ? 1 : 0;
524 }
525
526 //=============================================================================
527 //function : IsInfinite
528 //purpose  :
529 //=============================================================================
530 Standard_Boolean Graphic3d_Structure::IsInfinite() const
531 {
532   return IsDeleted()
533        || myCStructure->IsInfinite;
534 }
535
536 //=============================================================================
537 //function : GraphicClear
538 //purpose  :
539 //=============================================================================
540 void Graphic3d_Structure::GraphicClear (const Standard_Boolean theWithDestruction)
541 {
542   if (myCStructure.IsNull())
543   {
544     return;
545   }
546
547   // clean and empty each group
548   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
549   {
550     aGroupIter.ChangeValue()->Clear();
551   }
552   if (!theWithDestruction)
553   {
554     return;
555   }
556
557   while (!myCStructure->Groups().IsEmpty())
558   {
559     Handle(Graphic3d_Group) aGroup = myCStructure->Groups().First();
560     aGroup->Remove();
561   }
562   myCStructure->Clear();
563 }
564
565 //=============================================================================
566 //function : GraphicConnect
567 //purpose  :
568 //=============================================================================
569 void Graphic3d_Structure::GraphicConnect (const Handle(Graphic3d_Structure)& theDaughter)
570 {
571   myCStructure->Connect (*theDaughter->myCStructure);
572 }
573
574 //=============================================================================
575 //function : GraphicDisconnect
576 //purpose  :
577 //=============================================================================
578 void Graphic3d_Structure::GraphicDisconnect (const Handle(Graphic3d_Structure)& theDaughter)
579 {
580   myCStructure->Disconnect (*theDaughter->myCStructure);
581 }
582
583 //=============================================================================
584 //function : Groups
585 //purpose  :
586 //=============================================================================
587 const Graphic3d_SequenceOfGroup& Graphic3d_Structure::Groups() const
588 {
589   return myCStructure->Groups();
590 }
591
592 //=============================================================================
593 //function : NumberOfGroups
594 //purpose  :
595 //=============================================================================
596 Standard_Integer Graphic3d_Structure::NumberOfGroups() const
597 {
598   return myCStructure->Groups().Length();
599 }
600
601 //=============================================================================
602 //function : SetVisual
603 //purpose  :
604 //=============================================================================
605 void Graphic3d_Structure::SetVisual (const Graphic3d_TypeOfStructure theVisual)
606 {
607   if (IsDeleted()
608    || myVisual == theVisual)
609   {
610     return;
611   }
612
613   if (!myCStructure->stick)
614   {
615     myVisual = theVisual;
616     SetComputeVisual (theVisual);
617   }
618   else
619   {
620     Erase();
621     myVisual = theVisual;
622     SetComputeVisual (theVisual);
623     Display();
624   }
625 }
626
627 //=============================================================================
628 //function : SetZoomLimit
629 //purpose  :
630 //=============================================================================
631 void Graphic3d_Structure::SetZoomLimit (const Standard_Real theLimitInf,
632                                         const Standard_Real theLimitSup)
633 {
634   (void )theLimitInf;
635   (void )theLimitSup;
636   Graphic3d_StructureDefinitionError_Raise_if (theLimitInf <= 0.0,
637                                                "Bad value for ZoomLimit inf");
638   Graphic3d_StructureDefinitionError_Raise_if (theLimitSup <= 0.0,
639                                                "Bad value for ZoomLimit sup");
640   Graphic3d_StructureDefinitionError_Raise_if (theLimitSup < theLimitInf,
641                                                "ZoomLimit sup < ZoomLimit inf");
642 }
643
644 //=============================================================================
645 //function : Visual
646 //purpose  :
647 //=============================================================================
648 Graphic3d_TypeOfStructure Graphic3d_Structure::Visual() const
649 {
650   return myVisual;
651 }
652
653 //=============================================================================
654 //function : AcceptConnection
655 //purpose  :
656 //=============================================================================
657 Standard_Boolean Graphic3d_Structure::AcceptConnection (const Handle(Graphic3d_Structure)& theStructure1,
658                                                         const Handle(Graphic3d_Structure)& theStructure2,
659                                                         const Graphic3d_TypeOfConnection   theType)
660 {
661   // cycle detection
662   Graphic3d_MapOfStructure aSet;
663   Graphic3d_Structure::Network (theStructure2, theType, aSet);
664   return !aSet.Contains (theStructure1);
665 }
666
667 //=============================================================================
668 //function : Ancestors
669 //purpose  :
670 //=============================================================================
671 void Graphic3d_Structure::Ancestors (Graphic3d_MapOfStructure& theSet) const
672 {
673   for (Graphic3d_IndexedMapOfAddress::Iterator anIter (myAncestors); anIter.More(); anIter.Next())
674   {
675     theSet.Add ((Graphic3d_Structure* )anIter.Value());
676   }
677 }
678
679 //=============================================================================
680 //function : SetOwner
681 //purpose  :
682 //=============================================================================
683 void Graphic3d_Structure::SetOwner (const Standard_Address theOwner)
684 {
685   myOwner = theOwner;
686 }
687
688 //=============================================================================
689 //function : Owner
690 //purpose  :
691 //=============================================================================
692 Standard_Address Graphic3d_Structure::Owner() const
693 {
694   return myOwner;
695 }
696
697 //=============================================================================
698 //function : Descendants
699 //purpose  :
700 //=============================================================================
701 void Graphic3d_Structure::Descendants (Graphic3d_MapOfStructure& theSet) const
702 {
703   for (Graphic3d_IndexedMapOfAddress::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
704   {
705     theSet.Add ((Graphic3d_Structure* )anIter.Value());
706   }
707 }
708
709 //=============================================================================
710 //function : AppendAncestor
711 //purpose  :
712 //=============================================================================
713 Standard_Boolean Graphic3d_Structure::AppendAncestor (const Standard_Address theAncestor)
714 {
715   const Standard_Integer aSize = myAncestors.Size();
716
717   return myAncestors.Add (theAncestor) > aSize; // new object
718 }
719
720 //=============================================================================
721 //function : AppendDescendant
722 //purpose  :
723 //=============================================================================
724 Standard_Boolean Graphic3d_Structure::AppendDescendant (const Standard_Address theDescendant)
725 {
726   const Standard_Integer aSize = myDescendants.Size();
727
728   return myDescendants.Add (theDescendant) > aSize; // new object
729 }
730
731 //=============================================================================
732 //function : RemoveAncestor
733 //purpose  :
734 //=============================================================================
735 Standard_Boolean Graphic3d_Structure::RemoveAncestor (const Standard_Address theAncestor)
736 {
737   const Standard_Integer anIndex = myAncestors.FindIndex (theAncestor);
738
739   if (anIndex != 0)
740   {
741     myAncestors.Swap (anIndex, myAncestors.Size());
742     myAncestors.RemoveLast();
743   }
744
745   return anIndex != 0; // object was found
746 }
747
748 //=============================================================================
749 //function : RemoveDescendant
750 //purpose  :
751 //=============================================================================
752 Standard_Boolean Graphic3d_Structure::RemoveDescendant (const Standard_Address theDescendant)
753 {
754   const Standard_Integer anIndex = myDescendants.FindIndex (theDescendant);
755
756   if (anIndex != 0)
757   {
758     myDescendants.Swap (anIndex, myDescendants.Size());
759     myDescendants.RemoveLast();
760   }
761
762   return anIndex != 0; // object was found
763 }
764
765 //=============================================================================
766 //function : Connect
767 //purpose  :
768 //=============================================================================
769 void Graphic3d_Structure::Connect (const Handle(Graphic3d_Structure)& theStructure,
770                                    const Graphic3d_TypeOfConnection   theType,
771                                    const Standard_Boolean             theWithCheck)
772 {
773   if (IsDeleted())
774   {
775     return;
776   }
777
778   // cycle detection
779   if (theWithCheck
780    && !Graphic3d_Structure::AcceptConnection (this, theStructure, theType))
781   {
782     return;
783   }
784
785   const Standard_Address aStructure = theStructure.operator->();
786
787   if (theType == Graphic3d_TOC_DESCENDANT)
788   {
789     if (!AppendDescendant (aStructure))
790     {
791       return;
792     }
793
794     CalculateBoundBox();
795     theStructure->Connect (this, Graphic3d_TOC_ANCESTOR);
796
797     GraphicConnect (theStructure);
798     myStructureManager->Connect (this, theStructure);
799
800     Update (true);
801   }
802   else // Graphic3d_TOC_ANCESTOR
803   {
804     if (!AppendAncestor (aStructure))
805     {
806       return;
807     }
808
809     CalculateBoundBox();
810     theStructure->Connect (this, Graphic3d_TOC_DESCENDANT);
811
812     // myStructureManager->Connect is called in case if connection between parent and child
813   }
814 }
815
816 //=============================================================================
817 //function : Disconnect
818 //purpose  :
819 //=============================================================================
820 void Graphic3d_Structure::Disconnect (const Handle(Graphic3d_Structure)& theStructure)
821 {
822   if (IsDeleted())
823   {
824     return;
825   }
826
827   const Standard_Address aStructure = theStructure.operator->();
828
829   if (RemoveDescendant (aStructure))
830   {
831     theStructure->Disconnect (this);
832
833     GraphicDisconnect (theStructure);
834     myStructureManager->Disconnect (this, theStructure);
835
836     CalculateBoundBox();
837     Update (true);
838   }
839   else if (RemoveAncestor (aStructure))
840   {
841     theStructure->Disconnect (this);
842     CalculateBoundBox();
843
844     // no call of myStructureManager->Disconnect in case of an ancestor
845   }
846 }
847
848 //=============================================================================
849 //function : DisconnectAll
850 //purpose  :
851 //=============================================================================
852 void Graphic3d_Structure::DisconnectAll (const Graphic3d_TypeOfConnection theType)
853 {
854   if (IsDeleted()) return;
855
856   switch (theType)
857   {
858     case Graphic3d_TOC_DESCENDANT:
859     {
860       for (Standard_Integer anIdx = 1, aLength = myDescendants.Size(); anIdx <= aLength; ++anIdx)
861       {
862         // Value (1) instead of Value (i) as myDescendants
863         // is modified by :
864         // Graphic3d_Structure::Disconnect (AStructure)
865         // that takes AStructure from myDescendants
866         ((Graphic3d_Structure* )(myDescendants.FindKey (1)))->Disconnect (this);
867       }
868       break;
869     }
870     case Graphic3d_TOC_ANCESTOR:
871     {
872       for (Standard_Integer anIdx = 1, aLength = myAncestors.Size(); anIdx <= aLength; ++anIdx)
873       {
874         // Value (1) instead of Value (i) as myAncestors
875         // is modified by :
876         // Graphic3d_Structure::Disconnect (AStructure)
877         // that takes AStructure from myAncestors
878         ((Graphic3d_Structure* )(myAncestors.FindKey (1)))->Disconnect (this);
879       }
880       break;
881     }
882   }
883 }
884
885 //=============================================================================
886 //function : SetTransform
887 //purpose  :
888 //=============================================================================
889 void Graphic3d_Structure::SetTransformation (const Handle(Geom_Transformation)& theTrsf)
890 {
891   if (IsDeleted()) return;
892
893   const Standard_Boolean wasTransformed = IsTransformed();
894
895   if (!theTrsf.IsNull()
896     && theTrsf->Trsf().Form() == gp_Identity)
897   {
898     myCStructure->SetTransformation (Handle(Geom_Transformation)());
899   }
900   else
901   {
902     myCStructure->SetTransformation (theTrsf);
903   }
904
905   // If transformation, no validation of hidden already calculated parts
906   if (IsTransformed() || (!IsTransformed() && wasTransformed))
907   {
908     ReCompute();
909   }
910
911   myStructureManager->SetTransform (this, theTrsf);
912
913   Update (true);
914 }
915
916 //=============================================================================
917 //function : MinMaxValues
918 //purpose  :
919 //=============================================================================
920 Bnd_Box Graphic3d_Structure::MinMaxValues (const Standard_Boolean theToIgnoreInfiniteFlag) const
921 {
922   Graphic3d_BndBox3d aBox;
923   addTransformed (aBox, theToIgnoreInfiniteFlag);
924   if (!aBox.IsValid())
925   {
926     return Bnd_Box();
927   }
928
929   Bnd_Box aResult;
930   aResult.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
931                   aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
932
933   Standard_Real aLimMin = ShortRealFirst() + 1.0;
934   Standard_Real aLimMax = ShortRealLast()  - 1.0;
935   gp_Pnt aMin = aResult.CornerMin();
936   gp_Pnt aMax = aResult.CornerMax();
937   if (aMin.X() < aLimMin && aMin.Y() < aLimMin && aMin.Z() < aLimMin
938    && aMax.X() > aLimMax && aMax.Y() > aLimMax && aMax.Z() > aLimMax)
939   {
940     //For structure which infinite in all three dimensions the Whole bounding box will be returned
941     aResult.SetWhole();
942   }
943   return aResult;
944 }
945
946 //=============================================================================
947 //function : Identification
948 //purpose  :
949 //=============================================================================
950 Standard_Integer Graphic3d_Structure::Identification() const
951 {
952   return myCStructure->Id;
953 }
954
955 //=============================================================================
956 //function : SetTransformPersistence
957 //purpose  :
958 //=============================================================================
959 void Graphic3d_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
960 {
961   if (IsDeleted())
962   {
963     return;
964   }
965
966   myCStructure->SetTransformPersistence (theTrsfPers);
967 }
968
969 //=============================================================================
970 //function : Remove
971 //purpose  :
972 //=============================================================================
973 void Graphic3d_Structure::Remove (const Standard_Address           thePtr,
974                                   const Graphic3d_TypeOfConnection theType)
975 {
976   if (theType == Graphic3d_TOC_DESCENDANT)
977   {
978     RemoveDescendant (thePtr);
979   }
980   else
981   {
982     RemoveAncestor (thePtr);
983   }
984 }
985
986 //=============================================================================
987 //function : NewGroup
988 //purpose  :
989 //=============================================================================
990 Handle(Graphic3d_Group) Graphic3d_Structure::NewGroup()
991 {
992   return myCStructure->NewGroup (this);
993 }
994
995 //=============================================================================
996 //function : Remove
997 //purpose  :
998 //=============================================================================
999 void Graphic3d_Structure::Remove (const Handle(Graphic3d_Group)& theGroup)
1000 {
1001   if (theGroup.IsNull()
1002    || theGroup->myStructure != this)
1003   {
1004     return;
1005   }
1006
1007   myCStructure->RemoveGroup (theGroup);
1008   theGroup->myStructure = NULL;
1009 }
1010
1011 //=============================================================================
1012 //function : StructureManager
1013 //purpose  :
1014 //=============================================================================
1015 Handle(Graphic3d_StructureManager) Graphic3d_Structure::StructureManager() const
1016 {
1017   return myStructureManager;
1018 }
1019
1020 //=============================================================================
1021 //function : minMaxCoord
1022 //purpose  :
1023 //=============================================================================
1024 Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord() const
1025 {
1026   Graphic3d_BndBox4f aBnd;
1027   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
1028   {
1029     aBnd.Combine (aGroupIter.Value()->BoundingBox());
1030   }
1031   return aBnd;
1032 }
1033
1034 //=============================================================================
1035 //function : addTransformed
1036 //purpose  :
1037 //=============================================================================
1038 void Graphic3d_Structure::getBox (Graphic3d_BndBox3d&    theBox,
1039                                   const Standard_Boolean theToIgnoreInfiniteFlag) const
1040 {
1041   Graphic3d_BndBox4f aBoxF = minMaxCoord();
1042   if (aBoxF.IsValid())
1043   {
1044     theBox = Graphic3d_BndBox3d (Graphic3d_Vec3d ((Standard_Real )aBoxF.CornerMin().x(),
1045                                                   (Standard_Real )aBoxF.CornerMin().y(),
1046                                                   (Standard_Real )aBoxF.CornerMin().z()),
1047                                  Graphic3d_Vec3d ((Standard_Real )aBoxF.CornerMax().x(),
1048                                                   (Standard_Real )aBoxF.CornerMax().y(),
1049                                                   (Standard_Real )aBoxF.CornerMax().z()));
1050     if (IsInfinite()
1051     && !theToIgnoreInfiniteFlag)
1052     {
1053       const Graphic3d_Vec3d aDiagVec = theBox.CornerMax() - theBox.CornerMin();
1054       if (aDiagVec.SquareModulus() >= 500000.0 * 500000.0)
1055       {
1056         // bounding borders of infinite line has been calculated as own point in center of this line
1057         theBox = Graphic3d_BndBox3d ((theBox.CornerMin() + theBox.CornerMax()) * 0.5);
1058       }
1059       else
1060       {
1061         theBox = Graphic3d_BndBox3d (Graphic3d_Vec3d (RealFirst(), RealFirst(), RealFirst()),
1062                                      Graphic3d_Vec3d (RealLast(),  RealLast(),  RealLast()));
1063         return;
1064       }
1065     }
1066   }
1067 }
1068
1069 //=============================================================================
1070 //function : addTransformed
1071 //purpose  :
1072 //=============================================================================
1073 void Graphic3d_Structure::addTransformed (Graphic3d_BndBox3d&    theBox,
1074                                           const Standard_Boolean theToIgnoreInfiniteFlag) const
1075 {
1076   Graphic3d_BndBox3d aCombinedBox, aBox;
1077   getBox (aCombinedBox, theToIgnoreInfiniteFlag);
1078
1079   for (Graphic3d_IndexedMapOfAddress::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
1080   {
1081     const Graphic3d_Structure* aStruct = (const Graphic3d_Structure* )anIter.Value();
1082     aStruct->getBox (aBox, theToIgnoreInfiniteFlag);
1083     aCombinedBox.Combine (aBox);
1084   }
1085
1086   aBox = aCombinedBox;
1087   if (aBox.IsValid())
1088   {
1089     if (!myCStructure->Transformation().IsNull())
1090     {
1091       TransformBoundaries (myCStructure->Transformation()->Trsf(),
1092                            aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
1093                            aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
1094     }
1095
1096     // if box is still valid after transformation
1097     if (aBox.IsValid())
1098     {
1099       theBox.Combine (aBox);
1100     }
1101     else // it was infinite, return untransformed
1102     {
1103       theBox.Combine (aCombinedBox);
1104     }
1105   }
1106 }
1107
1108 //=============================================================================
1109 //function : Transforms
1110 //purpose  :
1111 //=============================================================================
1112 void Graphic3d_Structure::Transforms (const gp_Trsf& theTrsf,
1113                                       const Standard_Real theX,    const Standard_Real theY,    const Standard_Real theZ,
1114                                       Standard_Real&      theNewX, Standard_Real&      theNewY, Standard_Real&      theNewZ)
1115 {
1116   const Standard_Real aRL = RealLast();
1117   const Standard_Real aRF = RealFirst();
1118   theNewX = theX;
1119   theNewY = theY;
1120   theNewZ = theZ;
1121   if ((theX == aRF) || (theY == aRF) || (theZ == aRF)
1122    || (theX == aRL) || (theY == aRL) || (theZ == aRL))
1123   {
1124     return;
1125   }
1126
1127   theTrsf.Transforms (theNewX, theNewY, theNewZ);
1128 }
1129
1130 //=============================================================================
1131 //function : Transforms
1132 //purpose  :
1133 //=============================================================================
1134 void Graphic3d_Structure::TransformBoundaries (const gp_Trsf& theTrsf,
1135                                                Standard_Real& theXMin,
1136                                                Standard_Real& theYMin,
1137                                                Standard_Real& theZMin,
1138                                                Standard_Real& theXMax,
1139                                                Standard_Real& theYMax,
1140                                                Standard_Real& theZMax)
1141 {
1142   Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax, anU, aV, aW;
1143
1144   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMin, aXMin, aYMin, aZMin);
1145   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMax, aXMax, aYMax, aZMax);
1146
1147   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMax, anU, aV, aW);
1148   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1149   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1150   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1151
1152   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMax, anU, aV, aW);
1153   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1154   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1155   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1156
1157   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMin, anU, aV, aW);
1158   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1159   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1160   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1161
1162   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMin, anU, aV, aW);
1163   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1164   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1165   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1166
1167   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMax, anU, aV, aW);
1168   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1169   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1170   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1171
1172   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMin, anU, aV, aW);
1173   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1174   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1175   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1176
1177   theXMin = aXMin;
1178   theYMin = aYMin;
1179   theZMin = aZMin;
1180   theXMax = aXMax;
1181   theYMax = aYMax;
1182   theZMax = aZMax;
1183 }
1184
1185 //=============================================================================
1186 //function : Network
1187 //purpose  :
1188 //=============================================================================
1189 void Graphic3d_Structure::Network (const Handle(Graphic3d_Structure)& theStructure,
1190                                    const Graphic3d_TypeOfConnection   theType,
1191                                    Graphic3d_MapOfStructure&          theSet)
1192 {
1193   Graphic3d_MapOfStructure aSetD, aSetA;
1194   theStructure->Descendants (aSetD);
1195   theStructure->Ancestors   (aSetA);
1196   theSet.Add (theStructure);
1197   switch (theType)
1198   {
1199     case Graphic3d_TOC_DESCENDANT:
1200       for (Graphic3d_MapIteratorOfMapOfStructure anIter (aSetD); anIter.More(); anIter.Next())
1201       {
1202         Graphic3d_Structure::Network (anIter.Key(), theType, theSet);
1203       }
1204       break;
1205     case Graphic3d_TOC_ANCESTOR:
1206       for (Graphic3d_MapIteratorOfMapOfStructure anIter (aSetA); anIter.More(); anIter.Next())
1207       {
1208         Graphic3d_Structure::Network (anIter.Key (), theType, theSet);
1209       }
1210       break;
1211   }
1212 }
1213
1214 //=============================================================================
1215 //function : PrintNetwork
1216 //purpose  :
1217 //=============================================================================
1218 void Graphic3d_Structure::PrintNetwork (const Handle(Graphic3d_Structure)& theStructure,
1219                                         const Graphic3d_TypeOfConnection   theType)
1220 {
1221   Graphic3d_MapOfStructure aSet;
1222   Graphic3d_Structure::Network (theStructure, theType, aSet);
1223   for (Graphic3d_MapIteratorOfMapOfStructure anIter (aSet); anIter.More(); anIter.Next())
1224   {
1225     std::cout << "\tIdent " << (anIter.Key())->Identification () << "\n";
1226   }
1227   std::cout << std::flush;
1228 }
1229
1230 //=============================================================================
1231 //function : Update
1232 //purpose  :
1233 //=============================================================================
1234 void Graphic3d_Structure::Update (const bool theUpdateLayer) const
1235 {
1236   if (IsDeleted())
1237   {
1238     return;
1239   }
1240
1241   myStructureManager->Update (theUpdateLayer ? myCStructure->ZLayer() : Graphic3d_ZLayerId_UNKNOWN);
1242 }
1243
1244 //=============================================================================
1245 //function : GraphicTransform
1246 //purpose  :
1247 //=============================================================================
1248 void Graphic3d_Structure::GraphicTransform (const Handle(Geom_Transformation)& theTrsf)
1249 {
1250   myCStructure->SetTransformation (theTrsf);
1251 }
1252
1253 //=============================================================================
1254 //function : ComputeVisual
1255 //purpose  :
1256 //=============================================================================
1257 Graphic3d_TypeOfStructure Graphic3d_Structure::ComputeVisual() const
1258 {
1259   return myComputeVisual;
1260 }
1261
1262 //=============================================================================
1263 //function : SetComputeVisual
1264 //purpose  :
1265 //=============================================================================
1266 void Graphic3d_Structure::SetComputeVisual (const Graphic3d_TypeOfStructure theVisual)
1267 {
1268   // The ComputeVisual is saved only if the structure is declared TOS_ALL, TOS_WIREFRAME or TOS_SHADING.
1269   // This declaration permits to calculate proper representation of the structure calculated by Compute instead of passage to TOS_COMPUTED.
1270   if (theVisual != Graphic3d_TOS_COMPUTED)
1271   {
1272     myComputeVisual = theVisual;
1273   }
1274 }
1275
1276 //=============================================================================
1277 //function : SetHLRValidation
1278 //purpose  :
1279 //=============================================================================
1280 void Graphic3d_Structure::SetHLRValidation (const Standard_Boolean theFlag)
1281 {
1282   myCStructure->HLRValidation = theFlag ? 1 : 0;
1283 }
1284
1285 //=============================================================================
1286 //function : HLRValidation
1287 //purpose  :
1288 //=============================================================================
1289 Standard_Boolean Graphic3d_Structure::HLRValidation() const
1290 {
1291   // Hidden parts stored in <me> are valid if :
1292   // 1/ the owner is defined.
1293   // 2/ they are not invalid.
1294   return myOwner != NULL
1295       && myCStructure->HLRValidation != 0;
1296 }
1297
1298 //=======================================================================
1299 //function : SetZLayer
1300 //purpose  :
1301 //=======================================================================
1302 void Graphic3d_Structure::SetZLayer (const Graphic3d_ZLayerId theLayerId)
1303 {
1304   // if the structure is not displayed, unable to change its display layer
1305   if (IsDeleted ())
1306     return;
1307
1308   myStructureManager->ChangeZLayer (this, theLayerId);
1309   myCStructure->SetZLayer (theLayerId);
1310 }
1311
1312 //=======================================================================
1313 //function : GetZLayer
1314 //purpose  :
1315 //=======================================================================
1316 Graphic3d_ZLayerId Graphic3d_Structure::GetZLayer() const
1317 {
1318   return myCStructure->ZLayer();
1319 }
1320
1321 //=======================================================================
1322 //function : SetClipPlanes
1323 //purpose  :
1324 //=======================================================================
1325 void Graphic3d_Structure::SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
1326 {
1327   myCStructure->SetClipPlanes (thePlanes);
1328 }
1329
1330 //=======================================================================
1331 //function : GetClipPlanes
1332 //purpose  :
1333 //=======================================================================
1334 const Handle(Graphic3d_SequenceOfHClipPlane)& Graphic3d_Structure::ClipPlanes() const
1335 {
1336   return myCStructure->ClipPlanes();
1337 }
1338
1339 //=======================================================================
1340 //function : SetMutable
1341 //purpose  :
1342 //=======================================================================
1343 void Graphic3d_Structure::SetMutable (const Standard_Boolean theIsMutable)
1344 {
1345   myCStructure->IsMutable = theIsMutable;
1346 }
1347
1348 //=======================================================================
1349 //function : IsMutable
1350 //purpose  :
1351 //=======================================================================
1352 Standard_Boolean Graphic3d_Structure::IsMutable() const
1353 {
1354   return myCStructure->IsMutable;
1355 }