0024023: Revamp the OCCT Handle - gcc and clang
[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_ShadedShape.hxx>
38 #include <StdPrs_ToolShadedShape.hxx>
39 #include <StdPrs_WFDeflectionShape.hxx>
40 #include <StdPrs_WFShape.hxx>
41 #include <TopExp_Explorer.hxx>
42
43
44 //=======================================================================
45 //function : AIS_TexturedShape
46 //purpose  :
47 //=======================================================================
48 AIS_TexturedShape::AIS_TexturedShape (const TopoDS_Shape& theShape)
49 : AIS_Shape         (theShape),
50   myPredefTexture   (Graphic3d_NameOfTexture2D(0)),
51   myToMapTexture    (Standard_True),
52   myModulate        (Standard_True),
53   myUVOrigin        (0.0, 0.0),
54   myIsCustomOrigin  (Standard_True),
55   myUVRepeat        (1.0, 1.0),
56   myToRepeat        (Standard_True),
57   myUVScale         (1.0, 1.0),
58   myToScale         (Standard_True),
59   myToShowTriangles (Standard_False)
60 {
61 }
62
63 //=======================================================================
64 //function : SetTextureFileName
65 //purpose  :
66 //=======================================================================
67 void AIS_TexturedShape::SetTextureFileName (const TCollection_AsciiString& theTextureFileName)
68 {
69   myTexturePixMap.Nullify();
70
71   if (theTextureFileName.IsIntegerValue())
72   {
73     const Standard_Integer aValue = theTextureFileName.IntegerValue();
74     if (aValue < Graphic3d_Texture2D::NumberOfTextures()
75      && aValue >= 0)
76     {
77       myPredefTexture = Graphic3d_NameOfTexture2D (aValue);
78     }
79     else
80     {
81       Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: texture with ID ") + theTextureFileName
82                                        + " is undefined! Texture 0 will be used instead.", Message_Fail);
83       myPredefTexture = Graphic3d_NameOfTexture2D (0);
84     }
85     myTextureFile = "";
86   }
87   else
88   {
89     myTextureFile   = theTextureFileName;
90     myPredefTexture = Graphic3d_NOT_2D_UNKNOWN;
91   }
92 }
93
94 //=======================================================================
95 //function : SetTexturePixMap
96 //purpose  :
97 //=======================================================================
98 void AIS_TexturedShape::SetTexturePixMap (const Handle(Image_PixMap)& theTexturePixMap)
99 {
100   myTextureFile = "";
101   myPredefTexture = Graphic3d_NOT_2D_UNKNOWN;
102   myTexturePixMap = theTexturePixMap;
103 }
104
105 //=======================================================================
106 //function : SetTextureRepeat
107 //purpose  :
108 //=======================================================================
109
110 void AIS_TexturedShape::SetTextureRepeat (const Standard_Boolean theToRepeat,
111                                           const Standard_Real    theURepeat,
112                                           const Standard_Real    theVRepeat)
113 {
114   myToRepeat = theToRepeat;
115   myUVRepeat.SetCoord (theURepeat, theVRepeat);
116 }
117
118 //=======================================================================
119 //function : SetTextureMapOn
120 //purpose  :
121 //=======================================================================
122
123 void AIS_TexturedShape::SetTextureMapOn()
124 {
125   myToMapTexture = Standard_True;
126 }
127
128 //=======================================================================
129 //function : SetTextureMapOff
130 //purpose  :
131 //=======================================================================
132
133 void AIS_TexturedShape::SetTextureMapOff()
134 {
135   myToMapTexture = Standard_False;
136 }
137
138 //=======================================================================
139 //function : SetTextureOrigin
140 //purpose  :
141 //=======================================================================
142
143 void AIS_TexturedShape::SetTextureOrigin (const Standard_Boolean theToSetTextureOrigin,
144                                           const Standard_Real    theUOrigin,
145                                           const Standard_Real    theVOrigin)
146 {
147   myIsCustomOrigin = theToSetTextureOrigin;
148   myUVOrigin.SetCoord (theUOrigin, theVOrigin);
149 }
150
151 //=======================================================================
152 //function : SetTextureScale
153 //purpose  :
154 //=======================================================================
155
156 void AIS_TexturedShape::SetTextureScale (const Standard_Boolean theToSetTextureScale,
157                                          const Standard_Real    theScaleU,
158                                          const Standard_Real    theScaleV)
159 {
160   myToScale = theToSetTextureScale;
161   myUVScale.SetCoord (theScaleU, theScaleV);
162 }
163
164 //=======================================================================
165 //function : ShowTriangles
166 //purpose  :
167 //=======================================================================
168
169 void AIS_TexturedShape::ShowTriangles (const Standard_Boolean theToShowTriangles)
170 {
171   myToShowTriangles = theToShowTriangles;
172 }
173
174 //=======================================================================
175 //function : EnableTextureModulate
176 //purpose  :
177 //=======================================================================
178
179 void AIS_TexturedShape::EnableTextureModulate()
180 {
181   myModulate = Standard_True;
182 }
183
184 //=======================================================================
185 //function : DisableTextureModulate
186 //purpose  :
187 //=======================================================================
188
189 void AIS_TexturedShape::DisableTextureModulate()
190 {
191   myModulate = Standard_False;
192 }
193
194 //=======================================================================
195 //function : SetColor
196 //purpose  :
197 //=======================================================================
198
199 void AIS_TexturedShape::SetColor (const Quantity_Color& theColor)
200 {
201   AIS_Shape::SetColor (theColor);
202
203   for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt)
204   {
205     const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt);
206
207     if (aPrsModed.Mode() != 3)
208       continue;
209
210     updateAttributes (aPrsModed.Presentation()->Presentation());
211   }
212 }
213
214 //=======================================================================
215 //function : UnsetColor
216 //purpose  :
217 //=======================================================================
218
219 void AIS_TexturedShape::UnsetColor()
220 {
221   AIS_Shape::UnsetColor();
222
223   for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt)
224   {
225     const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt);
226
227     if (aPrsModed.Mode() != 3)
228       continue;
229     
230     Handle(Prs3d_Presentation) aPrs = aPrsModed.Presentation()->Presentation();
231     Handle(Graphic3d_Group)    aGroup = Prs3d_Root::CurrentGroup (aPrs);
232
233     Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->Link()->ShadingAspect()->Aspect();
234     Handle(Graphic3d_AspectLine3d)     aLineAsp  = myDrawer->Link()->LineAspect()->Aspect();
235     Quantity_Color aColor;
236     AIS_GraphicTool::GetInteriorColor (myDrawer->Link(), aColor);
237     anAreaAsp->SetInteriorColor (aColor);
238     aPrs->SetPrimitivesAspect (anAreaAsp);
239     aPrs->SetPrimitivesAspect (aLineAsp);
240     // Check if aspect of given type is set for the group, 
241     // because setting aspect for group with no already set aspect
242     // can lead to loss of presentation data
243     if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
244     {
245       aGroup->SetGroupPrimitivesAspect (anAreaAsp);
246     }
247     if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_LINE))
248     {
249       aGroup->SetGroupPrimitivesAspect (aLineAsp);
250     }
251
252     updateAttributes (aPrs);
253   }
254 }
255
256 //=======================================================================
257 //function : SetMaterial
258 //purpose  : 
259 //=======================================================================
260
261 void AIS_TexturedShape::SetMaterial (const Graphic3d_MaterialAspect& theMat)
262 {
263   AIS_Shape::SetMaterial (theMat);
264
265   for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt)
266   {
267     const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt);
268     
269     if (aPrsModed.Mode() != 3)
270       continue;
271     
272     updateAttributes (aPrsModed.Presentation()->Presentation());
273   }
274 }
275
276 //=======================================================================
277 //function : UnsetMaterial
278 //purpose  : 
279 //=======================================================================
280 void AIS_TexturedShape::UnsetMaterial()
281 {
282   AIS_Shape::UnsetMaterial();
283
284   for (Standard_Integer aPrsIt = 1; aPrsIt <= Presentations().Length(); ++aPrsIt)
285   {
286     const PrsMgr_ModedPresentation& aPrsModed = Presentations().Value (aPrsIt);
287
288     if (aPrsModed.Mode() != 3)
289       continue;
290
291     updateAttributes (aPrsModed.Presentation()->Presentation());
292   }
293 }
294
295 //=======================================================================
296 //function : UpdateAttributes
297 //purpose  :
298 //=======================================================================
299
300 void AIS_TexturedShape::UpdateAttributes()
301 {
302   updateAttributes (Presentation());
303 }
304
305 //=======================================================================
306 //function : updateAttributes
307 //purpose  :
308 //=======================================================================
309
310 void AIS_TexturedShape::updateAttributes (const Handle(Prs3d_Presentation)& thePrs)
311 {
312   myAspect = new Graphic3d_AspectFillArea3d (*myDrawer->ShadingAspect()->Aspect());
313   if (HasPolygonOffsets())
314   {
315     Standard_Integer aMode;
316     Standard_ShortReal aFactor, aUnits;
317     PolygonOffsets (aMode, aFactor, aUnits);
318     myAspect->SetPolygonOffsets (aMode, aFactor, aUnits);
319   }
320
321   Standard_Boolean hasTexture = Standard_False;
322   if (myToMapTexture)
323   {
324     TCollection_AsciiString aTextureDesc;
325     if (!myTexturePixMap.IsNull())
326     {
327       myTexture = new Graphic3d_Texture2Dmanual (myTexturePixMap);
328       aTextureDesc = " (custom image)";
329     }
330     else if (myPredefTexture != Graphic3d_NOT_2D_UNKNOWN)
331     {
332       myTexture = new Graphic3d_Texture2Dmanual (myPredefTexture);
333       aTextureDesc = TCollection_AsciiString(" (predefined texture ") + myTexture->GetId() + ")";
334     }
335     else
336     {
337       myTexture = new Graphic3d_Texture2Dmanual (myTextureFile.ToCString());
338       aTextureDesc = TCollection_AsciiString(" (") + myTextureFile + ")";
339     }
340
341     if (myModulate)
342     {
343       myTexture->EnableModulate();
344     }
345     else
346     {
347       myTexture->DisableModulate();
348     }
349
350     if (myTexture->IsDone())
351     {
352       hasTexture = Standard_True;
353     }
354     else
355     {
356       Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: texture can not be loaded ") + aTextureDesc, Message_Fail);
357     }
358   }
359
360   myAspect->SetTextureMap (myTexture);
361   if (hasTexture)
362   {
363     myAspect->SetTextureMapOn();
364   }
365   else
366   {
367     myAspect->SetTextureMapOff();
368   }
369
370   if (myToShowTriangles)
371   {
372     myAspect->SetEdgeOn();
373   }
374   else
375   {
376     myAspect->SetEdgeOff();
377   }
378
379   // Go through all groups to change fill aspect for all primitives
380   for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (thePrs->Groups()); aGroupIt.More(); aGroupIt.Next())
381   {
382     const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
383     if (!aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
384     {
385       continue;
386     }
387
388     if (aGroup->IsClosed())
389     {
390       myAspect->SuppressBackFace();
391     }
392     else
393     {
394       myAspect->AllowBackFace();
395     }
396
397     aGroup->SetGroupPrimitivesAspect (myAspect);
398   }
399 }
400
401 //=======================================================================
402 //function : Compute
403 //purpose  :
404 //=======================================================================
405
406 void AIS_TexturedShape::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
407                                  const Handle(Prs3d_Presentation)&           thePrs,
408                                  const Standard_Integer                      theMode)
409 {
410   thePrs->Clear();
411
412   if (myshape.IsNull())
413   {
414     return;
415   }
416
417   if (myshape.ShapeType() > TopAbs_FACE && myshape.ShapeType() < TopAbs_SHAPE)
418   {
419     thePrs->SetVisual (Graphic3d_TOS_ALL);
420     thePrs->SetDisplayPriority (myshape.ShapeType() + 2);
421   }
422
423   if (myshape.ShapeType() == TopAbs_COMPOUND)
424   {
425     TopExp_Explorer anExplor (myshape, TopAbs_VERTEX);
426     if (!anExplor.More())
427     {
428       return;
429     }
430   }
431
432   if (IsInfinite())
433   {
434     thePrs->SetInfiniteState (Standard_True);
435   }
436
437   switch (theMode)
438   {
439     case AIS_WireFrame:
440     {
441       StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
442       break;
443     }
444     case AIS_Shaded:
445     case 3: // texture mapping on triangulation
446     {
447       if (myDrawer->IsAutoTriangulation())
448       {
449         Standard_Real aPrevAngle;
450         Standard_Real aNewAngle;
451         Standard_Real aPrevCoeff;
452         Standard_Real aNewCoeff;
453
454         Standard_Boolean isOwnDeviationAngle       = OwnDeviationAngle (aNewAngle, aPrevAngle);
455         Standard_Boolean isOwnDeviationCoefficient = OwnDeviationCoefficient (aNewCoeff,aPrevCoeff);
456         if (((Abs (aNewAngle - aPrevAngle) > Precision::Angular()) && isOwnDeviationAngle) ||
457             ((Abs (aNewCoeff - aPrevCoeff) > Precision::Confusion()) && isOwnDeviationCoefficient))
458         {
459           BRepTools::Clean (myshape);
460         }
461       }
462
463       if (myshape.ShapeType() > TopAbs_FACE)
464       {
465         StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
466         break;
467       }
468
469       myDrawer->SetShadingAspectGlobal (Standard_False);
470       if (IsInfinite())
471       {
472         StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
473         break;
474       }
475       try
476       {
477         OCC_CATCH_SIGNALS
478         if (theMode == AIS_Shaded)
479         {
480           StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer);
481         }
482         else
483         {
484           StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer,
485                                    Standard_True,
486                                    myIsCustomOrigin ? myUVOrigin : gp_Pnt2d (0.0, 0.0),
487                                    myUVRepeat,
488                                    myToScale        ? myUVScale  : gp_Pnt2d (1.0, 1.0));
489           updateAttributes (thePrs);
490         }
491       }
492       catch (Standard_Failure)
493       {
494 #ifdef OCCT_DEBUG
495         std::cout << "AIS_TexturedShape::Compute() in ShadingMode failed \n";
496 #endif
497         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
498       }
499       break;
500     }
501     case 2: // Bounding box
502     {
503       if (IsInfinite())
504       {
505         StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
506       }
507       else
508       {
509         StdPrs_WFDeflectionRestrictedFace::AddBox (thePrs, BoundingBox(), myDrawer);
510       }
511       break;
512     }
513   }
514 }