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