0024047: Exception in TPrsStd_AISPresentation during destruction of TDocStd_Document
[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( aCtx.IsNull())
159     return;
160   if (myDrawer.IsNull()) {
161     myDrawer = new AIS_Drawer;
162 #ifdef DEB
163     cout << "AIS_InteractiveObject::SetContext DRAWER NUL!" << endl;
164 #endif
165   }
166   myDrawer->Link(aCtx->DefaultDrawer());
167 }
168
169 //=======================================================================
170 //function : 
171 //purpose  : 
172 //=======================================================================
173 Standard_Boolean AIS_InteractiveObject::HasOwner() const 
174 {
175   return (!myOwner.IsNull());
176 }
177
178
179
180 //=======================================================================
181 //function : 
182 //purpose  : 
183 //=======================================================================
184 void AIS_InteractiveObject::ClearOwner()
185 {
186   myOwner.Nullify();
187 }
188
189 //=======================================================================
190 //function : 
191 //purpose  : 
192 //=======================================================================
193 Standard_Boolean AIS_InteractiveObject::HasUsers() const 
194 {
195   return (!myUsers.IsEmpty());
196 }
197
198
199 //=======================================================================
200 //function : 
201 //purpose  : 
202 //=======================================================================
203 void AIS_InteractiveObject::AddUser(const Handle(Standard_Transient)& aUser)
204 {
205   myUsers.Append(aUser);
206 }
207
208 //=======================================================================
209 //function : 
210 //purpose  : 
211 //=======================================================================
212 void AIS_InteractiveObject::ClearUsers()
213 {
214   myUsers.Clear();
215 }
216
217
218 //=======================================================================
219 //function : 
220 //purpose  : 
221 //=======================================================================
222 void AIS_InteractiveObject::SetDisplayMode(const Standard_Integer aMode)
223 {
224 #ifdef BUC60632
225   if( AcceptDisplayMode(aMode) )
226 #endif
227     myDisplayMode = aMode;
228 }
229   
230
231 //=======================================================================
232 //function : 
233 //purpose  : 
234 //=======================================================================
235 void AIS_InteractiveObject::SetSelectionMode(const Standard_Integer aMode)
236 {
237   mySelectionMode = aMode;
238 }
239
240
241
242 //=======================================================================
243 //function : 
244 //purpose  : 
245 //=======================================================================
246 #ifdef GER61351
247 void AIS_InteractiveObject::SetCurrentFacingModel(const Aspect_TypeOfFacingModel aModel) {
248   myCurrentFacingModel = aModel;
249 }
250
251 //=======================================================================
252 //function : CurrentFacingModel
253 //purpose  : 
254 //=======================================================================
255
256 Aspect_TypeOfFacingModel AIS_InteractiveObject::CurrentFacingModel() const {
257   return myCurrentFacingModel;
258 }
259 #endif
260
261 //=======================================================================
262 //function : SetColor
263 //purpose  : 
264 //=======================================================================
265
266 void AIS_InteractiveObject::SetColor(const Quantity_NameOfColor aColor)
267 #ifdef GER61351
268 {
269   SetColor(Quantity_Color(aColor));
270 }
271
272 //=======================================================================
273 //function : SetColor
274 //purpose  : 
275 //=======================================================================
276
277 void AIS_InteractiveObject::SetColor(const Quantity_Color &aColor)
278 #endif
279 {
280   myOwnColor = aColor;
281   hasOwnColor = Standard_True;
282 }
283
284 //=======================================================================
285 //function : UnsetColor
286 //purpose  : 
287 //=======================================================================
288 void AIS_InteractiveObject::UnsetColor()
289 {
290   hasOwnColor = Standard_False;
291 }
292
293 //=======================================================================
294 //function : 
295 //purpose  : 
296 //=======================================================================
297 void AIS_InteractiveObject::SetWidth(const Standard_Real aValue)
298 {
299   myOwnWidth = aValue;
300 }
301
302 //=======================================================================
303 //function : 
304 //purpose  : 
305 //=======================================================================
306 void AIS_InteractiveObject::UnsetWidth()
307 {
308   myOwnWidth = 0.;
309 }
310
311
312 //=======================================================================
313 //function : 
314 //purpose  : 
315 //=======================================================================
316 //POP pour K4L
317 void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfMaterial aName)
318 //void AIS_InteractiveObject::SetMaterial(const Graphic3d_NameOfPhysicalMaterial aName)
319 {
320   if( HasColor() || IsTransparent() || HasMaterial() )
321     {
322       myDrawer->ShadingAspect()->SetMaterial(aName);
323     }
324   else 
325     {
326       myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
327       
328       myDrawer->ShadingAspect()->SetMaterial(aName);
329 #ifndef BUC60577        //???
330       myDrawer->ShadingAspect()->SetColor(AIS_GraphicTool::GetInteriorColor(myDrawer->Link()));
331 #endif
332     }
333   myOwnMaterial  = aName;
334   hasOwnMaterial = Standard_True;
335 }
336 //=======================================================================
337 //function : SetMaterial
338 //purpose  : 
339 //=======================================================================
340
341 void AIS_InteractiveObject::SetMaterial(const Graphic3d_MaterialAspect& aMat)
342 {
343 #ifdef BUC60577
344   if( HasColor() || IsTransparent() || HasMaterial() )
345 #else
346   if(hasOwnColor ||(myTransparency==0.0) || hasOwnMaterial )
347 #endif
348     {
349       myDrawer->ShadingAspect()->SetMaterial(aMat);
350     }
351   else 
352     {
353       myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
354       myDrawer->ShadingAspect()->SetMaterial(aMat);
355     }
356   hasOwnMaterial = Standard_True;
357   
358 }
359 //=======================================================================
360 //function : 
361 //purpose  : 
362 //=======================================================================
363 void AIS_InteractiveObject::UnsetMaterial()
364 {
365 #ifdef BUC60577
366   if( !HasMaterial() ) return;
367   if( HasColor() || IsTransparent()) {
368     myDrawer->ShadingAspect()->SetMaterial(
369                 AIS_GraphicTool::GetMaterial(myDrawer->Link()));
370     if( HasColor() ) SetColor(myOwnColor);
371     if( IsTransparent() ) SetTransparency(myTransparency);
372   }
373 #else
374   if(!hasOwnMaterial) return;
375   if(hasOwnColor ||(myTransparency==0.0))
376     {
377       myDrawer->ShadingAspect()->SetMaterial(AIS_GraphicTool::GetMaterial(myDrawer->Link()));
378     }
379 #endif
380   else{
381     Handle(Prs3d_ShadingAspect) SA;
382     myDrawer->SetShadingAspect(SA);
383   }
384   hasOwnMaterial = Standard_False;
385 }
386
387 //=======================================================================
388 //function : SetTransparency
389 //purpose  : 
390 //=======================================================================
391 void AIS_InteractiveObject::SetTransparency(const Standard_Real aValue)
392 {
393
394 #ifdef BUC60577                     // Back & Front material can be different !
395
396   if(!HasColor() && !IsTransparent() && !HasMaterial() ) {
397         myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
398       if(!myDrawer->Link().IsNull())
399         myDrawer->ShadingAspect()->SetMaterial(AIS_GraphicTool::GetMaterial(myDrawer->Link()));
400   }
401   Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
402   Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial();
403   FMat.SetTransparency(aValue); BMat.SetTransparency(aValue);
404   myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat);
405   myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat);
406 #else
407   if(aValue<0.0 || aValue>1.0) return;
408   
409   if(aValue<=0.05) 
410     {
411       UnsetTransparency();
412       return;
413     }
414   
415
416   if(hasOwnColor || hasOwnMaterial || myTransparency> 0.0)
417     {
418       Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
419       Mat.SetTransparency(aValue);
420       myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(Mat);
421       myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(Mat);
422     }
423   else
424     {
425       myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
426       if(!myDrawer->Link().IsNull())
427         myDrawer->ShadingAspect()->SetMaterial(AIS_GraphicTool::GetMaterial(myDrawer->Link()));
428       Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
429       Mat.SetTransparency(aValue);
430       myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(Mat);
431       myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(Mat);
432     }
433 #endif
434   myTransparency = aValue;
435 }
436
437 //=======================================================================
438 //function : UnsetTransparency
439 //purpose  : 
440 //=======================================================================
441 void AIS_InteractiveObject::UnsetTransparency()
442 {
443 #ifdef BUC60577                     // Back & Front material can be different !
444     if(HasColor() || HasMaterial() )
445     {
446       Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
447       Graphic3d_MaterialAspect BMat = myDrawer->ShadingAspect()->Aspect()->BackMaterial();
448       FMat.SetTransparency(0.); BMat.SetTransparency(0.);
449       myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat);
450       myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(BMat);
451     }
452 #else
453     if(hasOwnColor || hasOwnMaterial )
454     {
455       Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
456       Mat.SetTransparency(0.0);
457 //      myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(Mat);
458 //      myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(Mat);
459        myDrawer->ShadingAspect()->SetMaterial(Mat);
460     }
461 #endif
462   else{
463     Handle (Prs3d_ShadingAspect) SA;
464     myDrawer->SetShadingAspect(SA);
465   }
466   myTransparency =0.0;
467 }
468 //=======================================================================
469 //function : Transparency
470 //purpose  : 
471 //=======================================================================
472 Standard_Real AIS_InteractiveObject::Transparency() const 
473 {
474   return (myTransparency<=0.05 ? 0 : myTransparency);
475 // Graphic3d_MaterialAspect Mat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
476 // return Mat.Transparency();
477 }
478
479 //=======================================================================
480 //function : SetAttributes
481 //purpose  : 
482 //=======================================================================
483
484 void AIS_InteractiveObject::SetAttributes(const Handle(AIS_Drawer)& aDrawer)
485 {myDrawer = aDrawer;}
486
487
488 //=======================================================================
489 //function : UnsetAttributes
490 //purpose  : 
491 //=======================================================================
492 void AIS_InteractiveObject::UnsetAttributes()
493 {
494   Handle(AIS_Drawer) dr = new AIS_Drawer();
495   if(myDrawer->HasLink())
496     dr->Link(myDrawer->Link());
497   myDrawer       = dr;
498   hasOwnColor    = Standard_False;
499   hasOwnMaterial = Standard_False;
500   myOwnWidth     = 0.0;
501   myTransparency = 0.0;
502 }
503
504 //=======================================================================
505 //function : 
506 //purpose  : 
507 //=======================================================================
508 void AIS_InteractiveObject::MustRecomputePrs(const Standard_Integer ) const 
509 {}
510
511 //=======================================================================
512 //function : 
513 //purpose  : 
514 //=======================================================================
515 const TColStd_ListOfInteger& AIS_InteractiveObject::ListOfRecomputeModes() const 
516 {return myToRecomputeModes;}
517
518 //=======================================================================
519 //function : 
520 //purpose  : 
521 //=======================================================================
522 void AIS_InteractiveObject::SetRecomputeOk()
523 {myToRecomputeModes.Clear();}
524
525
526 //=======================================================================
527 //function : AcceptDisplayMode
528 //purpose  : 
529 //=======================================================================
530
531 Standard_Boolean  AIS_InteractiveObject::AcceptDisplayMode(const Standard_Integer ) const
532 {return Standard_True;}
533
534 //=======================================================================
535 //function : DefaultDisplayMode
536 //purpose  : 
537 //=======================================================================
538
539 Standard_Integer AIS_InteractiveObject::DefaultDisplayMode() const
540 {return 0;}
541
542
543 //=======================================================================
544 //function : SetInfiniteState
545 //purpose  : 
546 //=======================================================================
547 void AIS_InteractiveObject::SetInfiniteState(const Standard_Boolean aFlag)
548 {
549   myInfiniteState = aFlag;
550   Handle(Prs3d_Presentation) P;
551
552   for(Standard_Integer i =1; i<=myPresentations.Length();i++){
553     P = Handle(Prs3d_Presentation)::DownCast(myPresentations(i).Presentation());
554     if(!P.IsNull())
555       P->SetInfiniteState(myInfiniteState);}
556 }
557
558 #ifdef IMP020200
559 //=======================================================================
560 //function : SetTransformation
561 //purpose  : 
562 //=======================================================================
563 void AIS_InteractiveObject::SetTransformation(const Handle(Geom_Transformation)& aTrsf, const Standard_Boolean postConcatenate, const Standard_Boolean updateSelection) {
564
565   if(!GetContext().IsNull()){
566     const PrsMgr_Presentations& prs = Presentations(); 
567     Handle(Prs3d_Presentation) P;
568     Standard_Integer mode;
569     myHasTransformation = Standard_True;
570     for( Standard_Integer i=1 ; i<=prs.Length() ; i++ ) {
571       mode = prs(i).Mode();
572       P = GetContext()->MainPrsMgr()->CastPresentation(this,mode)->Presentation();
573       if( postConcatenate ) P->Multiply(aTrsf);
574       else                  P->Transform(aTrsf);
575       if( updateSelection ) {
576 #ifdef IMP220501
577         myCTXPtr->ClearSelected(Standard_True);
578         myCTXPtr->RecomputeSelectionOnly(this);
579 #else
580         if( HasSelection(mode) ) {
581           UpdateSelection(mode);      
582         }
583 #endif
584       }
585     }
586   }
587 }
588
589 //=======================================================================
590 //function : SetTransformation
591 //purpose  : 
592 //=======================================================================
593 void AIS_InteractiveObject::UnsetTransformation() {
594 #ifdef OCC708
595   static Handle(Geom_Transformation) trsf = new Geom_Transformation( gp_Trsf() );
596 #else
597 Handle(Geom_Transformation) trsf;
598 #endif
599
600     SetTransformation(trsf);    // Set identity transformation
601     myHasTransformation = Standard_False;
602 }
603
604 //=======================================================================
605 //function : Transformation
606 //purpose  : 
607 //=======================================================================
608 Handle(Geom_Transformation) AIS_InteractiveObject::Transformation() {
609 Handle(Geom_Transformation) trsf; 
610
611   if(!GetContext().IsNull() ) {
612     const PrsMgr_Presentations& prs = Presentations(); 
613     if( prs.Length() > 0 ) {
614       Handle(Prs3d_Presentation) P = 
615           GetContext()->MainPrsMgr()->CastPresentation(this,1)->Presentation();
616       trsf = P->Transformation();
617     }
618   }
619
620   return trsf;
621 }
622
623 //=======================================================================
624 //function : HasTransformation
625 //purpose  : 
626 //=======================================================================
627 Standard_Boolean AIS_InteractiveObject::HasTransformation() const {
628
629   return myHasTransformation;
630 }
631 #endif
632
633 #ifdef IMP140200
634 //=======================================================================
635 //function : HasPresentation
636 //purpose  : 
637 //=======================================================================
638 Standard_Boolean AIS_InteractiveObject::HasPresentation() const {
639
640   if( !GetContext().IsNull() && 
641         GetContext()->MainPrsMgr()->HasPresentation(this,myDisplayMode) ) {
642     return Standard_True;
643   }
644
645   return Standard_False;
646 }
647
648 //=======================================================================
649 //function : Presentation
650 //purpose  : 
651 //=======================================================================
652 Handle(Prs3d_Presentation) AIS_InteractiveObject::Presentation() const {
653 Handle(Prs3d_Presentation) prs;
654
655   if( HasPresentation() ) {
656     prs = GetContext()->MainPrsMgr()->
657                 CastPresentation(this,myDisplayMode)->Presentation();
658   }
659
660   return prs;
661 }
662
663 //=======================================================================
664 //function : SetAspect 
665 //purpose  : 
666 //=======================================================================
667 void AIS_InteractiveObject::SetAspect(const Handle(Prs3d_BasicAspect)& anAspect,
668                                       const Standard_Boolean globalChange) {
669
670   if( HasPresentation() ) {
671     Handle(Prs3d_Presentation) prs = Presentation();
672     { Handle(Prs3d_ShadingAspect) aspect =
673                         Handle(Prs3d_ShadingAspect)::DownCast(anAspect);
674       if( !aspect.IsNull() ) {
675         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
676         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
677         return;
678       }
679     }
680     { Handle(Prs3d_LineAspect) aspect =
681                         Handle(Prs3d_LineAspect)::DownCast(anAspect);
682       if( !aspect.IsNull() ) {
683         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
684         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
685         return;
686       }
687     }
688     { Handle(Prs3d_PointAspect) aspect =
689                         Handle(Prs3d_PointAspect)::DownCast(anAspect);
690       if( !aspect.IsNull() ) {
691         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
692         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
693         return;
694       }
695     }
696     { Handle(Prs3d_TextAspect) aspect =
697                         Handle(Prs3d_TextAspect)::DownCast(anAspect);
698       if( !aspect.IsNull() ) {
699         if( globalChange ) prs->SetPrimitivesAspect(aspect->Aspect());
700         Prs3d_Root::CurrentGroup(prs)->SetGroupPrimitivesAspect(aspect->Aspect());
701         return;
702       }
703     }
704   }
705 }
706 #endif
707
708 // OCC4895 SAN 22/03/04 High-level interface for controlling polygon offsets
709
710 //=======================================================================
711 //function : SetPolygonOffsets 
712 //purpose  : 
713 //======================================================================= 
714 void AIS_InteractiveObject::SetPolygonOffsets(const Standard_Integer    aMode,
715                                               const Standard_ShortReal  aFactor,
716                                               const Standard_ShortReal  aUnits) 
717 {
718   if ( !HasPolygonOffsets() )
719     myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
720
721   myDrawer->ShadingAspect()->Aspect()->SetPolygonOffsets( aMode, aFactor, aUnits );
722
723   // Modify existing presentations 
724   Handle(Graphic3d_Structure) aStruct;
725   for( Standard_Integer i = 1, n = myPresentations.Length(); i <= n; i++ ) {
726     Handle(PrsMgr_Presentation3d) aPrs3d =
727       Handle(PrsMgr_Presentation3d)::DownCast( myPresentations(i).Presentation() );
728     if ( !aPrs3d.IsNull() ) {
729       aStruct = Handle(Graphic3d_Structure)::DownCast( aPrs3d->Presentation() );
730       if( !aStruct.IsNull() ) {
731         aStruct->SetPrimitivesAspect( myDrawer->ShadingAspect()->Aspect() );
732         // Workaround for issue 23115: Need to update also groups, because their
733         // face aspect ALWAYS overrides the structure's.
734         const Graphic3d_SequenceOfGroup& aGroups = aStruct->Groups();
735         Standard_Integer aGroupIndex = 1, aGroupNb = aGroups.Length();
736         for ( ; aGroupIndex <= aGroupNb; aGroupIndex++ ) {
737           Handle(Graphic3d_Group) aGrp = aGroups.Value(aGroupIndex);
738           if ( !aGrp.IsNull() && aGrp->IsGroupPrimitivesAspectSet(Graphic3d_ASPECT_FILL_AREA) ) {
739             Handle(Graphic3d_AspectFillArea3d) aFaceAsp = new Graphic3d_AspectFillArea3d();
740             Handle(Graphic3d_AspectLine3d) aLineAsp = new Graphic3d_AspectLine3d();
741             Handle(Graphic3d_AspectMarker3d) aPntAsp = new Graphic3d_AspectMarker3d();
742             Handle(Graphic3d_AspectText3d) aTextAsp = new Graphic3d_AspectText3d();
743             // TODO: Add methods for retrieving individual aspects from Graphic3d_Group
744             aGrp->GroupPrimitivesAspect(aLineAsp, aTextAsp, aPntAsp, aFaceAsp);
745             aFaceAsp->SetPolygonOffsets(aMode, aFactor, aUnits);
746             // TODO: Issue 23118 - This line kills texture data in the group...
747             aGrp->SetGroupPrimitivesAspect(aFaceAsp);
748           }
749         }
750       }
751     }
752   }
753 }
754
755
756 //=======================================================================
757 //function : HasPolygonOffsets 
758 //purpose  : 
759 //=======================================================================
760 Standard_Boolean AIS_InteractiveObject::HasPolygonOffsets() const
761 {
762   return !( myDrawer->ShadingAspect().IsNull() || 
763           ( !myDrawer->Link().IsNull() && 
764           myDrawer->ShadingAspect() == myDrawer->Link()->ShadingAspect() ) );
765 }
766
767 //=======================================================================
768 //function : PolygonOffsets 
769 //purpose  : 
770 //=======================================================================
771 void AIS_InteractiveObject::PolygonOffsets(Standard_Integer&    aMode,
772                                            Standard_ShortReal&  aFactor,
773                                            Standard_ShortReal&  aUnits) const 
774 {
775   if( HasPolygonOffsets() )
776     myDrawer->ShadingAspect()->Aspect()->PolygonOffsets( aMode, aFactor, aUnits );
777 }
778 // OCC4895 SAN 22/03/04 High-level interface for controlling polygon offsets