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