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