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