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