0024837: Visualization - revise design and implementation of connected Interactive...
[occt.git] / src / PrsMgr / PrsMgr_PresentableObject.cxx
1 // Created on: 1997-12-16
2 // Created by: Jean Louis Frenkel
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <PrsMgr_PresentableObject.ixx>
18 #include <PrsMgr_Presentation.hxx>
19 #include <PrsMgr_ModedPresentation.hxx>
20 #include <PrsMgr_PresentationManager.hxx>
21 #include <TColStd_ListIteratorOfListOfInteger.hxx>
22 #include <TColStd_MapOfInteger.hxx>
23 #include <Graphic3d_TypeOfStructure.hxx>
24 #include <Geom_Transformation.hxx>
25
26 //=======================================================================
27 //function : PrsMgr_PresentableObject
28 //purpose  :
29 //=======================================================================
30 PrsMgr_PresentableObject::PrsMgr_PresentableObject (const PrsMgr_TypeOfPresentation3d theType)
31 : myTypeOfPresentation3d (theType),
32   myIsMutable (Standard_False),
33   myHasOwnPresentations (Standard_True),
34   myParent (NULL)
35 {
36   myTransformPersistence.Flag = 0;
37   myTransformPersistence.Point.x = 0.0;
38   myTransformPersistence.Point.y = 0.0;
39   myTransformPersistence.Point.z = 0.0;
40 }
41
42 //=======================================================================
43 //function : ~PrsMgr_PresentableObject
44 //purpose  : destructor
45 //=======================================================================
46 PrsMgr_PresentableObject::~PrsMgr_PresentableObject()
47 {
48   gp_Trsf anIdentity;
49   for (PrsMgr_ListOfPresentableObjectsIter anIter (myChildren); anIter.More(); anIter.Next())
50   {
51     anIter.Value()->SetCombinedParentTransform (anIdentity);
52     anIter.Value()->myParent = NULL;
53   }
54 }
55
56 //=======================================================================
57 //function : Fill
58 //purpose  : 
59 //=======================================================================
60 void PrsMgr_PresentableObject::Fill (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
61                                      const Handle(PrsMgr_Presentation)&        thePrs,
62                                      const Standard_Integer                    theMode)
63 {
64   Handle(Prs3d_Presentation) aStruct3d = thePrs->Presentation();
65   Compute (thePrsMgr, aStruct3d, theMode);
66   UpdateTransformation (aStruct3d);
67   aStruct3d->SetClipPlanes (myClipPlanes);
68   aStruct3d->SetTransformPersistence (GetTransformPersistenceMode(), GetTransformPersistencePoint());
69 }
70
71 //=======================================================================
72 //function : Compute
73 //purpose  :
74 //=======================================================================
75 void PrsMgr_PresentableObject::Compute (const Handle(PrsMgr_PresentationManager)& /*aPresentationManager*/,
76                                         const Handle(Prs3d_Presentation)& /*aPresentation*/,
77                                         const Standard_Integer /*aMode*/)
78 {
79   Standard_NotImplemented::Raise("cannot compute in a 3d visualizer");
80 }
81
82 //=======================================================================
83 //function : Compute
84 //purpose  : 
85 //=======================================================================
86 void PrsMgr_PresentableObject::Compute(const Handle(Prs3d_Projector)& /*aProjector*/,
87                                        const Handle(Prs3d_Presentation)& /*aPresentation*/)
88 {
89   Standard_NotImplemented::Raise("cannot compute under a specific projector");
90 }
91
92 //=======================================================================
93 //function : Compute
94 //purpose  : 
95 //=======================================================================
96 void PrsMgr_PresentableObject::Compute(const Handle(Prs3d_Projector)& /* aProjector*/,
97                                        const Handle(Geom_Transformation)& /*aTrsf*/,
98                                                                const Handle(Prs3d_Presentation)& /*aPresentation*/)
99 {
100   Standard_NotImplemented::Raise("cannot compute under a specific projector");
101 }
102
103 //=======================================================================
104 //function : Update
105 //purpose  : 
106 //=======================================================================
107 void PrsMgr_PresentableObject::Update (const Standard_Boolean AllModes) {
108   Standard_Integer l = myPresentations.Length();
109   Handle(PrsMgr_PresentationManager) PM; 
110   for (Standard_Integer i=1; i <= l; i++) {
111     PM = myPresentations(i).Presentation()->PresentationManager();
112     if(AllModes) 
113       PM->Update(this,myPresentations(i).Mode());
114     else{
115       if(PM->IsDisplayed(this,myPresentations(i).Mode()) ||
116          PM->IsHighlighted(this,myPresentations(i).Mode())){
117         PM->Update(this,myPresentations(i).Mode());
118       }
119       else
120         SetToUpdate(myPresentations(i).Mode());
121     }
122   }
123 }
124
125 //=======================================================================
126 //function : Update
127 //purpose  : 
128 //=======================================================================
129 void PrsMgr_PresentableObject::Update (const Standard_Integer aMode, const Standard_Boolean ClearOther) {
130   Standard_Integer l = myPresentations.Length();
131   for (Standard_Integer i=1; i <= l; i++) {
132     if( myPresentations(i).Mode() == aMode){
133        Handle(PrsMgr_PresentationManager) PM=
134          myPresentations(i).Presentation()->PresentationManager();
135        
136        if(PM->IsDisplayed(this,aMode) ||
137           PM->IsHighlighted(this,aMode)){
138          PM->Update(this,aMode);
139          myPresentations(i).Presentation()->SetUpdateStatus(Standard_False);
140          
141        }
142        else
143          SetToUpdate(myPresentations(i).Mode());
144      }
145     
146   }
147   if(ClearOther) {
148     PrsMgr_Presentations save;
149     save =  myPresentations; 
150     myPresentations.Clear();
151     for (Standard_Integer i=1; i <= l; i++) {
152       if( save(i).Mode() == aMode) myPresentations.Append(save(i));
153     }
154   }
155
156 }
157
158 //=======================================================================
159 //function : Presentations
160 //purpose  : 
161 //=======================================================================
162 PrsMgr_Presentations& PrsMgr_PresentableObject::Presentations() {
163   return myPresentations;
164 }
165
166 //=======================================================================
167 //function : HasTransformation
168 //purpose  : 
169 //=======================================================================
170 Standard_Boolean PrsMgr_PresentableObject::HasTransformation() const 
171 {
172   return myTransformation.Form() != gp_Identity;
173 }
174
175 //=======================================================================
176 //function : SetToUpdate
177 //purpose  : 
178 //=======================================================================
179 void PrsMgr_PresentableObject::SetToUpdate(const Standard_Integer aMode)
180 {
181   for(Standard_Integer IP =1; IP<=myPresentations.Length();IP++){
182     if(myPresentations(IP).Mode()==aMode)
183       myPresentations(IP).Presentation()->SetUpdateStatus(Standard_True);
184   }
185 }
186
187 //=======================================================================
188 //function : SetToUpdate
189 //purpose  :
190 //=======================================================================
191 void PrsMgr_PresentableObject::SetToUpdate()
192 {
193   for(Standard_Integer IP =1; IP<=myPresentations.Length();IP++){
194     myPresentations(IP).Presentation()->SetUpdateStatus(Standard_True);
195   }
196 }
197
198 //=======================================================================
199 //function : ToBeUpdated
200 //purpose  : gets the list of modes to be updated
201 //=======================================================================
202 void PrsMgr_PresentableObject::ToBeUpdated(TColStd_ListOfInteger& OutList) const
203 {
204   OutList.Clear();
205   // on dimensionne les buckets a la taille de la seq.
206   static TColStd_MapOfInteger MI(myPresentations.Length()); 
207   
208   for(Standard_Integer IP =1; IP<=myPresentations.Length();IP++){
209     const PrsMgr_ModedPresentation& MP = myPresentations(IP);
210     if(MP.Presentation()->MustBeUpdated())
211       if(!MI.Contains(MP.Mode())){
212         OutList.Append(MP.Mode());
213         MI.Add(MP.Mode());
214       }
215   }
216   MI.Clear();
217 }
218
219 //=======================================================================
220 //function : SetTypeOfPresentation
221 //purpose  :
222 //=======================================================================
223 void PrsMgr_PresentableObject::SetTypeOfPresentation (const PrsMgr_TypeOfPresentation3d theType)
224 {
225   myTypeOfPresentation3d = theType;
226   for(Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
227   {
228     const Handle(PrsMgr_Presentation)& aPrs  = myPresentations (aPrsIter).Presentation();
229     aPrs->Presentation()->SetVisual (myTypeOfPresentation3d == PrsMgr_TOP_ProjectorDependant
230                                    ? Graphic3d_TOS_COMPUTED
231                                    : Graphic3d_TOS_ALL);
232   }
233 }
234
235 //=======================================================================
236 //function : SetLocalTransformation
237 //purpose  : WARNING : use with only 3D objects...
238 //=======================================================================
239 void PrsMgr_PresentableObject::SetLocalTransformation (const gp_Trsf& theTransformation) 
240 {
241   myLocalTransformation = theTransformation;
242   UpdateTransformation();
243 }
244
245 //=======================================================================
246 //function : ResetTransformation
247 //purpose  : 
248 //=======================================================================
249 void PrsMgr_PresentableObject::ResetTransformation() 
250 {
251   SetLocalTransformation (gp_Trsf());  
252 }
253
254 //=======================================================================
255 //function : SetCombinedParentTransform
256 //purpose  : 
257 //=======================================================================
258 void PrsMgr_PresentableObject::SetCombinedParentTransform (const gp_Trsf& theTransformation) 
259 {
260   myCombinedParentTransform = theTransformation;
261   UpdateTransformation();
262 }
263
264 //=======================================================================
265 //function : UpdateTransformation
266 //purpose  :
267 //=======================================================================
268 void PrsMgr_PresentableObject::UpdateTransformation()
269 {
270   myTransformation = myCombinedParentTransform * myLocalTransformation;
271   Handle(Geom_Transformation) aTrsf = new Geom_Transformation (myTransformation);
272
273   for (Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
274   {
275     myPresentations (aPrsIter).Presentation()->Transform (aTrsf);
276   }
277   
278   PrsMgr_ListOfPresentableObjectsIter anIter (myChildren);
279
280   for (; anIter.More(); anIter.Next())
281   {
282     anIter.Value()->SetCombinedParentTransform (myTransformation);
283   }
284 }
285
286 //=======================================================================
287 //function : UpdateTransformation
288 //purpose  : 
289 //=======================================================================
290 void PrsMgr_PresentableObject::UpdateTransformation(const Handle(Prs3d_Presentation)& P)
291 {
292   Handle(Geom_Transformation) aTrsf = new Geom_Transformation (myTransformation);
293   P->Transform (aTrsf);  
294 }
295
296 //=======================================================================
297 //function : SetTransformPersistence
298 //purpose  :
299 //=======================================================================
300 void PrsMgr_PresentableObject::SetTransformPersistence (const Graphic3d_TransModeFlags& theFlag,
301                                                         const gp_Pnt&                   thePoint)
302 {
303   myTransformPersistence.Flag    = theFlag;
304   myTransformPersistence.Point.x = (Standard_ShortReal )thePoint.X();
305   myTransformPersistence.Point.y = (Standard_ShortReal )thePoint.Y();
306   myTransformPersistence.Point.z = (Standard_ShortReal )thePoint.Z();
307   for (Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
308   {
309     const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
310     if (!aPrs3d.IsNull()
311      && !aPrs3d->Presentation().IsNull())
312     {
313       aPrs3d->Presentation()->SetTransformPersistence (theFlag, thePoint);
314       aPrs3d->Presentation()->ReCompute();
315     }
316   }
317 }
318
319 //=======================================================================
320 //function : SetTransformPersistence
321 //purpose  : 
322 //=======================================================================
323 void  PrsMgr_PresentableObject::SetTransformPersistence( 
324                                        const Graphic3d_TransModeFlags& TheFlag )
325 {
326   SetTransformPersistence( TheFlag, gp_Pnt(0,0,0) );
327 }
328
329 //=======================================================================
330 //function : GetTransformPersistence
331 //purpose  : 
332 //=======================================================================
333 Graphic3d_TransModeFlags  PrsMgr_PresentableObject::GetTransformPersistenceMode() const
334 {
335   return myTransformPersistence.Flag;
336 }
337
338 //=======================================================================
339 //function : GetTransformPersistence
340 //purpose  : 
341 //=======================================================================
342 gp_Pnt  PrsMgr_PresentableObject::GetTransformPersistencePoint() const
343 {
344   return gp_Pnt( myTransformPersistence.Point.x, myTransformPersistence.Point.y, myTransformPersistence.Point.z );
345 }
346
347 //=======================================================================
348 //function : AddChild
349 //purpose  : 
350 //=======================================================================
351 void PrsMgr_PresentableObject::AddChild (const Handle(PrsMgr_PresentableObject)& theObject)
352 {
353   Handle(PrsMgr_PresentableObject) aHandleGuard = theObject;
354   if (theObject->myParent != NULL)
355   {
356     theObject->myParent->RemoveChild (aHandleGuard);
357   }
358
359   myChildren.Append (theObject);  
360   theObject->myParent = this;
361   theObject->SetCombinedParentTransform (myTransformation);
362 }
363
364 //=======================================================================
365 //function : RemoveChild
366 //purpose  : 
367 //=======================================================================
368 void PrsMgr_PresentableObject::RemoveChild (const Handle(PrsMgr_PresentableObject)& theObject)
369 {
370   PrsMgr_ListOfPresentableObjectsIter anIter (myChildren);
371   for (; anIter.More(); anIter.Next())
372   {
373     if (anIter.Value() == theObject)
374     {
375       theObject->myParent = NULL;
376       theObject->SetCombinedParentTransform (gp_Trsf());
377       myChildren.Remove (anIter);
378       break;
379     }
380   }
381 }
382
383 //=======================================================================
384 //function : SetZLayer
385 //purpose  :
386 //=======================================================================
387 void PrsMgr_PresentableObject::SetZLayer 
388   (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
389    const Standard_Integer theLayerId)
390 {
391   if (!thePrsMgr.IsNull())
392     thePrsMgr->SetZLayer (this, theLayerId);
393 }
394
395 //=======================================================================
396 //function : GetZLayer
397 //purpose  :
398 //=======================================================================
399 Standard_Integer PrsMgr_PresentableObject::GetZLayer 
400   (const Handle(PrsMgr_PresentationManager)& thePrsMgr) const
401 {
402   if (!thePrsMgr.IsNull())
403     return thePrsMgr->GetZLayer (this);
404
405   return -1;
406 }
407
408 // =======================================================================
409 // function : AddClipPlane
410 // purpose  :
411 // =======================================================================
412 void PrsMgr_PresentableObject::AddClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
413 {
414   // add to collection and process changes
415   myClipPlanes.Append (thePlane);
416   UpdateClipping();
417 }
418
419 // =======================================================================
420 // function : RemoveClipPlane
421 // purpose  :
422 // =======================================================================
423 void PrsMgr_PresentableObject::RemoveClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
424 {
425   // remove from collection and process changes
426   Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (myClipPlanes);
427   for (; aPlaneIt.More(); aPlaneIt.Next())
428   {
429     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
430     if (aPlane != thePlane)
431       continue;
432
433     myClipPlanes.Remove (aPlaneIt);
434     UpdateClipping();
435     return;
436   }
437 }
438
439 // =======================================================================
440 // function : SetClipPlanes
441 // purpose  :
442 // =======================================================================
443 void PrsMgr_PresentableObject::SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes)
444 {
445   // change collection and process changes
446   myClipPlanes = thePlanes;
447   UpdateClipping();
448 }
449
450 // =======================================================================
451 // function : UpdateClipping
452 // purpose  :
453 // =======================================================================
454 void PrsMgr_PresentableObject::UpdateClipping()
455 {
456   // affect generated structures
457   for (Standard_Integer aPrsIt = 1; aPrsIt <= myPresentations.Length(); ++aPrsIt)
458   {
459     // pass over presentation manager 3d mechanism right to the structures -
460     // we do not interested in display mode collections.
461     const PrsMgr_ModedPresentation& aModedPrs = myPresentations (aPrsIt);
462     if (aModedPrs.Presentation().IsNull()
463      || aModedPrs.Presentation()->Presentation().IsNull())
464     {
465       continue;
466     }
467
468     aModedPrs.Presentation()->Presentation()->SetClipPlanes (myClipPlanes);
469   }
470 }
471
472 // =======================================================================
473 // function : SetMutable
474 // purpose  :
475 // =======================================================================
476 void PrsMgr_PresentableObject::SetMutable (const Standard_Boolean theIsMutable)
477 {
478   if (myIsMutable == theIsMutable)
479   {
480     return;
481   }
482
483   myIsMutable = theIsMutable;
484   for (Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
485   {
486     const PrsMgr_ModedPresentation& aModedPrs = myPresentations (aPrsIter);
487     if (aModedPrs.Presentation().IsNull()
488      || aModedPrs.Presentation()->Presentation().IsNull())
489     {
490       continue;
491     }
492
493     aModedPrs.Presentation()->Presentation()->SetMutable (theIsMutable);
494   }
495 }
496
497 // =======================================================================
498 // function : IsMutable
499 // purpose  :
500 // =======================================================================
501 const Standard_Boolean PrsMgr_PresentableObject::IsMutable() const
502 {
503   return myIsMutable;
504 }