0023501: Redundant triangulation cleaning/generation (1) in AIS_Shape.cxx
[occt.git] / src / XCAFPrs / XCAFPrs_AISObject.cxx
1 // Created on: 2000-08-11
2 // Created by: Andrey BETENEV
3 // Copyright (c) 2000-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #include <XCAFPrs_AISObject.ixx>
22 #include <TCollection_ExtendedString.hxx>
23 #include <gp_Pnt.hxx>
24 #include <Prs3d_Text.hxx>
25 #include <Prs3d_LengthAspect.hxx>
26 #include <XCAFDoc_ShapeTool.hxx>
27
28 #include <Standard_ErrorHandler.hxx>
29 #include <Standard_Failure.hxx>
30
31 #include <Precision.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <TopoDS_Iterator.hxx>
34 #include <BRepTools.hxx>
35
36 #include <StdPrs_WFDeflectionShape.hxx>
37 #include <StdPrs_ShadedShape.hxx>
38 #include <StdPrs_WFShape.hxx>
39 #include <AIS_Drawer.hxx>
40 #include <Graphic3d_Group.hxx>
41 #include <Quantity_Color.hxx>
42 #include <Aspect_TypeOfLine.hxx>
43 #include <Prs3d_LineAspect.hxx>
44 #include <Graphic3d_AspectLine3d.hxx>
45 #include <BRep_Builder.hxx>
46 #include <TopoDS_Compound.hxx>
47 #include <XCAFPrs_Style.hxx>
48 #include <TopoDS_Shape.hxx>
49 #include <XCAFPrs_DataMapOfShapeStyle.hxx>
50 #include <TDF_LabelSequence.hxx>
51 #include <XCAFPrs_DataMapOfStyleShape.hxx>
52 #include <TopoDS.hxx>
53 #include <XCAFPrs_DataMapIteratorOfDataMapOfStyleShape.hxx>
54 #include <Graphic3d_AspectFillArea3d.hxx>
55 #include <Aspect_InteriorStyle.hxx>
56 #include <Aspect_TypeOfLine.hxx>
57 #include <Prs3d_ShadingAspect.hxx>
58
59 #include <Prs3d_IsoAspect.hxx>
60 #include <XCAFPrs.hxx>
61
62 #include <TDataStd_Name.hxx>
63 #include <BRepBndLib.hxx>
64
65 #include <TPrsStd_AISPresentation.hxx>
66
67 #ifdef DEBUG
68 #include <DBRep.hxx>
69 #endif
70
71
72 //=======================================================================
73 //function : XCAFPrs_AISObject
74 //purpose  : 
75 //=======================================================================
76
77 XCAFPrs_AISObject::XCAFPrs_AISObject (const TDF_Label &lab) : AIS_Shape(TopoDS_Shape())
78 {
79   myLabel = lab;
80
81   TopoDS_Shape shape;
82   if ( XCAFDoc_ShapeTool::GetShape ( myLabel, shape ) && ! shape.IsNull() ) 
83     Set ( shape );
84 }
85
86 //=======================================================================
87 //function : SetColor
88 //purpose  : 
89 //=======================================================================
90
91 void XCAFPrs_AISObject::SetColor(const Quantity_Color &aCol)
92 {
93   AIS_Shape::SetColor(aCol);
94   LoadRecomputable(1);
95 }
96
97 //=======================================================================
98 //function : UnsetColor
99 //purpose  : 
100 //=======================================================================
101
102 void XCAFPrs_AISObject::UnsetColor()
103 {
104   if (HasColor())
105   {
106     AIS_Shape::UnsetColor();
107     LoadRecomputable(1);
108   }
109   else
110   {
111     myToRecomputeModes.Clear();
112   }
113 }
114
115 //=======================================================================
116 //function : SetMaterial
117 //purpose  : 
118 //=======================================================================
119
120 void XCAFPrs_AISObject::SetMaterial(const Graphic3d_NameOfMaterial aMat)
121 {
122   AIS_Shape::SetMaterial(aMat);
123   LoadRecomputable(1);
124 }
125
126 //=======================================================================
127 //function : SetMaterial
128 //purpose  : 
129 //=======================================================================
130
131 void XCAFPrs_AISObject::SetMaterial(const Graphic3d_MaterialAspect& aMat)
132 {
133   AIS_Shape::SetMaterial(aMat);
134   LoadRecomputable(1);
135 }
136
137 //=======================================================================
138 //function : UnsetMaterial
139 //purpose  : 
140 //=======================================================================
141
142 void XCAFPrs_AISObject::UnsetMaterial()
143 {
144   if (HasMaterial())
145   {
146     AIS_Shape::UnsetMaterial();
147     LoadRecomputable(1);
148   }
149   else
150   {
151     myToRecomputeModes.Clear();
152   }
153 }
154
155 //=======================================================================
156 //function : SetTransparency
157 //purpose  : 
158 //=======================================================================
159
160 void XCAFPrs_AISObject::SetTransparency(const Standard_Real AValue)
161 {
162   AIS_Shape::SetTransparency(AValue);
163   LoadRecomputable(1);
164 }
165
166 //=======================================================================
167 //function : UnsetTransparency
168 //purpose  : 
169 //=======================================================================
170
171 void XCAFPrs_AISObject::UnsetTransparency()
172 {
173   AIS_Shape::UnsetTransparency();
174   LoadRecomputable(1);
175 }
176
177 //=======================================================================
178 //function : AddStyledItem
179 //purpose  : 
180 //=======================================================================
181
182 void XCAFPrs_AISObject::AddStyledItem (const XCAFPrs_Style &style, 
183                                        const TopoDS_Shape &shape, 
184                                        const Handle(PrsMgr_PresentationManager3d)&, // aPresentationManager,
185                                        const Handle(Prs3d_Presentation)& aPrs,
186                                        const Standard_Integer aMode)
187
188   // remember current color settings
189   Handle(Graphic3d_AspectFillArea3d) a4bis = myDrawer->ShadingAspect()->Aspect();
190   Aspect_InteriorStyle aStyle;
191   Quantity_Color aIntColor, aEdgeColor;
192   Aspect_TypeOfLine aType;
193   Standard_Real aWidth;
194   a4bis->Values(aStyle,aIntColor,aEdgeColor,aType,aWidth);
195   Graphic3d_MaterialAspect FMAT = a4bis->FrontMaterial();
196   Quantity_Color aFColor = FMAT.Color();
197
198   Quantity_Color aColor1, aColor2;
199   Aspect_TypeOfLine aLine1, aLine2;
200   Standard_Real aWigth1, aWigth2;
201   Handle(Prs3d_LineAspect) waUFB = myDrawer->UnFreeBoundaryAspect();
202   waUFB->Aspect()->Values(aColor1,aLine1,aWigth1);
203   Handle(Prs3d_LineAspect) waFB = myDrawer->FreeBoundaryAspect();
204   waFB->Aspect()->Values(aColor2,aLine2,aWigth2);
205
206   Quantity_Color aColor;
207   Aspect_TypeOfLine aLine;
208   Standard_Real aWigth;
209   Handle(Prs3d_LineAspect) wa = myDrawer->WireAspect();
210   wa->Aspect()->Values(aColor,aLine,aWigth);
211
212   Quantity_Color aColorU, aColorV;
213   Aspect_TypeOfLine aLineU, aLineV;
214   Standard_Real aWigthU, aWigthV;
215   Handle(Prs3d_IsoAspect) UIso = myDrawer->UIsoAspect();
216   Handle(Prs3d_IsoAspect) VIso = myDrawer->VIsoAspect();
217   UIso->Aspect()->Values(aColorU,aLineU,aWigthU);
218   VIso->Aspect()->Values(aColorV,aLineV,aWigthV);
219   
220   // Set colors etc. for current shape according to style
221   if ( style.IsSetColorCurv() ) {
222     Quantity_Color Color = style.GetColorCurv();
223     waUFB->SetColor ( Color.Name() );
224     waFB->SetColor ( Color.Name() );
225     wa->SetColor ( Color.Name() );
226   }
227   if ( style.IsSetColorSurf() ) {
228     Quantity_Color Color = style.GetColorSurf();
229     a4bis->SetInteriorColor(Color);
230     FMAT.SetColor(Color);
231     a4bis->SetFrontMaterial(FMAT);
232     UIso->SetColor ( Color.Name() );
233     VIso->SetColor ( Color.Name() );
234   }
235
236   // force drawing isos on planes
237   Standard_Boolean drawIsosPln = myDrawer->IsoOnPlane();
238   myDrawer->SetIsoOnPlane (Standard_True);
239   
240   // add shape to presentation
241   switch (aMode) {
242   case 0:{
243     try { OCC_CATCH_SIGNALS  StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer); }
244     catch (Standard_Failure) { 
245 #ifdef DEB
246       cout << "AIS_Shape::Compute() failed: exception " <<
247               Standard_Failure::Caught()->DynamicType()->Name() << ": " <<
248               Standard_Failure::Caught()->GetMessageString() << endl;
249 #endif
250 //      cout << "a Shape should be incorrect: No Compute can be maked on it  "<< endl;     
251 // on calcule une presentation de la boite englobante
252 //      Compute(aPresentationManager,aPrs,2);
253     }
254     break;
255   }
256   case 1:
257     {
258       Standard_Real prevangle ;
259       Standard_Real newangle  ; 
260       Standard_Real prevcoeff ;
261       Standard_Real newcoeff  ; 
262       
263       Standard_Boolean isOwnDeviationAngle = OwnDeviationAngle(newangle,prevangle);
264       Standard_Boolean isOwnDeviationCoefficient = OwnDeviationCoefficient(newcoeff,prevcoeff);
265       if (((Abs (newangle - prevangle) > Precision::Angular()) && isOwnDeviationAngle) ||
266           ((Abs (newcoeff - prevcoeff) > Precision::Confusion()) && isOwnDeviationCoefficient)) { 
267 #ifdef DEB
268           cout << "AIS_Shape : compute"<<endl;
269           cout << "newangl   : " << newangle << " # de " << "prevangl  : " << prevangle << " OU "<<endl;
270           cout << "newcoeff  : " << newcoeff << " # de " << "prevcoeff : " << prevcoeff << endl;
271 #endif
272           BRepTools::Clean(shape);
273         }
274     
275       //shading seulement a partir de face...
276       try {
277         OCC_CATCH_SIGNALS
278         if ((Standard_Integer) shape.ShapeType()>4)
279           StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer);
280         else {
281           myDrawer->SetShadingAspectGlobal(Standard_False);
282           if (IsInfinite()) 
283             StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer);
284           else
285             StdPrs_ShadedShape::Add(aPrs,shape,myDrawer);
286         }
287       }
288       catch (Standard_Failure) {
289 #ifdef DEB
290         cout << "AIS_Shape::Compute() in ShadingMode failed: exception " <<
291                 Standard_Failure::Caught()->DynamicType()->Name() << ": " <<
292                 Standard_Failure::Caught()->GetMessageString() << endl;
293 #endif
294         // last resort: try to display as wireframe
295         try {
296           OCC_CATCH_SIGNALS
297           StdPrs_WFShape::Add(aPrs,shape,myDrawer);
298         }
299         catch (Standard_Failure) {
300         }
301       }
302       break;
303     }
304   case 2:
305     {
306       // boite englobante
307       if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,shape,myDrawer);
308       else DisplayBox(aPrs,BoundingBox(),myDrawer);
309     }
310   }
311
312   // Restore initial settings
313   if ( style.IsSetColorCurv() ) {
314     waUFB->SetColor ( aColor1.Name() );
315     waFB->SetColor ( aColor2.Name() );
316     wa->SetColor ( aColor.Name() );
317   }
318   if ( style.IsSetColorSurf() ) {
319     a4bis->SetInteriorColor(aIntColor);
320     FMAT.SetColor(aFColor);
321     a4bis->SetFrontMaterial(FMAT);
322     UIso->SetColor ( aColorU );
323     VIso->SetColor ( aColorV );
324   }
325   myDrawer->SetIsoOnPlane (drawIsosPln);
326 }
327
328 //=======================================================================
329 //function : DisplayText
330 //purpose  : 
331 //=======================================================================
332
333 static void DisplayText (const TDF_Label& aLabel,
334                          const Handle(Prs3d_Presentation)& aPrs,
335                          const Handle(Prs3d_TextAspect)& anAspect,
336                          const TopLoc_Location& aLocation)
337 {
338   // first label itself
339   Handle (TDataStd_Name) aName;
340   if (aLabel.FindAttribute (TDataStd_Name::GetID(), aName)) {
341     TopoDS_Shape aShape;
342     if (XCAFDoc_ShapeTool::GetShape (aLabel, aShape)) {
343       // find the position to display as middle of the bounding box
344       aShape.Move (aLocation);
345       Bnd_Box aBox;
346       BRepBndLib::Add (aShape, aBox);
347       if ( ! aBox.IsVoid() ) 
348       {
349         Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
350         aBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
351         gp_Pnt aPnt (0.5 * (aXmin + aXmax), 0.5 * (aYmin + aYmax), 0.5 * (aZmin + aZmax));
352         Prs3d_Text::Draw( aPrs, anAspect, aName->Get(), aPnt);
353       }
354     }
355   }
356
357   TDF_LabelSequence seq;
358   
359   // attibutes of subshapes
360   if (XCAFDoc_ShapeTool::GetSubShapes (aLabel, seq)) {
361     Standard_Integer i = 1;
362     for (i = 1; i <= seq.Length(); i++) {
363       TDF_Label aL = seq.Value (i);
364       DisplayText (aL, aPrs, anAspect, aLocation); //suppose that subshapes do not contain locations
365     }
366   }
367   
368   // attibutes of components
369   seq.Clear();
370   if (XCAFDoc_ShapeTool::GetComponents (aLabel, seq)) {
371     Standard_Integer i = 1;
372     for (i = 1; i <= seq.Length(); i++) {
373       TDF_Label aL = seq.Value (i);
374       DisplayText (aL, aPrs, anAspect, aLocation);
375       TDF_Label aRefLabel;
376       
377       // attributes of referrences
378       TopLoc_Location aLoc = XCAFDoc_ShapeTool::GetLocation (aL);
379       if (XCAFDoc_ShapeTool::GetReferredShape (aL, aRefLabel)) {
380         DisplayText (aRefLabel, aPrs, anAspect, aLoc);
381       }
382     }
383   }
384 }
385                          
386 //=======================================================================
387 //function : Compute
388 //purpose  : 
389 //=======================================================================
390 // The Compute() method is copied from AIS_Shape::Compute and enhanced to 
391 // support different color settings for different subshapes of a single shape
392   
393 void XCAFPrs_AISObject::Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
394                                  const Handle(Prs3d_Presentation)& aPrs,
395                                  const Standard_Integer aMode)
396 {  
397 #ifdef DEB
398   //cout << "XCAFPrs_AISObject: Update called" << endl;
399 #endif
400   aPrs->Clear();
401
402   // abv: 06 Mar 00: to have good colors
403   Handle(TPrsStd_AISPresentation) prs = Handle(TPrsStd_AISPresentation)::DownCast ( GetOwner() );
404   if ( prs.IsNull() || !prs->HasOwnMaterial() )
405     AIS_Shape::SetMaterial ( Graphic3d_NOM_PLASTIC );
406
407   TopoDS_Shape shape;
408   if ( ! XCAFDoc_ShapeTool::GetShape ( myLabel, shape ) || shape.IsNull() ) return;
409
410   // wire,edge,vertex -> pas de HLR + priorite display superieure
411   Standard_Integer TheType = (Standard_Integer)shape.ShapeType();
412   if(TheType>4 && TheType<8) {
413     aPrs->SetVisual(Graphic3d_TOS_ALL);
414     aPrs->SetDisplayPriority(TheType+2);
415   }
416   // Shape vide -> Assemblage vide.
417   if (shape.ShapeType() == TopAbs_COMPOUND) {
418     TopoDS_Iterator anExplor (shape);
419     if (!anExplor.More()) {
420       return;
421     }
422   }
423   if (IsInfinite()) aPrs->SetInfiniteState(Standard_True); //pas de prise en compte lors du FITALL
424   
425   // collect information on colored subshapes
426   TopLoc_Location L;
427   XCAFPrs_DataMapOfShapeStyle settings;
428   XCAFPrs::CollectStyleSettings ( myLabel, L, settings );
429 #ifdef DEB
430   //cout << "Styles collected" << endl;
431 #endif
432
433   // dispatch (sub)shapes by their styles
434   XCAFPrs_DataMapOfStyleShape items;
435   XCAFPrs_Style DefStyle;
436   DefaultStyle (DefStyle);
437   XCAFPrs::DispatchStyles ( shape, settings, items, DefStyle );
438 #ifdef DEB
439   //cout << "Dispatch done" << endl;
440 #endif
441
442   // add subshapes to presentation (one shape per style)
443   XCAFPrs_DataMapIteratorOfDataMapOfStyleShape it ( items );
444 #ifdef DEB
445   //Standard_Integer i=1;
446 #endif
447   for ( ; it.More(); it.Next() ) {
448     XCAFPrs_Style s = it.Key();
449 #ifdef DEB
450     //cout << "Style " << i << ": [" << 
451     //  ( s.IsSetColorSurf() ? Quantity_Color::StringName ( s.GetColorSurf().Name() ) : "" ) << ", " <<
452     //  ( s.IsSetColorCurv() ? Quantity_Color::StringName ( s.GetColorCurv().Name() ) : "" ) << "]" <<
453         //" --> si_" << i << ( s.IsVisible() ? "" : " <invisible>" ) << endl;
454     //i++;
455 #endif
456     if (! s.IsVisible() ) continue;
457     Prs3d_Root::NewGroup(aPrs);
458     AddStyledItem ( s, it.Value(), aPresentationManager, aPrs, aMode );
459   }
460   
461   if ( XCAFPrs::GetViewNameMode() ) {
462   // Displaying Name attributes
463 #ifdef DEB
464     //cout << "Now display name of shapes" << endl;
465 #endif
466     aPrs->SetDisplayPriority(10);
467     DisplayText (myLabel, aPrs, Attributes()->LengthAspect()->TextAspect(), TopLoc_Location());//no location
468   }
469 #ifdef DEB
470   //cout << "Compute finished" << endl;
471 #endif
472   
473   aPrs->ReCompute(); // for hidden line recomputation if necessary...
474 }
475
476 //=======================================================================
477 //function : DefaultStyle
478 //purpose  : DefaultStyle() can be redefined by subclasses in order to set custom default style
479 //=======================================================================
480 void XCAFPrs_AISObject::DefaultStyle (XCAFPrs_Style& aStyle) const
481 {
482   static const Quantity_Color White ( Quantity_NOC_WHITE );
483   aStyle.SetColorSurf ( White );
484   aStyle.SetColorCurv ( White );
485 }