0029814: Modeling Data - add method TopoDS_Shape::NbChildren() for simple check of...
[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 void AIS_Shape::setColor (const Handle(Prs3d_Drawer)& theDrawer,
350                           const Quantity_Color&       theColor) const
351 {
352   if (!theDrawer->HasOwnShadingAspect())
353   {
354     theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
355     if (theDrawer->HasLink())
356     {
357       *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
358     }
359   }
360   if (!theDrawer->HasOwnLineAspect())
361   {
362     theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
363     if (theDrawer->HasLink())
364     {
365       *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
366     }
367   }
368   if (!theDrawer->HasOwnWireAspect())
369   {
370     theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
371     if (theDrawer->HasLink())
372     {
373       *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
374     }
375   }
376   if (!theDrawer->HasOwnPointAspect())
377   {
378     theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_PLUS, Quantity_NOC_BLACK, 1.0));
379     if (theDrawer->HasLink())
380     {
381       *theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
382     }
383   }
384   if (!theDrawer->HasOwnFreeBoundaryAspect())
385   {
386     theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
387     if (theDrawer->HasLink())
388     {
389       *theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
390     }
391   }
392   if (!theDrawer->HasOwnUnFreeBoundaryAspect())
393   {
394     theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
395     if (theDrawer->HasLink())
396     {
397       *theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
398     }
399   }
400   if (!theDrawer->HasOwnSeenLineAspect())
401   {
402     theDrawer->SetSeenLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
403     if (theDrawer->HasLink())
404     {
405       *theDrawer->SeenLineAspect()->Aspect() = *theDrawer->Link()->SeenLineAspect()->Aspect();
406     }
407   }
408
409   // override color
410   theDrawer->ShadingAspect()->SetColor (theColor, myCurrentFacingModel);
411   theDrawer->LineAspect()->SetColor (theColor);
412   theDrawer->WireAspect()->SetColor (theColor);
413   theDrawer->PointAspect()->SetColor (theColor);
414   theDrawer->FreeBoundaryAspect()->SetColor (theColor);
415   theDrawer->UnFreeBoundaryAspect()->SetColor (theColor);
416   theDrawer->SeenLineAspect()->SetColor (theColor);
417 }
418
419 //=======================================================================
420 //function : SetColor
421 //purpose  :
422 //=======================================================================
423
424 void AIS_Shape::SetColor (const Quantity_Color& theColor)
425 {
426   setColor (myDrawer, theColor);
427   myDrawer->SetColor (theColor);
428   hasOwnColor = Standard_True;
429
430   // modify shading presentation without re-computation
431   const PrsMgr_Presentations&        aPrsList     = Presentations();
432   Handle(Graphic3d_AspectFillArea3d) anAreaAspect = myDrawer->ShadingAspect()->Aspect();
433   Handle(Graphic3d_AspectLine3d)     aLineAspect  = myDrawer->LineAspect()->Aspect();
434   Handle(Graphic3d_AspectMarker3d)   aPointAspect = myDrawer->PointAspect()->Aspect();
435   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
436   {
437     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
438     if (aPrsModed.Mode() != AIS_Shaded)
439     {
440       continue;
441     }
442
443     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
444     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
445     {
446       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
447
448       // Check if aspect of given type is set for the group, 
449       // because setting aspect for group with no already set aspect
450       // can lead to loss of presentation data
451       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
452       {
453         aGroup->SetGroupPrimitivesAspect (anAreaAspect);
454       }
455       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_LINE))
456       {
457         aGroup->SetGroupPrimitivesAspect (aLineAspect);
458       }
459       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER))
460       {
461         aGroup->SetGroupPrimitivesAspect (aPointAspect);
462       }
463     }
464   }
465
466   LoadRecomputable (AIS_WireFrame);
467   LoadRecomputable (2);
468 }
469
470 //=======================================================================
471 //function : UnsetColor
472 //purpose  :
473 //=======================================================================
474
475 void AIS_Shape::UnsetColor()
476 {
477   if (!HasColor())
478   {
479     myToRecomputeModes.Clear();
480     return;
481   }
482   hasOwnColor = Standard_False;
483   myDrawer->SetColor (myDrawer->HasLink() ? myDrawer->Link()->Color() : Quantity_Color (Quantity_NOC_WHITE));
484
485   if (!HasWidth())
486   {
487     Handle(Prs3d_LineAspect) anEmptyAsp;
488     myDrawer->SetLineAspect          (anEmptyAsp);
489     myDrawer->SetWireAspect          (anEmptyAsp);
490     myDrawer->SetFreeBoundaryAspect  (anEmptyAsp);
491     myDrawer->SetUnFreeBoundaryAspect(anEmptyAsp);
492     myDrawer->SetSeenLineAspect      (anEmptyAsp);
493   }
494   else
495   {
496     Quantity_Color aColor = Quantity_NOC_YELLOW;
497     if (myDrawer->HasLink())
498     {
499       AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Line,   aColor);
500     }
501     myDrawer->LineAspect()->SetColor (aColor);
502     aColor = Quantity_NOC_RED;
503     if (myDrawer->HasLink())
504     {
505       AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Wire,   aColor);
506     }
507     myDrawer->WireAspect()->SetColor (aColor);
508     aColor = Quantity_NOC_GREEN;
509     if (myDrawer->HasLink())
510     {
511       AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Free,   aColor);
512     }
513     myDrawer->FreeBoundaryAspect()->SetColor (aColor);
514     aColor = Quantity_NOC_YELLOW;
515     if (myDrawer->HasLink())
516     {
517       AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_UnFree, aColor);
518     }
519     myDrawer->UnFreeBoundaryAspect()->SetColor (aColor);
520     if (myDrawer->HasLink())
521     {
522       AIS_GraphicTool::GetLineColor (myDrawer->Link(), AIS_TOA_Seen,   aColor);
523     }
524     myDrawer->SeenLineAspect()->SetColor (aColor);
525   }
526
527   if (!myDrawer->HasOwnShadingAspect())
528   {
529     //
530   }
531   else if (HasMaterial()
532         || IsTransparent()
533         || myDrawer->ShadingAspect()->Aspect()->ToMapTexture())
534   {
535     const Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
536     Graphic3d_MaterialAspect mat = aDefaultMat;
537     Quantity_Color anInteriorColors[2] = {Quantity_NOC_CYAN1, Quantity_NOC_CYAN1};
538     if (myDrawer->HasLink())
539     {
540       anInteriorColors[0] = myDrawer->Link()->ShadingAspect()->Aspect()->InteriorColor();
541       anInteriorColors[1] = myDrawer->Link()->ShadingAspect()->Aspect()->BackInteriorColor();
542     }
543     if (HasMaterial() || myDrawer->HasLink())
544     {
545       const Handle(Graphic3d_AspectFillArea3d)& aSrcAspect = (HasMaterial() ? myDrawer : myDrawer->Link())->ShadingAspect()->Aspect();
546       mat = myCurrentFacingModel != Aspect_TOFM_BACK_SIDE
547           ? aSrcAspect->FrontMaterial()
548           : aSrcAspect->BackMaterial();
549     }
550     if (HasMaterial())
551     {
552       const Quantity_Color aColor = myDrawer->HasLink()
553                                   ? myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel)
554                                   : aDefaultMat.AmbientColor();
555       mat.SetColor (aColor);
556     }
557     if (IsTransparent())
558     {
559       Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
560       mat.SetTransparency (Standard_ShortReal(aTransp));
561     }
562     myDrawer->ShadingAspect()->SetMaterial (mat, myCurrentFacingModel);
563     myDrawer->ShadingAspect()->Aspect()->SetInteriorColor    (anInteriorColors[0]);
564     myDrawer->ShadingAspect()->Aspect()->SetBackInteriorColor(anInteriorColors[1]);
565   }
566   else
567   {
568     myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
569   }
570   myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
571
572   // modify shading presentation without re-computation
573   const PrsMgr_Presentations&        aPrsList  = Presentations();
574   Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
575   Handle(Graphic3d_AspectLine3d)     aLineAsp  = myDrawer->LineAspect()->Aspect();
576   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
577   {
578     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
579     if (aPrsModed.Mode() != AIS_Shaded)
580     {
581       continue;
582     }
583
584     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
585     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
586     {
587       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
588
589       // Check if aspect of given type is set for the group,
590       // because setting aspect for group with no already set aspect
591       // can lead to loss of presentation data
592       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
593       {
594         aGroup->SetGroupPrimitivesAspect (anAreaAsp);
595       }
596       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_LINE))
597       {
598         aGroup->SetGroupPrimitivesAspect (aLineAsp);
599       }
600     }
601   }
602
603   LoadRecomputable (AIS_WireFrame);
604   LoadRecomputable (2);
605 }
606
607 //=======================================================================
608 //function : setWidth
609 //purpose  :
610 //=======================================================================
611
612 void AIS_Shape::setWidth (const Handle(Prs3d_Drawer)& theDrawer,
613                           const Standard_Real         theLineWidth) const
614 {
615   if (!theDrawer->HasOwnLineAspect())
616   {
617     theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
618     if (theDrawer->HasLink())
619     {
620       *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
621     }
622   }
623   if (!theDrawer->HasOwnWireAspect())
624   {
625     theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
626     if (theDrawer->HasLink())
627     {
628       *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
629     }
630   }
631   if (!theDrawer->HasOwnFreeBoundaryAspect())
632   {
633     theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
634     if (theDrawer->HasLink())
635     {
636       *theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
637     }
638   }
639   if (!theDrawer->HasOwnUnFreeBoundaryAspect())
640   {
641     theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
642     if (theDrawer->HasLink())
643     {
644       *theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
645     }
646   }
647   if (!theDrawer->HasOwnSeenLineAspect())
648   {
649     theDrawer->SetSeenLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
650     if (theDrawer->HasLink())
651     {
652       *theDrawer->SeenLineAspect()->Aspect() = *theDrawer->Link()->SeenLineAspect()->Aspect();
653     }
654   }
655
656   // override width
657   theDrawer->LineAspect()->SetWidth (theLineWidth);
658   theDrawer->WireAspect()->SetWidth (theLineWidth);
659   theDrawer->FreeBoundaryAspect()->SetWidth (theLineWidth);
660   theDrawer->UnFreeBoundaryAspect()->SetWidth (theLineWidth);
661   theDrawer->SeenLineAspect()->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 (myDrawer->HasLink() ?
705       AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Line) : 1.);
706     myDrawer->WireAspect()          ->SetWidth (myDrawer->HasLink() ?
707       AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Wire) : 1.);
708     myDrawer->FreeBoundaryAspect()  ->SetWidth (myDrawer->HasLink() ?
709       AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Free) : 1.);
710     myDrawer->UnFreeBoundaryAspect()->SetWidth (myDrawer->HasLink() ?
711       AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_UnFree) : 1.);
712     myDrawer->SeenLineAspect()      ->SetWidth (myDrawer->HasLink() ?
713       AIS_GraphicTool::GetLineWidth (myDrawer->Link(), AIS_TOA_Seen) : 1.);
714   }
715   LoadRecomputable (AIS_WireFrame);
716 }
717
718 //=======================================================================
719 //function : setMaterial
720 //purpose  :
721 //=======================================================================
722
723 void AIS_Shape::setMaterial (const Handle(Prs3d_Drawer)&     theDrawer,
724                              const Graphic3d_MaterialAspect& theMaterial,
725                              const Standard_Boolean          theToKeepColor,
726                              const Standard_Boolean          theToKeepTransp) const
727 {
728   const Quantity_Color aColor  = theDrawer->ShadingAspect()->Material     (myCurrentFacingModel).Color();
729   const Standard_Real  aTransp = theDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
730   if (!theDrawer->HasOwnShadingAspect())
731   {
732     theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
733     if (theDrawer->HasLink())
734     {
735       *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
736     }
737   }
738   theDrawer->ShadingAspect()->SetMaterial (theMaterial, myCurrentFacingModel);
739
740   if (theToKeepColor)
741   {
742     theDrawer->ShadingAspect()->SetColor (aColor, myCurrentFacingModel);
743   }
744   if (theToKeepTransp)
745   {
746     theDrawer->ShadingAspect()->SetTransparency (aTransp, myCurrentFacingModel);
747   }
748 }
749
750 //=======================================================================
751 //function : SetMaterial
752 //purpose  :
753 //=======================================================================
754
755 void AIS_Shape::SetMaterial (const Graphic3d_MaterialAspect& theMat)
756 {
757   setMaterial (myDrawer, theMat, HasColor(), IsTransparent());
758   hasOwnMaterial = Standard_True;
759
760   // modify shading presentation without re-computation
761   const PrsMgr_Presentations&        aPrsList  = Presentations();
762   Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
763   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
764   {
765     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
766     if (aPrsModed.Mode() != AIS_Shaded)
767     {
768       continue;
769     }
770
771     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
772     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
773     {
774       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
775
776       // Check if aspect of given type is set for the group, 
777       // because setting aspect for group with no already set aspect
778       // can lead to loss of presentation data
779       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
780       {
781         aGroup->SetGroupPrimitivesAspect (anAreaAsp);
782       }
783     }
784   }
785
786   myRecomputeEveryPrs = Standard_False; // no mode to recalculate  :only viewer update
787   myToRecomputeModes.Clear();
788 }
789
790 //=======================================================================
791 //function : UnsetMaterial
792 //purpose  :
793 //=======================================================================
794
795 void AIS_Shape::UnsetMaterial()
796 {
797   if (!HasMaterial())
798   {
799     return;
800   }
801
802   if (!myDrawer->HasOwnShadingAspect())
803   {
804     //
805   }
806   else if (HasColor()
807         || IsTransparent()
808         || myDrawer->ShadingAspect()->Aspect()->ToMapTexture())
809   {
810     if(myDrawer->HasLink())
811     {
812       myDrawer->ShadingAspect()->SetMaterial (myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel),
813                                               myCurrentFacingModel);
814     }
815     if (HasColor())
816     {
817       myDrawer->ShadingAspect()->SetColor        (myDrawer->Color(),        myCurrentFacingModel);
818       myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
819     }
820   }
821   else
822   {
823     myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
824   }
825   hasOwnMaterial = Standard_False;
826
827   // modify shading presentation without re-computation
828   const PrsMgr_Presentations&        aPrsList  = Presentations();
829   Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
830   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
831   {
832     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
833     if (aPrsModed.Mode() != AIS_Shaded)
834     {
835       continue;
836     }
837
838     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
839     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
840     {
841       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
842       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
843       {
844         aGroup->SetGroupPrimitivesAspect (anAreaAsp);
845       }
846     }
847   }
848
849   myRecomputeEveryPrs = Standard_False; // no mode to recalculate :only viewer update
850   myToRecomputeModes.Clear();  
851 }
852
853 //=======================================================================
854 //function : setTransparency
855 //purpose  :
856 //=======================================================================
857
858 void AIS_Shape::setTransparency (const Handle(Prs3d_Drawer)& theDrawer,
859                                  const Standard_Real         theValue) const
860 {
861   if (!theDrawer->HasOwnShadingAspect())
862   {
863     theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
864     if (theDrawer->HasLink())
865     {
866       *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
867     }
868   }
869
870   // override transparency
871   theDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel);
872 }
873
874 //=======================================================================
875 //function : SetTransparency
876 //purpose  :
877 //=======================================================================
878
879 void AIS_Shape::SetTransparency (const Standard_Real theValue)
880 {
881   setTransparency (myDrawer, theValue);
882   myDrawer->SetTransparency ((Standard_ShortReal )theValue);
883
884   // modify shading presentation without re-computation
885   const PrsMgr_Presentations&        aPrsList  = Presentations();
886   Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
887   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
888   {
889     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
890     if (aPrsModed.Mode() != AIS_Shaded)
891     {
892       continue;
893     }
894
895     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
896     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
897     {
898       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
899       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
900       {
901         aGroup->SetGroupPrimitivesAspect (anAreaAsp);
902       }
903     }
904   }
905
906   myRecomputeEveryPrs = Standard_False; // no mode to recalculate - only viewer update
907   myToRecomputeModes.Clear();
908 }
909
910 //=======================================================================
911 //function : UnsetTransparency
912 //purpose  :
913 //=======================================================================
914
915 void AIS_Shape::UnsetTransparency()
916 {
917   myDrawer->SetTransparency (0.0f);
918   if (!myDrawer->HasOwnShadingAspect())
919   {
920     return;
921   }
922   else if (HasColor()
923         || HasMaterial()
924         || myDrawer->ShadingAspect()->Aspect()->ToMapTexture())
925   {
926     myDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
927   }
928   else
929   {
930     myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
931   }
932
933   // modify shading presentation without re-computation
934   const PrsMgr_Presentations&        aPrsList  = Presentations();
935   Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
936   for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
937   {
938     const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
939     if (aPrsModed.Mode() != AIS_Shaded)
940     {
941       continue;
942     }
943
944     const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
945     for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
946     {
947       const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
948       if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
949       {
950         aGroup->SetGroupPrimitivesAspect (anAreaAsp);
951       }
952     }
953   }
954
955   myRecomputeEveryPrs = Standard_False; // no mode to recalculate :only viewer update
956   myToRecomputeModes.Clear();
957 }
958
959 //=======================================================================
960 //function : LoadRecomputable
961 //purpose  : 
962 //=======================================================================
963
964 void AIS_Shape::LoadRecomputable(const Standard_Integer TheMode)
965 {
966   myRecomputeEveryPrs = Standard_False;
967   if(!IsInList(myToRecomputeModes,TheMode))
968     myToRecomputeModes.Append(TheMode);
969 }
970
971 //=======================================================================
972 //function : BoundingBox
973 //purpose  : 
974 //=======================================================================
975
976 const Bnd_Box& AIS_Shape::BoundingBox()  
977 {
978   if (myshape.ShapeType() == TopAbs_COMPOUND && myshape.NbChildren() == 0)
979   {
980     // empty Shape  -> empty Assembly.
981     myBB.SetVoid ();
982     return myBB;
983   }
984
985   if(myCompBB) {
986     BRepBndLib::AddClose(myshape, myBB);
987     myCompBB = Standard_False;
988   }
989   return myBB;
990 }
991
992 //*****
993 //***** Reset
994 //=======================================================================
995 //function : SetOwnDeviationCoefficient
996 //purpose  : resets myhasOwnDeviationCoefficient to Standard_False and
997 //           returns Standard_True if it change
998 //=======================================================================
999
1000 Standard_Boolean AIS_Shape::SetOwnDeviationCoefficient ()
1001 {
1002   Standard_Boolean itSet = myDrawer->HasOwnDeviationCoefficient();
1003   if(itSet)  myDrawer->SetDeviationCoefficient();
1004   return itSet;
1005 }
1006
1007 //=======================================================================
1008 //function : SetHLROwnDeviationCoefficient
1009 //purpose  : resets myhasOwnHLRDeviationCoefficient to Standard_False and
1010 //           returns Standard_True if it change
1011 //=======================================================================
1012
1013 Standard_Boolean AIS_Shape::SetOwnHLRDeviationCoefficient ()
1014 {
1015   Standard_Boolean itSet = myDrawer->HasOwnHLRDeviationCoefficient();
1016   if(itSet)  myDrawer->SetHLRDeviationCoefficient();
1017   return itSet;
1018
1019 }
1020
1021 //=======================================================================
1022 //function : SetOwnDeviationAngle
1023 //purpose  : resets myhasOwnDeviationAngle to Standard_False and
1024 //           returns Standard_True if it change
1025 //=======================================================================
1026
1027 Standard_Boolean AIS_Shape::SetOwnDeviationAngle ()
1028 {
1029   Standard_Boolean itSet = myDrawer->HasOwnDeviationAngle();
1030   if(itSet)  myDrawer->SetDeviationAngle();
1031   return itSet;
1032
1033 }
1034
1035 //=======================================================================
1036 //function : SetOwnHLRDeviationAngle
1037 //purpose  : resets myhasOwnHLRDeviationAngle to Standard_False and
1038 //           returns Standard_True if it change
1039 //=======================================================================
1040
1041 Standard_Boolean AIS_Shape::SetOwnHLRDeviationAngle ()
1042 {
1043   Standard_Boolean itSet = myDrawer->HasOwnHLRDeviationAngle();
1044   if(itSet)  myDrawer->SetHLRAngle();
1045   return itSet;
1046
1047 }
1048 //***** SetOwn
1049 //=======================================================================
1050 //function : SetOwnDeviationCoefficient
1051 //purpose  : 
1052 //=======================================================================
1053
1054 void AIS_Shape::SetOwnDeviationCoefficient ( const Standard_Real  aCoefficient )
1055 {
1056   myDrawer->SetDeviationCoefficient( aCoefficient );
1057   SetToUpdate(0) ; // WireFrame
1058   SetToUpdate(1) ; // Shadding
1059 }
1060
1061 //=======================================================================
1062 //function : SetOwnHLRDeviationCoefficient
1063 //purpose  : 
1064 //=======================================================================
1065
1066 void AIS_Shape::SetOwnHLRDeviationCoefficient ( const Standard_Real  aCoefficient )
1067 {
1068   myDrawer->SetHLRDeviationCoefficient( aCoefficient );
1069   
1070 }
1071
1072 //=======================================================================
1073 //function : SetOwnDeviationAngle
1074 //purpose  : 
1075 //=======================================================================
1076
1077 void AIS_Shape::SetOwnDeviationAngle ( const Standard_Real  anAngle )
1078 {
1079
1080   myDrawer->SetDeviationAngle(anAngle );
1081   SetToUpdate(0) ;   // WireFrame
1082 }
1083 //=======================================================================
1084 //function : SetOwnDeviationAngle
1085 //purpose  : 
1086 //=======================================================================
1087
1088 void AIS_Shape::SetAngleAndDeviation ( const Standard_Real  anAngle )
1089 {
1090   Standard_Real OutAngl,OutDefl;
1091   HLRBRep::PolyHLRAngleAndDeflection(anAngle,OutAngl,OutDefl);
1092   SetOwnDeviationAngle(anAngle) ;
1093   SetOwnDeviationCoefficient(OutDefl) ;
1094   myInitAng = anAngle;
1095   SetToUpdate(0);
1096   SetToUpdate(1);
1097 }
1098
1099 //=======================================================================
1100 //function : UserAngle
1101 //purpose  : 
1102 //=======================================================================
1103
1104 Standard_Real AIS_Shape::UserAngle() const
1105 {
1106   return myInitAng ==0. ? GetContext()->DeviationAngle(): myInitAng;
1107 }
1108
1109
1110 //=======================================================================
1111 //function : SetHLRAngleAndDeviation
1112 //purpose  : 
1113 //=======================================================================
1114
1115 void AIS_Shape::SetHLRAngleAndDeviation ( const Standard_Real  anAngle )
1116 {
1117   Standard_Real OutAngl,OutDefl;
1118   HLRBRep::PolyHLRAngleAndDeflection(anAngle,OutAngl,OutDefl);
1119   SetOwnHLRDeviationAngle( OutAngl );
1120   SetOwnHLRDeviationCoefficient(OutDefl);
1121
1122 }
1123 //=======================================================================
1124 //function : SetOwnHLRDeviationAngle
1125 //purpose  : 
1126 //=======================================================================
1127
1128 void AIS_Shape::SetOwnHLRDeviationAngle ( const Standard_Real  anAngle )
1129 {
1130   myDrawer->SetHLRAngle( anAngle );
1131 }
1132
1133 //***** GetOwn
1134 //=======================================================================
1135 //function : OwnDeviationCoefficient
1136 //purpose  : 
1137 //=======================================================================
1138
1139 Standard_Boolean AIS_Shape::OwnDeviationCoefficient ( Standard_Real &  aCoefficient,
1140                                                       Standard_Real & aPreviousCoefficient ) const
1141 {
1142   aCoefficient = myDrawer->DeviationCoefficient();
1143   aPreviousCoefficient = myDrawer->PreviousDeviationCoefficient ();
1144   return myDrawer->HasOwnDeviationCoefficient() ;
1145 }
1146
1147 //=======================================================================
1148 //function : OwnHLRDeviationCoefficient
1149 //purpose  : 
1150 //=======================================================================
1151
1152 Standard_Boolean AIS_Shape::OwnHLRDeviationCoefficient ( Standard_Real & aCoefficient,
1153                                                          Standard_Real & aPreviousCoefficient ) const
1154 {
1155   aCoefficient = myDrawer->HLRDeviationCoefficient();
1156   aPreviousCoefficient = myDrawer->PreviousHLRDeviationCoefficient ();
1157   return myDrawer->HasOwnHLRDeviationCoefficient();
1158
1159 }
1160
1161 //=======================================================================
1162 //function : OwnDeviationAngle
1163 //purpose  : 
1164 //=======================================================================
1165
1166 Standard_Boolean AIS_Shape::OwnDeviationAngle ( Standard_Real &  anAngle,
1167                                                 Standard_Real & aPreviousAngle ) const
1168 {
1169   anAngle = myDrawer->DeviationAngle();
1170   aPreviousAngle = myDrawer->PreviousDeviationAngle (); 
1171   return myDrawer->HasOwnDeviationAngle();
1172 }
1173
1174 //=======================================================================
1175 //function : OwnHLRDeviationAngle
1176 //purpose  : 
1177 //=======================================================================
1178
1179 Standard_Boolean AIS_Shape::OwnHLRDeviationAngle ( Standard_Real &  anAngle,
1180                                                    Standard_Real & aPreviousAngle ) const
1181 {
1182   anAngle = myDrawer->HLRAngle();
1183   aPreviousAngle = myDrawer->PreviousHLRDeviationAngle (); 
1184   return myDrawer->HasOwnHLRDeviationAngle();
1185 }