0030124: Visualization, AIS_InteractiveObject - clean up confusing Presentation inval...
[occt.git] / src / AIS / AIS_InteractiveObject.cxx
1 // Created on: 1996-12-18
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1996-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 <AIS_InteractiveObject.hxx>
18
19 #include <AIS_GraphicTool.hxx>
20 #include <AIS_InteractiveContext.hxx>
21 #include <Aspect_PolygonOffsetMode.hxx>
22 #include <Bnd_Box.hxx>
23 #include <Graphic3d_AspectFillArea3d.hxx>
24 #include <Graphic3d_AspectLine3d.hxx>
25 #include <Graphic3d_AspectMarker3d.hxx>
26 #include <Graphic3d_AspectText3d.hxx>
27 #include <Graphic3d_BndBox4f.hxx>
28 #include <Graphic3d_CStructure.hxx>
29 #include <Graphic3d_Group.hxx>
30 #include <Graphic3d_MaterialAspect.hxx>
31 #include <Graphic3d_Structure.hxx>
32 #include <Prs3d_BasicAspect.hxx>
33 #include <Prs3d_LineAspect.hxx>
34 #include <Prs3d_PointAspect.hxx>
35 #include <Prs3d_Presentation.hxx>
36 #include <Prs3d_Root.hxx>
37 #include <Prs3d_ShadingAspect.hxx>
38 #include <Prs3d_TextAspect.hxx>
39 #include <PrsMgr_ModedPresentation.hxx>
40 #include <PrsMgr_PresentationManager3d.hxx>
41 #include <Quantity_Color.hxx>
42 #include <Standard_Transient.hxx>
43 #include <Standard_Type.hxx>
44 #include <TColStd_ListIteratorOfListOfInteger.hxx>
45
46 IMPLEMENT_STANDARD_RTTIEXT(AIS_InteractiveObject,SelectMgr_SelectableObject)
47
48 //=======================================================================
49 //function : AIS_InteractiveObject
50 //purpose  : 
51 //=======================================================================
52 AIS_InteractiveObject::AIS_InteractiveObject (const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d)
53 : SelectMgr_SelectableObject (aTypeOfPresentation3d),
54   myCTXPtr (NULL),
55   myOwnWidth (0.0f),
56   myCurrentFacingModel (Aspect_TOFM_BOTH_SIDE),
57   myInfiniteState (Standard_False),
58   hasOwnColor (Standard_False),
59   hasOwnMaterial (Standard_False)
60 {
61   SetCurrentFacingModel();
62 }
63
64 //=======================================================================
65 //function : Redisplay
66 //purpose  :
67 //=======================================================================
68 void AIS_InteractiveObject::Redisplay (const Standard_Boolean AllModes)
69 {
70   if (myCTXPtr == NULL)
71     return;
72
73   myCTXPtr->Redisplay (this, Standard_False, AllModes);
74 }
75
76 //=======================================================================
77 //function : Type
78 //purpose  : 
79 //=======================================================================
80
81 AIS_KindOfInteractive AIS_InteractiveObject::Type() const 
82 {return AIS_KOI_None;}
83
84 //=======================================================================
85 //function : Signature
86 //purpose  : 
87 //=======================================================================
88
89 Standard_Integer AIS_InteractiveObject::Signature() const 
90 {return -1;}
91
92 //=======================================================================
93 //function : 
94 //purpose  : 
95 //=======================================================================
96 Handle(AIS_InteractiveContext) AIS_InteractiveObject::GetContext() const 
97 {
98   return myCTXPtr;
99 }
100
101 //=======================================================================
102 //function : SetContext
103 //purpose  :
104 //=======================================================================
105 void AIS_InteractiveObject::SetContext (const Handle(AIS_InteractiveContext)& theCtx)
106 {
107   if (myCTXPtr == theCtx.get())
108   {
109     return;
110   }
111
112   myCTXPtr = theCtx.get();
113   if (!theCtx.IsNull())
114   {
115     myDrawer->Link (theCtx->DefaultDrawer());
116   }
117 }
118
119 //=======================================================================
120 //function : 
121 //purpose  : 
122 //=======================================================================
123 Standard_Boolean AIS_InteractiveObject::HasOwner() const 
124 {
125   return (!myOwner.IsNull());
126 }
127
128
129
130 //=======================================================================
131 //function : 
132 //purpose  : 
133 //=======================================================================
134 void AIS_InteractiveObject::ClearOwner()
135 {
136   myOwner.Nullify();
137 }
138
139 //=======================================================================
140 //function : SetDisplayMode
141 //purpose  :
142 //=======================================================================
143 void AIS_InteractiveObject::SetDisplayMode (const Standard_Integer theMode)
144 {
145   if (AcceptDisplayMode (theMode))
146   {
147     myDrawer->SetDisplayMode (theMode);
148   }
149 }
150
151 //=======================================================================
152 //function : 
153 //purpose  : 
154 //=======================================================================
155 void AIS_InteractiveObject::SetCurrentFacingModel(const Aspect_TypeOfFacingModel aModel) {
156   myCurrentFacingModel = aModel;
157 }
158
159 //=======================================================================
160 //function : CurrentFacingModel
161 //purpose  : 
162 //=======================================================================
163
164 Aspect_TypeOfFacingModel AIS_InteractiveObject::CurrentFacingModel() const {
165   return myCurrentFacingModel;
166 }
167
168 //=======================================================================
169 //function : SetColor
170 //purpose  : 
171 //=======================================================================
172
173 void AIS_InteractiveObject::SetColor(const Quantity_Color& theColor)
174 {
175   myDrawer->SetColor (theColor);
176   hasOwnColor = Standard_True;
177 }
178
179 //=======================================================================
180 //function : UnsetColor
181 //purpose  : 
182 //=======================================================================
183 void AIS_InteractiveObject::UnsetColor()
184 {
185   hasOwnColor = Standard_False;
186 }
187
188 //=======================================================================
189 //function : 
190 //purpose  : 
191 //=======================================================================
192 void AIS_InteractiveObject::SetWidth(const Standard_Real aValue)
193 {
194   myOwnWidth = (Standard_ShortReal )aValue;
195 }
196
197 //=======================================================================
198 //function : 
199 //purpose  : 
200 //=======================================================================
201 void AIS_InteractiveObject::UnsetWidth()
202 {
203   myOwnWidth = 0.0f;
204 }
205
206 //=======================================================================
207 //function : Material
208 //purpose  :
209 //=======================================================================
210 Graphic3d_NameOfMaterial AIS_InteractiveObject::Material() const
211 {
212   return myDrawer->ShadingAspect()->Material().Name();
213 }
214
215 //=======================================================================
216 //function : SetMaterial
217 //purpose  :
218 //=======================================================================
219 void AIS_InteractiveObject::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
220 {
221   if (!myDrawer->HasOwnShadingAspect())
222   {
223     myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
224     if (myDrawer->HasLink())
225     {
226       *myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect();
227     }
228   }
229
230   myDrawer->ShadingAspect()->SetMaterial (theMaterial);
231   hasOwnMaterial = Standard_True;
232 }
233
234 //=======================================================================
235 //function : UnsetMaterial
236 //purpose  :
237 //=======================================================================
238 void AIS_InteractiveObject::UnsetMaterial()
239 {
240   if (!HasMaterial())
241   {
242     return;
243   }
244
245   if (HasColor() || IsTransparent())
246   {
247     if(myDrawer->HasLink())
248     {
249       myDrawer->ShadingAspect()->SetMaterial (AIS_GraphicTool::GetMaterial (myDrawer->Link()));
250     }
251
252     if (HasColor())
253     {
254       SetColor (myDrawer->Color());
255     }
256
257     if (IsTransparent())
258     {
259       SetTransparency (myDrawer->Transparency());
260     }
261   }
262   else
263   {
264     Handle(Prs3d_ShadingAspect) anAspect;
265     myDrawer->SetShadingAspect (anAspect);
266   }
267
268   hasOwnMaterial = Standard_False;
269 }
270
271 //=======================================================================
272 //function : SetTransparency
273 //purpose  :
274 //=======================================================================
275 void AIS_InteractiveObject::SetTransparency (const Standard_Real theValue)
276 {
277   if (!myDrawer->HasOwnShadingAspect())
278   {
279     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
280     if(myDrawer->HasLink())
281       myDrawer->ShadingAspect()->SetMaterial(AIS_GraphicTool::GetMaterial(myDrawer->Link()));
282   }
283
284   myDrawer->ShadingAspect()->Aspect()->ChangeFrontMaterial().SetTransparency (Standard_ShortReal(theValue));
285   myDrawer->ShadingAspect()->Aspect()->ChangeBackMaterial() .SetTransparency (Standard_ShortReal(theValue));
286   myDrawer->SetTransparency (Standard_ShortReal(theValue));
287 }
288
289 //=======================================================================
290 //function : UnsetTransparency
291 //purpose  : 
292 //=======================================================================
293 void AIS_InteractiveObject::UnsetTransparency()
294 {
295   if(HasColor() || HasMaterial() )
296   {
297     myDrawer->ShadingAspect()->Aspect()->ChangeFrontMaterial().SetTransparency (0.0f);
298     myDrawer->ShadingAspect()->Aspect()->ChangeBackMaterial() .SetTransparency (0.0f);
299   }
300   else{
301     Handle (Prs3d_ShadingAspect) SA;
302     myDrawer->SetShadingAspect(SA);
303   }
304   myDrawer->SetTransparency (0.0f);
305 }
306 //=======================================================================
307 //function : Transparency
308 //purpose  : 
309 //=======================================================================
310 Standard_Real AIS_InteractiveObject::Transparency() const 
311 {
312   return (myDrawer->Transparency() <= 0.005f ? 0.0 : myDrawer->Transparency());
313 // Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
314 // return Mat.Transparency();
315 }
316
317 //=======================================================================
318 //function : UnsetAttributes
319 //purpose  : 
320 //=======================================================================
321 void AIS_InteractiveObject::UnsetAttributes()
322 {
323   SelectMgr_SelectableObject::UnsetAttributes();
324
325   hasOwnColor    = Standard_False;
326   hasOwnMaterial = Standard_False;
327   myOwnWidth     = 0.0f;
328   myDrawer->SetTransparency (0.0f);
329 }
330
331 //=======================================================================
332 //function : AcceptDisplayMode
333 //purpose  : 
334 //=======================================================================
335
336 Standard_Boolean  AIS_InteractiveObject::AcceptDisplayMode(const Standard_Integer ) const
337 {return Standard_True;}
338
339 //=======================================================================
340 //function : DefaultDisplayMode
341 //purpose  : 
342 //=======================================================================
343
344 Standard_Integer AIS_InteractiveObject::DefaultDisplayMode() const
345 {return 0;}
346
347
348 //=======================================================================
349 //function : SetInfiniteState
350 //purpose  : 
351 //=======================================================================
352 void AIS_InteractiveObject::SetInfiniteState(const Standard_Boolean aFlag)
353 {
354   myInfiniteState = aFlag;
355   Handle(Prs3d_Presentation) P;
356
357   for(Standard_Integer i =1; i<=myPresentations.Length();i++)
358   {
359     P = myPresentations(i).Presentation()->Presentation();
360     if(!P.IsNull())
361       P->SetInfiniteState(myInfiniteState);
362   }
363 }
364
365 //=======================================================================
366 //function : HasPresentation
367 //purpose  :
368 //=======================================================================
369 Standard_Boolean AIS_InteractiveObject::HasPresentation() const
370 {
371   return HasInteractiveContext()
372       && myCTXPtr->MainPrsMgr()->HasPresentation (this, myDrawer->DisplayMode());
373 }
374
375 //=======================================================================
376 //function : Presentation
377 //purpose  :
378 //=======================================================================
379 Handle(Prs3d_Presentation) AIS_InteractiveObject::Presentation() const
380 {
381   if (!HasInteractiveContext())
382   {
383     return Handle(Prs3d_Presentation)();
384   }
385
386   Handle(PrsMgr_Presentation) aPrs = myCTXPtr->MainPrsMgr()->Presentation (this, myDrawer->DisplayMode(), false);
387   return !aPrs.IsNull()
388        ? aPrs->Presentation()
389        : Handle(Prs3d_Presentation)();
390 }
391
392 //=======================================================================
393 //function : SetAspect 
394 //purpose  : 
395 //=======================================================================
396 void AIS_InteractiveObject::SetAspect(const Handle(Prs3d_BasicAspect)& anAspect)
397 {
398
399   if( HasPresentation() ) {
400     Handle(Prs3d_Presentation) prs = Presentation();
401     { Handle(Prs3d_ShadingAspect) aspect =
402                         Handle(Prs3d_ShadingAspect)::DownCast(anAspect);
403       if( !aspect.IsNull() ) {
404         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
405         return;
406       }
407     }
408     { Handle(Prs3d_LineAspect) aspect =
409                         Handle(Prs3d_LineAspect)::DownCast(anAspect);
410       if( !aspect.IsNull() ) {
411         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
412         return;
413       }
414     }
415     { Handle(Prs3d_PointAspect) aspect =
416                         Handle(Prs3d_PointAspect)::DownCast(anAspect);
417       if( !aspect.IsNull() ) {
418         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
419         return;
420       }
421     }
422     { Handle(Prs3d_TextAspect) aspect =
423                         Handle(Prs3d_TextAspect)::DownCast(anAspect);
424       if( !aspect.IsNull() ) {
425         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
426         return;
427       }
428     }
429   }
430 }
431
432 //=======================================================================
433 //function : SetPolygonOffsets 
434 //purpose  : 
435 //======================================================================= 
436 void AIS_InteractiveObject::SetPolygonOffsets(const Standard_Integer    aMode,
437                                               const Standard_ShortReal  aFactor,
438                                               const Standard_ShortReal  aUnits) 
439 {
440   if ( !HasPolygonOffsets() )
441     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
442
443   myDrawer->ShadingAspect()->Aspect()->SetPolygonOffsets( aMode, aFactor, aUnits );
444   SynchronizeAspects();
445 }
446
447 //=======================================================================
448 //function : HasPolygonOffsets 
449 //purpose  : 
450 //=======================================================================
451 Standard_Boolean AIS_InteractiveObject::HasPolygonOffsets() const
452 {
453   return !( myDrawer->ShadingAspect().IsNull() || 
454           ( myDrawer->HasLink() &&
455           myDrawer->ShadingAspect() == myDrawer->Link()->ShadingAspect() ) );
456 }
457
458 //=======================================================================
459 //function : PolygonOffsets 
460 //purpose  : 
461 //=======================================================================
462 void AIS_InteractiveObject::PolygonOffsets(Standard_Integer&    aMode,
463                                            Standard_ShortReal&  aFactor,
464                                            Standard_ShortReal&  aUnits) const 
465 {
466   if( HasPolygonOffsets() )
467     myDrawer->ShadingAspect()->Aspect()->PolygonOffsets( aMode, aFactor, aUnits );
468 }
469
470 //=======================================================================
471 //function : BoundingBox
472 //purpose  : Returns bounding box of object correspondingly to its
473 //           current display mode
474 //=======================================================================
475 void AIS_InteractiveObject::BoundingBox (Bnd_Box& theBndBox)
476 {
477   if (myDrawer->DisplayMode() == -1)
478   {
479     if (!myPresentations.IsEmpty())
480     {
481       const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations.First().Presentation();
482       const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
483       const Graphic3d_BndBox3d& aBndBox = aStruct->CStructure()->BoundingBox();
484
485       if (!aBndBox.IsValid())
486       {
487         theBndBox.SetVoid();
488         return;
489       }
490
491       theBndBox.Update (aBndBox.CornerMin().x(), aBndBox.CornerMin().y(), aBndBox.CornerMin().z(),
492                         aBndBox.CornerMax().x(), aBndBox.CornerMax().y(), aBndBox.CornerMax().z());
493       return;
494     }
495     else
496     {
497       for (PrsMgr_ListOfPresentableObjectsIter aPrsIter (Children()); aPrsIter.More(); aPrsIter.Next())
498       {
499         Handle(AIS_InteractiveObject) aChild (Handle(AIS_InteractiveObject)::DownCast (aPrsIter.Value()));
500         if (aChild.IsNull())
501         {
502           continue;
503         }
504         Bnd_Box aBox;
505         aChild->BoundingBox (aBox);
506         theBndBox.Add (aBox);
507       }
508       return;
509     }
510   }
511   else
512   {
513     for (Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
514     {
515       if (myPresentations (aPrsIter).Mode() == myDrawer->DisplayMode())
516       {
517         const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
518         const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
519         const Graphic3d_BndBox3d& aBndBox = aStruct->CStructure()->BoundingBox();
520
521         if (!aBndBox.IsValid())
522         {
523           theBndBox.SetVoid();
524           return;
525         }
526
527         theBndBox.Update (aBndBox.CornerMin().x(), aBndBox.CornerMin().y(), aBndBox.CornerMin().z(),
528                           aBndBox.CornerMax().x(), aBndBox.CornerMax().y(), aBndBox.CornerMax().z());
529         return;
530       }
531     }
532   }
533 }
534
535 //=======================================================================
536 //function : SetIsoOnTriangulation
537 //purpose  : Enables or disables isoline on triangulation building
538 //=======================================================================
539 void AIS_InteractiveObject::SetIsoOnTriangulation (const Standard_Boolean theIsEnabled)
540 {
541   myDrawer->SetIsoOnTriangulation (theIsEnabled);
542 }
543
544 //=======================================================================
545 //function : SynchronizeAspects
546 //purpose  :
547 //=======================================================================
548 void AIS_InteractiveObject::SynchronizeAspects()
549 {
550   for (PrsMgr_Presentations::Iterator aPrsIter (myPresentations); aPrsIter.More(); aPrsIter.Next())
551   {
552     const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.ChangeValue().Presentation();
553     if (aPrs3d.IsNull()
554      || aPrs3d->Presentation().IsNull())
555     {
556       continue;
557     }
558
559     for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPrs3d->Presentation()->Groups()); aGroupIter.More(); aGroupIter.Next())
560     {
561       if (!aGroupIter.Value().IsNull())
562       {
563         aGroupIter.ChangeValue()->SynchronizeAspects();
564       }
565     }
566   }
567 }
568
569 //=======================================================================
570 //function : replaceAspects
571 //purpose  :
572 //=======================================================================
573 void AIS_InteractiveObject::replaceAspects (const Graphic3d_MapOfAspectsToAspects& theMap)
574 {
575   if (theMap.IsEmpty())
576   {
577     return;
578   }
579
580   for (PrsMgr_Presentations::Iterator aPrsIter (myPresentations); aPrsIter.More(); aPrsIter.Next())
581   {
582     const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.ChangeValue().Presentation();
583     if (aPrs3d.IsNull()
584      || aPrs3d->Presentation().IsNull())
585     {
586       continue;
587     }
588
589     for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPrs3d->Presentation()->Groups()); aGroupIter.More(); aGroupIter.Next())
590     {
591       if (!aGroupIter.Value().IsNull())
592       {
593         aGroupIter.ChangeValue()->ReplaceAspects (theMap);
594       }
595     }
596   }
597 }