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