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