0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / PrsMgr / PrsMgr_Presentation.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <PrsMgr_Presentation.ixx>
16 #include <PrsMgr_PresentationManager.hxx>
17 #include <PrsMgr_Prs.hxx>
18 #include <PrsMgr_ModedPresentation.hxx>
19
20 #include <Graphic3d_Structure.hxx>
21 #include <Visual3d_View.hxx>
22 #include <Precision.hxx>
23 #include <Prs3d_Presentation.hxx>
24
25 namespace
26 {
27   enum BeforeHighlightState
28   {
29     State_Empty,
30     State_Hidden,
31     State_Visible
32   };
33
34   static BeforeHighlightState StructureState(const Handle(PrsMgr_Prs)& theStructure)
35   {
36     return !theStructure->IsDisplayed() ?
37       State_Empty : !theStructure->IsVisible() ?
38         State_Hidden : State_Visible;
39   }
40 }
41
42 //=======================================================================
43 //function : PrsMgr_Presentation
44 //purpose  :
45 //=======================================================================
46 PrsMgr_Presentation::PrsMgr_Presentation (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
47                                           const Handle(PrsMgr_PresentableObject)&     thePrsObject)
48 : myPresentationManager  (thePrsMgr),
49   myPresentableObject    (thePrsObject.operator->()),
50   myMustBeUpdated        (Standard_False),
51   myBeforeHighlightState (State_Empty)
52 {
53   myStructure = new PrsMgr_Prs (thePrsMgr->StructureManager(),
54                                 this, thePrsObject->TypeOfPresentation3d());
55   myStructure->SetOwner (myPresentableObject);
56   myStructure->SetMutable (myPresentableObject->IsMutable());
57 }
58
59 //=======================================================================
60 //function : Display
61 //purpose  :
62 //=======================================================================
63 void PrsMgr_Presentation::Display()
64 {
65   display (Standard_False);
66   myBeforeHighlightState = State_Visible;
67 }
68
69 //=======================================================================
70 //function : display
71 //purpose  :
72 //=======================================================================
73 void PrsMgr_Presentation::display (const Standard_Boolean theIsHighlight)
74 {
75   if (!myStructure->IsDisplayed())
76   {
77     myStructure->SetIsForHighlight (theIsHighlight);
78     myStructure->Display();
79   }
80   else if (!myStructure->IsVisible())
81   {
82     SetVisible (Standard_True);
83     myStructure->SetIsForHighlight (theIsHighlight);
84   }
85 }
86
87 //=======================================================================
88 //function : Erase
89 //purpose  :
90 //=======================================================================
91 void PrsMgr_Presentation::Erase()
92 {
93   if (myStructure.IsNull())
94   {
95     return;
96   }
97
98   // Erase structure from structure manager
99   myStructure->Erase();
100   myStructure->Clear();
101   // Disconnect other structures
102   myStructure->DisconnectAll (Graphic3d_TOC_DESCENDANT);
103   // Clear groups and remove graphic structure
104   myStructure.Nullify();
105 }
106
107 //=======================================================================
108 //function : SetVisible
109 //purpose  :
110 //=======================================================================
111 void PrsMgr_Presentation::SetVisible (const Standard_Boolean theValue)
112 {
113   myStructure->SetVisible (theValue);
114 }
115
116 //=======================================================================
117 //function : Highlight
118 //purpose  :
119 //=======================================================================
120 void PrsMgr_Presentation::Highlight (const Aspect_TypeOfHighlightMethod theMethod,
121                                      const Quantity_Color&              theColor)
122 {
123   if (!IsHighlighted())
124   {
125     myBeforeHighlightState = StructureState (myStructure);
126   }
127
128   display (Standard_True);
129   myStructure->Highlight (theMethod, theColor);
130 }
131
132 //=======================================================================
133 //function : Unhighlight
134 //purpose  :
135 //=======================================================================
136 void PrsMgr_Presentation::Unhighlight() const
137 {
138   myStructure->UnHighlight();
139   switch (myBeforeHighlightState)
140   {
141  case State_Visible:
142     return;
143  case State_Hidden:
144     myStructure->SetVisible (Standard_False);
145     break;
146  case State_Empty:
147     myStructure->Erase();
148     break;
149   }
150 }
151
152 //=======================================================================
153 //function : Clear
154 //purpose  :
155 //=======================================================================
156 void PrsMgr_Presentation::Clear()
157 {
158   // This modification remove the contain of the structure:
159   // Consequence:
160   //    1. The memory zone of the group is reused
161   //    2. The speed for animation is constant
162   //myPresentableObject = NULL;
163   SetUpdateStatus (Standard_True);
164   if (myStructure.IsNull())
165   {
166     return;
167   }
168
169   myStructure->Clear (Standard_True);
170   //  myStructure->Clear(Standard_False);
171   myStructure->RemoveAll();
172 }
173
174 //=======================================================================
175 //function : IsDisplayed
176 //purpose  :
177 //=======================================================================
178 Standard_Boolean PrsMgr_Presentation::IsDisplayed() const
179 {
180   return  myStructure->IsDisplayed()
181       &&  myStructure->IsVisible();
182 }
183
184 //=======================================================================
185 //function : IsHighlighted
186 //purpose  :
187 //=======================================================================
188 Standard_Boolean PrsMgr_Presentation::IsHighlighted() const
189 {
190   return myStructure->IsHighlighted();
191 }
192
193 //=======================================================================
194 //function : DisplayPriority
195 //purpose  :
196 //=======================================================================
197 Standard_Integer PrsMgr_Presentation::DisplayPriority() const
198 {
199   return myStructure->DisplayPriority();
200 }
201
202 //=======================================================================
203 //function : SetDisplayPriority
204 //purpose  :
205 //=======================================================================
206 void PrsMgr_Presentation::SetDisplayPriority (const Standard_Integer theNewPrior)
207 {
208   myStructure->SetDisplayPriority (theNewPrior);
209 }
210
211 //=======================================================================
212 //function : Connect
213 //purpose  :
214 //=======================================================================
215 void PrsMgr_Presentation::Connect (const Handle(PrsMgr_Presentation)& theOther) const
216 {
217   myStructure->Connect (theOther->Presentation());
218 }
219
220 //=======================================================================
221 //function : Transform
222 //purpose  :
223 //=======================================================================
224 void PrsMgr_Presentation::Transform (const Handle(Geom_Transformation)& theTrsf) const
225 {
226   myStructure->Transform (theTrsf);
227 }
228
229 //=======================================================================
230 //function : Place
231 //purpose  :
232 //=======================================================================
233 void PrsMgr_Presentation::Place (const Quantity_Length theX,
234                                  const Quantity_Length theY,
235                                  const Quantity_Length theZ) const
236 {
237   myStructure->Place (theX, theY, theZ);
238 }
239
240 //=======================================================================
241 //function : Multiply
242 //purpose  :
243 //=======================================================================
244 void PrsMgr_Presentation::Multiply (const Handle(Geom_Transformation)& theTrsf) const
245 {
246   myStructure->Multiply (theTrsf);
247 }
248
249 //=======================================================================
250 //function : Move
251 //purpose  :
252 //=======================================================================
253 void PrsMgr_Presentation::Move (const Quantity_Length theX,
254                                 const Quantity_Length theY,
255                                 const Quantity_Length theZ) const
256 {
257   myStructure->Move (theX, theY, theZ);
258 }
259
260 //=======================================================================
261 //function : SetShadingAspect
262 //purpose  :
263 //=======================================================================
264 void PrsMgr_Presentation::SetShadingAspect (const Handle(Prs3d_ShadingAspect)& theShadingAspect) const
265 {
266   myStructure->SetShadingAspect (theShadingAspect);
267 }
268
269 //=======================================================================
270 //function : Compute
271 //purpose  : Methods for hidden parts...
272 //=======================================================================
273 Handle(Graphic3d_Structure) PrsMgr_Presentation::Compute (const Handle(Graphic3d_DataStructureManager)& theProjector)
274 {
275   Handle(Prs3d_Presentation) aPrs = new Prs3d_Presentation (myPresentationManager->StructureManager());
276   myPresentableObject->Compute (Projector (theProjector), aPrs);
277   return aPrs;
278 }
279
280 //=======================================================================
281 //function : Compute
282 //purpose  :
283 //=======================================================================
284 void PrsMgr_Presentation::Compute (const Handle(Graphic3d_Structure)& theStructure)
285 {
286   Standard_Integer aDispMode = 0;
287   Standard_Integer aPresentationsNumber = myPresentableObject->myPresentations.Length();
288   for (Standard_Integer anIter = 1; anIter <= aPresentationsNumber; ++anIter)
289   {
290     const PrsMgr_ModedPresentation& aModedPresentation = myPresentableObject->myPresentations.Value (anIter);
291     if (aModedPresentation.Presentation().operator->() == this)
292     {
293       aDispMode = aModedPresentation.Mode();
294       break;
295     }
296   }
297
298   Handle(Prs3d_Presentation) aPrs3d = Handle(Prs3d_Presentation)::DownCast (theStructure);
299   myPresentableObject->Compute (myPresentationManager, aPrs3d, aDispMode);
300 }
301
302 //=======================================================================
303 //function : Compute
304 //purpose  :
305 //=======================================================================
306 void PrsMgr_Presentation::Compute (const Handle(Graphic3d_DataStructureManager)& theProjector,
307                                    const Handle(Graphic3d_Structure)&            theStructToFill)
308 {
309   theStructToFill->Clear();
310   Handle(Prs3d_Presentation) aPrs (Handle(Prs3d_Presentation)::DownCast (theStructToFill));
311   myPresentableObject->Compute (Projector (theProjector), aPrs);
312 }
313
314 //=======================================================================
315 //function : Compute
316 //purpose  :
317 //=======================================================================
318 Handle(Graphic3d_Structure) PrsMgr_Presentation::Compute (const Handle(Graphic3d_DataStructureManager)& theProjector,
319                                                           const Handle(Geom_Transformation)&            theTrsf)
320 {
321   Handle(Prs3d_Presentation) aPrs3d = new Prs3d_Presentation (myPresentationManager->StructureManager());
322   if (theTrsf->Form() == gp_Translation)
323   {
324     myPresentableObject->Compute (Projector (theProjector), aPrs3d);
325     aPrs3d->Transform (theTrsf);
326     return aPrs3d;
327   }
328
329   // waiting that something is done in gp_Trsf...rob
330   for (Standard_Integer i = 1; i <= 3; ++i)
331   {
332     for (Standard_Integer j = 1; j <= 3; ++j)
333     {
334       if (i != j)
335       {
336         if (Abs (theTrsf->Value (i, j)) > Precision::Confusion())
337         {
338           myPresentableObject->Compute (Projector (theProjector), theTrsf, aPrs3d);
339           return aPrs3d;
340         }
341       }
342     }
343   }
344
345   myPresentableObject->Compute (Projector (theProjector), aPrs3d);
346   aPrs3d->Transform (theTrsf);
347   return aPrs3d;
348 }
349
350 //=======================================================================
351 //function : Compute
352 //purpose  :
353 //=======================================================================
354 void PrsMgr_Presentation::Compute (const Handle(Graphic3d_DataStructureManager)& theProjector,
355                                    const Handle(Geom_Transformation)&            theTrsf,
356                                    const Handle(Graphic3d_Structure)&            theStructToFill)
357 {
358   // recompute HLR after transformation in all the case
359   Handle(Prs3d_Presentation) aPrs = Handle(Prs3d_Presentation)::DownCast (theStructToFill);
360   theStructToFill->Clear();
361   myPresentableObject->Compute (Projector (theProjector), theTrsf, aPrs);
362 }
363
364 //=======================================================================
365 //function : Projector
366 //purpose  :
367 //=======================================================================
368 Handle(Prs3d_Projector) PrsMgr_Presentation::Projector (const Handle(Graphic3d_DataStructureManager)& theProjector)
369 {
370   Handle(Graphic3d_Camera) aCamera (Handle(Visual3d_View)::DownCast (theProjector)->Camera());
371   const gp_Dir aDir = aCamera->Direction().Reversed();
372   const gp_Pnt anAt = aCamera->Center();
373   const gp_Dir anUp = aCamera->Up();
374   Handle(Prs3d_Projector) aProj = new Prs3d_Projector (!aCamera->IsOrthographic(),
375                                                        aCamera->Scale(),
376                                                        aDir.X(), aDir.Y(), aDir.Z(),
377                                                        anAt.X(), anAt.Y(), anAt.Z(),
378                                                        anUp.X(), anUp.Y(), anUp.Z());
379   return aProj;
380 }
381
382 //=======================================================================
383 //function : Destroy
384 //purpose  :
385 //=======================================================================
386 void PrsMgr_Presentation::Destroy()
387 {
388   Erase();
389 }
390
391 //=======================================================================
392 //function : SetZLayer
393 //purpose  :
394 //=======================================================================
395 void PrsMgr_Presentation::SetZLayer (Standard_Integer theLayerId)
396 {
397   myStructure->SetZLayer (theLayerId);
398 }
399
400 //=======================================================================
401 //function : GetZLayer
402 //purpose  :
403 //=======================================================================
404 Standard_Integer PrsMgr_Presentation::GetZLayer() const
405 {
406   return myStructure->GetZLayer();
407 }