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