0025933: Visualization - Forward AIS_InteractiveObject::Redisplay() execution to...
[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 // Modified :   22/03/04 ; SAN : OCC4895 High-level interface for controlling polygon offsets 
18
19 #include <AIS_InteractiveObject.ixx>
20
21 #include <Aspect_PolygonOffsetMode.hxx>
22 #include <Prs3d_ShadingAspect.hxx>
23 #include <Prs3d_LineAspect.hxx>
24 #include <Prs3d_PointAspect.hxx>
25 #include <Prs3d_TextAspect.hxx>
26 #include <Prs3d_Presentation.hxx>
27 #include <Prs3d_Root.hxx>
28 #include <PrsMgr_ModedPresentation.hxx>
29 #include <PrsMgr_PresentationManager3d.hxx>
30 #include <TColStd_ListIteratorOfListOfInteger.hxx>
31 #include <AIS_GraphicTool.hxx>
32 #include <Graphic3d_AspectFillArea3d.hxx>
33 #include <Graphic3d_AspectLine3d.hxx>
34 #include <Graphic3d_AspectMarker3d.hxx>
35 #include <Graphic3d_AspectText3d.hxx>
36 #include <Graphic3d_Group.hxx>
37 #include <Graphic3d_Structure.hxx>
38
39
40 //=======================================================================
41 //function : AIS_InteractiveObject
42 //purpose  : 
43 //=======================================================================
44
45 AIS_InteractiveObject::
46 AIS_InteractiveObject(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
47 SelectMgr_SelectableObject(aTypeOfPresentation3d),
48 myTransparency(0.),
49 myOwnColor(Quantity_NOC_WHITE),
50 myOwnMaterial(Graphic3d_NOM_DEFAULT),
51 myHilightMode(-1),
52 myOwnWidth(0.0),
53 myInfiniteState(Standard_False),
54 hasOwnColor(Standard_False),
55 hasOwnMaterial(Standard_False),
56 myCurrentFacingModel(Aspect_TOFM_BOTH_SIDE),
57 myRecomputeEveryPrs(Standard_True),
58 myCTXPtr(NULL),
59 mySelPriority(-1),
60 myDisplayMode (-1),
61 mySelectionMode(0),
62 mystate(0)
63 {
64   Handle (AIS_InteractiveContext) Bid;
65   myCTXPtr = Bid.operator->();
66   SetCurrentFacingModel();
67 }
68
69 //=======================================================================
70 //function : Redisplay
71 //purpose  :
72 //=======================================================================
73 void AIS_InteractiveObject::Redisplay (const Standard_Boolean AllModes)
74 {
75   if (myCTXPtr == NULL)
76     return;
77
78   myCTXPtr->Redisplay (this, Standard_False, AllModes);
79 }
80
81 //=======================================================================
82 //function : Type
83 //purpose  : 
84 //=======================================================================
85
86 AIS_KindOfInteractive AIS_InteractiveObject::Type() const 
87 {return AIS_KOI_None;}
88
89 //=======================================================================
90 //function : Signature
91 //purpose  : 
92 //=======================================================================
93
94 Standard_Integer AIS_InteractiveObject::Signature() const 
95 {return -1;}
96
97 //=======================================================================
98 //function : RecomputeEveryPrs
99 //purpose  : 
100 //=======================================================================
101
102 Standard_Boolean  AIS_InteractiveObject::RecomputeEveryPrs() const 
103 {return myRecomputeEveryPrs;}
104
105 //=======================================================================
106 //function : 
107 //purpose  : 
108 //=======================================================================
109 Standard_Boolean AIS_InteractiveObject::HasInteractiveContext() const 
110 {
111   Handle (AIS_InteractiveContext) aNull;
112   return  (myCTXPtr != aNull.operator->());
113 }
114
115 //=======================================================================
116 //function : 
117 //purpose  : 
118 //=======================================================================
119 Handle(AIS_InteractiveContext) AIS_InteractiveObject::GetContext() const 
120 {
121   return myCTXPtr;
122 }
123
124 //=======================================================================
125 //function : 
126 //purpose  : 
127 //=======================================================================
128 void AIS_InteractiveObject::SetContext(const Handle(AIS_InteractiveContext)& aCtx)
129 {
130   myCTXPtr = aCtx.operator->();
131   if( aCtx.IsNull())
132     return;
133   myDrawer->Link(aCtx->DefaultDrawer());
134 }
135
136 //=======================================================================
137 //function : 
138 //purpose  : 
139 //=======================================================================
140 Standard_Boolean AIS_InteractiveObject::HasOwner() const 
141 {
142   return (!myOwner.IsNull());
143 }
144
145
146
147 //=======================================================================
148 //function : 
149 //purpose  : 
150 //=======================================================================
151 void AIS_InteractiveObject::ClearOwner()
152 {
153   myOwner.Nullify();
154 }
155
156 //=======================================================================
157 //function : 
158 //purpose  : 
159 //=======================================================================
160 Standard_Boolean AIS_InteractiveObject::HasUsers() const 
161 {
162   return (!myUsers.IsEmpty());
163 }
164
165
166 //=======================================================================
167 //function : 
168 //purpose  : 
169 //=======================================================================
170 void AIS_InteractiveObject::AddUser(const Handle(Standard_Transient)& aUser)
171 {
172   myUsers.Append(aUser);
173 }
174
175 //=======================================================================
176 //function : 
177 //purpose  : 
178 //=======================================================================
179 void AIS_InteractiveObject::ClearUsers()
180 {
181   myUsers.Clear();
182 }
183
184
185 //=======================================================================
186 //function : 
187 //purpose  : 
188 //=======================================================================
189 void AIS_InteractiveObject::SetDisplayMode(const Standard_Integer aMode)
190 {
191   if( AcceptDisplayMode(aMode) )
192     myDisplayMode = aMode;
193 }
194   
195
196 //=======================================================================
197 //function : 
198 //purpose  : 
199 //=======================================================================
200 void AIS_InteractiveObject::SetSelectionMode(const Standard_Integer aMode)
201 {
202   mySelectionMode = aMode;
203 }
204
205
206
207 //=======================================================================
208 //function : 
209 //purpose  : 
210 //=======================================================================
211 void AIS_InteractiveObject::SetCurrentFacingModel(const Aspect_TypeOfFacingModel aModel) {
212   myCurrentFacingModel = aModel;
213 }
214
215 //=======================================================================
216 //function : CurrentFacingModel
217 //purpose  : 
218 //=======================================================================
219
220 Aspect_TypeOfFacingModel AIS_InteractiveObject::CurrentFacingModel() const {
221   return myCurrentFacingModel;
222 }
223
224 //=======================================================================
225 //function : SetColor
226 //purpose  : 
227 //=======================================================================
228
229 void AIS_InteractiveObject::SetColor(const Quantity_NameOfColor aColor)
230 {
231   SetColor(Quantity_Color(aColor));
232 }
233
234 //=======================================================================
235 //function : SetColor
236 //purpose  : 
237 //=======================================================================
238
239 void AIS_InteractiveObject::SetColor(const Quantity_Color &aColor)
240 {
241   myOwnColor = aColor;
242   hasOwnColor = Standard_True;
243 }
244
245 //=======================================================================
246 //function : UnsetColor
247 //purpose  : 
248 //=======================================================================
249 void AIS_InteractiveObject::UnsetColor()
250 {
251   hasOwnColor = Standard_False;
252 }
253
254 //=======================================================================
255 //function : 
256 //purpose  : 
257 //=======================================================================
258 void AIS_InteractiveObject::SetWidth(const Standard_Real aValue)
259 {
260   myOwnWidth = aValue;
261 }
262
263 //=======================================================================
264 //function : 
265 //purpose  : 
266 //=======================================================================
267 void AIS_InteractiveObject::UnsetWidth()
268 {
269   myOwnWidth = 0.;
270 }
271
272
273 //=======================================================================
274 //function : 
275 //purpose  : 
276 //=======================================================================
277 //POP pour K4L
278 void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfMaterial aName)
279 //void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfPhysicalMaterial aName)
280 {
281   if( HasColor() || IsTransparent() || HasMaterial() )
282   {
283     myDrawer->ShadingAspect()->SetMaterial(aName);
284   }
285   else
286   {
287     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
288     myDrawer->ShadingAspect()->SetMaterial(aName);
289   }
290   myOwnMaterial  = aName;
291   hasOwnMaterial = Standard_True;
292 }
293 //=======================================================================
294 //function : SetMaterial
295 //purpose  : 
296 //=======================================================================
297
298 void AIS_InteractiveObject::SetMaterial(const Graphic3d_MaterialAspect& aMat)
299 {
300   if (HasColor() || IsTransparent() || HasMaterial())
301   {
302     myDrawer->ShadingAspect()->SetMaterial(aMat);
303   }
304   else
305   {
306     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
307     myDrawer->ShadingAspect()->SetMaterial(aMat);
308   }
309   hasOwnMaterial = Standard_True;
310 }
311 //=======================================================================
312 //function : 
313 //purpose  : 
314 //=======================================================================
315 void AIS_InteractiveObject::UnsetMaterial()
316 {
317   if( !HasMaterial() ) return;
318   if (HasColor() || IsTransparent())
319   {
320     if(myDrawer->HasLink())
321     {
322       myDrawer->ShadingAspect()->SetMaterial (AIS_GraphicTool::GetMaterial (myDrawer->Link()));
323     }
324     if (HasColor()) SetColor (myOwnColor);
325     if (IsTransparent()) SetTransparency (myTransparency);
326   }
327   else{
328     Handle(Prs3d_ShadingAspect) SA;
329     myDrawer->SetShadingAspect(SA);
330   }
331   hasOwnMaterial = Standard_False;
332 }
333
334 //=======================================================================
335 //function : SetTransparency
336 //purpose  : 
337 //=======================================================================
338 void AIS_InteractiveObject::SetTransparency(const Standard_Real aValue)
339 {
340   if(!HasColor() && !IsTransparent() && !HasMaterial())
341   {
342     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
343     if(myDrawer->HasLink())
344       myDrawer->ShadingAspect()->SetMaterial(AIS_GraphicTool::GetMaterial(myDrawer->Link()));
345   }
346   Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
347   Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial();
348   FMat.SetTransparency(aValue); BMat.SetTransparency(aValue);
349   myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat);
350   myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat);
351   myTransparency = aValue;
352 }
353
354 //=======================================================================
355 //function : UnsetTransparency
356 //purpose  : 
357 //=======================================================================
358 void AIS_InteractiveObject::UnsetTransparency()
359 {
360   if(HasColor() || HasMaterial() )
361   {
362     Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
363     Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial();
364     FMat.SetTransparency(0.); BMat.SetTransparency(0.);
365     myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat);
366     myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat);
367   }
368   else{
369     Handle (Prs3d_ShadingAspect) SA;
370     myDrawer->SetShadingAspect(SA);
371   }
372   myTransparency =0.0;
373 }
374 //=======================================================================
375 //function : Transparency
376 //purpose  : 
377 //=======================================================================
378 Standard_Real AIS_InteractiveObject::Transparency() const 
379 {
380   return (myTransparency<=0.05 ? 0 : myTransparency);
381 // Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
382 // return Mat.Transparency();
383 }
384
385 //=======================================================================
386 //function : UnsetAttributes
387 //purpose  : 
388 //=======================================================================
389 void AIS_InteractiveObject::UnsetAttributes()
390 {
391   SelectMgr_SelectableObject::UnsetAttributes();
392
393   hasOwnColor    = Standard_False;
394   hasOwnMaterial = Standard_False;
395   myOwnWidth     = 0.0;
396   myTransparency = 0.0;
397 }
398
399 //=======================================================================
400 //function : 
401 //purpose  : 
402 //=======================================================================
403 void AIS_InteractiveObject::MustRecomputePrs(const Standard_Integer ) const 
404 {}
405
406 //=======================================================================
407 //function : 
408 //purpose  : 
409 //=======================================================================
410 const TColStd_ListOfInteger& AIS_InteractiveObject::ListOfRecomputeModes() const 
411 {return myToRecomputeModes;}
412
413 //=======================================================================
414 //function : 
415 //purpose  : 
416 //=======================================================================
417 void AIS_InteractiveObject::SetRecomputeOk()
418 {myToRecomputeModes.Clear();}
419
420
421 //=======================================================================
422 //function : AcceptDisplayMode
423 //purpose  : 
424 //=======================================================================
425
426 Standard_Boolean  AIS_InteractiveObject::AcceptDisplayMode(const Standard_Integer ) const
427 {return Standard_True;}
428
429 //=======================================================================
430 //function : DefaultDisplayMode
431 //purpose  : 
432 //=======================================================================
433
434 Standard_Integer AIS_InteractiveObject::DefaultDisplayMode() const
435 {return 0;}
436
437
438 //=======================================================================
439 //function : SetInfiniteState
440 //purpose  : 
441 //=======================================================================
442 void AIS_InteractiveObject::SetInfiniteState(const Standard_Boolean aFlag)
443 {
444   myInfiniteState = aFlag;
445   Handle(Prs3d_Presentation) P;
446
447   for(Standard_Integer i =1; i<=myPresentations.Length();i++)
448   {
449     P = myPresentations(i).Presentation()->Presentation();
450     if(!P.IsNull())
451       P->SetInfiniteState(myInfiniteState);
452   }
453 }
454
455 //=======================================================================
456 //function : HasPresentation
457 //purpose  :
458 //=======================================================================
459 Standard_Boolean AIS_InteractiveObject::HasPresentation() const
460 {
461   return !GetContext().IsNull()
462        && GetContext()->MainPrsMgr()->HasPresentation (this, myDisplayMode);
463 }
464
465 //=======================================================================
466 //function : Presentation
467 //purpose  :
468 //=======================================================================
469 Handle(Prs3d_Presentation) AIS_InteractiveObject::Presentation() const
470 {
471   return HasPresentation()
472        ? GetContext()->MainPrsMgr()->Presentation (this, myDisplayMode)->Presentation()
473        : Handle(Prs3d_Presentation)();
474 }
475
476 //=======================================================================
477 //function : SetAspect 
478 //purpose  : 
479 //=======================================================================
480 void AIS_InteractiveObject::SetAspect(const Handle(Prs3d_BasicAspect)& anAspect,
481                                       const Standard_Boolean globalChange) {
482
483   if( HasPresentation() ) {
484     Handle(Prs3d_Presentation) prs = Presentation();
485     { Handle(Prs3d_ShadingAspect) aspect =
486                         Handle(Prs3d_ShadingAspect)::DownCast(anAspect);
487       if( !aspect.IsNull() ) {
488         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
489         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
490         return;
491       }
492     }
493     { Handle(Prs3d_LineAspect) aspect =
494                         Handle(Prs3d_LineAspect)::DownCast(anAspect);
495       if( !aspect.IsNull() ) {
496         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
497         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
498         return;
499       }
500     }
501     { Handle(Prs3d_PointAspect) aspect =
502                         Handle(Prs3d_PointAspect)::DownCast(anAspect);
503       if( !aspect.IsNull() ) {
504         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
505         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
506         return;
507       }
508     }
509     { Handle(Prs3d_TextAspect) aspect =
510                         Handle(Prs3d_TextAspect)::DownCast(anAspect);
511       if( !aspect.IsNull() ) {
512         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
513         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
514         return;
515       }
516     }
517   }
518 }
519
520 //=======================================================================
521 //function : SetPolygonOffsets 
522 //purpose  : 
523 //======================================================================= 
524 void AIS_InteractiveObject::SetPolygonOffsets(const Standard_Integer    aMode,
525                                               const Standard_ShortReal  aFactor,
526                                               const Standard_ShortReal  aUnits) 
527 {
528   if ( !HasPolygonOffsets() )
529     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
530
531   myDrawer->ShadingAspect()->Aspect()->SetPolygonOffsets( aMode, aFactor, aUnits );
532
533   // Modify existing presentations 
534   for (Standard_Integer aPrsIter = 1, n = myPresentations.Length(); aPrsIter <= n; ++aPrsIter)
535   {
536     const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
537     if ( !aPrs3d.IsNull() ) {
538       const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
539       if( !aStruct.IsNull() ) {
540         aStruct->SetPrimitivesAspect( myDrawer->ShadingAspect()->Aspect() );
541         // Workaround for issue 23115: Need to update also groups, because their
542         // face aspect ALWAYS overrides the structure's.
543         const Graphic3d_SequenceOfGroup& aGroups = aStruct->Groups();
544         for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
545         {
546           Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
547           if (aGrp.IsNull()
548           || !aGrp->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
549           {
550             continue;
551           }
552
553           Handle(Graphic3d_AspectFillArea3d) aFaceAsp = new Graphic3d_AspectFillArea3d();
554           Handle(Graphic3d_AspectLine3d)     aLineAsp = new Graphic3d_AspectLine3d();
555           Handle(Graphic3d_AspectMarker3d)   aPntAsp  = new Graphic3d_AspectMarker3d();
556           Handle(Graphic3d_AspectText3d)     aTextAsp = new Graphic3d_AspectText3d();
557           // TODO: Add methods for retrieving individual aspects from Graphic3d_Group
558           aGrp->GroupPrimitivesAspect(aLineAsp, aTextAsp, aPntAsp, aFaceAsp);
559           aFaceAsp->SetPolygonOffsets(aMode, aFactor, aUnits);
560           aGrp->SetGroupPrimitivesAspect(aFaceAsp);
561         }
562       }
563     }
564   }
565 }
566
567 //=======================================================================
568 //function : HasPolygonOffsets 
569 //purpose  : 
570 //=======================================================================
571 Standard_Boolean AIS_InteractiveObject::HasPolygonOffsets() const
572 {
573   return !( myDrawer->ShadingAspect().IsNull() || 
574           ( myDrawer->HasLink() &&
575           myDrawer->ShadingAspect() == myDrawer->Link()->ShadingAspect() ) );
576 }
577
578 //=======================================================================
579 //function : PolygonOffsets 
580 //purpose  : 
581 //=======================================================================
582 void AIS_InteractiveObject::PolygonOffsets(Standard_Integer&    aMode,
583                                            Standard_ShortReal&  aFactor,
584                                            Standard_ShortReal&  aUnits) const 
585 {
586   if( HasPolygonOffsets() )
587     myDrawer->ShadingAspect()->Aspect()->PolygonOffsets( aMode, aFactor, aUnits );
588 }