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