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