1c51cef632bbda88e1666ef08ecd2614b4805d6a
[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 Handle(Graphic3d_TransformPers)& theTrsfPers)
1107 {
1108   if (IsDeleted())
1109   {
1110     return;
1111   }
1112
1113   myCStructure->SetTransformPersistence (theTrsfPers);
1114 }
1115
1116 //=============================================================================
1117 //function : Remove
1118 //purpose  :
1119 //=============================================================================
1120 void Graphic3d_Structure::Remove (const Standard_Address           thePtr,
1121                                   const Graphic3d_TypeOfConnection theType)
1122 {
1123   if (theType == Graphic3d_TOC_DESCENDANT)
1124   {
1125     RemoveDescendant (thePtr);
1126   }
1127   else
1128   {
1129     RemoveAncestor (thePtr);
1130   }
1131 }
1132
1133 //=============================================================================
1134 //function : NewGroup
1135 //purpose  :
1136 //=============================================================================
1137 Handle(Graphic3d_Group) Graphic3d_Structure::NewGroup()
1138 {
1139   return myCStructure->NewGroup (this);
1140 }
1141
1142 //=============================================================================
1143 //function : Remove
1144 //purpose  :
1145 //=============================================================================
1146 void Graphic3d_Structure::Remove (const Handle(Graphic3d_Group)& theGroup)
1147 {
1148   if (theGroup.IsNull()
1149    || theGroup->myStructure != this)
1150   {
1151     return;
1152   }
1153
1154   myCStructure->RemoveGroup (theGroup);
1155   theGroup->myStructure = NULL;
1156 }
1157
1158 //=============================================================================
1159 //function : StructureManager
1160 //purpose  :
1161 //=============================================================================
1162 Handle(Graphic3d_StructureManager) Graphic3d_Structure::StructureManager() const
1163 {
1164   return myStructureManager;
1165 }
1166
1167 //=============================================================================
1168 //function : minMaxCoord
1169 //purpose  :
1170 //=============================================================================
1171 Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord() const
1172 {
1173   Graphic3d_BndBox4f aBnd;
1174   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
1175   {
1176     aBnd.Combine (aGroupIter.Value()->BoundingBox());
1177   }
1178   return aBnd;
1179 }
1180
1181 //=============================================================================
1182 //function : addTransformed
1183 //purpose  :
1184 //=============================================================================
1185 void Graphic3d_Structure::getBox (Graphic3d_BndBox4d&    theBox,
1186                                   const Standard_Boolean theToIgnoreInfiniteFlag) const
1187 {
1188   Graphic3d_BndBox4f aBoxF = minMaxCoord();
1189   if (aBoxF.IsValid())
1190   {
1191     theBox = Graphic3d_BndBox4d (Graphic3d_Vec4d ((Standard_Real )aBoxF.CornerMin().x(),
1192                                                   (Standard_Real )aBoxF.CornerMin().y(),
1193                                                   (Standard_Real )aBoxF.CornerMin().z(),
1194                                                   (Standard_Real )aBoxF.CornerMin().w()),
1195                                  Graphic3d_Vec4d ((Standard_Real )aBoxF.CornerMax().x(),
1196                                                   (Standard_Real )aBoxF.CornerMax().y(),
1197                                                   (Standard_Real )aBoxF.CornerMax().z(),
1198                                                   (Standard_Real )aBoxF.CornerMax().w()));
1199     if (IsInfinite()
1200     && !theToIgnoreInfiniteFlag)
1201     {
1202       const Graphic3d_Vec4d aDiagVec = theBox.CornerMax() - theBox.CornerMin();
1203       if (aDiagVec.xyz().SquareModulus() >= 500000.0 * 500000.0)
1204       {
1205         // bounding borders of infinite line has been calculated as own point in center of this line
1206         theBox = Graphic3d_BndBox4d ((theBox.CornerMin() + theBox.CornerMax()) * 0.5);
1207       }
1208       else
1209       {
1210         theBox = Graphic3d_BndBox4d (Graphic3d_Vec4d (RealFirst(), RealFirst(), RealFirst(), 1.0),
1211                                      Graphic3d_Vec4d (RealLast(),  RealLast(),  RealLast(),  1.0));
1212         return;
1213       }
1214     }
1215   }
1216 }
1217
1218 //=============================================================================
1219 //function : addTransformed
1220 //purpose  :
1221 //=============================================================================
1222 void Graphic3d_Structure::addTransformed (Graphic3d_BndBox4d&    theBox,
1223                                           const Standard_Boolean theToIgnoreInfiniteFlag) const
1224 {
1225   Graphic3d_BndBox4d aCombinedBox, aBox;
1226   getBox (aCombinedBox, theToIgnoreInfiniteFlag);
1227
1228   for (Graphic3d_IndexedMapOfAddress::Iterator anIter (myDescendants); anIter.More(); anIter.Next())
1229   {
1230     const Graphic3d_Structure* aStruct = (const Graphic3d_Structure* )anIter.Value();
1231     aStruct->getBox (aBox, theToIgnoreInfiniteFlag);
1232     aCombinedBox.Combine (aBox);
1233   }
1234
1235   aBox = aCombinedBox;
1236   if (aBox.IsValid())
1237   {
1238     TColStd_Array2OfReal aTrsf (0, 3, 0, 3);
1239     Transform (aTrsf);
1240     TransformBoundaries (aTrsf, aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
1241                                 aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
1242
1243     // if box is still valid after transformation
1244     if (aBox.IsValid())
1245     {
1246       theBox.Combine (aBox);
1247     }
1248     else // it was infinite, return untransformed
1249     {
1250       theBox.Combine (aCombinedBox);
1251     }
1252   }
1253 }
1254
1255 //=============================================================================
1256 //function : Transforms
1257 //purpose  :
1258 //=============================================================================
1259 void Graphic3d_Structure::Transforms (const TColStd_Array2OfReal& theTrsf,
1260                                       const Standard_Real theX,    const Standard_Real theY,    const Standard_Real theZ,
1261                                       Standard_Real&      theNewX, Standard_Real&      theNewY, Standard_Real&      theNewZ)
1262 {
1263   const Standard_Real aRL = RealLast();
1264   const Standard_Real aRF = RealFirst();
1265   if ((theX == aRF) || (theY == aRF) || (theZ == aRF)
1266    || (theX == aRL) || (theY == aRL) || (theZ == aRL))
1267   {
1268     theNewX = theX;
1269     theNewY = theY;
1270     theNewZ = theZ;
1271   }
1272   else
1273   {
1274     Standard_Real A, B, C, D;
1275     A       = theTrsf (0, 0);
1276     B       = theTrsf (0, 1);
1277     C       = theTrsf (0, 2);
1278     D       = theTrsf (0, 3);
1279     theNewX = A * theX + B * theY + C * theZ + D;
1280     A       = theTrsf (1, 0);
1281     B       = theTrsf (1, 1);
1282     C       = theTrsf (1, 2);
1283     D       = theTrsf (1, 3);
1284     theNewY = A * theX + B * theY + C * theZ + D;
1285     A       = theTrsf (2, 0);
1286     B       = theTrsf (2, 1);
1287     C       = theTrsf (2, 2);
1288     D       = theTrsf (2, 3);
1289     theNewZ = A * theX + B * theY + C * theZ + D;
1290   }
1291 }
1292
1293 //=============================================================================
1294 //function : Transforms
1295 //purpose  :
1296 //=============================================================================
1297 Graphic3d_Vector Graphic3d_Structure::Transforms (const TColStd_Array2OfReal& theTrsf,
1298                                                   const Graphic3d_Vector&     theCoord)
1299 {
1300   Standard_Real anXYZ[3];
1301   Graphic3d_Structure::Transforms (theTrsf,
1302                                    theCoord.X(), theCoord.Y(), theCoord.Z(),
1303                                    anXYZ[0], anXYZ[1], anXYZ[2]);
1304   return Graphic3d_Vector (anXYZ[0], anXYZ[1], anXYZ[2]);
1305 }
1306
1307 //=============================================================================
1308 //function : Transforms
1309 //purpose  :
1310 //=============================================================================
1311 Graphic3d_Vertex Graphic3d_Structure::Transforms (const TColStd_Array2OfReal& theTrsf,
1312                                                   const Graphic3d_Vertex&     theCoord)
1313 {
1314   Standard_Real anXYZ[3];
1315   Graphic3d_Structure::Transforms (theTrsf,
1316                                    theCoord.X(), theCoord.Y(), theCoord.Z(),
1317                                    anXYZ[0], anXYZ[1], anXYZ[2]);
1318   return Graphic3d_Vertex (anXYZ[0], anXYZ[1], anXYZ[2]);
1319 }
1320
1321 //=============================================================================
1322 //function : Transforms
1323 //purpose  :
1324 //=============================================================================
1325 void Graphic3d_Structure::TransformBoundaries (const TColStd_Array2OfReal& theTrsf,
1326                                                Standard_Real& theXMin,
1327                                                Standard_Real& theYMin,
1328                                                Standard_Real& theZMin,
1329                                                Standard_Real& theXMax,
1330                                                Standard_Real& theYMax,
1331                                                Standard_Real& theZMax)
1332 {
1333   Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax, anU, aV, aW;
1334
1335   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMin, aXMin, aYMin, aZMin);
1336   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMax, aXMax, aYMax, aZMax);
1337
1338   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMin, theZMax, anU, aV, aW);
1339   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1340   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1341   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1342
1343   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMax, anU, aV, aW);
1344   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1345   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1346   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1347
1348   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMin, theZMin, anU, aV, aW);
1349   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1350   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1351   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1352
1353   Graphic3d_Structure::Transforms (theTrsf, theXMax, theYMax, theZMin, anU, aV, aW);
1354   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1355   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1356   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1357
1358   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMax, anU, aV, aW);
1359   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1360   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1361   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1362
1363   Graphic3d_Structure::Transforms (theTrsf, theXMin, theYMax, theZMin, anU, aV, aW);
1364   aXMin = Min (anU, aXMin); aXMax = Max (anU, aXMax);
1365   aYMin = Min (aV,  aYMin); aYMax = Max (aV,  aYMax);
1366   aZMin = Min (aW,  aZMin); aZMax = Max (aW,  aZMax);
1367
1368   theXMin = aXMin;
1369   theYMin = aYMin;
1370   theZMin = aZMin;
1371   theXMax = aXMax;
1372   theYMax = aYMax;
1373   theZMax = aZMax;
1374 }
1375
1376 //=============================================================================
1377 //function : Network
1378 //purpose  :
1379 //=============================================================================
1380 void Graphic3d_Structure::Network (const Handle(Graphic3d_Structure)& theStructure,
1381                                    const Graphic3d_TypeOfConnection   theType,
1382                                    Graphic3d_MapOfStructure&          theSet)
1383 {
1384   Graphic3d_MapOfStructure aSetD, aSetA;
1385   theStructure->Descendants (aSetD);
1386   theStructure->Ancestors   (aSetA);
1387   theSet.Add (theStructure);
1388   switch (theType)
1389   {
1390     case Graphic3d_TOC_DESCENDANT:
1391       for (Graphic3d_MapIteratorOfMapOfStructure anIter (aSetD); anIter.More(); anIter.Next())
1392       {
1393         Graphic3d_Structure::Network (anIter.Key(), theType, theSet);
1394       }
1395       break;
1396     case Graphic3d_TOC_ANCESTOR:
1397       for (Graphic3d_MapIteratorOfMapOfStructure anIter (aSetA); anIter.More(); anIter.Next())
1398       {
1399         Graphic3d_Structure::Network (anIter.Key (), theType, theSet);
1400       }
1401       break;
1402   }
1403 }
1404
1405 //=============================================================================
1406 //function : PrintNetwork
1407 //purpose  :
1408 //=============================================================================
1409 void Graphic3d_Structure::PrintNetwork (const Handle(Graphic3d_Structure)& theStructure,
1410                                         const Graphic3d_TypeOfConnection   theType)
1411 {
1412   Graphic3d_MapOfStructure aSet;
1413   Graphic3d_Structure::Network (theStructure, theType, aSet);
1414   for (Graphic3d_MapIteratorOfMapOfStructure anIter (aSet); anIter.More(); anIter.Next())
1415   {
1416     std::cout << "\tIdent " << (anIter.Key())->Identification () << "\n";
1417   }
1418   std::cout << std::flush;
1419 }
1420
1421 //=============================================================================
1422 //function : Update
1423 //purpose  :
1424 //=============================================================================
1425 void Graphic3d_Structure::Update (const bool theUpdateLayer) const
1426 {
1427   if (IsDeleted())
1428   {
1429     return;
1430   }
1431
1432   myStructureManager->Update (myStructureManager->UpdateMode(),
1433                               theUpdateLayer ? myCStructure->ZLayer() : Graphic3d_ZLayerId_UNKNOWN);
1434 }
1435
1436 //=============================================================================
1437 //function : GraphicHighlight
1438 //purpose  :
1439 //=============================================================================
1440 void Graphic3d_Structure::GraphicHighlight (const Aspect_TypeOfHighlightMethod theMethod)
1441 {
1442   myCStructure->highlight = 1;
1443   myHighlightMethod = theMethod;
1444   switch (theMethod)
1445   {
1446     case Aspect_TOHM_COLOR:
1447     {
1448       myCStructure->HighlightWithColor (myHighlightColor, Standard_True);
1449       break;
1450     }
1451     case Aspect_TOHM_BOUNDBOX:
1452     {
1453       myCStructure->HighlightColor = myHighlightColor;
1454       myCStructure->HighlightWithBndBox (this, Standard_True);
1455       break;
1456     }
1457   }
1458 }
1459
1460 //=============================================================================
1461 //function : GraphicTransform
1462 //purpose  :
1463 //=============================================================================
1464 void Graphic3d_Structure::GraphicTransform (const TColStd_Array2OfReal& theMatrix)
1465 {
1466   for (Standard_Integer i = 0; i <= 3; ++i)
1467   {
1468     for (Standard_Integer j = 0; j <= 3; ++j)
1469     {
1470       myCStructure->Transformation.ChangeValue (i, j) = float (theMatrix (i, j));
1471     }
1472   }
1473   myCStructure->UpdateTransformation();
1474 }
1475
1476 //=============================================================================
1477 //function : GraphicUnHighlight
1478 //purpose  :
1479 //=============================================================================
1480 void Graphic3d_Structure::GraphicUnHighlight()
1481 {
1482   myCStructure->highlight = 0;
1483   switch (myHighlightMethod)
1484   {
1485     case Aspect_TOHM_COLOR:
1486       myCStructure->HighlightWithColor (Graphic3d_Vec3 (0.0f, 0.0f, 0.0f), Standard_False);
1487       break;
1488     case Aspect_TOHM_BOUNDBOX:
1489       myCStructure->HighlightWithBndBox (this, Standard_False);
1490       break;
1491   }
1492 }
1493
1494 //=============================================================================
1495 //function : ComputeVisual
1496 //purpose  :
1497 //=============================================================================
1498 Graphic3d_TypeOfStructure Graphic3d_Structure::ComputeVisual() const
1499 {
1500   return myComputeVisual;
1501 }
1502
1503 //=============================================================================
1504 //function : SetComputeVisual
1505 //purpose  :
1506 //=============================================================================
1507 void Graphic3d_Structure::SetComputeVisual (const Graphic3d_TypeOfStructure theVisual)
1508 {
1509   // The ComputeVisual is saved only if the structure is declared TOS_ALL, TOS_WIREFRAME or TOS_SHADING.
1510   // This declaration permits to calculate proper representation of the structure calculated by Compute instead of passage to TOS_COMPUTED.
1511   if (theVisual != Graphic3d_TOS_COMPUTED)
1512   {
1513     myComputeVisual = theVisual;
1514   }
1515 }
1516
1517 //=============================================================================
1518 //function : SetHLRValidation
1519 //purpose  :
1520 //=============================================================================
1521 void Graphic3d_Structure::SetHLRValidation (const Standard_Boolean theFlag)
1522 {
1523   myCStructure->HLRValidation = theFlag ? 1 : 0;
1524 }
1525
1526 //=============================================================================
1527 //function : HLRValidation
1528 //purpose  :
1529 //=============================================================================
1530 Standard_Boolean Graphic3d_Structure::HLRValidation() const
1531 {
1532   // Hidden parts stored in <me> are valid if :
1533   // 1/ the owner is defined.
1534   // 2/ they are not invalid.
1535   return myOwner != NULL
1536       && myCStructure->HLRValidation != 0;
1537 }
1538
1539 //=======================================================================
1540 //function : SetZLayer
1541 //purpose  :
1542 //=======================================================================
1543 void Graphic3d_Structure::SetZLayer (const Graphic3d_ZLayerId theLayerId)
1544 {
1545   // if the structure is not displayed, unable to change its display layer
1546   if (IsDeleted ())
1547     return;
1548
1549   myStructureManager->ChangeZLayer (this, theLayerId);
1550   myCStructure->SetZLayer (theLayerId);
1551 }
1552
1553 //=======================================================================
1554 //function : GetZLayer
1555 //purpose  :
1556 //=======================================================================
1557 Graphic3d_ZLayerId Graphic3d_Structure::GetZLayer() const
1558 {
1559   return myCStructure->ZLayer();
1560 }
1561
1562 //=======================================================================
1563 //function : SetClipPlanes
1564 //purpose  :
1565 //=======================================================================
1566 void Graphic3d_Structure::SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
1567 {
1568   myCStructure->SetClipPlanes (thePlanes);
1569 }
1570
1571 //=======================================================================
1572 //function : GetClipPlanes
1573 //purpose  :
1574 //=======================================================================
1575 const Handle(Graphic3d_SequenceOfHClipPlane)& Graphic3d_Structure::ClipPlanes() const
1576 {
1577   return myCStructure->ClipPlanes();
1578 }
1579
1580 //=======================================================================
1581 //function : SetMutable
1582 //purpose  :
1583 //=======================================================================
1584 void Graphic3d_Structure::SetMutable (const Standard_Boolean theIsMutable)
1585 {
1586   myCStructure->IsMutable = theIsMutable;
1587 }
1588
1589 //=======================================================================
1590 //function : IsMutable
1591 //purpose  :
1592 //=======================================================================
1593 Standard_Boolean Graphic3d_Structure::IsMutable() const
1594 {
1595   return myCStructure->IsMutable;
1596 }