0025459: Visualization - AIS_ColoredShape::SetMaterial() should not reset custom...
[occt.git] / src / AIS / AIS_Shape.cxx
1 // Created on: 1996-12-20
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 #include <AIS_Shape.ixx>
18
19
20 #include <Standard_ErrorHandler.hxx>
21 #include <OSD_Timer.hxx>
22 #include <TColStd_ListIteratorOfListOfInteger.hxx>
23
24 #include <Quantity_Color.hxx>
25
26 #include <gp_Pnt.hxx>
27 #include <Bnd_Box.hxx>
28 #include <BRep_Builder.hxx>
29 #include <BRepTools_ShapeSet.hxx>
30 #include <BRepTools.hxx>
31 #include <BRepBndLib.hxx>
32 #include <TopExp.hxx>
33 #include <TopExp_Explorer.hxx>
34
35 #include <Aspect_TypeOfLine.hxx>
36 #include <Graphic3d_Structure.hxx>
37 #include <Graphic3d_Group.hxx>
38 #include <Graphic3d_AspectLine3d.hxx>
39 #include <Graphic3d_AspectText3d.hxx>
40 #include <Graphic3d_AspectMarker3d.hxx>
41 #include <Graphic3d_AspectFillArea3d.hxx>
42 #include <Graphic3d_ArrayOfPolylines.hxx>
43 #include <Graphic3d_MaterialAspect.hxx>
44 #include <Graphic3d_SequenceOfGroup.hxx>
45
46 #include <Prs3d.hxx>
47 #include <Prs3d_Presentation.hxx>
48 #include <Prs3d_Root.hxx>
49 #include <Prs3d_ShadingAspect.hxx>
50 #include <Prs3d_Drawer.hxx>
51 #include <Prs3d_IsoAspect.hxx>
52
53 #include <StdPrs_WFShape.hxx>
54 #include <StdPrs_WFDeflectionShape.hxx>
55 #include <StdPrs_ShadedShape.hxx>
56 #include <StdPrs_HLRShape.hxx>
57 #include <StdPrs_HLRPolyShape.hxx>
58
59 #include <PrsMgr_ModedPresentation.hxx>
60
61 #include <Select3D_SensitiveEntity.hxx>
62 #include <StdSelect.hxx>
63 #include <StdSelect_BRepSelectionTool.hxx>
64 #include <StdSelect_BRepOwner.hxx>
65 #include <StdSelect_DisplayMode.hxx>
66
67 #include <AIS_GraphicTool.hxx>
68 #include <AIS_InteractiveContext.hxx>
69 #include <AIS_Drawer.hxx>
70 #include <HLRBRep.hxx>
71 #include <Precision.hxx>
72
73 #include <Standard_Failure.hxx>
74 #include <Standard_ErrorHandler.hxx>
75 #include <Select3D_SensitiveBox.hxx>
76 #include <TopoDS_Iterator.hxx>
77
78 static Standard_Boolean myFirstCompute;
79
80 static Standard_Boolean IsInList(const TColStd_ListOfInteger& LL, const Standard_Integer aMode)
81 {
82   TColStd_ListIteratorOfListOfInteger It(LL);
83   for(;It.More();It.Next()){
84     if(It.Value()==aMode) 
85       return Standard_True;}
86   return Standard_False;
87 }
88
89 //==================================================
90 // Function: 
91 // Purpose :
92 //==================================================
93
94 AIS_Shape::
95 AIS_Shape(const TopoDS_Shape& shap):
96 AIS_InteractiveObject(PrsMgr_TOP_ProjectorDependant),
97 myshape(shap),
98 myCompBB(Standard_True),
99 myInitAng(0.)
100 {
101   myFirstCompute = Standard_True;
102   SetHilightMode(0);
103   myDrawer->SetShadingAspectGlobal(Standard_False);
104 }
105
106 //=======================================================================
107 //function : Type
108 //purpose  : 
109 //=======================================================================
110 AIS_KindOfInteractive AIS_Shape::Type() const 
111 {return AIS_KOI_Shape;}
112
113
114 //=======================================================================
115 //function : Signature
116 //purpose  : 
117 //=======================================================================
118 Standard_Integer AIS_Shape::Signature() const 
119 {return 0;}
120
121 //=======================================================================
122 //function : AcceptShapeDecomposition
123 //purpose  : 
124 //=======================================================================
125 Standard_Boolean AIS_Shape::AcceptShapeDecomposition() const 
126 {return Standard_True;}
127
128 //=======================================================================
129 //function : Compute
130 //purpose  : 
131 //=======================================================================
132 void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
133                         const Handle(Prs3d_Presentation)& aPrs,
134                         const Standard_Integer aMode)
135 {  
136   aPrs->Clear();
137   if(myshape.IsNull()) return;
138
139   // wire,edge,vertex -> pas de HLR + priorite display superieure
140   Standard_Integer TheType = (Standard_Integer) myshape.ShapeType();
141   if(TheType>4 && TheType<8) {
142     aPrs->SetVisual(Graphic3d_TOS_ALL);
143     aPrs->SetDisplayPriority(TheType+2);
144   }
145   // Shape vide -> Assemblage vide.
146   if (myshape.ShapeType() == TopAbs_COMPOUND) {
147     TopoDS_Iterator anExplor (myshape);
148
149     if (!anExplor.More()) {
150       return;
151     }
152   }
153
154   if (IsInfinite()) aPrs->SetInfiniteState(Standard_True); //not taken in account duting FITALL
155   switch (aMode) {
156   case 0:{
157     try { OCC_CATCH_SIGNALS  StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); }
158     catch (Standard_Failure) { 
159 #ifdef OCCT_DEBUG
160       cout << "AIS_Shape::Compute()  failed"<< endl;
161       cout << "a Shape should be incorrect : No Compute can be maked on it  "<< endl;     
162 #endif
163 // presentation of the bounding box is calculated
164 //      Compute(aPresentationManager,aPrs,2);
165     }
166     break;
167   }
168   case 1:
169     {
170       Standard_Real anAnglePrev, anAngleNew, aCoeffPrev, aCoeffNew;
171       Standard_Boolean isOwnDeviationAngle       = OwnDeviationAngle      (anAngleNew, anAnglePrev);
172       Standard_Boolean isOwnDeviationCoefficient = OwnDeviationCoefficient(aCoeffNew,  aCoeffPrev);
173       if ((isOwnDeviationAngle       && Abs (anAngleNew - anAnglePrev) > Precision::Angular())
174        || (isOwnDeviationCoefficient && Abs (aCoeffNew  - aCoeffPrev)  > Precision::Confusion()))
175       {
176         BRepTools::Clean (myshape);
177       }
178
179       //shading only on face...
180       if ((Standard_Integer) myshape.ShapeType()>4)
181         StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
182       else {
183         myDrawer->SetShadingAspectGlobal(Standard_False);
184         if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
185         else {
186           {
187             try {
188               OCC_CATCH_SIGNALS
189               StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer);
190             }
191             catch (Standard_Failure) {
192 #ifdef OCCT_DEBUG
193               cout << "AIS_Shape::Compute() in ShadingMode failed"<< endl;
194 #endif
195               StdPrs_WFShape::Add(aPrs,myshape,myDrawer);
196             }
197           }
198         }
199       }
200       Standard_Real value = Transparency() ;
201       if( value > 0. ) {
202         SetTransparency( value );
203       }
204       break;
205     }
206   case 2:
207     {
208       // bounding box
209       if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
210       else StdPrs_WFDeflectionRestrictedFace::AddBox (aPrs, BoundingBox(), myDrawer);
211     }
212   } // end switch
213   aPrs->ReCompute(); // for hidden line recomputation if necessary...
214 }
215
216 //=======================================================================
217 //function : Compute
218 //purpose  : Hidden Line Removal
219 //=======================================================================
220 void AIS_Shape::Compute(const Handle(Prs3d_Projector)& aProjector,
221                         const Handle(Prs3d_Presentation)& aPresentation)
222 {
223   Compute(aProjector,aPresentation,myshape);
224 }
225
226 //=======================================================================
227 //function : Compute
228 //purpose  : 
229 //=======================================================================
230
231 void AIS_Shape::Compute(const Handle(Prs3d_Projector)&     aProjector,
232                         const Handle(Geom_Transformation)& TheTrsf,
233                         const Handle(Prs3d_Presentation)&  aPresentation)
234 {
235   const TopLoc_Location& loc = myshape.Location();
236   TopoDS_Shape shbis = myshape.Located(TopLoc_Location(TheTrsf->Trsf())*loc);
237   Compute(aProjector,aPresentation,shbis);
238 }
239
240 //=======================================================================
241 //function : Compute
242 //purpose  : 
243 //=======================================================================
244
245 void AIS_Shape::Compute(const Handle(Prs3d_Projector)& aProjector,
246                         const Handle(Prs3d_Presentation)& aPresentation,
247                         const TopoDS_Shape& SH)
248 {
249   if (SH.ShapeType() == TopAbs_COMPOUND) {
250     TopoDS_Iterator anExplor (SH);
251
252     if (!anExplor.More()) // Shape vide -> Assemblage vide.
253       return;
254   }
255
256   Handle (Prs3d_Drawer) defdrawer = GetContext()->DefaultDrawer();
257   if (defdrawer->DrawHiddenLine()) 
258     {myDrawer->EnableDrawHiddenLine();}
259   else {myDrawer->DisableDrawHiddenLine();}
260
261   Aspect_TypeOfDeflection prevdef = defdrawer->TypeOfDeflection();
262   defdrawer->SetTypeOfDeflection(Aspect_TOD_RELATIVE);
263
264 // coefficients for calculation
265
266   Standard_Real prevangle, newangle ,prevcoeff,newcoeff ; 
267   Standard_Boolean isOwnHLRDeviationAngle = OwnHLRDeviationAngle(newangle,prevangle);
268   Standard_Boolean isOwnHLRDeviationCoefficient = OwnHLRDeviationCoefficient(newcoeff,prevcoeff);
269   if (((Abs (newangle - prevangle) > Precision::Angular()) && isOwnHLRDeviationAngle) ||
270       ((Abs (newcoeff - prevcoeff) > Precision::Confusion()) && isOwnHLRDeviationCoefficient)) {
271 #ifdef OCCT_DEBUG
272       cout << "AIS_Shape : compute"<<endl;
273       cout << "newangle  : " << newangle << " # de " << "prevangl  : " << prevangle << " OU "<<endl;
274       cout << "newcoeff  : " << newcoeff << " # de " << "prevcoeff : " << prevcoeff << endl;
275 #endif
276       BRepTools::Clean(SH);
277     }
278   
279   {
280     try {
281       OCC_CATCH_SIGNALS
282       switch (TypeOfHLR()) {
283         case Prs3d_TOH_Algo:
284           StdPrs_HLRShape::Add (aPresentation, SH, myDrawer, aProjector);
285           break;
286         case Prs3d_TOH_PolyAlgo:
287         default:
288           StdPrs_HLRPolyShape::Add (aPresentation, SH, myDrawer, aProjector);
289           break;
290       }
291     }
292     catch (Standard_Failure) {
293 #ifdef OCCT_DEBUG
294       cout <<"AIS_Shape::Compute(Proj) HLR Algorithm failed" << endl;
295 #endif
296       StdPrs_WFShape::Add(aPresentation,SH,myDrawer);
297     }
298   }
299
300   defdrawer->SetTypeOfDeflection (prevdef);
301 }
302
303 //=======================================================================
304 //function : SelectionType
305 //purpose  : gives the type according to the Index of Selection Mode
306 //=======================================================================
307
308 TopAbs_ShapeEnum AIS_Shape::SelectionType(const Standard_Integer aMode)
309 {
310   switch(aMode){
311   case 1:
312     return TopAbs_VERTEX;
313   case 2:
314     return TopAbs_EDGE;
315   case 3:
316     return TopAbs_WIRE;
317   case 4:
318     return TopAbs_FACE;
319   case 5:
320     return TopAbs_SHELL;
321   case 6:
322     return TopAbs_SOLID;
323   case 7:
324     return TopAbs_COMPSOLID;
325   case 8:
326     return TopAbs_COMPOUND;
327   case 0:
328   default:
329     return TopAbs_SHAPE;
330   }
331   
332 }
333 //=======================================================================
334 //function : SelectionType
335 //purpose  : gives the SelectionMode according to the Type od Decomposition...
336 //=======================================================================
337 Standard_Integer AIS_Shape::SelectionMode(const TopAbs_ShapeEnum aType)
338 {
339   switch(aType){
340   case TopAbs_VERTEX:
341     return 1;
342   case TopAbs_EDGE:
343     return 2;
344   case TopAbs_WIRE:
345     return 3;
346   case  TopAbs_FACE:
347     return 4;
348   case TopAbs_SHELL:
349     return 5;
350   case TopAbs_SOLID:
351     return 6;
352   case TopAbs_COMPSOLID:
353     return 7;
354   case TopAbs_COMPOUND:
355     return 8;
356   case TopAbs_SHAPE:
357   default:
358     return 0;
359   }
360 }
361
362
363 //=======================================================================
364 //function : ComputeSelection
365 //purpose  : 
366 //=======================================================================
367
368 void AIS_Shape::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
369                                               const Standard_Integer aMode)
370 {
371   if(myshape.IsNull()) return;
372   if (myshape.ShapeType() == TopAbs_COMPOUND) {
373     TopoDS_Iterator anExplor (myshape);
374
375     if (!anExplor.More()) // empty Shape -> empty Assembly.
376       return;
377   }
378
379   static TopAbs_ShapeEnum TypOfSel;
380   TypOfSel = AIS_Shape::SelectionType(aMode);
381   TopoDS_Shape shape = myshape;
382
383 // POP protection against crash in low layers
384
385   Standard_Real aDeflection = Prs3d::GetDeflection(shape, myDrawer);
386   Standard_Boolean autoTriangulation = Standard_True;
387   try {  
388     OCC_CATCH_SIGNALS
389     StdSelect_BRepSelectionTool::Load(aSelection,
390                                       this,
391                                       shape,
392                                       TypOfSel,
393                                       aDeflection,
394                                       myDrawer->HLRAngle(),
395                                       autoTriangulation); 
396   } catch ( Standard_Failure ) {
397 //    cout << "a Shape should be incorrect : A Selection on the Bnd  is activated   "<<endl;
398     if ( aMode == 0 ) {
399       Bnd_Box B = BoundingBox();
400       Handle(StdSelect_BRepOwner) aOwner = new StdSelect_BRepOwner(shape,this);
401       Handle(Select3D_SensitiveBox) aSensitiveBox = new Select3D_SensitiveBox(aOwner,B);
402       aSelection->Add(aSensitiveBox);
403     }
404   }
405
406   // insert the drawer in the BrepOwners for hilight...
407   StdSelect::SetDrawerForBRepOwner(aSelection,myDrawer);
408 }
409
410 Quantity_NameOfColor AIS_Shape::Color() const {
411 Quantity_Color aColor;
412   Color(aColor);
413   return aColor.Name();
414 }
415
416 void AIS_Shape::Color( Quantity_Color& aColor ) const {
417   aColor = myDrawer->ShadingAspect()->Color(myCurrentFacingModel);
418 }
419
420 Graphic3d_NameOfMaterial AIS_Shape::Material() const {
421   return (myDrawer->ShadingAspect()->Material(myCurrentFacingModel)).Name();
422 }
423
424 Standard_Real AIS_Shape::Transparency() const {
425   return myDrawer->ShadingAspect()->Transparency(myCurrentFacingModel);
426 }
427
428 //=======================================================================
429 //function : SetColor
430 //purpose  : 
431 //=======================================================================
432
433 void AIS_Shape::SetColor(const Quantity_NameOfColor aCol)
434 {
435   SetColor(Quantity_Color(aCol));
436 }
437
438 //=======================================================================
439 //function : setColor
440 //purpose  :
441 //=======================================================================
442
443 void AIS_Shape::setColor (const Handle(AIS_Drawer)& theDrawer,
444                           const Quantity_Color&     theColor) const
445 {
446   if (!theDrawer->HasShadingAspect())
447   {
448     theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
449     *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
450   }
451   if (!theDrawer->HasLineAspect())
452   {
453     theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
454     *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
455   }
456   if (!theDrawer->HasWireAspect())
457   {
458     theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
459     *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
460   }
461   if (!theDrawer->HasPointAspect())
462   {
463     theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_BLACK, 1.0));
464     *theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
465   }
466   // disable dedicated line aspects
467   theDrawer->SetFreeBoundaryAspect  (theDrawer->LineAspect());
468   theDrawer->SetUnFreeBoundaryAspect(theDrawer->LineAspect());
469   theDrawer->SetSeenLineAspect      (theDrawer->LineAspect());
470
471   // override color
472   theDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel);
473   theDrawer->SetShadingAspectGlobal (Standard_False);
474   theDrawer->LineAspect()->SetColor (theColor);
475   theDrawer->WireAspect()->SetColor (theColor);
476   theDrawer->PointAspect()->SetColor (theColor);
477 }
478
479 //=======================================================================
480 //function : SetColor
481 //purpose  :
482 //=======================================================================
483
484 void AIS_Shape::SetColor (const Quantity_Color& theColor)
485 {
486   setColor (myDrawer, theColor);
487   myOwnColor  = theColor;
488   hasOwnColor = Standard_True;
489
490   // modify shading presentation without re-computation
491   const PrsMgr_Presentations&        aPrsList     = Presentations();
492   Handle(Graphic3d_AspectFillArea3d) anAreaAspect = myDrawer->ShadingAspect()->Aspect();
493   Handle(Graphic3d_AspectLine3d)     aLineAspect  = myDrawer->LineAspect()->Aspect();
494   Handle(Graphic3d_AspectMarker3d)   aPointAspect = myDrawer->PointAspect()->Aspect();
495   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
496   {
497     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
498     if (aPrsModed.Mode() != AIS_Shaded)
499     {
500       continue;
501     }
502
503     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
504
505     // Set aspects for presentation
506     aPrs->SetPrimitivesAspect (anAreaAspect);
507     aPrs->SetPrimitivesAspect (aLineAspect);
508     aPrs->SetPrimitivesAspect (aPointAspect);
509
510     // Go through all groups to change color for all primitives
511     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
512     {
513       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
514
515       // Check if aspect of given type is set for the group, 
516       // because setting aspect for group with no already set aspect
517       // can lead to loss of presentation data
518       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
519       {
520         aGroup->SetGroupPrimitivesAspect (anAreaAspect);
521       }
522       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_LINE))
523       {
524         aGroup->SetGroupPrimitivesAspect (aLineAspect);
525       }
526       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER))
527       {
528         aGroup->SetGroupPrimitivesAspect (aPointAspect);
529       }
530     }
531   }
532
533   LoadRecomputable (AIS_WireFrame);
534   LoadRecomputable (2);
535 }
536
537 //=======================================================================
538 //function : UnsetColor
539 //purpose  :
540 //=======================================================================
541
542 void AIS_Shape::UnsetColor()
543 {
544   if (!HasColor())
545   {
546     myToRecomputeModes.Clear();
547     return;
548   }
549   hasOwnColor = Standard_False;
550
551   if (!HasWidth())
552   {
553     Handle(Prs3d_LineAspect) anEmptyAsp;
554     myDrawer->SetLineAspect          (anEmptyAsp);
555     myDrawer->SetWireAspect          (anEmptyAsp);
556     myDrawer->SetFreeBoundaryAspect  (anEmptyAsp);
557     myDrawer->SetUnFreeBoundaryAspect(anEmptyAsp);
558     myDrawer->SetSeenLineAspect      (anEmptyAsp);
559   }
560   else
561   {
562     Quantity_Color aColor;
563     AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Line,   aColor);
564     myDrawer->LineAspect()->SetColor (aColor);
565     AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Wire,   aColor);
566     myDrawer->WireAspect()->SetColor (aColor);
567     AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Free,   aColor);
568     myDrawer->FreeBoundaryAspect()->SetColor (aColor);
569     AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_UnFree, aColor);
570     myDrawer->UnFreeBoundaryAspect()->SetColor (aColor);
571     AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Seen,   aColor);
572     myDrawer->SeenLineAspect()->SetColor (aColor);
573   }
574
575   if (HasMaterial()
576    || IsTransparent())
577   {
578     Graphic3d_MaterialAspect mat = AIS_GraphicTool::GetMaterial(HasMaterial()? myDrawer : myDrawer->Link());
579     if (HasMaterial())
580     {
581       Quantity_Color aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
582       mat.SetColor (aColor);
583     }
584     if (IsTransparent())
585     {
586       Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
587       mat.SetTransparency (aTransp);
588     }
589     myDrawer->ShadingAspect()->SetMaterial (mat ,myCurrentFacingModel);
590   }
591   else
592   {
593     myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
594   }
595   myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
596
597   // modify shading presentation without re-computation
598   const PrsMgr_Presentations&        aPrsList  = Presentations();
599   Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->Link()->ShadingAspect()->Aspect();
600   Handle(Graphic3d_AspectLine3d)     aLineAsp  = myDrawer->Link()->LineAspect()->Aspect();
601   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
602   {
603     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
604     if (aPrsModed.Mode() != AIS_Shaded)
605     {
606       continue;
607     }
608
609     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
610
611     aPrs->SetPrimitivesAspect (anAreaAsp);
612     aPrs->SetPrimitivesAspect (aLineAsp);
613
614     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
615     {
616       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
617
618       // Check if aspect of given type is set for the group,
619       // because setting aspect for group with no already set aspect
620       // can lead to loss of presentation data
621       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
622       {
623         aGroup->SetGroupPrimitivesAspect (anAreaAsp);
624       }
625       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_LINE))
626       {
627         aGroup->SetGroupPrimitivesAspect (aLineAsp);
628       }
629     }
630   }
631
632   LoadRecomputable (AIS_WireFrame);
633   LoadRecomputable (2);
634 }
635
636 //=======================================================================
637 //function : setWidth
638 //purpose  :
639 //=======================================================================
640
641 void AIS_Shape::setWidth (const Handle(AIS_Drawer)& theDrawer,
642                           const Standard_Real       theLineWidth) const
643 {
644   if (!theDrawer->HasLineAspect())
645   {
646     theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
647     *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
648   }
649   if (!theDrawer->HasWireAspect())
650   {
651     theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
652     *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
653   }
654   // disable dedicated line aspects
655   theDrawer->SetFreeBoundaryAspect  (theDrawer->LineAspect());
656   theDrawer->SetUnFreeBoundaryAspect(theDrawer->LineAspect());
657   theDrawer->SetSeenLineAspect      (theDrawer->LineAspect());
658
659   // override width
660   theDrawer->LineAspect()->SetWidth (theLineWidth);
661   theDrawer->WireAspect()->SetWidth (theLineWidth);
662 }
663
664 //=======================================================================
665 //function : SetWidth
666 //purpose  : 
667 //=======================================================================
668
669 void AIS_Shape::SetWidth (const Standard_Real theLineWidth)
670 {
671   setWidth (myDrawer, theLineWidth);
672   myOwnWidth = theLineWidth;
673   LoadRecomputable (AIS_WireFrame); // means that it is necessary to recompute only the wireframe....
674   LoadRecomputable (2);             // and the bounding box...
675 }
676
677 //=======================================================================
678 //function : UnsetWidth
679 //purpose  :
680 //=======================================================================
681
682 void AIS_Shape::UnsetWidth()
683 {
684   if (myOwnWidth == 0.0)
685   {
686     myToRecomputeModes.Clear();
687     return;
688   }
689
690   myOwnWidth = 0.0;
691
692   Handle(Prs3d_LineAspect) anEmptyAsp;
693
694   if (!HasColor())
695   {
696     myDrawer->SetLineAspect          (anEmptyAsp);
697     myDrawer->SetWireAspect          (anEmptyAsp);
698     myDrawer->SetFreeBoundaryAspect  (anEmptyAsp);
699     myDrawer->SetUnFreeBoundaryAspect(anEmptyAsp);
700     myDrawer->SetSeenLineAspect      (anEmptyAsp);
701   }
702   else
703   {
704     myDrawer->LineAspect()          ->SetWidth (AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Line));
705     myDrawer->WireAspect()          ->SetWidth (AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Wire));
706     myDrawer->FreeBoundaryAspect()  ->SetWidth (AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Free));
707     myDrawer->UnFreeBoundaryAspect()->SetWidth (AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_UnFree));
708     myDrawer->SeenLineAspect()      ->SetWidth (AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Seen));
709   }
710   LoadRecomputable (AIS_WireFrame);
711 }
712
713 //=======================================================================
714 //function : setMaterial
715 //purpose  :
716 //=======================================================================
717
718 void AIS_Shape::setMaterial (const Handle(AIS_Drawer)&       theDrawer,
719                              const Graphic3d_MaterialAspect& theMaterial,
720                              const Standard_Boolean          theToKeepColor,
721                              const Standard_Boolean          theToKeepTransp) const
722 {
723   const Quantity_Color aColor  = theDrawer->ShadingAspect()->Material     (myCurrentFacingModel).Color();
724   const Standard_Real  aTransp = theDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
725   if (!theDrawer->HasShadingAspect())
726   {
727     theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
728     *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
729   }
730   theDrawer->ShadingAspect()->SetMaterial (theMaterial, myCurrentFacingModel);
731
732   if (theToKeepColor)
733   {
734     theDrawer->ShadingAspect()->SetColor (aColor, myCurrentFacingModel);
735   }
736   if (theToKeepTransp)
737   {
738     theDrawer->ShadingAspect()->SetTransparency (aTransp, myCurrentFacingModel);
739   }
740 }
741
742 //=======================================================================
743 //function : SetMaterial
744 //purpose  : 
745 //=======================================================================
746
747 void AIS_Shape::SetMaterial(const Graphic3d_NameOfMaterial aMat)
748 {
749   SetMaterial(Graphic3d_MaterialAspect(aMat));
750 }
751
752 //=======================================================================
753 //function : SetMaterial
754 //purpose  :
755 //=======================================================================
756
757 void AIS_Shape::SetMaterial (const Graphic3d_MaterialAspect& theMat)
758 {
759   setMaterial (myDrawer, theMat, HasColor(), IsTransparent());
760   hasOwnMaterial = Standard_True;
761
762   // modify shading presentation without re-computation
763   const PrsMgr_Presentations&        aPrsList  = Presentations();
764   Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
765   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
766   {
767     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
768     if (aPrsModed.Mode() != AIS_Shaded)
769     {
770       continue;
771     }
772
773     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
774     aPrs->SetPrimitivesAspect (anAreaAsp);
775     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
776     {
777       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
778
779       // Check if aspect of given type is set for the group, 
780       // because setting aspect for group with no already set aspect
781       // can lead to loss of presentation data
782       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
783       {
784         aGroup->SetGroupPrimitivesAspect (anAreaAsp);
785       }
786     }
787   }
788
789   myRecomputeEveryPrs = Standard_False; // no mode to recalculate  :only viewer update
790   myToRecomputeModes.Clear();
791 }
792
793 //=======================================================================
794 //function : UnsetMaterial
795 //purpose  :
796 //=======================================================================
797
798 void AIS_Shape::UnsetMaterial()
799 {
800   if (!HasMaterial())
801   {
802     return;
803   }
804
805   if (HasColor()
806    || IsTransparent())
807   {
808     myDrawer->ShadingAspect()->SetMaterial (myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel),
809                                             myCurrentFacingModel);
810     if (HasColor())
811     {
812       myDrawer->ShadingAspect()->SetColor        (myOwnColor,     myCurrentFacingModel);
813       myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
814     }
815   }
816   else
817   {
818     myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
819   }
820   hasOwnMaterial = Standard_False;
821
822   // modify shading presentation without re-computation
823   const PrsMgr_Presentations&        aPrsList  = Presentations();
824   Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
825   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
826   {
827     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
828     if (aPrsModed.Mode() != AIS_Shaded)
829     {
830       continue;
831     }
832
833     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
834     aPrs->SetPrimitivesAspect (anAreaAsp);
835     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
836     {
837       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
838       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
839       {
840         aGroup->SetGroupPrimitivesAspect (anAreaAsp);
841       }
842     }
843   }
844
845   myRecomputeEveryPrs = Standard_False; // no mode to recalculate :only viewer update
846   myToRecomputeModes.Clear();  
847 }
848
849 //=======================================================================
850 //function : setTransparency
851 //purpose  :
852 //=======================================================================
853
854 void AIS_Shape::setTransparency (const Handle(AIS_Drawer)& theDrawer,
855                                  const Standard_Real       theValue) const
856 {
857   if (!theDrawer->HasShadingAspect())
858   {
859     theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
860     *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
861   }
862
863   // override transparency
864   theDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel);
865 }
866
867 //=======================================================================
868 //function : SetTransparency
869 //purpose  :
870 //=======================================================================
871
872 void AIS_Shape::SetTransparency (const Standard_Real theValue)
873 {
874   setTransparency (myDrawer, theValue);
875   myTransparency = theValue;
876
877   // modify shading presentation without re-computation
878   const PrsMgr_Presentations&        aPrsList  = Presentations();
879   Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
880   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
881   {
882     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
883     if (aPrsModed.Mode() != AIS_Shaded)
884     {
885       continue;
886     }
887
888     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
889     aPrs->SetPrimitivesAspect (anAreaAsp);
890     aPrs->SetDisplayPriority (10); // force highest priority for translucent objects
891     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
892     {
893       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
894       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
895       {
896         aGroup->SetGroupPrimitivesAspect (anAreaAsp);
897       }
898     }
899   }
900
901   myRecomputeEveryPrs = Standard_False; // no mode to recalculate - only viewer update
902   myToRecomputeModes.Clear();
903 }
904
905 //=======================================================================
906 //function : UnsetTransparency
907 //purpose  :
908 //=======================================================================
909
910 void AIS_Shape::UnsetTransparency()
911 {
912   myTransparency = 0.0;
913   if (!myDrawer->HasShadingAspect())
914   {
915     return;
916   }
917   else if (HasColor() || HasMaterial())
918   {
919     myDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
920   }
921   else
922   {
923     myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
924   }
925
926   // modify shading presentation without re-computation
927   const PrsMgr_Presentations&        aPrsList  = Presentations();
928   Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
929   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
930   {
931     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
932     if (aPrsModed.Mode() != AIS_Shaded)
933     {
934       continue;
935     }
936
937     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
938     aPrs->SetPrimitivesAspect (anAreaAsp);
939     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
940     {
941       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
942       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
943       {
944         aGroup->SetGroupPrimitivesAspect (anAreaAsp);
945       }
946     }
947     aPrs->ResetDisplayPriority();
948   }
949
950   myRecomputeEveryPrs = Standard_False; // no mode to recalculate :only viewer update
951   myToRecomputeModes.Clear();
952 }
953
954 //=======================================================================
955 //function : LoadRecomputable
956 //purpose  : 
957 //=======================================================================
958
959 void AIS_Shape::LoadRecomputable(const Standard_Integer TheMode)
960 {
961   myRecomputeEveryPrs = Standard_False;
962   if(!IsInList(myToRecomputeModes,TheMode))
963     myToRecomputeModes.Append(TheMode);
964 }
965
966 //=======================================================================
967 //function : BoundingBox
968 //purpose  : 
969 //=======================================================================
970
971 const Bnd_Box& AIS_Shape::BoundingBox()  
972 {
973   if (myshape.ShapeType() == TopAbs_COMPOUND) {
974     TopoDS_Iterator anExplor (myshape);
975
976     if (!anExplor.More()) { // empty Shape  -> empty Assembly.
977       myBB.SetVoid();
978       return myBB;
979     }
980   }
981
982   if(myCompBB) {
983     BRepBndLib::AddClose(myshape, myBB);
984     myCompBB = Standard_False;
985   }
986   return myBB;
987 }
988
989 //*****
990 //***** Reset
991 //=======================================================================
992 //function : SetOwnDeviationCoefficient
993 //purpose  : resets myhasOwnDeviationCoefficient to Standard_False and
994 //           returns Standard_True if it change
995 //=======================================================================
996
997 Standard_Boolean AIS_Shape::SetOwnDeviationCoefficient ()
998 {
999   Standard_Boolean itSet = myDrawer->IsOwnDeviationCoefficient();
1000   if(itSet)  myDrawer->SetDeviationCoefficient();
1001   return itSet;
1002 }
1003
1004 //=======================================================================
1005 //function : SetHLROwnDeviationCoefficient
1006 //purpose  : resets myhasOwnHLRDeviationCoefficient to Standard_False and
1007 //           returns Standard_True if it change
1008 //=======================================================================
1009
1010 Standard_Boolean AIS_Shape::SetOwnHLRDeviationCoefficient ()
1011 {
1012   Standard_Boolean itSet = myDrawer->IsOwnHLRDeviationCoefficient();
1013   if(itSet)  myDrawer->SetHLRDeviationCoefficient();
1014   return itSet;
1015
1016 }
1017
1018 //=======================================================================
1019 //function : SetOwnDeviationAngle
1020 //purpose  : resets myhasOwnDeviationAngle to Standard_False and
1021 //           returns Standard_True if it change
1022 //=======================================================================
1023
1024 Standard_Boolean AIS_Shape::SetOwnDeviationAngle ()
1025 {
1026   Standard_Boolean itSet = myDrawer->IsOwnDeviationAngle();
1027   if(itSet)  myDrawer->SetDeviationAngle();
1028   return itSet;
1029
1030 }
1031
1032 //=======================================================================
1033 //function : SetOwnHLRDeviationAngle
1034 //purpose  : resets myhasOwnHLRDeviationAngle to Standard_False and
1035 //           returns Standard_True if it change
1036 //=======================================================================
1037
1038 Standard_Boolean AIS_Shape::SetOwnHLRDeviationAngle ()
1039 {
1040   Standard_Boolean itSet = myDrawer->IsOwnHLRDeviationAngle();
1041   if(itSet)  myDrawer->SetHLRAngle();
1042   return itSet;
1043
1044 }
1045 //***** SetOwn
1046 //=======================================================================
1047 //function : SetOwnDeviationCoefficient
1048 //purpose  : 
1049 //=======================================================================
1050
1051 void AIS_Shape::SetOwnDeviationCoefficient ( const Standard_Real  aCoefficient )
1052 {
1053   myDrawer->SetDeviationCoefficient( aCoefficient );
1054   SetToUpdate(0) ; // WireFrame
1055   SetToUpdate(1) ; // Shadding
1056 }
1057
1058 //=======================================================================
1059 //function : SetOwnHLRDeviationCoefficient
1060 //purpose  : 
1061 //=======================================================================
1062
1063 void AIS_Shape::SetOwnHLRDeviationCoefficient ( const Standard_Real  aCoefficient )
1064 {
1065   myDrawer->SetHLRDeviationCoefficient( aCoefficient );
1066   
1067 }
1068
1069 //=======================================================================
1070 //function : SetOwnDeviationAngle
1071 //purpose  : 
1072 //=======================================================================
1073
1074 void AIS_Shape::SetOwnDeviationAngle ( const Standard_Real  anAngle )
1075 {
1076
1077   myDrawer->SetDeviationAngle(anAngle );
1078   SetToUpdate(0) ;   // WireFrame
1079 }
1080 //=======================================================================
1081 //function : SetOwnDeviationAngle
1082 //purpose  : 
1083 //=======================================================================
1084
1085 void AIS_Shape::SetAngleAndDeviation ( const Standard_Real  anAngle )
1086 {
1087   Standard_Real OutAngl,OutDefl;
1088   HLRBRep::PolyHLRAngleAndDeflection(anAngle,OutAngl,OutDefl);
1089   SetOwnDeviationAngle(anAngle) ;
1090   SetOwnDeviationCoefficient(OutDefl) ;
1091   myInitAng = anAngle;
1092   SetToUpdate(0);
1093   SetToUpdate(1);
1094 }
1095
1096 //=======================================================================
1097 //function : UserAngle
1098 //purpose  : 
1099 //=======================================================================
1100
1101 Standard_Real AIS_Shape::UserAngle() const
1102 {
1103   return myInitAng ==0. ? GetContext()->DeviationAngle(): myInitAng;
1104 }
1105
1106
1107 //=======================================================================
1108 //function : SetHLRAngleAndDeviation
1109 //purpose  : 
1110 //=======================================================================
1111
1112 void AIS_Shape::SetHLRAngleAndDeviation ( const Standard_Real  anAngle )
1113 {
1114   Standard_Real OutAngl,OutDefl;
1115   HLRBRep::PolyHLRAngleAndDeflection(anAngle,OutAngl,OutDefl);
1116   SetOwnHLRDeviationAngle( OutAngl );
1117   SetOwnHLRDeviationCoefficient(OutDefl);
1118
1119 }
1120 //=======================================================================
1121 //function : SetOwnHLRDeviationAngle
1122 //purpose  : 
1123 //=======================================================================
1124
1125 void AIS_Shape::SetOwnHLRDeviationAngle ( const Standard_Real  anAngle )
1126 {
1127   myDrawer->SetHLRAngle( anAngle );
1128 }
1129
1130 //***** GetOwn
1131 //=======================================================================
1132 //function : OwnDeviationCoefficient
1133 //purpose  : 
1134 //=======================================================================
1135
1136 Standard_Boolean AIS_Shape::OwnDeviationCoefficient ( Standard_Real &  aCoefficient,
1137                                                       Standard_Real & aPreviousCoefficient ) const
1138 {
1139   aCoefficient = myDrawer->DeviationCoefficient();
1140   aPreviousCoefficient = myDrawer->PreviousDeviationCoefficient ();
1141   return myDrawer->IsOwnDeviationCoefficient() ;
1142 }
1143
1144 //=======================================================================
1145 //function : OwnHLRDeviationCoefficient
1146 //purpose  : 
1147 //=======================================================================
1148
1149 Standard_Boolean AIS_Shape::OwnHLRDeviationCoefficient ( Standard_Real & aCoefficient,
1150                                                          Standard_Real & aPreviousCoefficient ) const
1151 {
1152   aCoefficient = myDrawer->HLRDeviationCoefficient();
1153   aPreviousCoefficient = myDrawer->PreviousHLRDeviationCoefficient ();
1154   return myDrawer->IsOwnHLRDeviationCoefficient();
1155
1156 }
1157
1158 //=======================================================================
1159 //function : OwnDeviationAngle
1160 //purpose  : 
1161 //=======================================================================
1162
1163 Standard_Boolean AIS_Shape::OwnDeviationAngle ( Standard_Real &  anAngle,
1164                                                 Standard_Real & aPreviousAngle ) const
1165 {
1166   anAngle = myDrawer->DeviationAngle();
1167   aPreviousAngle = myDrawer->PreviousDeviationAngle (); 
1168   return myDrawer->IsOwnDeviationAngle();
1169 }
1170
1171 //=======================================================================
1172 //function : OwnHLRDeviationAngle
1173 //purpose  : 
1174 //=======================================================================
1175
1176 Standard_Boolean AIS_Shape::OwnHLRDeviationAngle ( Standard_Real &  anAngle,
1177                                                    Standard_Real & aPreviousAngle ) const
1178 {
1179   anAngle = myDrawer->HLRAngle();
1180   aPreviousAngle = myDrawer->PreviousHLRDeviationAngle (); 
1181   return myDrawer->IsOwnHLRDeviationAngle();
1182 }