c568148927da94c1cc573801b9f90850074be87e
[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   {
542     P = myPresentations(i).Presentation()->Presentation();
543     if(!P.IsNull())
544       P->SetInfiniteState(myInfiniteState);
545   }
546 }
547
548 //=======================================================================
549 //function : SetTransformation
550 //purpose  :
551 //=======================================================================
552 void AIS_InteractiveObject::SetTransformation (const Handle(Geom_Transformation)& theTrsf,
553                                                const Standard_Boolean             theToPostConcatenate,
554                                                const Standard_Boolean             theToUpdateSelection)
555 {
556   if (GetContext().IsNull())
557   {
558     return;
559   }
560
561   const PrsMgr_Presentations& aPrsList = Presentations();
562   myHasTransformation = Standard_True;
563   for (Standard_Integer aPrsIter = 1; aPrsIter <= aPrsList.Length(); ++aPrsIter)
564   {
565     const Standard_Integer aMode = aPrsList (aPrsIter).Mode();
566     Handle(Prs3d_Presentation) aPrs = GetContext()->MainPrsMgr()->Presentation (this, aMode)->Presentation();
567     theToPostConcatenate ? aPrs->Multiply  (theTrsf)
568                          : aPrs->Transform (theTrsf);
569     if (theToUpdateSelection)
570     {
571       myCTXPtr->ClearSelected (Standard_True);
572       myCTXPtr->RecomputeSelectionOnly (this);
573     }
574   }
575 }
576
577 //=======================================================================
578 //function : SetTransformation
579 //purpose  : 
580 //=======================================================================
581 void AIS_InteractiveObject::UnsetTransformation() {
582 #ifdef OCC708
583   static Handle(Geom_Transformation) trsf = new Geom_Transformation( gp_Trsf() );
584 #else
585 Handle(Geom_Transformation) trsf;
586 #endif
587
588     SetTransformation(trsf);    // Set identity transformation
589     myHasTransformation = Standard_False;
590 }
591
592 //=======================================================================
593 //function : Transformation
594 //purpose  :
595 //=======================================================================
596 Handle(Geom_Transformation) AIS_InteractiveObject::Transformation()
597 {
598   if (GetContext().IsNull())
599   {
600     return Handle(Geom_Transformation)();
601   }
602
603   const PrsMgr_Presentations& aPrsList = Presentations();
604   if (aPrsList.Length() > 0)
605   {
606     Handle(Prs3d_Presentation) aPrs = GetContext()->MainPrsMgr()->Presentation (this, 1)->Presentation();
607     return aPrs->Transformation();
608   }
609   return Handle(Geom_Transformation)();
610 }
611
612 //=======================================================================
613 //function : HasTransformation
614 //purpose  : 
615 //=======================================================================
616 Standard_Boolean AIS_InteractiveObject::HasTransformation() const {
617
618   return myHasTransformation;
619 }
620
621 //=======================================================================
622 //function : HasPresentation
623 //purpose  :
624 //=======================================================================
625 Standard_Boolean AIS_InteractiveObject::HasPresentation() const
626 {
627   return !GetContext().IsNull()
628        && GetContext()->MainPrsMgr()->HasPresentation (this, myDisplayMode);
629 }
630
631 //=======================================================================
632 //function : Presentation
633 //purpose  :
634 //=======================================================================
635 Handle(Prs3d_Presentation) AIS_InteractiveObject::Presentation() const
636 {
637   return HasPresentation()
638        ? GetContext()->MainPrsMgr()->Presentation (this, myDisplayMode)->Presentation()
639        : Handle(Prs3d_Presentation)();
640 }
641
642 //=======================================================================
643 //function : SetAspect 
644 //purpose  : 
645 //=======================================================================
646 void AIS_InteractiveObject::SetAspect(const Handle(Prs3d_BasicAspect)& anAspect,
647                                       const Standard_Boolean globalChange) {
648
649   if( HasPresentation() ) {
650     Handle(Prs3d_Presentation) prs = Presentation();
651     { Handle(Prs3d_ShadingAspect) aspect =
652                         Handle(Prs3d_ShadingAspect)::DownCast(anAspect);
653       if( !aspect.IsNull() ) {
654         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
655         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
656         return;
657       }
658     }
659     { Handle(Prs3d_LineAspect) aspect =
660                         Handle(Prs3d_LineAspect)::DownCast(anAspect);
661       if( !aspect.IsNull() ) {
662         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
663         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
664         return;
665       }
666     }
667     { Handle(Prs3d_PointAspect) aspect =
668                         Handle(Prs3d_PointAspect)::DownCast(anAspect);
669       if( !aspect.IsNull() ) {
670         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
671         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
672         return;
673       }
674     }
675     { Handle(Prs3d_TextAspect) aspect =
676                         Handle(Prs3d_TextAspect)::DownCast(anAspect);
677       if( !aspect.IsNull() ) {
678         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
679         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
680         return;
681       }
682     }
683   }
684 }
685
686 //=======================================================================
687 //function : SetPolygonOffsets 
688 //purpose  : 
689 //======================================================================= 
690 void AIS_InteractiveObject::SetPolygonOffsets(const Standard_Integer    aMode,
691                                               const Standard_ShortReal  aFactor,
692                                               const Standard_ShortReal  aUnits) 
693 {
694   if ( !HasPolygonOffsets() )
695     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
696
697   myDrawer->ShadingAspect()->Aspect()->SetPolygonOffsets( aMode, aFactor, aUnits );
698
699   // Modify existing presentations 
700   for (Standard_Integer aPrsIter = 1, n = myPresentations.Length(); aPrsIter <= n; ++aPrsIter)
701   {
702     const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter).Presentation();
703     if ( !aPrs3d.IsNull() ) {
704       const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
705       if( !aStruct.IsNull() ) {
706         aStruct->SetPrimitivesAspect( myDrawer->ShadingAspect()->Aspect() );
707         // Workaround for issue 23115: Need to update also groups, because their
708         // face aspect ALWAYS overrides the structure's.
709         const Graphic3d_SequenceOfGroup& aGroups = aStruct->Groups();
710         for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
711         {
712           Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
713           if (aGrp.IsNull()
714           || !aGrp->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
715           {
716             continue;
717           }
718
719           Handle(Graphic3d_AspectFillArea3d) aFaceAsp = new Graphic3d_AspectFillArea3d();
720           Handle(Graphic3d_AspectLine3d)     aLineAsp = new Graphic3d_AspectLine3d();
721           Handle(Graphic3d_AspectMarker3d)   aPntAsp  = new Graphic3d_AspectMarker3d();
722           Handle(Graphic3d_AspectText3d)     aTextAsp = new Graphic3d_AspectText3d();
723           // TODO: Add methods for retrieving individual aspects from Graphic3d_Group
724           aGrp->GroupPrimitivesAspect(aLineAsp, aTextAsp, aPntAsp, aFaceAsp);
725           aFaceAsp->SetPolygonOffsets(aMode, aFactor, aUnits);
726           aGrp->SetGroupPrimitivesAspect(aFaceAsp);
727         }
728       }
729     }
730   }
731 }
732
733 //=======================================================================
734 //function : HasPolygonOffsets 
735 //purpose  : 
736 //=======================================================================
737 Standard_Boolean AIS_InteractiveObject::HasPolygonOffsets() const
738 {
739   return !( myDrawer->ShadingAspect().IsNull() || 
740           ( !myDrawer->Link().IsNull() && 
741           myDrawer->ShadingAspect() == myDrawer->Link()->ShadingAspect() ) );
742 }
743
744 //=======================================================================
745 //function : PolygonOffsets 
746 //purpose  : 
747 //=======================================================================
748 void AIS_InteractiveObject::PolygonOffsets(Standard_Integer&    aMode,
749                                            Standard_ShortReal&  aFactor,
750                                            Standard_ShortReal&  aUnits) const 
751 {
752   if( HasPolygonOffsets() )
753     myDrawer->ShadingAspect()->Aspect()->PolygonOffsets( aMode, aFactor, aUnits );
754 }