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