0024622: Add method to AIS_TexturedShape class to assign texture data directly from...
[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_Drawer.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 <Precision.hxx>
27 #include <Prs3d_Presentation.hxx>
28 #include <Prs3d_Root.hxx>
29 #include <Prs3d_ShadingAspect.hxx>
30 #include <PrsMgr_PresentationManager3d.hxx>
31 #include <Standard_ErrorHandler.hxx>
32 #include <StdPrs_ShadedShape.hxx>
33 #include <StdPrs_WFDeflectionShape.hxx>
34 #include <StdPrs_WFShape.hxx>
35 #include <TopExp_Explorer.hxx>
36
37 IMPLEMENT_STANDARD_HANDLE (AIS_TexturedShape, AIS_Shape)
38 IMPLEMENT_STANDARD_RTTIEXT(AIS_TexturedShape, AIS_Shape)
39
40 //=======================================================================
41 //function : AIS_TexturedShape
42 //purpose  :
43 //=======================================================================
44 AIS_TexturedShape::AIS_TexturedShape (const TopoDS_Shape& theShape)
45 : AIS_Shape         (theShape),
46   myPredefTexture   (Graphic3d_NameOfTexture2D(0)),
47   myToMapTexture    (Standard_True),
48   myModulate        (Standard_True),
49   myUVOrigin        (0.0, 0.0),
50   myIsCustomOrigin  (Standard_True),
51   myUVRepeat        (1.0, 1.0),
52   myToRepeat        (Standard_True),
53   myUVScale         (1.0, 1.0),
54   myToScale         (Standard_True),
55   myToShowTriangles (Standard_False)
56 {
57 }
58
59 //=======================================================================
60 //function : SetTextureFileName
61 //purpose  :
62 //=======================================================================
63 void AIS_TexturedShape::SetTextureFileName (const TCollection_AsciiString& theTextureFileName)
64 {
65   myTexturePixMap.Nullify();
66
67   if (theTextureFileName.IsIntegerValue())
68   {
69     const Standard_Integer aValue = theTextureFileName.IntegerValue();
70     if (aValue < Graphic3d_Texture2D::NumberOfTextures()
71      && aValue >= 0)
72     {
73       myPredefTexture = Graphic3d_NameOfTexture2D (aValue);
74     }
75     else
76     {
77       std::cout << "Texture " << theTextureFileName << " doesn't exist\n";
78       std::cout << "Using Texture 0 instead ...\n";
79       myPredefTexture = Graphic3d_NameOfTexture2D (0);
80     }
81     myTextureFile = "";
82   }
83   else
84   {
85     myTextureFile   = theTextureFileName;
86     myPredefTexture = Graphic3d_NOT_2D_UNKNOWN;
87   }
88 }
89
90 //=======================================================================
91 //function : SetTexturePixMap
92 //purpose  :
93 //=======================================================================
94 void AIS_TexturedShape::SetTexturePixMap (const Handle(Image_PixMap)& theTexturePixMap)
95 {
96   myTextureFile = "";
97   myPredefTexture = Graphic3d_NOT_2D_UNKNOWN;
98   myTexturePixMap = theTexturePixMap;
99 }
100
101 //=======================================================================
102 //function : SetTextureRepeat
103 //purpose  :
104 //=======================================================================
105
106 void AIS_TexturedShape::SetTextureRepeat (const Standard_Boolean theToRepeat,
107                                           const Standard_Real    theURepeat,
108                                           const Standard_Real    theVRepeat)
109 {
110   myToRepeat = theToRepeat;
111   myUVRepeat.SetCoord (theURepeat, theVRepeat);
112 }
113
114 //=======================================================================
115 //function : SetTextureMapOn
116 //purpose  :
117 //=======================================================================
118
119 void AIS_TexturedShape::SetTextureMapOn()
120 {
121   myToMapTexture = Standard_True;
122 }
123
124 //=======================================================================
125 //function : SetTextureMapOff
126 //purpose  :
127 //=======================================================================
128
129 void AIS_TexturedShape::SetTextureMapOff()
130 {
131   myToMapTexture = Standard_False;
132 }
133
134 //=======================================================================
135 //function : SetTextureOrigin
136 //purpose  :
137 //=======================================================================
138
139 void AIS_TexturedShape::SetTextureOrigin (const Standard_Boolean theToSetTextureOrigin,
140                                           const Standard_Real    theUOrigin,
141                                           const Standard_Real    theVOrigin)
142 {
143   myIsCustomOrigin = theToSetTextureOrigin;
144   myUVOrigin.SetCoord (theUOrigin, theVOrigin);
145 }
146
147 //=======================================================================
148 //function : SetTextureScale
149 //purpose  :
150 //=======================================================================
151
152 void AIS_TexturedShape::SetTextureScale (const Standard_Boolean theToSetTextureScale,
153                                          const Standard_Real    theScaleU,
154                                          const Standard_Real    theScaleV)
155 {
156   myToScale = theToSetTextureScale;
157   myUVScale.SetCoord (theScaleU, theScaleV);
158 }
159
160 //=======================================================================
161 //function : ShowTriangles
162 //purpose  :
163 //=======================================================================
164
165 void AIS_TexturedShape::ShowTriangles (const Standard_Boolean theToShowTriangles)
166 {
167   myToShowTriangles = theToShowTriangles;
168 }
169
170 //=======================================================================
171 //function : EnableTextureModulate
172 //purpose  :
173 //=======================================================================
174
175 void AIS_TexturedShape::EnableTextureModulate()
176 {
177   myModulate = Standard_True;
178 }
179
180 //=======================================================================
181 //function : DisableTextureModulate
182 //purpose  :
183 //=======================================================================
184
185 void AIS_TexturedShape::DisableTextureModulate()
186 {
187   myModulate = Standard_False;
188 }
189
190 //=======================================================================
191 //function : UpdateAttributes
192 //purpose  :
193 //=======================================================================
194
195 void AIS_TexturedShape::UpdateAttributes()
196 {
197   Prs3d_ShadingAspect aDummy;
198   myAspect = aDummy.Aspect();
199   Handle(Prs3d_Presentation) aPrs = Presentation();
200   if (!myToMapTexture)
201   {
202     myAspect->SetTextureMapOff();
203     return;
204   }
205
206   if (!myTexturePixMap.IsNull())
207   {
208     myTexture = new Graphic3d_Texture2Dmanual (myTexturePixMap);
209   }
210   else if (myPredefTexture != Graphic3d_NOT_2D_UNKNOWN)
211   {
212     myTexture = new Graphic3d_Texture2Dmanual (myPredefTexture);
213   }
214   else
215   {
216     myTexture = new Graphic3d_Texture2Dmanual (myTextureFile.ToCString());
217   }
218
219   myAspect->SetTextureMapOn();
220
221   myAspect->SetTextureMap (myTexture);
222   if (!myTexture->IsDone())
223   {
224     std::cout << "An error occurred while building texture \n";
225     return;
226   }
227
228   if (myToShowTriangles)
229     myAspect->SetEdgeOn();
230   else
231     myAspect->SetEdgeOff();
232
233   Prs3d_Root::CurrentGroup (aPrs)->SetGroupPrimitivesAspect (myAspect);
234 }
235
236 //=======================================================================
237 //function : Compute
238 //purpose  :
239 //=======================================================================
240
241 void AIS_TexturedShape::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
242                                  const Handle(Prs3d_Presentation)&           thePrs,
243                                  const Standard_Integer                      theMode)
244 {
245   thePrs->Clear();
246
247   if (myshape.IsNull())
248   {
249     return;
250   }
251
252   if (myshape.ShapeType() > TopAbs_FACE && myshape.ShapeType() < TopAbs_SHAPE)
253   {
254     thePrs->SetVisual (Graphic3d_TOS_ALL);
255     thePrs->SetDisplayPriority (myshape.ShapeType() + 2);
256   }
257
258   if (myshape.ShapeType() == TopAbs_COMPOUND)
259   {
260     TopExp_Explorer anExplor (myshape, TopAbs_VERTEX);
261     if (!anExplor.More())
262     {
263       return;
264     }
265   }
266
267   if (IsInfinite())
268   {
269     thePrs->SetInfiniteState (Standard_True);
270   }
271
272   switch (theMode)
273   {
274     case AIS_WireFrame:
275     {
276       StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
277       break;
278     }
279     case AIS_Shaded:
280     {
281       Standard_Real prevangle;
282       Standard_Real newangle;
283       Standard_Real prevcoeff;
284       Standard_Real newcoeff;
285
286       Standard_Boolean isOwnDeviationAngle = OwnDeviationAngle(newangle,prevangle);
287       Standard_Boolean isOwnDeviationCoefficient = OwnDeviationCoefficient(newcoeff,prevcoeff);
288       if (((Abs (newangle - prevangle) > Precision::Angular()) && isOwnDeviationAngle) ||
289           ((Abs (newcoeff - prevcoeff) > Precision::Confusion()) && isOwnDeviationCoefficient)) {
290         BRepTools::Clean (myshape);
291       }
292       if (myshape.ShapeType() > TopAbs_FACE)
293       {
294         StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
295         break;
296       }
297       myDrawer->SetShadingAspectGlobal (Standard_False);
298       if (IsInfinite())
299       {
300         StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
301         break;
302       }
303       try
304       {
305         OCC_CATCH_SIGNALS
306         StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer);
307       }
308       catch (Standard_Failure)
309       {
310         std::cout << "AIS_TexturedShape::Compute() in ShadingMode failed \n";
311         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
312       }
313       break;
314     }
315     case 2: // Bounding box
316     {
317       if (IsInfinite())
318       {
319         StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
320       }
321       else
322       {
323         AIS_Shape::DisplayBox (thePrs, BoundingBox(), myDrawer);
324       }
325       break;
326     }
327     case 3: // texture mapping on triangulation
328     {
329       BRepTools::Clean  (myshape);
330       BRepTools::Update (myshape);
331
332       {
333         Handle(Prs3d_ShadingAspect) aPrs3d_ShadingAspect = new Prs3d_ShadingAspect();
334         myAspect = aPrs3d_ShadingAspect->Aspect();
335
336         // Issue 23115: copy polygon offset settings passed through myDrawer
337         if (HasPolygonOffsets())
338         {
339           Standard_Integer aMode;
340           Standard_ShortReal aFactor, aUnits;
341           PolygonOffsets(aMode, aFactor, aUnits);
342           myAspect->SetPolygonOffsets(aMode, aFactor, aUnits);
343         }
344       }
345       if (!myToMapTexture)
346       {
347         myAspect->SetTextureMapOff();
348         return;
349       }
350       myAspect->SetTextureMapOn();
351
352       if (!myTexturePixMap.IsNull())
353       {
354         myTexture = new Graphic3d_Texture2Dmanual (myTexturePixMap);
355       }
356       else if (myPredefTexture != Graphic3d_NOT_2D_UNKNOWN)
357       {
358         myTexture = new Graphic3d_Texture2Dmanual (myPredefTexture);
359       }
360       else
361       {
362         myTexture = new Graphic3d_Texture2Dmanual (myTextureFile.ToCString());
363       }
364
365       if (!myTexture->IsDone())
366       {
367         std::cout << "An error occurred while building texture \n";
368         return;
369       }
370
371       if (myModulate)
372         myTexture->EnableModulate();
373       else
374         myTexture->DisableModulate();
375
376       myAspect->SetTextureMap (myTexture);
377       if (myToShowTriangles)
378         myAspect->SetEdgeOn();
379       else
380         myAspect->SetEdgeOff();
381
382       if (myToRepeat)
383         myTexture->EnableRepeat();
384       else
385         myTexture->DisableRepeat();
386
387       try
388       {
389         OCC_CATCH_SIGNALS
390         StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer,
391                                  Standard_True,
392                                  myIsCustomOrigin ? myUVOrigin : gp_Pnt2d (0.0, 0.0),
393                                  myUVRepeat,
394                                  myToScale        ? myUVScale  : gp_Pnt2d (1.0, 1.0));
395         // within primitive arrays - object should be in one group of primitives
396         Prs3d_Root::CurrentGroup (thePrs)->SetGroupPrimitivesAspect (myAspect);
397       }
398       catch (Standard_Failure)
399       {
400         std::cout << "AIS_TexturedShape::Compute() in ShadingMode failed \n";
401         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
402       }
403       break;
404     }
405   }
406 }