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