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