0023501: Redundant triangulation cleaning/generation (1) in AIS_Shape.cxx
[occt.git] / src / AIS / AIS_TexturedShape.cxx
1 // Created on: 2001-07-02
2 // Created by: Mathias BOSSHARD
3 // Copyright (c) 2001-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 // Modified:
21 ////////////////////////////////////////////////////////////////////////
22
23
24 #include <AIS_TexturedShape.ixx>
25 #include <Standard_ErrorHandler.hxx>
26
27 #include <AIS_Drawer.hxx>
28 #include <AIS_InteractiveContext.hxx>
29 #include <BRepTools.hxx>
30 #include <gp_Pnt2d.hxx>
31 #include <Graphic3d_AspectFillArea3d.hxx>
32 #include <Graphic3d_Group.hxx>
33 #include <Graphic3d_StructureManager.hxx>
34 #include <Graphic3d_Texture2Dmanual.hxx>
35 #include <Precision.hxx>
36 #include <Prs3d_Presentation.hxx>
37 #include <Prs3d_Root.hxx>
38 #include <Prs3d_ShadingAspect.hxx>
39 #include <PrsMgr_PresentationManager3d.hxx>
40 #include <StdPrs_ShadedShape.hxx>
41 #include <StdPrs_WFDeflectionShape.hxx>
42 #include <StdPrs_WFShape.hxx>
43 #include <TopExp_Explorer.hxx>
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   myTextureFile (""),
53   DoRepeat (Standard_True),
54   myURepeat (1.0),
55   myVRepeat (1.0),
56   DoMapTexture (Standard_True),
57   DoSetTextureOrigin (Standard_True),
58   myUOrigin (0.0),
59   myVOrigin (0.0),
60   DoSetTextureScale (Standard_True),
61   myScaleU (1.0),
62   myScaleV (1.0),
63   DoShowTriangles (Standard_False),
64   myModulate (Standard_True)
65 {
66 }
67
68 //=======================================================================
69 //function : SetTextureFileName
70 //purpose  :
71 //=======================================================================
72 void AIS_TexturedShape::SetTextureFileName (const TCollection_AsciiString& theTextureFileName)
73 {
74   if (theTextureFileName.IsIntegerValue())
75   {
76     if (theTextureFileName.IntegerValue() < Graphic3d_Texture2D::NumberOfTextures()
77      && theTextureFileName.IntegerValue() >= 0)
78     {
79       myPredefTexture = Graphic3d_NameOfTexture2D (theTextureFileName.IntegerValue());
80     }
81     else
82     {
83       std::cout << "Texture " << theTextureFileName << " doesn't exist \n";
84       std::cout << "Using Texture 0 instead ...\n";
85       myPredefTexture = Graphic3d_NameOfTexture2D (0);
86     }
87     myTextureFile = "";
88   }
89   else
90   {
91     myTextureFile   = theTextureFileName;
92     myPredefTexture = Graphic3d_NameOfTexture2D (-1);
93   }
94 }
95
96 //=======================================================================
97 //function : SetTextureRepeat
98 //purpose  :
99 //=======================================================================
100
101 void AIS_TexturedShape::SetTextureRepeat (const Standard_Boolean theRepeatYN,
102                                           const Standard_Real    theURepeat,
103                                           const Standard_Real    theVRepeat)
104 {
105   DoRepeat  = theRepeatYN;
106   myURepeat = theURepeat;
107   myVRepeat = theVRepeat;
108 }
109
110 //=======================================================================
111 //function : SetTextureMapOn
112 //purpose  :
113 //=======================================================================
114
115 void AIS_TexturedShape::SetTextureMapOn()
116 {
117   DoMapTexture = Standard_True;
118 }
119
120 //=======================================================================
121 //function : SetTextureMapOff
122 //purpose  :
123 //=======================================================================
124
125 void AIS_TexturedShape::SetTextureMapOff()
126 {
127   DoMapTexture = Standard_False;
128 }
129
130 //=======================================================================
131 //function : SetTextureOrigin
132 //purpose  :
133 //=======================================================================
134
135 void AIS_TexturedShape::SetTextureOrigin (const Standard_Boolean toSetTextureOriginYN,
136                                           const Standard_Real    theUOrigin,
137                                           const Standard_Real    theVOrigin)
138 {
139   DoSetTextureOrigin = toSetTextureOriginYN;
140   myUOrigin = theUOrigin;
141   myVOrigin = theVOrigin;
142 }
143
144 //=======================================================================
145 //function : SetTextureScale
146 //purpose  :
147 //=======================================================================
148
149 void AIS_TexturedShape::SetTextureScale (const Standard_Boolean toSetTextureScaleYN,
150                                          const Standard_Real    theScaleU,
151                                          const Standard_Real    theScaleV)
152 {
153   DoSetTextureScale = toSetTextureScaleYN;
154   myScaleU = theScaleU;
155   myScaleV = theScaleV;
156 }
157
158 //=======================================================================
159 //function : ShowTriangles
160 //purpose  :
161 //=======================================================================
162
163 void AIS_TexturedShape::ShowTriangles (const Standard_Boolean toShowTrianglesYN)
164 {
165   DoShowTriangles = toShowTrianglesYN;
166 }
167
168 //=======================================================================
169 //function : EnableTextureModulate
170 //purpose  :
171 //=======================================================================
172
173 void AIS_TexturedShape::EnableTextureModulate()
174 {
175   myModulate = Standard_True;
176 }
177
178 //=======================================================================
179 //function : DisableTextureModulate
180 //purpose  :
181 //=======================================================================
182
183 void AIS_TexturedShape::DisableTextureModulate()
184 {
185   myModulate = Standard_False;
186 }
187
188 //=======================================================================
189 //function : UpdateAttributes
190 //purpose  :
191 //=======================================================================
192
193 void AIS_TexturedShape::UpdateAttributes()
194 {
195   Prs3d_ShadingAspect aDummy;
196   myAspect = aDummy.Aspect();
197   Handle(Prs3d_Presentation) aPrs = Presentation();
198   if (!DoMapTexture)
199   {
200     myAspect->SetTextureMapOff();
201     return;
202   }
203
204   if (myPredefTexture != -1)
205     mytexture = new Graphic3d_Texture2Dmanual (myPredefTexture);
206   else
207     mytexture = new Graphic3d_Texture2Dmanual (myTextureFile.ToCString());
208
209   myAspect->SetTextureMapOn();
210
211   myAspect->SetTextureMap (mytexture);
212   if (!mytexture->IsDone())
213   {
214     std::cout << "An error occured while building texture \n";
215     return;
216   }
217
218   if (DoShowTriangles)
219     myAspect->SetEdgeOn();
220   else
221     myAspect->SetEdgeOff();
222
223   Prs3d_Root::CurrentGroup (aPrs)->SetGroupPrimitivesAspect (myAspect);
224 }
225
226 //=======================================================================
227 //function : Compute
228 //purpose  :
229 //=======================================================================
230
231 void AIS_TexturedShape::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePresManager*/,
232                                  const Handle(Prs3d_Presentation)&           thePrs,
233                                  const Standard_Integer                      theMode)
234 {
235   thePrs->Clear();
236
237   if (myshape.IsNull())
238   {
239     return;
240   }
241
242   if (myshape.ShapeType() > TopAbs_FACE && myshape.ShapeType() < TopAbs_SHAPE)
243   {
244     thePrs->SetVisual (Graphic3d_TOS_ALL);
245     thePrs->SetDisplayPriority (myshape.ShapeType() + 2);
246   }
247
248   if (myshape.ShapeType() == TopAbs_COMPOUND)
249   {
250     TopExp_Explorer anExplor (myshape, TopAbs_VERTEX);
251     if (!anExplor.More())
252     {
253       return;
254     }
255   }
256
257   if (IsInfinite())
258   {
259     thePrs->SetInfiniteState (Standard_True);
260   }
261
262   switch (theMode)
263   {
264     case 0: // Wireframe
265     {
266       StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
267       break;
268     }
269     case 1: // Shading
270     {
271       Standard_Real prevangle;
272       Standard_Real newangle;
273       Standard_Real prevcoeff;
274       Standard_Real newcoeff;
275
276       Standard_Boolean isOwnDeviationAngle = OwnDeviationAngle(newangle,prevangle);
277       Standard_Boolean isOwnDeviationCoefficient = OwnDeviationCoefficient(newcoeff,prevcoeff);
278       if (((Abs (newangle - prevangle) > Precision::Angular()) && isOwnDeviationAngle) ||
279           ((Abs (newcoeff - prevcoeff) > Precision::Confusion()) && isOwnDeviationCoefficient)) {
280         BRepTools::Clean (myshape);
281       }
282       if (myshape.ShapeType() > TopAbs_FACE)
283       {
284         StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
285         break;
286       }
287       myDrawer->SetShadingAspectGlobal (Standard_False);
288       if (IsInfinite())
289       {
290         StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
291         break;
292       }
293       try
294       {
295         OCC_CATCH_SIGNALS
296         StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer);
297       }
298       catch (Standard_Failure)
299       {
300         std::cout << "AIS_TexturedShape::Compute() in ShadingMode failed \n";
301         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
302       }
303       break;
304     }
305
306     case 2: // Bounding box
307     {
308       if (IsInfinite())
309       {
310         StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer);
311       }
312       else
313       {
314         AIS_Shape::DisplayBox (thePrs, BoundingBox(), myDrawer);
315       }
316       break;
317     }
318
319     case 3: // texture mapping on triangulation
320     {
321       BRepTools::Clean (myshape);
322       BRepTools::Update (myshape);
323
324       {
325         Handle(Prs3d_ShadingAspect) aPrs3d_ShadingAspect = new Prs3d_ShadingAspect();
326         myAspect = aPrs3d_ShadingAspect->Aspect();
327
328         // Issue 23115: copy polygon offset settings passed through myDrawer
329         if (HasPolygonOffsets())
330         {
331           Standard_Integer aMode;
332           Standard_ShortReal aFactor, aUnits;
333           PolygonOffsets(aMode, aFactor, aUnits);
334           myAspect->SetPolygonOffsets(aMode, aFactor, aUnits);
335         }
336       }
337       if (!DoMapTexture)
338       {
339         myAspect->SetTextureMapOff();
340         return;
341       }
342       myAspect->SetTextureMapOn();
343
344       if (myPredefTexture != -1)
345         mytexture = new Graphic3d_Texture2Dmanual (myPredefTexture);
346       else
347         mytexture = new Graphic3d_Texture2Dmanual (myTextureFile.ToCString());
348
349       if (!mytexture->IsDone())
350       {
351         std::cout << "An error occured while building texture \n";
352         return;
353       }
354
355       if (myModulate)
356         mytexture->EnableModulate();
357       else
358         mytexture->DisableModulate();
359
360       myAspect->SetTextureMap (mytexture);
361       if (DoShowTriangles)
362         myAspect->SetEdgeOn();
363       else
364         myAspect->SetEdgeOff();
365
366       if (DoRepeat)
367         mytexture->EnableRepeat();
368       else
369         mytexture->DisableRepeat();
370
371       const gp_Pnt2d aUVOrigin (myUOrigin, myVOrigin);
372       const gp_Pnt2d aUVRepeat (myURepeat, myVRepeat);
373       const gp_Pnt2d aUVScale  (myScaleU,  myScaleV);
374       try
375       {
376         OCC_CATCH_SIGNALS
377         StdPrs_ShadedShape::Add (thePrs, myshape, myDrawer,
378                                  Standard_True, aUVOrigin, aUVRepeat, aUVScale);
379         // within primitive arrays - object should be in one group of primitives
380         Prs3d_Root::CurrentGroup (thePrs)->SetGroupPrimitivesAspect (myAspect);
381       }
382       catch (Standard_Failure)
383       {
384         std::cout << "AIS_TexturedShape::Compute() in ShadingMode failed \n";
385         StdPrs_WFShape::Add (thePrs, myshape, myDrawer);
386       }
387       break;
388     }
389   }
390 }
391
392 Standard_Boolean AIS_TexturedShape::TextureMapState() const
393 {
394   return DoMapTexture;
395 }
396
397 Standard_Real AIS_TexturedShape::URepeat() const
398 {
399   return myURepeat;
400 }
401
402 Standard_Boolean AIS_TexturedShape::TextureRepeat() const
403 {
404   return DoRepeat;
405 }
406
407 Standard_Real AIS_TexturedShape::Deflection() const
408 {
409   return myDeflection;
410 }
411
412 Standard_CString AIS_TexturedShape::TextureFile() const
413 {
414   return myTextureFile.ToCString();
415 }
416
417 Standard_Real AIS_TexturedShape::VRepeat() const
418 {
419   return myVRepeat;
420 }
421
422 Standard_Boolean AIS_TexturedShape::ShowTriangles() const
423 {
424   return DoShowTriangles;
425 }
426
427 Standard_Real AIS_TexturedShape::TextureUOrigin() const
428 {
429   return myUOrigin;
430 }
431
432 Standard_Real AIS_TexturedShape::TextureVOrigin() const
433 {
434   return myVOrigin;
435 }
436
437 Standard_Real AIS_TexturedShape::TextureScaleU() const
438 {
439   return myScaleU;
440 }
441
442 Standard_Real AIS_TexturedShape::TextureScaleV() const
443 {
444   return myScaleV;
445 }
446
447 Standard_Boolean AIS_TexturedShape::TextureScale() const
448 {
449   return DoSetTextureScale;
450 }
451
452 Standard_Boolean AIS_TexturedShape::TextureOrigin() const
453 {
454   return DoSetTextureOrigin;
455 }
456
457 Standard_Boolean AIS_TexturedShape::TextureModulate() const
458 {
459   return myModulate;
460 }