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