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