0029902: Data Exchange, XCAF - provide extended Material definition for visualization...
[occt.git] / src / XCAFPrs / XCAFPrs_AISObject.cxx
1 // Created on: 2000-08-11
2 // Created by: Andrey BETENEV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <XCAFPrs_AISObject.hxx>
17
18 #include <AIS_DisplayMode.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRepBndLib.hxx>
21 #include <gp_Pnt.hxx>
22 #include <Graphic3d_AspectFillArea3d.hxx>
23 #include <Graphic3d_AspectLine3d.hxx>
24 #include <Graphic3d_Texture2Dmanual.hxx>
25 #include <Prs3d_Drawer.hxx>
26 #include <Prs3d_DimensionAspect.hxx>
27 #include <Prs3d_IsoAspect.hxx>
28 #include <Prs3d_LineAspect.hxx>
29 #include <Prs3d_ShadingAspect.hxx>
30 #include <Prs3d_Text.hxx>
31 #include <TDataStd_Name.hxx>
32 #include <TDF_LabelSequence.hxx>
33 #include <TPrsStd_AISPresentation.hxx>
34 #include <TopoDS_Iterator.hxx>
35 #include <XCAFDoc_ShapeTool.hxx>
36 #include <XCAFPrs.hxx>
37 #include <XCAFPrs_IndexedDataMapOfShapeStyle.hxx>
38 #include <XCAFPrs_DataMapIteratorOfIndexedDataMapOfShapeStyle.hxx>
39 #include <XCAFPrs_Style.hxx>
40
41 IMPLEMENT_STANDARD_RTTIEXT(XCAFPrs_AISObject,AIS_ColoredShape)
42
43 //=======================================================================
44 //function : XCAFPrs_AISObject
45 //purpose  : 
46 //=======================================================================
47
48 XCAFPrs_AISObject::XCAFPrs_AISObject (const TDF_Label& theLabel)
49 : AIS_ColoredShape(TopoDS_Shape()),
50   myToSyncStyles (Standard_True)
51 {
52   // define plastic material by default for proper color reproduction
53   setMaterial (myDrawer, Graphic3d_NOM_PLASTIC, Standard_False, Standard_False);
54   hasOwnMaterial = Standard_True;
55
56   myLabel = theLabel;
57 }
58
59 //=======================================================================
60 //function : DisplayText
61 //purpose  : 
62 //=======================================================================
63
64 static void DisplayText (const TDF_Label& aLabel,
65                          const Handle(Prs3d_Presentation)& aPrs,
66                          const Handle(Prs3d_TextAspect)& anAspect,
67                          const TopLoc_Location& aLocation)
68 {
69   // first label itself
70   Handle (TDataStd_Name) aName;
71   if (aLabel.FindAttribute (TDataStd_Name::GetID(), aName)) {
72     TopoDS_Shape aShape;
73     if (XCAFDoc_ShapeTool::GetShape (aLabel, aShape)) {
74       // find the position to display as middle of the bounding box
75       aShape.Move (aLocation);
76       Bnd_Box aBox;
77       BRepBndLib::Add (aShape, aBox);
78       if ( ! aBox.IsVoid() ) 
79       {
80         Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
81         aBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
82         gp_Pnt aPnt (0.5 * (aXmin + aXmax), 0.5 * (aYmin + aYmax), 0.5 * (aZmin + aZmax));
83         Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPrs), anAspect, aName->Get(), aPnt);
84       }
85     }
86   }
87
88   TDF_LabelSequence seq;
89   
90   // attibutes of subshapes
91   if (XCAFDoc_ShapeTool::GetSubShapes (aLabel, seq)) {
92     Standard_Integer i = 1;
93     for (i = 1; i <= seq.Length(); i++) {
94       TDF_Label aL = seq.Value (i);
95       DisplayText (aL, aPrs, anAspect, aLocation); //suppose that subshapes do not contain locations
96     }
97   }
98   
99   // attibutes of components
100   seq.Clear();
101   if (XCAFDoc_ShapeTool::GetComponents (aLabel, seq)) {
102     Standard_Integer i = 1;
103     for (i = 1; i <= seq.Length(); i++) {
104       TDF_Label aL = seq.Value (i);
105       DisplayText (aL, aPrs, anAspect, aLocation);
106       TDF_Label aRefLabel;
107       
108       // attributes of referrences
109       TopLoc_Location aLoc = XCAFDoc_ShapeTool::GetLocation (aL);
110       if (XCAFDoc_ShapeTool::GetReferredShape (aL, aRefLabel)) {
111         DisplayText (aRefLabel, aPrs, anAspect, aLoc);
112       }
113     }
114   }
115 }
116
117 //=======================================================================
118 //function : DispatchStyles
119 //purpose  :
120 //=======================================================================
121 void XCAFPrs_AISObject::DispatchStyles (const Standard_Boolean theToSyncStyles)
122 {
123   myToSyncStyles = theToSyncStyles;
124   myShapeColors.Clear();
125
126   TopoDS_Shape aShape;
127   if (!XCAFDoc_ShapeTool::GetShape (myLabel, aShape) || aShape.IsNull())
128   {
129     Set (TopoDS_Shape());
130     return;
131   }
132   Set (aShape);
133
134   // Collecting information on colored subshapes
135   TopLoc_Location aLoc;
136   XCAFPrs_IndexedDataMapOfShapeStyle aSettings;
137   XCAFPrs::CollectStyleSettings (myLabel, aLoc, aSettings);
138
139   // Getting default colors
140   XCAFPrs_Style aDefStyle;
141   DefaultStyle (aDefStyle);
142   setStyleToDrawer (myDrawer, aDefStyle, aDefStyle, myDrawer->ShadingAspect()->Aspect()->FrontMaterial());
143
144   // collect sub-shapes with the same style into compounds
145   BRep_Builder aBuilder;
146   NCollection_IndexedDataMap<XCAFPrs_Style, TopoDS_Compound, XCAFPrs_Style> aStyleGroups;
147   for (XCAFPrs_DataMapIteratorOfIndexedDataMapOfShapeStyle aStyledShapeIter (aSettings);
148        aStyledShapeIter.More(); aStyledShapeIter.Next())
149   {
150     TopoDS_Compound aComp;
151     if (aStyleGroups.FindFromKey (aStyledShapeIter.Value(), aComp))
152     {
153       aBuilder.Add (aComp, aStyledShapeIter.Key());
154       continue;
155     }
156
157     aBuilder.MakeCompound (aComp);
158     aBuilder.Add (aComp, aStyledShapeIter.Key());
159     TopoDS_Compound* aMapShape = aStyleGroups.ChangeSeek (aStyledShapeIter.Value());
160     if (aMapShape == NULL)
161       aStyleGroups.Add (aStyledShapeIter.Value(), aComp);
162     else
163       *aMapShape = aComp;
164   }
165   aSettings.Clear();
166
167   // assign custom aspects
168   for (NCollection_IndexedDataMap<XCAFPrs_Style, TopoDS_Compound, XCAFPrs_Style>::Iterator aStyleGroupIter (aStyleGroups);
169        aStyleGroupIter.More(); aStyleGroupIter.Next())
170   {
171     const TopoDS_Compound& aComp = aStyleGroupIter.Value();
172     TopoDS_Iterator aShapeIter (aComp);
173     TopoDS_Shape aShapeCur = aShapeIter.Value();
174     aShapeIter.Next();
175     if (aShapeIter.More())
176     {
177       aShapeCur = aComp;
178     }
179
180     Handle(AIS_ColoredDrawer) aDrawer = new AIS_ColoredDrawer (myDrawer);
181     myShapeColors.Bind (aShapeCur, aDrawer);
182     const XCAFPrs_Style& aStyle = aStyleGroupIter.Key();
183     aDrawer->SetHidden (!aStyle.IsVisible());
184     if (!aStyle.Material().IsNull()
185      && !aStyle.Material()->IsEmpty())
186     {
187       aDrawer->SetOwnMaterial();
188     }
189     if (aStyle.IsSetColorSurf()
190      || aStyle.IsSetColorCurv())
191     {
192       aDrawer->SetOwnColor (Quantity_Color());
193     }
194     setStyleToDrawer (aDrawer, aStyle, aDefStyle, myDrawer->ShadingAspect()->Aspect()->FrontMaterial());
195   }
196   aStyleGroups.Clear();
197 }
198
199 //=======================================================================
200 //function : Compute
201 //purpose  :
202 //=======================================================================
203 void XCAFPrs_AISObject::Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
204                                  const Handle(Prs3d_Presentation)&           thePrs,
205                                  const Standard_Integer                      theMode)
206 {
207   // update shape and sub-shapes styles only on first compute, or on first recompute
208   if (myToSyncStyles)
209   {
210     Standard_Boolean toMapStyles = myToSyncStyles;
211     for (PrsMgr_Presentations::Iterator aPrsIter (myPresentations); aPrsIter.More(); aPrsIter.Next())
212     {
213       if (aPrsIter.Value() != thePrs
214       && !aPrsIter.Value()->MustBeUpdated())
215       {
216         toMapStyles = Standard_False;
217         break;
218       }
219     }
220     if (toMapStyles)
221     {
222       DispatchStyles (Standard_True);
223     }
224   }
225   if (myshape.IsNull())
226   {
227     return;
228   }
229
230   if (myshape.ShapeType() == TopAbs_COMPOUND)
231   {
232     if (myshape.NbChildren() == 0)
233     {
234       return;
235     }
236   }
237
238   AIS_ColoredShape::Compute (thePresentationManager, thePrs, theMode);
239
240   if (XCAFPrs::GetViewNameMode())
241   {
242     // Displaying Name attributes
243     thePrs->SetDisplayPriority (10);
244     DisplayText (myLabel, thePrs, Attributes()->DimensionAspect()->TextAspect(), TopLoc_Location());//no location
245   }
246 }
247
248 //=======================================================================
249 //function : setStyleToDrawer
250 //purpose  :
251 //=======================================================================
252 void XCAFPrs_AISObject::setStyleToDrawer (const Handle(Prs3d_Drawer)& theDrawer,
253                                           const XCAFPrs_Style& theStyle,
254                                           const XCAFPrs_Style& theDefStyle,
255                                           const Graphic3d_MaterialAspect& theDefMaterial)
256 {
257   theDrawer->SetupOwnShadingAspect();
258   theDrawer->SetOwnLineAspects();
259
260   Quantity_ColorRGBA aSurfColor = theDefStyle.GetColorSurfRGBA();
261   Quantity_Color     aCurvColor = theDefStyle.GetColorCurv();
262   Graphic3d_MaterialAspect aMaterial = theDefMaterial;
263   const Handle(XCAFDoc_VisMaterial)& anXMat = !theStyle.Material().IsNull() ? theStyle.Material() : theDefStyle.Material();
264   if (!anXMat.IsNull()
265    && !anXMat->IsEmpty())
266   {
267     anXMat->FillAspect (theDrawer->ShadingAspect()->Aspect());
268     aMaterial = theDrawer->ShadingAspect()->Aspect()->FrontMaterial();
269     aSurfColor = Quantity_ColorRGBA (aMaterial.Color(), aMaterial.Alpha());
270     aCurvColor = aMaterial.Color();
271   }
272   if (theStyle.IsSetColorSurf())
273   {
274     aSurfColor = theStyle.GetColorSurfRGBA();
275     aMaterial.SetColor (aSurfColor.GetRGB());
276     aMaterial.SetAlpha (aSurfColor.Alpha());
277   }
278   if (theStyle.IsSetColorCurv())
279   {
280     aCurvColor = theStyle.GetColorCurv();
281   }
282
283   theDrawer->UnFreeBoundaryAspect()->SetColor (aCurvColor);
284   theDrawer->FreeBoundaryAspect()->SetColor (aCurvColor);
285   theDrawer->WireAspect()->SetColor (aCurvColor);
286
287   theDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aSurfColor);
288   theDrawer->ShadingAspect()->Aspect()->SetFrontMaterial (aMaterial);
289   theDrawer->UIsoAspect()->SetColor (aSurfColor.GetRGB());
290   theDrawer->VIsoAspect()->SetColor (aSurfColor.GetRGB());
291 }
292
293 //=======================================================================
294 //function : DefaultStyle
295 //purpose  : DefaultStyle() can be redefined by subclasses in order to set custom default style
296 //=======================================================================
297 void XCAFPrs_AISObject::DefaultStyle (XCAFPrs_Style& theStyle) const
298 {
299   theStyle.SetColorSurf (Quantity_NOC_WHITE);
300   theStyle.SetColorCurv (Quantity_NOC_WHITE);
301 }
302
303 // =======================================================================
304 // function : SetMaterial
305 // purpose  :
306 // =======================================================================
307 void XCAFPrs_AISObject::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
308 {
309   XCAFPrs_Style aDefStyle;
310   DefaultStyle (aDefStyle);
311   setMaterial (myDrawer, theMaterial, HasColor(), IsTransparent());
312   setStyleToDrawer (myDrawer, aDefStyle, aDefStyle, myDrawer->ShadingAspect()->Aspect()->FrontMaterial());
313   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
314   {
315     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
316     if (aDrawer->HasOwnMaterial())
317     {
318       continue;
319     }
320
321     if (aDrawer->HasOwnShadingAspect())
322     {
323       // take current color
324       const Quantity_ColorRGBA aSurfColor = aDrawer->ShadingAspect()->Aspect()->InteriorColorRGBA();
325       Graphic3d_MaterialAspect aMaterial = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
326       aMaterial.SetColor (aSurfColor.GetRGB());
327       aMaterial.SetAlpha (aSurfColor.Alpha());
328       aDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aSurfColor);
329       aDrawer->ShadingAspect()->Aspect()->SetFrontMaterial (aMaterial);
330     }
331   }
332   SynchronizeAspects();
333 }