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