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