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