46c7bf47852d07030507df247ad13d7bbeeaa438
[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 <Prs3d_Drawer.hxx>
25 #include <Prs3d_DimensionAspect.hxx>
26 #include <Prs3d_IsoAspect.hxx>
27 #include <Prs3d_LineAspect.hxx>
28 #include <Prs3d_ShadingAspect.hxx>
29 #include <Prs3d_Text.hxx>
30 #include <TDataStd_Name.hxx>
31 #include <TDF_LabelSequence.hxx>
32 #include <TPrsStd_AISPresentation.hxx>
33 #include <TopoDS_Iterator.hxx>
34 #include <XCAFDoc_ShapeTool.hxx>
35 #include <XCAFPrs.hxx>
36 #include <XCAFPrs_IndexedDataMapOfShapeStyle.hxx>
37 #include <XCAFPrs_DataMapIteratorOfIndexedDataMapOfShapeStyle.hxx>
38 #include <XCAFPrs_Style.hxx>
39
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   Quantity_Color aColorCurv = aDefStyle.GetColorCurv();
143   Quantity_ColorRGBA aColorSurf = aDefStyle.GetColorSurfRGBA();
144
145   SetColors (myDrawer, aColorCurv, aColorSurf);
146
147   // collect sub-shapes with the same style into compounds
148   BRep_Builder aBuilder;
149   NCollection_IndexedDataMap<XCAFPrs_Style, TopoDS_Compound, XCAFPrs_Style> aStyleGroups;
150   for (XCAFPrs_DataMapIteratorOfIndexedDataMapOfShapeStyle aStyledShapeIter (aSettings);
151        aStyledShapeIter.More(); aStyledShapeIter.Next())
152   {
153     TopoDS_Compound aComp;
154     if (aStyleGroups.FindFromKey (aStyledShapeIter.Value(), aComp))
155     {
156       aBuilder.Add (aComp, aStyledShapeIter.Key());
157       continue;
158     }
159
160     aBuilder.MakeCompound (aComp);
161     aBuilder.Add (aComp, aStyledShapeIter.Key());
162     TopoDS_Compound* aMapShape = aStyleGroups.ChangeSeek (aStyledShapeIter.Value());
163     if (aMapShape == NULL)
164       aStyleGroups.Add (aStyledShapeIter.Value(), aComp);
165     else
166       *aMapShape = aComp;
167   }
168   aSettings.Clear();
169
170   // assign custom aspects
171   for (NCollection_IndexedDataMap<XCAFPrs_Style, TopoDS_Compound, XCAFPrs_Style>::Iterator aStyleGroupIter (aStyleGroups);
172        aStyleGroupIter.More(); aStyleGroupIter.Next())
173   {
174     const TopoDS_Compound& aComp = aStyleGroupIter.Value();
175     TopoDS_Iterator aShapeIter (aComp);
176     TopoDS_Shape aShapeCur = aShapeIter.Value();
177     aShapeIter.Next();
178     if (aShapeIter.More())
179     {
180       aShapeCur = aComp;
181     }
182
183     Handle(AIS_ColoredDrawer) aDrawer = new AIS_ColoredDrawer (myDrawer);
184     myShapeColors.Bind (aShapeCur, aDrawer);
185     const XCAFPrs_Style& aStyle = aStyleGroupIter.Key();
186     aDrawer->SetHidden (!aStyle.IsVisible());
187
188     aColorCurv = aStyle.IsSetColorCurv() ? aStyle.GetColorCurv()     : aDefStyle.GetColorCurv();
189     aColorSurf = aStyle.IsSetColorSurf() ? aStyle.GetColorSurfRGBA() : aDefStyle.GetColorSurfRGBA();
190
191     SetColors (aDrawer, aColorCurv, aColorSurf);
192   }
193   aStyleGroups.Clear();
194 }
195
196 //=======================================================================
197 //function : Compute
198 //purpose  :
199 //=======================================================================
200 void XCAFPrs_AISObject::Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
201                                  const Handle(Prs3d_Presentation)&           thePrs,
202                                  const Standard_Integer                      theMode)
203 {
204   // update shape and sub-shapes styles only on first compute, or on first recompute
205   if (myToSyncStyles)
206   {
207     Standard_Boolean toMapStyles = myToSyncStyles;
208     for (PrsMgr_Presentations::Iterator aPrsIter (myPresentations); aPrsIter.More(); aPrsIter.Next())
209     {
210       if (aPrsIter.Value().Presentation()->Presentation() != thePrs
211       && !aPrsIter.Value().Presentation()->MustBeUpdated())
212       {
213         toMapStyles = Standard_False;
214         break;
215       }
216     }
217     if (toMapStyles)
218     {
219       DispatchStyles (Standard_True);
220     }
221   }
222   if (myshape.IsNull())
223   {
224     return;
225   }
226
227   if (myshape.ShapeType() == TopAbs_COMPOUND)
228   {
229     if (myshape.NbChildren() == 0)
230     {
231       return;
232     }
233   }
234
235   AIS_ColoredShape::Compute (thePresentationManager, thePrs, theMode);
236
237   if (XCAFPrs::GetViewNameMode())
238   {
239     // Displaying Name attributes
240     thePrs->SetDisplayPriority (10);
241     DisplayText (myLabel, thePrs, Attributes()->DimensionAspect()->TextAspect(), TopLoc_Location());//no location
242   }
243 }
244
245 //=======================================================================
246 //function : SetColors
247 //purpose  :
248 //=======================================================================
249 void XCAFPrs_AISObject::SetColors (const Handle(Prs3d_Drawer)& theDrawer,
250                                    const Quantity_Color&       theColorCurv,
251                                    const Quantity_ColorRGBA&   theColorSurf)
252 {
253   if (!theDrawer->HasOwnShadingAspect())
254   {
255     theDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
256     if (theDrawer->HasLink())
257     {
258       *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect();
259     }
260   }
261   if (!theDrawer->HasOwnLineAspect())
262   {
263     theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
264     if (theDrawer->HasLink())
265     {
266       *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
267     }
268   }
269   if (!theDrawer->HasOwnWireAspect())
270   {
271     theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
272     if (theDrawer->HasLink())
273     {
274       *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
275     }
276   }
277   if (!theDrawer->HasOwnUIsoAspect())
278   {
279     theDrawer->SetUIsoAspect (new Prs3d_IsoAspect (Quantity_NOC_GRAY75, Aspect_TOL_SOLID, 0.5, 1));
280     if (theDrawer->HasLink())
281     {
282       *theDrawer->UIsoAspect()->Aspect() = *theDrawer->Link()->UIsoAspect()->Aspect();
283       theDrawer->UIsoAspect()->SetNumber (theDrawer->Link()->UIsoAspect()->Number());
284     }
285   }
286   if (!theDrawer->HasOwnVIsoAspect())
287   {
288     theDrawer->SetVIsoAspect (new Prs3d_IsoAspect (Quantity_NOC_GRAY75, Aspect_TOL_SOLID, 0.5, 1));
289     if (theDrawer->HasLink())
290     {
291       *theDrawer->VIsoAspect()->Aspect() = *theDrawer->Link()->VIsoAspect()->Aspect();
292       theDrawer->VIsoAspect()->SetNumber (theDrawer->Link()->VIsoAspect()->Number());
293     }
294   }
295   if (!theDrawer->HasOwnFreeBoundaryAspect())
296   {
297     theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
298     if (theDrawer->HasLink())
299     {
300       *theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
301     }
302   }
303   if (!theDrawer->HasOwnUnFreeBoundaryAspect())
304   {
305     theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
306     if (theDrawer->HasLink())
307     {
308       *theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
309     }
310   }
311
312   theDrawer->UnFreeBoundaryAspect()->SetColor (theColorCurv);
313   theDrawer->FreeBoundaryAspect()->SetColor (theColorCurv);
314   theDrawer->WireAspect()->SetColor (theColorCurv);
315
316   Graphic3d_MaterialAspect aMaterial = myDrawer->ShadingAspect()->Aspect()->FrontMaterial();
317   aMaterial.SetColor (theColorSurf.GetRGB());
318   aMaterial.SetAlpha (theColorSurf.Alpha());
319   theDrawer->ShadingAspect()->Aspect()->SetInteriorColor (theColorSurf);
320   theDrawer->ShadingAspect()->Aspect()->SetFrontMaterial (aMaterial);
321   theDrawer->UIsoAspect()->SetColor (theColorSurf.GetRGB());
322   theDrawer->VIsoAspect()->SetColor (theColorSurf.GetRGB());
323 }
324
325 //=======================================================================
326 //function : DefaultStyle
327 //purpose  : DefaultStyle() can be redefined by subclasses in order to set custom default style
328 //=======================================================================
329 void XCAFPrs_AISObject::DefaultStyle (XCAFPrs_Style& theStyle) const
330 {
331   theStyle.SetColorSurf (Quantity_NOC_WHITE);
332   theStyle.SetColorCurv (Quantity_NOC_WHITE);
333 }
334
335 // =======================================================================
336 // function : SetMaterial
337 // purpose  :
338 // =======================================================================
339 void XCAFPrs_AISObject::SetMaterial (const Graphic3d_MaterialAspect& theMaterial)
340 {
341   XCAFPrs_Style aDefStyle;
342   DefaultStyle (aDefStyle);
343   setMaterial (myDrawer, theMaterial, HasColor(), IsTransparent());
344   SetColors (myDrawer, aDefStyle.GetColorCurv(), aDefStyle.GetColorSurf());
345   for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next())
346   {
347     const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value();
348
349     // take current color
350     const Quantity_Color     aColorCurv = aDrawer->WireAspect()->Aspect()->Color();
351     const Quantity_ColorRGBA aSurfColor = aDrawer->ShadingAspect()->Aspect()->InteriorColorRGBA();
352
353     // SetColors() will take the material from myDrawer
354     SetColors (aDrawer, aColorCurv, aSurfColor);
355   }
356   SynchronizeAspects();
357 }