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