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