0023710: Simplification of presentation managment classes
[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 #define BUC60577        //GG_101099     Enable to compute correctly
20 //                      transparency with more than one object in the view.
21
22 #define GER61351        //GG_171199     Enable to set an object RGB color
23 //                      instead a restricted object NameOfColor. 
24 //                      Add SetCurrentFacingModel() method
25
26 #define BUC60632        //GG 15/03/00 Add protection on SetDisplayMode()
27 //                      method, compute only authorized presentation.
28
29 #define OCC708          //SAV unsetting transformation correctly
30
31 #include <AIS_InteractiveObject.ixx>
32
33 #include <Aspect_PolygonOffsetMode.hxx>
34 #include <Prs3d_ShadingAspect.hxx>
35 #include <Prs3d_LineAspect.hxx>
36 #include <Prs3d_PointAspect.hxx>
37 #include <Prs3d_TextAspect.hxx>
38 #include <Prs3d_Presentation.hxx>
39 #include <Prs3d_Root.hxx>
40 #include <PrsMgr_ModedPresentation.hxx>
41 #include <PrsMgr_PresentationManager3d.hxx>
42 #include <TColStd_ListIteratorOfListOfInteger.hxx>
43 #include <AIS_GraphicTool.hxx>
44 #include <Graphic3d_AspectFillArea3d.hxx>
45 #include <Graphic3d_AspectLine3d.hxx>
46 #include <Graphic3d_AspectMarker3d.hxx>
47 #include <Graphic3d_AspectText3d.hxx>
48 #include <Graphic3d_Group.hxx>
49 #include <Graphic3d_Structure.hxx>
50
51
52 //=======================================================================
53 //function : AIS_InteractiveObject
54 //purpose  : 
55 //=======================================================================
56
57 AIS_InteractiveObject::
58 AIS_InteractiveObject(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
59 SelectMgr_SelectableObject(aTypeOfPresentation3d),
60 myDrawer(new AIS_Drawer()),
61 myTransparency(0.),
62 myOwnColor(Quantity_NOC_WHITE),
63 myOwnMaterial(Graphic3d_NOM_DEFAULT),
64 myHilightMode(-1),
65 myOwnWidth(0.0),
66 myInfiniteState(Standard_False),
67 hasOwnColor(Standard_False),
68 hasOwnMaterial(Standard_False),
69 myCurrentFacingModel(Aspect_TOFM_BOTH_SIDE),
70 myRecomputeEveryPrs(Standard_True),
71 myCTXPtr(NULL),
72 mySelPriority(-1),
73 myDisplayMode (-1),
74 mySelectionMode(0),
75 mystate(0),
76 myHasTransformation(Standard_False)
77 {
78   Handle (AIS_InteractiveContext) Bid;
79   myCTXPtr = Bid.operator->();
80 #ifdef GER61351
81   SetCurrentFacingModel();
82 #endif
83 }
84
85 //=======================================================================
86 //function : Redisplay
87 //purpose  : 
88 //=======================================================================
89
90 void AIS_InteractiveObject::Redisplay(const Standard_Boolean AllModes)
91 {
92   Update(AllModes);
93   UpdateSelection();
94 }
95
96 //=======================================================================
97 //function : Type
98 //purpose  : 
99 //=======================================================================
100
101 AIS_KindOfInteractive AIS_InteractiveObject::Type() const 
102 {return AIS_KOI_None;}
103
104 //=======================================================================
105 //function : Signature
106 //purpose  : 
107 //=======================================================================
108
109 Standard_Integer AIS_InteractiveObject::Signature() const 
110 {return -1;}
111
112 //=======================================================================
113 //function : RecomputeEveryPrs
114 //purpose  : 
115 //=======================================================================
116
117 Standard_Boolean  AIS_InteractiveObject::RecomputeEveryPrs() const 
118 {return myRecomputeEveryPrs;}
119
120 //=======================================================================
121 //function : 
122 //purpose  : 
123 //=======================================================================
124 Standard_Boolean AIS_InteractiveObject::HasInteractiveContext() const 
125 {
126   Handle (AIS_InteractiveContext) aNull;
127   return  (myCTXPtr != aNull.operator->());
128 }
129
130 //=======================================================================
131 //function : 
132 //purpose  : 
133 //=======================================================================
134 Handle(AIS_InteractiveContext) AIS_InteractiveObject::GetContext() const 
135 {
136   return myCTXPtr;
137 }
138
139 //=======================================================================
140 //function : 
141 //purpose  : 
142 //=======================================================================
143 void AIS_InteractiveObject::SetContext(const Handle(AIS_InteractiveContext)& aCtx)
144 {
145   myCTXPtr = aCtx.operator->();
146   if( aCtx.IsNull())
147     return;
148   if (myDrawer.IsNull()) {
149     myDrawer = new AIS_Drawer;
150 #ifdef DEB
151     cout << "AIS_InteractiveObject::SetContext DRAWER NUL!" << endl;
152 #endif
153   }
154   myDrawer->Link(aCtx->DefaultDrawer());
155 }
156
157 //=======================================================================
158 //function : 
159 //purpose  : 
160 //=======================================================================
161 Standard_Boolean AIS_InteractiveObject::HasOwner() const 
162 {
163   return (!myOwner.IsNull());
164 }
165
166
167
168 //=======================================================================
169 //function : 
170 //purpose  : 
171 //=======================================================================
172 void AIS_InteractiveObject::ClearOwner()
173 {
174   myOwner.Nullify();
175 }
176
177 //=======================================================================
178 //function : 
179 //purpose  : 
180 //=======================================================================
181 Standard_Boolean AIS_InteractiveObject::HasUsers() const 
182 {
183   return (!myUsers.IsEmpty());
184 }
185
186
187 //=======================================================================
188 //function : 
189 //purpose  : 
190 //=======================================================================
191 void AIS_InteractiveObject::AddUser(const Handle(Standard_Transient)& aUser)
192 {
193   myUsers.Append(aUser);
194 }
195
196 //=======================================================================
197 //function : 
198 //purpose  : 
199 //=======================================================================
200 void AIS_InteractiveObject::ClearUsers()
201 {
202   myUsers.Clear();
203 }
204
205
206 //=======================================================================
207 //function : 
208 //purpose  : 
209 //=======================================================================
210 void AIS_InteractiveObject::SetDisplayMode(const Standard_Integer aMode)
211 {
212 #ifdef BUC60632
213   if( AcceptDisplayMode(aMode) )
214 #endif
215     myDisplayMode = aMode;
216 }
217   
218
219 //=======================================================================
220 //function : 
221 //purpose  : 
222 //=======================================================================
223 void AIS_InteractiveObject::SetSelectionMode(const Standard_Integer aMode)
224 {
225   mySelectionMode = aMode;
226 }
227
228
229
230 //=======================================================================
231 //function : 
232 //purpose  : 
233 //=======================================================================
234 #ifdef GER61351
235 void AIS_InteractiveObject::SetCurrentFacingModel(const Aspect_TypeOfFacingModel aModel) {
236   myCurrentFacingModel = aModel;
237 }
238
239 //=======================================================================
240 //function : CurrentFacingModel
241 //purpose  : 
242 //=======================================================================
243
244 Aspect_TypeOfFacingModel AIS_InteractiveObject::CurrentFacingModel() const {
245   return myCurrentFacingModel;
246 }
247 #endif
248
249 //=======================================================================
250 //function : SetColor
251 //purpose  : 
252 //=======================================================================
253
254 void AIS_InteractiveObject::SetColor(const Quantity_NameOfColor aColor)
255 #ifdef GER61351
256 {
257   SetColor(Quantity_Color(aColor));
258 }
259
260 //=======================================================================
261 //function : SetColor
262 //purpose  : 
263 //=======================================================================
264
265 void AIS_InteractiveObject::SetColor(const Quantity_Color &aColor)
266 #endif
267 {
268   myOwnColor = aColor;
269   hasOwnColor = Standard_True;
270 }
271
272 //=======================================================================
273 //function : UnsetColor
274 //purpose  : 
275 //=======================================================================
276 void AIS_InteractiveObject::UnsetColor()
277 {
278   hasOwnColor = Standard_False;
279 }
280
281 //=======================================================================
282 //function : 
283 //purpose  : 
284 //=======================================================================
285 void AIS_InteractiveObject::SetWidth(const Standard_Real aValue)
286 {
287   myOwnWidth = aValue;
288 }
289
290 //=======================================================================
291 //function : 
292 //purpose  : 
293 //=======================================================================
294 void AIS_InteractiveObject::UnsetWidth()
295 {
296   myOwnWidth = 0.;
297 }
298
299
300 //=======================================================================
301 //function : 
302 //purpose  : 
303 //=======================================================================
304 //POP pour K4L
305 void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfMaterial aName)
306 //void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfPhysicalMaterial aName)
307 {
308   if( HasColor() || IsTransparent() || HasMaterial() )
309     {
310       myDrawer->ShadingAspect()->SetMaterial(aName);
311     }
312   else 
313     {
314       myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
315       
316       myDrawer->ShadingAspect()->SetMaterial(aName);
317 #ifndef BUC60577        //???
318       myDrawer->ShadingAspect()->SetColor(AIS_GraphicTool::GetInteriorColor(myDrawer->Link()));
319 #endif
320     }
321   myOwnMaterial  = aName;
322   hasOwnMaterial = Standard_True;
323 }
324 //=======================================================================
325 //function : SetMaterial
326 //purpose  : 
327 //=======================================================================
328
329 void AIS_InteractiveObject::SetMaterial(const Graphic3d_MaterialAspect& aMat)
330 {
331 #ifdef BUC60577
332   if( HasColor() || IsTransparent() || HasMaterial() )
333 #else
334   if(hasOwnColor ||(myTransparency==0.0) || hasOwnMaterial )
335 #endif
336     {
337       myDrawer->ShadingAspect()->SetMaterial(aMat);
338     }
339   else 
340     {
341       myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
342       myDrawer->ShadingAspect()->SetMaterial(aMat);
343     }
344   hasOwnMaterial = Standard_True;
345   
346 }
347 //=======================================================================
348 //function : 
349 //purpose  : 
350 //=======================================================================
351 void AIS_InteractiveObject::UnsetMaterial()
352 {
353 #ifdef BUC60577
354   if( !HasMaterial() ) return;
355   if( HasColor() || IsTransparent()) {
356     myDrawer->ShadingAspect()->SetMaterial(
357                 AIS_GraphicTool::GetMaterial(myDrawer->Link()));
358     if( HasColor() ) SetColor(myOwnColor);
359     if( IsTransparent() ) SetTransparency(myTransparency);
360   }
361 #else
362   if(!hasOwnMaterial) return;
363   if(hasOwnColor ||(myTransparency==0.0))
364     {
365       myDrawer->ShadingAspect()->SetMaterial(AIS_GraphicTool::GetMaterial(myDrawer->Link()));
366     }
367 #endif
368   else{
369     Handle(Prs3d_ShadingAspect) SA;
370     myDrawer->SetShadingAspect(SA);
371   }
372   hasOwnMaterial = Standard_False;
373 }
374
375 //=======================================================================
376 //function : SetTransparency
377 //purpose  : 
378 //=======================================================================
379 void AIS_InteractiveObject::SetTransparency(const Standard_Real aValue)
380 {
381
382 #ifdef BUC60577                     // Back & Front material can be different !
383
384   if(!HasColor() && !IsTransparent() && !HasMaterial() ) {
385         myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
386       if(!myDrawer->Link().IsNull())
387         myDrawer->ShadingAspect()->SetMaterial(AIS_GraphicTool::GetMaterial(myDrawer->Link()));
388   }
389   Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
390   Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial();
391   FMat.SetTransparency(aValue); BMat.SetTransparency(aValue);
392   myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat);
393   myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat);
394 #else
395   if(aValue<0.0 || aValue>1.0) return;
396   
397   if(aValue<=0.05) 
398     {
399       UnsetTransparency();
400       return;
401     }
402   
403
404   if(hasOwnColor || hasOwnMaterial || myTransparency> 0.0)
405     {
406       Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
407       Mat.SetTransparency(aValue);
408       myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(Mat);
409       myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(Mat);
410     }
411   else
412     {
413       myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
414       if(!myDrawer->Link().IsNull())
415         myDrawer->ShadingAspect()->SetMaterial(AIS_GraphicTool::GetMaterial(myDrawer->Link()));
416       Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
417       Mat.SetTransparency(aValue);
418       myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(Mat);
419       myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(Mat);
420     }
421 #endif
422   myTransparency = aValue;
423 }
424
425 //=======================================================================
426 //function : UnsetTransparency
427 //purpose  : 
428 //=======================================================================
429 void AIS_InteractiveObject::UnsetTransparency()
430 {
431 #ifdef BUC60577                     // Back & Front material can be different !
432     if(HasColor() || HasMaterial() )
433     {
434       Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
435       Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial();
436       FMat.SetTransparency(0.); BMat.SetTransparency(0.);
437       myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat);
438       myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat);
439     }
440 #else
441     if(hasOwnColor || hasOwnMaterial )
442     {
443       Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
444       Mat.SetTransparency(0.0);
445 //      myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(Mat);
446 //      myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(Mat);
447        myDrawer->ShadingAspect()->SetMaterial(Mat);
448     }
449 #endif
450   else{
451     Handle (Prs3d_ShadingAspect) SA;
452     myDrawer->SetShadingAspect(SA);
453   }
454   myTransparency =0.0;
455 }
456 //=======================================================================
457 //function : Transparency
458 //purpose  : 
459 //=======================================================================
460 Standard_Real AIS_InteractiveObject::Transparency() const 
461 {
462   return (myTransparency<=0.05 ? 0 : myTransparency);
463 // Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
464 // return Mat.Transparency();
465 }
466
467 //=======================================================================
468 //function : SetAttributes
469 //purpose  : 
470 //=======================================================================
471
472 void AIS_InteractiveObject::SetAttributes(const Handle(AIS_Drawer)& aDrawer)
473 {myDrawer = aDrawer;}
474
475
476 //=======================================================================
477 //function : UnsetAttributes
478 //purpose  : 
479 //=======================================================================
480 void AIS_InteractiveObject::UnsetAttributes()
481 {
482   Handle(AIS_Drawer) dr = new AIS_Drawer();
483   if(myDrawer->HasLink())
484     dr->Link(myDrawer->Link());
485   myDrawer       = dr;
486   hasOwnColor    = Standard_False;
487   hasOwnMaterial = Standard_False;
488   myOwnWidth     = 0.0;
489   myTransparency = 0.0;
490 }
491
492 //=======================================================================
493 //function : 
494 //purpose  : 
495 //=======================================================================
496 void AIS_InteractiveObject::MustRecomputePrs(const Standard_Integer ) const 
497 {}
498
499 //=======================================================================
500 //function : 
501 //purpose  : 
502 //=======================================================================
503 const TColStd_ListOfInteger& AIS_InteractiveObject::ListOfRecomputeModes() const 
504 {return myToRecomputeModes;}
505
506 //=======================================================================
507 //function : 
508 //purpose  : 
509 //=======================================================================
510 void AIS_InteractiveObject::SetRecomputeOk()
511 {myToRecomputeModes.Clear();}
512
513
514 //=======================================================================
515 //function : AcceptDisplayMode
516 //purpose  : 
517 //=======================================================================
518
519 Standard_Boolean  AIS_InteractiveObject::AcceptDisplayMode(const Standard_Integer ) const
520 {return Standard_True;}
521
522 //=======================================================================
523 //function : DefaultDisplayMode
524 //purpose  : 
525 //=======================================================================
526
527 Standard_Integer AIS_InteractiveObject::DefaultDisplayMode() const
528 {return 0;}
529
530
531 //=======================================================================
532 //function : SetInfiniteState
533 //purpose  : 
534 //=======================================================================
535 void AIS_InteractiveObject::SetInfiniteState(const Standard_Boolean aFlag)
536 {
537   myInfiniteState = aFlag;
538   Handle(Prs3d_Presentation) P;
539
540   for(Standard_Integer i =1; i<=myPresentations.Length();i++){
541     P = Handle(Prs3d_Presentation)::DownCast(myPresentations(i).Presentation());
542     if(!P.IsNull())
543       P->SetInfiniteState(myInfiniteState);}
544 }
545
546 //=======================================================================
547 //function : SetTransformation
548 //purpose  :
549 //=======================================================================
550 void AIS_InteractiveObject::SetTransformation (const Handle(Geom_Transformation)& theTrsf,
551                                                const Standard_Boolean             theToPostConcatenate,
552                                                const Standard_Boolean             theToUpdateSelection)
553 {
554   if (GetContext().IsNull())
555   {
556     return;
557   }
558
559   const PrsMgr_Presentations& aPrsList = Presentations();
560   myHasTransformation = Standard_True;
561   for (Standard_Integer aPrsIter = 1; aPrsIter <= aPrsList.Length(); ++aPrsIter)
562   {
563     const Standard_Integer aMode = aPrsList (aPrsIter).Mode();
564     Handle(Prs3d_Presentation) aPrs = GetContext()->MainPrsMgr()->Presentation (this, aMode)->Presentation();
565     theToPostConcatenate ? aPrs->Multiply  (theTrsf)
566                          : aPrs->Transform (theTrsf);
567     if (theToUpdateSelection)
568     {
569       myCTXPtr->ClearSelected (Standard_True);
570       myCTXPtr->RecomputeSelectionOnly (this);
571     }
572   }
573 }
574
575 //=======================================================================
576 //function : SetTransformation
577 //purpose  : 
578 //=======================================================================
579 void AIS_InteractiveObject::UnsetTransformation() {
580 #ifdef OCC708
581   static Handle(Geom_Transformation) trsf = new Geom_Transformation( gp_Trsf() );
582 #else
583 Handle(Geom_Transformation) trsf;
584 #endif
585
586     SetTransformation(trsf);    // Set identity transformation
587     myHasTransformation = Standard_False;
588 }
589
590 //=======================================================================
591 //function : Transformation
592 //purpose  :
593 //=======================================================================
594 Handle(Geom_Transformation) AIS_InteractiveObject::Transformation()
595 {
596   if (GetContext().IsNull())
597   {
598     return Handle(Geom_Transformation)();
599   }
600
601   const PrsMgr_Presentations& aPrsList = Presentations();
602   if (aPrsList.Length() > 0)
603   {
604     Handle(Prs3d_Presentation) aPrs = GetContext()->MainPrsMgr()->Presentation (this, 1)->Presentation();
605     return aPrs->Transformation();
606   }
607   return Handle(Geom_Transformation)();
608 }
609
610 //=======================================================================
611 //function : HasTransformation
612 //purpose  : 
613 //=======================================================================
614 Standard_Boolean AIS_InteractiveObject::HasTransformation() const {
615
616   return myHasTransformation;
617 }
618
619 //=======================================================================
620 //function : HasPresentation
621 //purpose  :
622 //=======================================================================
623 Standard_Boolean AIS_InteractiveObject::HasPresentation() const
624 {
625   return !GetContext().IsNull()
626        && GetContext()->MainPrsMgr()->HasPresentation (this, myDisplayMode);
627 }
628
629 //=======================================================================
630 //function : Presentation
631 //purpose  :
632 //=======================================================================
633 Handle(Prs3d_Presentation) AIS_InteractiveObject::Presentation() const
634 {
635   return HasPresentation()
636        ? GetContext()->MainPrsMgr()->Presentation (this, myDisplayMode)->Presentation()
637        : Handle(Prs3d_Presentation)();
638 }
639
640 //=======================================================================
641 //function : SetAspect 
642 //purpose  : 
643 //=======================================================================
644 void AIS_InteractiveObject::SetAspect(const Handle(Prs3d_BasicAspect)& anAspect,
645                                       const Standard_Boolean globalChange) {
646
647   if( HasPresentation() ) {
648     Handle(Prs3d_Presentation) prs = Presentation();
649     { Handle(Prs3d_ShadingAspect) aspect =
650                         Handle(Prs3d_ShadingAspect)::DownCast(anAspect);
651       if( !aspect.IsNull() ) {
652         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
653         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
654         return;
655       }
656     }
657     { Handle(Prs3d_LineAspect) aspect =
658                         Handle(Prs3d_LineAspect)::DownCast(anAspect);
659       if( !aspect.IsNull() ) {
660         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
661         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
662         return;
663       }
664     }
665     { Handle(Prs3d_PointAspect) aspect =
666                         Handle(Prs3d_PointAspect)::DownCast(anAspect);
667       if( !aspect.IsNull() ) {
668         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
669         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
670         return;
671       }
672     }
673     { Handle(Prs3d_TextAspect) aspect =
674                         Handle(Prs3d_TextAspect)::DownCast(anAspect);
675       if( !aspect.IsNull() ) {
676         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
677         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
678         return;
679       }
680     }
681   }
682 }
683
684 //=======================================================================
685 //function : SetPolygonOffsets 
686 //purpose  : 
687 //======================================================================= 
688 void AIS_InteractiveObject::SetPolygonOffsets(const Standard_Integer    aMode,
689                                               const Standard_ShortReal  aFactor,
690                                               const Standard_ShortReal  aUnits) 
691 {
692   if ( !HasPolygonOffsets() )
693     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
694
695   myDrawer->ShadingAspect()->Aspect()->SetPolygonOffsets( aMode, aFactor, aUnits );
696
697   // Modify existing presentations 
698   for (Standard_Integer aPrsIter = 1, n = myPresentations.Length(); aPrsIter <= n; ++aPrsIter)
699   {
700     const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
701     if ( !aPrs3d.IsNull() ) {
702       const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
703       if( !aStruct.IsNull() ) {
704         aStruct->SetPrimitivesAspect( myDrawer->ShadingAspect()->Aspect() );
705         // Workaround for issue 23115: Need to update also groups, because their
706         // face aspect ALWAYS overrides the structure's.
707         const Graphic3d_SequenceOfGroup& aGroups = aStruct->Groups();
708         for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
709         {
710           Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
711           if (aGrp.IsNull()
712           || !aGrp->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
713           {
714             continue;
715           }
716
717           Handle(Graphic3d_AspectFillArea3d) aFaceAsp = new Graphic3d_AspectFillArea3d();
718           Handle(Graphic3d_AspectLine3d)     aLineAsp = new Graphic3d_AspectLine3d();
719           Handle(Graphic3d_AspectMarker3d)   aPntAsp  = new Graphic3d_AspectMarker3d();
720           Handle(Graphic3d_AspectText3d)     aTextAsp = new Graphic3d_AspectText3d();
721           // TODO: Add methods for retrieving individual aspects from Graphic3d_Group
722           aGrp->GroupPrimitivesAspect(aLineAsp, aTextAsp, aPntAsp, aFaceAsp);
723           aFaceAsp->SetPolygonOffsets(aMode, aFactor, aUnits);
724           aGrp->SetGroupPrimitivesAspect(aFaceAsp);
725         }
726       }
727     }
728   }
729 }
730
731 //=======================================================================
732 //function : HasPolygonOffsets 
733 //purpose  : 
734 //=======================================================================
735 Standard_Boolean AIS_InteractiveObject::HasPolygonOffsets() const
736 {
737   return !( myDrawer->ShadingAspect().IsNull() || 
738           ( !myDrawer->Link().IsNull() && 
739           myDrawer->ShadingAspect() == myDrawer->Link()->ShadingAspect() ) );
740 }
741
742 //=======================================================================
743 //function : PolygonOffsets 
744 //purpose  : 
745 //=======================================================================
746 void AIS_InteractiveObject::PolygonOffsets(Standard_Integer&    aMode,
747                                            Standard_ShortReal&  aFactor,
748                                            Standard_ShortReal&  aUnits) const 
749 {
750   if( HasPolygonOffsets() )
751     myDrawer->ShadingAspect()->Aspect()->PolygonOffsets( aMode, aFactor, aUnits );
752 }