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