0029570: Visualization, Graphic3d_Aspect - merge Graphic3d_Group aspects
[occt.git] / src / AIS / AIS_TexturedShape.cxx
1 // Created on: 2001-07-02
2 // Created by: Mathias BOSSHARD
3 // Copyright (c) 2001-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 <AIS_TexturedShape.hxx>
17
18 #include <AIS_GraphicTool.hxx>
19 #include <AIS_InteractiveContext.hxx>
20 #include <BRepTools.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <Graphic3d_AspectFillArea3d.hxx>
23 #include <Graphic3d_Group.hxx>
24 #include <Graphic3d_StructureManager.hxx>
25 #include <Graphic3d_Texture2Dmanual.hxx>
26 #include <Message.hxx>
27 #include <Message_Messenger.hxx>
28 #include <Precision.hxx>
29 #include <Prs3d_Drawer.hxx>
30 #include <Prs3d_Presentation.hxx>
31 #include <PrsMgr_ModedPresentation.hxx>
32 #include <Prs3d_Root.hxx>
33 #include <Prs3d_LineAspect.hxx>
34 #include <Prs3d_ShadingAspect.hxx>
35 #include <PrsMgr_PresentationManager3d.hxx>
36 #include <Standard_ErrorHandler.hxx>
37 #include <StdPrs_BndBox.hxx>
38 #include <StdPrs_ShadedShape.hxx>
39 #include <StdPrs_ToolTriangulatedShape.hxx>
40 #include <StdPrs_WFShape.hxx>
41 #include <TopExp_Explorer.hxx>
42
43
44 IMPLEMENT_STANDARD_RTTIEXT(AIS_TexturedShape,AIS_Shape)
45
46 //=======================================================================
47 //function : AIS_TexturedShape
48 //purpose  :
49 //=======================================================================
50 AIS_TexturedShape::AIS_TexturedShape (const TopoDS_Shape& theShape)
51 : AIS_Shape         (theShape),
52   myPredefTexture   (Graphic3d_NameOfTexture2D(0)),
53   myToMapTexture    (Standard_True),
54   myModulate        (Standard_True),
55   myIsCustomOrigin  (Standard_True),
56   myToRepeat        (Standard_True),
57   myToScale         (Standard_True),
58   myToShowTriangles (Standard_False)
59 {
60 }
61
62 //=======================================================================
63 //function : SetTextureFileName
64 //purpose  :
65 //=======================================================================
66 void AIS_TexturedShape::SetTextureFileName (const TCollection_AsciiString& theTextureFileName)
67 {
68   myTexturePixMap.Nullify();
69
70   if (theTextureFileName.IsIntegerValue())
71   {
72     const Standard_Integer aValue = theTextureFileName.IntegerValue();
73     if (aValue < Graphic3d_Texture2D::NumberOfTextures()
74      && aValue >= 0)
75     {
76       myPredefTexture = Graphic3d_NameOfTexture2D (aValue);
77     }
78     else
79     {
80       Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: texture with ID ") + theTextureFileName
81                                        + " is undefined! Texture 0 will be used instead.", Message_Fail);
82       myPredefTexture = Graphic3d_NameOfTexture2D (0);
83     }
84     myTextureFile = "";
85   }
86   else
87   {
88     myTextureFile   = theTextureFileName;
89     myPredefTexture = Graphic3d_NOT_2D_UNKNOWN;
90   }
91 }
92
93 //=======================================================================
94 //function : SetTexturePixMap
95 //purpose  :
96 //=======================================================================
97 void AIS_TexturedShape::SetTexturePixMap (const Handle(Image_PixMap)& theTexturePixMap)
98 {
99   myTextureFile = "";
100   myPredefTexture = Graphic3d_NOT_2D_UNKNOWN;
101   myTexturePixMap = theTexturePixMap;
102 }
103
104 //=======================================================================
105 //function : SetTextureRepeat
106 //purpose  :
107 //=======================================================================
108
109 void AIS_TexturedShape::SetTextureRepeat (const Standard_Boolean theToRepeat,
110                                           const Standard_Real    theURepeat,
111                                           const Standard_Real    theVRepeat)
112 {
113   myToRepeat = theToRepeat;
114   myUVRepeat.SetCoord (theURepeat, theVRepeat);
115 }
116
117 //=======================================================================
118 //function : SetTextureMapOn
119 //purpose  :
120 //=======================================================================
121
122 void AIS_TexturedShape::SetTextureMapOn()
123 {
124   myToMapTexture = Standard_True;
125 }
126
127 //=======================================================================
128 //function : SetTextureMapOff
129 //purpose  :
130 //=======================================================================
131
132 void AIS_TexturedShape::SetTextureMapOff()
133 {
134   myToMapTexture = Standard_False;
135 }
136
137 //=======================================================================
138 //function : SetTextureOrigin
139 //purpose  :
140 //=======================================================================
141
142 void AIS_TexturedShape::SetTextureOrigin (const Standard_Boolean theToSetTextureOrigin,
143                                           const Standard_Real    theUOrigin,
144                                           const Standard_Real    theVOrigin)
145 {
146   myIsCustomOrigin = theToSetTextureOrigin;
147   myUVOrigin.SetCoord (theUOrigin, theVOrigin);
148 }
149
150 //=======================================================================
151 //function : SetTextureScale
152 //purpose  :
153 //=======================================================================
154
155 void AIS_TexturedShape::SetTextureScale (const Standard_Boolean theToSetTextureScale,
156                                          const Standard_Real    theScaleU,
157                                          const Standard_Real    theScaleV)
158 {
159   myToScale = theToSetTextureScale;
160   myUVScale.SetCoord (theScaleU, theScaleV);
161 }
162
163 //=======================================================================
164 //function : ShowTriangles
165 //purpose  :
166 //=======================================================================
167
168 void AIS_TexturedShape::ShowTriangles (const Standard_Boolean theToShowTriangles)
169 {
170   myToShowTriangles = theToShowTriangles;
171 }
172
173 //=======================================================================
174 //function : EnableTextureModulate
175 //purpose  :
176 //=======================================================================
177
178 void AIS_TexturedShape::EnableTextureModulate()
179 {
180   myModulate = Standard_True;
181 }
182
183 //=======================================================================
184 //function : DisableTextureModulate
185 //purpose  :
186 //=======================================================================
187
188 void AIS_TexturedShape::DisableTextureModulate()
189 {
190   myModulate = Standard_False;
191 }
192
193 //=======================================================================
194 //function : SetColor
195 //purpose  :
196 //=======================================================================
197
198 void AIS_TexturedShape::SetColor (const Quantity_Color& theColor)
199 {
200   AIS_Shape::SetColor (theColor);
201
202   for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt)
203   {
204     const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt);
205
206     if (aPrsModed.Mode() != 3)
207       continue;
208
209     updateAttributes (aPrsModed.Presentation()->Presentation());
210   }
211 }
212
213 //=======================================================================
214 //function : UnsetColor
215 //purpose  :
216 //=======================================================================
217
218 void AIS_TexturedShape::UnsetColor()
219 {
220   AIS_Shape::UnsetColor();
221 }
222
223 //=======================================================================
224 //function : SetMaterial
225 //purpose  : 
226 //=======================================================================
227
228 void AIS_TexturedShape::SetMaterial (const Graphic3d_MaterialAspect& theMat)
229 {
230   AIS_Shape::SetMaterial (theMat);
231
232   for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt)
233   {
234     const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt);
235     
236     if (aPrsModed.Mode() != 3)
237       continue;
238     
239     updateAttributes (aPrsModed.Presentation()->Presentation());
240   }
241 }
242
243 //=======================================================================
244 //function : UnsetMaterial
245 //purpose  : 
246 //=======================================================================
247 void AIS_TexturedShape::UnsetMaterial()
248 {
249   AIS_Shape::UnsetMaterial();
250
251   for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt)
252   {
253     const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt);
254
255     if (aPrsModed.Mode() != 3)
256       continue;
257
258     updateAttributes (aPrsModed.Presentation()->Presentation());
259   }
260 }
261
262 //=======================================================================
263 //function : UpdateAttributes
264 //purpose  :
265 //=======================================================================
266
267 void AIS_TexturedShape::UpdateAttributes()
268 {
269   updateAttributes (Presentation());
270 }
271
272 //=======================================================================
273 //function : updateAttributes
274 //purpose  :
275 //=======================================================================
276
277 void AIS_TexturedShape::updateAttributes (const Handle(Prs3d_Presentation)& thePrs)
278 {
279   myAspect = new Graphic3d_AspectFillArea3d (*myDrawer->ShadingAspect()->Aspect());
280   if (HasPolygonOffsets())
281   {
282     Standard_Integer aMode;
283     Standard_ShortReal aFactor, aUnits;
284     PolygonOffsets (aMode, aFactor, aUnits);
285     myAspect->SetPolygonOffsets (aMode, aFactor, aUnits);
286   }
287
288   Standard_Boolean hasTexture = Standard_False;
289   if (myToMapTexture)
290   {
291     TCollection_AsciiString aTextureDesc;
292     if (!myTexturePixMap.IsNull())
293     {
294       myTexture = new Graphic3d_Texture2Dmanual (myTexturePixMap);
295       aTextureDesc = " (custom image)";
296     }
297     else if (myPredefTexture != Graphic3d_NOT_2D_UNKNOWN)
298     {
299       myTexture = new Graphic3d_Texture2Dmanual (myPredefTexture);
300       aTextureDesc = TCollection_AsciiString(" (predefined texture ") + myTexture->GetId() + ")";
301     }
302     else
303     {
304       myTexture = new Graphic3d_Texture2Dmanual (myTextureFile.ToCString());
305       aTextureDesc = TCollection_AsciiString(" (") + myTextureFile + ")";
306     }
307
308     if (myModulate)
309     {
310       myTexture->EnableModulate();
311     }
312     else
313     {
314       myTexture->DisableModulate();
315     }
316
317     if (myTexture->IsDone())
318     {
319       hasTexture = Standard_True;
320     }
321     else
322     {
323       Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: texture can not be loaded ") + aTextureDesc, Message_Fail);
324     }
325   }
326
327   myAspect->SetTextureMap (myTexture);
328   if (hasTexture)
329   {
330     myAspect->SetTextureMapOn();
331   }
332   else
333   {
334     myAspect->SetTextureMapOff();
335   }
336
337   if (myToShowTriangles)
338   {
339     myAspect->SetEdgeOn();
340   }
341   else
342   {
343     myAspect->SetEdgeOff();
344   }
345
346   // Go through all groups to change fill aspect for all primitives
347   for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (thePrs->Groups()); aGroupIt.More(); aGroupIt.Next())
348   {
349     const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
350     aGroup->SetGroupPrimitivesAspect (myAspect);
351   }
352 }
353
354 //=======================================================================
355 //function : Compute
356 //purpose  :
357 //=======================================================================
358
359 void AIS_TexturedShape::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
360                                  const Handle(Prs3d_Presentation)&           thePrs,
361                                  const Standard_Integer                      theMode)
362 {
363   if (myshape.IsNull())
364   {
365     return;
366   }
367
368   if (myshape.ShapeType() > TopAbs_FACE && myshape.ShapeType() < TopAbs_SHAPE)
369   {
370     thePrs->SetVisual (Graphic3d_TOS_ALL);
371     thePrs->SetDisplayPriority (myshape.ShapeType() + 2);
372   }
373
374   if (myshape.ShapeType() == TopAbs_COMPOUND)
375   {
376     TopExp_Explorer anExplor (myshape, TopAbs_VERTEX);
377     if (!anExplor.More())
378     {
379       return;
380     }
381   }
382
383   if (IsInfinite())
384   {
385     thePrs->SetInfiniteState (Standard_True);
386   }
387
388   switch (theMode)
389   {
390     case AIS_WireFrame:
391     {
392       StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
393       StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
394       break;
395     }
396     case AIS_Shaded:
397     case 3: // texture mapping on triangulation
398     {
399       StdPrs_ToolTriangulatedShape::ClearOnOwnDeflectionChange (myshape, myDrawer, Standard_True);
400       if (myshape.ShapeType() > TopAbs_FACE)
401       {
402         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
403         break;
404       }
405
406       if (IsInfinite())
407       {
408         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
409         break;
410       }
411       try
412       {
413         OCC_CATCH_SIGNALS
414         if (theMode == AIS_Shaded)
415         {
416           StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer);
417         }
418         else
419         {
420           StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer,
421                                    Standard_True,
422                                    myIsCustomOrigin ? myUVOrigin : gp_Pnt2d (0.0, 0.0),
423                                    myUVRepeat,
424                                    myToScale        ? myUVScale  : gp_Pnt2d (1.0, 1.0));
425           updateAttributes (thePrs);
426         }
427       }
428       catch (Standard_Failure)
429       {
430 #ifdef OCCT_DEBUG
431         std::cout << "AIS_TexturedShape::Compute() in ShadingMode failed \n";
432 #endif
433         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
434       }
435       break;
436     }
437     case 2: // Bounding box
438     {
439       if (IsInfinite())
440       {
441         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
442       }
443       else
444       {
445         StdPrs_BndBox::Add (thePrs, BoundingBox(), myDrawer);
446       }
447       break;
448     }
449   }
450 }