OCC22199 OpenGL memory leaks in TKOpenGl
[occt.git] / src / AIS / AIS_TexturedShape.cxx
CommitLineData
7fd59977 1// File: AIS_TexturedShape.cdl
2// Created: Mon Jul 2 11:32:59 2001
3// Author: Mathias BOSSHARD
4// <mbd@pomalox.paris1.matra-dtv.fr>
5// Copyright: Matra Datavision 2001
6//
7// Modified:
8//
9//
10//
11////////////////////////////////////////////////////////////////////////
12
13
14#include <AIS_TexturedShape.ixx>
15#include <Standard_ErrorHandler.hxx>
16
17#include <BRepTools.hxx>
18#include <gp_Vec.hxx>
19#include <Graphic3d_StructureManager.hxx>
20#include <Graphic3d_Texture2Dmanual.hxx>
21#include <Graphic3d_AspectFillArea3d.hxx>
22#include <AIS_InteractiveContext.hxx>
23#include <Prs3d_ShadingAspect.hxx>
24#include <Prs3d_Root.hxx>
25#include <PrsMgr_PresentationManager3d.hxx>
26#include <Prs3d_Presentation.hxx>
27#include <TopExp_Explorer.hxx>
28#include <StdPrs_WFDeflectionShape.hxx>
29#include <Graphic3d_Group.hxx>
30#include <AIS_Drawer.hxx>
31#include <StdPrs_WFShape.hxx>
32#include <StdPrs_ShadedShape.hxx>
33#include <StdPrs_ToolShadedShape.hxx>
34#include <Precision.hxx>
35#include <BRepMesh.hxx>
36#include <Poly_Triangulation.hxx>
37#include <Poly_Connect.hxx>
38#include <Graphic3d_Array1OfVertexNT.hxx>
39#include <Aspect_Array1OfEdge.hxx>
40#include <TColgp_Array1OfDir.hxx>
41#include <TColgp_Array1OfPnt2d.hxx>
42
43#define MAX2(X, Y) ( Abs(X) > Abs(Y)? Abs(X) : Abs(Y) )
44#define MAX3(X, Y, Z) ( MAX2 ( MAX2(X,Y) , Z) )
45
46//////////////////////////////////////////////////////////////////////
47// CONSTRUCTOR / DESTRUCTOR
48//////////////////////////////////////////////////////////////////////
49
50//=======================================================================
51//function : AIS_TexturedShape
52//purpose :
53//=======================================================================
54
55AIS_TexturedShape::AIS_TexturedShape(const TopoDS_Shape& ashape):AIS_Shape(ashape),
56 myPredefTexture(Graphic3d_NameOfTexture2D(0)),
57 myTextureFile(""),
58 DoRepeat(Standard_True),
59 myURepeat(1.0),
60 myVRepeat(1.0),
61 DoMapTexture(Standard_True),
62 DoSetTextureOrigin(Standard_True),
63 myUOrigin(0.0),
64 myVOrigin(0.0),
65 DoSetTextureScale(Standard_True),
66 myScaleU(1.0),
67 myScaleV(1.0),
68 DoShowTriangles(Standard_False),
69 myModulate(Standard_True)
70{
71}
72
73//////////////////////////////////////////////////////////////////////
74// TEXTURE MAPPING MANAGEMENT METHODS
75//////////////////////////////////////////////////////////////////////
76
77//=======================================================================
78//function : SetTextureFileName
79//purpose :
80//=======================================================================
81
82void AIS_TexturedShape::SetTextureFileName(const TCollection_AsciiString& TextureFileName)
83{
84 if (TextureFileName.IsIntegerValue())
85 {
86 if(TextureFileName.IntegerValue()<Graphic3d_Texture2D::NumberOfTextures() && TextureFileName.IntegerValue()>=0)
87 myPredefTexture = (Graphic3d_NameOfTexture2D)(TextureFileName.IntegerValue());
88 else
89 {
90 cout << "Texture "<<TextureFileName<<" doesn't exist \n"<< endl;
91 cout << "Using Texture 0 instead ...\n"<< endl;
92 myPredefTexture = (Graphic3d_NameOfTexture2D)(0);
93 }
94 myTextureFile = "";
95 }
96 else
97 {
98 myTextureFile = TextureFileName;
99 myPredefTexture = (Graphic3d_NameOfTexture2D)(-1);
100 }
101}
102
103//=======================================================================
104//function : SetTextureRepeat
105//purpose :
106//=======================================================================
107
108void AIS_TexturedShape::SetTextureRepeat(const Standard_Boolean RepeatYN,
109 const Standard_Real URepeat,
110 const Standard_Real VRepeat)
111{
112 DoRepeat = RepeatYN;
113 myURepeat = URepeat;
114 myVRepeat = VRepeat;
115}
116
117//=======================================================================
118//function : SetTextureMapOn
119//purpose :
120//=======================================================================
121
122void AIS_TexturedShape::SetTextureMapOn()
123{
124 DoMapTexture = Standard_True;
125}
126
127//=======================================================================
128//function : SetTextureMapOff
129//purpose :
130//=======================================================================
131
132void AIS_TexturedShape::SetTextureMapOff()
133{
134 DoMapTexture = Standard_False;
135}
136
137//=======================================================================
138//function : SetTextureOrigin
139//purpose :
140//=======================================================================
141
142void AIS_TexturedShape::SetTextureOrigin(const Standard_Boolean SetTextureOriginYN, const Standard_Real UOrigin, const Standard_Real VOrigin)
143{
144 DoSetTextureOrigin = SetTextureOriginYN;
145 myUOrigin = UOrigin;
146 myVOrigin = VOrigin;
147}
148
149//=======================================================================
150//function : SetTextureScale
151//purpose :
152//=======================================================================
153
154void AIS_TexturedShape::SetTextureScale(const Standard_Boolean SetTextureScaleYN, const Standard_Real ScaleU, const Standard_Real ScaleV)
155{
156 DoSetTextureScale = SetTextureScaleYN;
157 myScaleU = ScaleU;
158 myScaleV = ScaleV;
159}
160
161//=======================================================================
162//function : TriangleIsValid
163//purpose :
164//=======================================================================
165
166Standard_Boolean AIS_TexturedShape::TriangleIsValid(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) const
167{
168 gp_Vec V1(P1,P2); // V1=(P1,P2)
169 gp_Vec V2(P2,P3); // V2=(P2,P3)
170 gp_Vec V3(P3,P1); // V3=(P3,P1)
171
172 if ((V1.SquareMagnitude() > 1.e-10) && (V2.SquareMagnitude() > 1.e-10) && (V3.SquareMagnitude() > 1.e-10))
173 {
174 V1.Cross(V2); // V1 = Normal
175 if (V1.SquareMagnitude() > 1.e-10)
176 return Standard_True;
177 else
178 return Standard_False;
179 }
180 else
181 return Standard_False;
182
183}
184
185//=======================================================================
186//function : ShowTriangles
187//purpose :
188//=======================================================================
189
190void AIS_TexturedShape::ShowTriangles(const Standard_Boolean ShowTrianglesYN)
191{
192 DoShowTriangles = ShowTrianglesYN;
193}
194
195//=======================================================================
196//function : EnableTextureModulate
197//purpose :
198//=======================================================================
199
200void AIS_TexturedShape::EnableTextureModulate()
201{
202 myModulate = Standard_True;
203}
204
205//=======================================================================
206//function : DisableTextureModulate
207//purpose :
208//=======================================================================
209
210void AIS_TexturedShape::DisableTextureModulate()
211{
212 myModulate = Standard_False;
213}
214
215//=======================================================================
216//function : UpdateAttributes
217//purpose :
218//=======================================================================
219
220void AIS_TexturedShape::UpdateAttributes()
221{
222 Handle(Graphic3d_StructureManager) aStrucMana = GetContext()->MainPrsMgr()->StructureManager();
223 myAspect = (new Prs3d_ShadingAspect())->Aspect();
224 Handle(Prs3d_Presentation) aPrs = Presentation();
225 if (!DoMapTexture)
226 {
227 myAspect->SetTextureMapOff();
228 return;
229 }
230
231 if(myPredefTexture!=-1)
232 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myPredefTexture);
233 else
234 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myTextureFile.ToCString());
235
236 myAspect->SetTextureMapOn();
237
238 myAspect->SetTextureMap(mytexture);
239 if (!mytexture->IsDone())
240 {
241 cout << "An error occured while building texture \n" <<endl;
242 return;
243 }
244
245 if (DoShowTriangles)
246 myAspect->SetEdgeOn();
247 else
248 myAspect->SetEdgeOff();
249
250 Prs3d_Root::CurrentGroup(aPrs)->SetGroupPrimitivesAspect(myAspect);
251}
252
253//=======================================================================
254//function : Compute
255//purpose :
256//=======================================================================
257
258void AIS_TexturedShape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
259 const Handle(Prs3d_Presentation)& aPrs,
260 const Standard_Integer aMode)
261{
262 aPrs->Clear();
263
264 if(myshape.IsNull()) return;
265
266 Standard_Integer TheType;
267 TheType = (Standard_Integer) myshape.ShapeType();
268 if(TheType>4 && TheType<8)
269 {
270 aPrs->SetVisual(Graphic3d_TOS_ALL);
271 aPrs->SetDisplayPriority(TheType+2);
272 }
273
274 if (myshape.ShapeType() == TopAbs_COMPOUND)
275 {
276 TopExp_Explorer anExplor (myshape, TopAbs_VERTEX);
277 if (!anExplor.More()) {return;}
278 }
279
280 if (IsInfinite())
281 aPrs->SetInfiniteState(Standard_True);
282
283 switch (aMode)
284 {
285
286 case 0: // Wireframe
287 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
288 break;
289
290 case 1: // Shading)
291 {
292 Standard_Real prevangle ;
293 Standard_Real newangle ;
294 Standard_Real prevcoeff ;
295 Standard_Real newcoeff ;
296
297 if (OwnDeviationAngle(newangle,prevangle) || OwnDeviationCoefficient(newcoeff,prevcoeff))
298 if (Abs (newangle - prevangle) > Precision::Angular() || Abs (newcoeff - prevcoeff) > Precision::Confusion() )
299 {
300 BRepTools::Clean(myshape);
301 }
302 if ((Standard_Integer) myshape.ShapeType()>4)
303 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
304 else
305 {
306 myDrawer->SetShadingAspectGlobal(Standard_False);
307 if (IsInfinite())
308 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
309 else
310 {
311 try
312 {
313 OCC_CATCH_SIGNALS
314 StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer);
315 }
316 catch (Standard_Failure)
317 {
318 cout <<"AIS_TexturedShape::Compute() in ShadingMode failed \n" <<endl;
319 StdPrs_WFShape::Add(aPrs,myshape,myDrawer);
320 }
321 }
322 }
323 break;
324 }
325
326 case 2: // Bounding box
327 {
328 if (IsInfinite())
329 {
330 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
331 }
332 else
333 {
334 AIS_Shape::DisplayBox(aPrs,BoundingBox(),myDrawer);
335 }
336 break;
337 }
338
339 case 3: // texture mapping on triangulation
340 {
341 BRepTools::Clean(myshape);
342 BRepTools::Update(myshape);
343
344 Handle(Graphic3d_StructureManager) aStrucMana = GetContext()->MainPrsMgr()->StructureManager();
161c4476
K
345 {
346 Handle(Prs3d_ShadingAspect) aPrs3d_ShadingAspect = new Prs3d_ShadingAspect;
347 myAspect = aPrs3d_ShadingAspect->Aspect();
348 }
7fd59977 349 if (!DoMapTexture)
350 {
351 myAspect->SetTextureMapOff();
352 return;
353 }
354 myAspect->SetTextureMapOn();
355
356 if(myPredefTexture!=-1)
357 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myPredefTexture);
358 else
359 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myTextureFile.ToCString());
360
361 if (!mytexture->IsDone())
362 {
363 cout <<"An error occured while building texture \n" <<endl;
364 return;
365 }
366 if (myModulate)
367 mytexture->EnableModulate();
368 else
369 mytexture->DisableModulate();
370
371 myAspect->SetTextureMap(mytexture);
372 if (DoShowTriangles)
373 myAspect->SetEdgeOn();
374 else
375 myAspect->SetEdgeOff();
376
377 if (DoRepeat)
378 mytexture->EnableRepeat();
379 else
380 mytexture->DisableRepeat();
381
382 myDeflection = AIS_Shape::GetDeflection(myshape,myDrawer);
383 BRepMesh::Mesh(myshape,myDeflection);
384 // Adds a triangulation of the shape myshape to its topological data structure.
385 // This triangulation is computed with the deflection myDeflection.
386
387#ifdef DEBUG
388 cout <<"Deflection = " << myDeflection << "\n" << endl;
389#endif
390
391 StdPrs_ToolShadedShape SST;
392
393 Standard_Integer NumFace;
394 TopExp_Explorer ExpFace;
395
396 for( NumFace=0,ExpFace.Init(myshape,TopAbs_FACE); ExpFace.More(); ExpFace.Next(),NumFace++ )
397 {
398 TopoDS_Face myFace = TopoDS::Face(ExpFace.Current());
399 TopLoc_Location aLocation = myFace.Location();
400
401#ifdef DEBUG
402 cout << "J\'explore actuellement la face " << NumFace << "\n" << endl;
403#endif
404 Handle(Poly_Triangulation) myT = BRep_Tool::Triangulation(myFace, aLocation);
405 // Returns the Triangulation of the face. It is a null handle if there is no triangulation.
406
407 if (myT.IsNull())
408 {
409#ifdef DEBUG
410 cout << "Triangulation of the face "<< i <<" is null \n"<< endl;
411#endif
412 return;
413 }
414 Poly_Connect pc(myT);
415 const TColgp_Array1OfPnt& Nodes = myT->Nodes();
416 const TColgp_Array1OfPnt2d& UVNodes = myT->UVNodes();
417 const Poly_Array1OfTriangle& triangles = myT->Triangles();
418 TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper());
419
420 SST.Normal(myFace, pc, myNormal);
421 BRepTools::UVBounds(myFace,Umin, Umax, Vmin, Vmax);
422 dUmax = (Umax - Umin);
423 dVmax = (Vmax - Vmin);
424 Handle(Graphic3d_Group) mygroup = Prs3d_Root::CurrentGroup(aPrs);
425
426 Standard_Integer nnn = myT->NbTriangles(); // nnn : nombre de triangles
427 Standard_Integer nt, n1, n2, n3 = 0; // nt : triangle courant
428 // ni : sommet i du triangle courant
429 for (nt = 1; nt <= nnn; nt++)
430 {
431#ifdef DEBUG
432 cout << "On traite actuellement le triangle : "<< nt <<"\n";
433#endif
434 if (SST.Orientation(myFace) == TopAbs_REVERSED) // si la face est "reversed"
435 triangles(nt).Get(n1,n3,n2); // le triangle est n1,n3,n2
436 else
437 triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
438
439 if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
440 { // Associates a vertexNT to each node
441 Graphic3d_Array1OfVertexNT Points(1,3);
442 Aspect_Array1OfEdge aretes(1,3);
443
444 mygroup->BeginPrimitives();
445 {
446 gp_Pnt p = Nodes(n1).Transformed(aLocation.Transformation());
447 gp_Pnt q = Nodes(n2).Transformed(aLocation.Transformation());
448 gp_Pnt r = Nodes(n3).Transformed(aLocation.Transformation());
449
450 Points(1).SetCoord(p.X(), p.Y(), p.Z());
451 Points(2).SetCoord(q.X(), q.Y(), q.Z());
452 Points(3).SetCoord(r.X(), r.Y(), r.Z());
453
454 Points(1).SetNormal(myNormal(n1).X(), myNormal(n1).Y(), myNormal(n1).Z());
455 Points(2).SetNormal(myNormal(n2).X(), myNormal(n2).Y(), myNormal(n2).Z());
456 Points(3).SetNormal(myNormal(n3).X(), myNormal(n3).Y(), myNormal(n3).Z());
457
458 Points(1).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n1).X()-Umin))/dUmax)/myScaleU,
459 (-myVOrigin+(myVRepeat*(UVNodes(n1).Y()-Vmin))/dVmax)/myScaleV);
460 Points(2).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n2).X()-Umin))/dUmax)/myScaleU,
461 (-myVOrigin+(myVRepeat*(UVNodes(n2).Y()-Vmin))/dVmax)/myScaleV);
462 Points(3).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n3).X()-Umin))/dUmax)/myScaleU,
463 (-myVOrigin+(myVRepeat*(UVNodes(n3).Y()-Vmin))/dVmax)/myScaleV);
464
465 aretes(1).SetValues(1, 2, Aspect_TOE_INVISIBLE);
466 aretes(2).SetValues(2, 3, Aspect_TOE_INVISIBLE);
467 aretes(3).SetValues(3, 1, Aspect_TOE_INVISIBLE);
468 }
469 mygroup->EndPrimitives();
470 mygroup->TriangleSet(Points, aretes, Standard_True);
471
472 } // end of "if the triangle is valid
473 } // end of the "parcours" of the triangles
474 mygroup->SetGroupPrimitivesAspect(myAspect);
475 }// end of the exploration of the shape in faces
476 break;
477 }// end case 3
478
479 } // end switch
480 // aPrs->ReCompute(); // for hidden line recomputation if necessary...
481}
482
483
484
485
486
487/////////////////////////////////////////////////////////
488// QUERY METHODS
489/////////////////////////////////////////////////////////
490
491
492
493Standard_Boolean AIS_TexturedShape::TextureMapState() const
494{
495 return DoMapTexture;
496}
497
498Standard_Real AIS_TexturedShape::URepeat() const
499{
500 return myURepeat;
501}
502
503Standard_Boolean AIS_TexturedShape::TextureRepeat() const
504{
505 return DoRepeat;
506}
507
508Standard_Real AIS_TexturedShape::Deflection() const
509{
510 return myDeflection;
511}
512
513Standard_CString AIS_TexturedShape::TextureFile() const
514{
515 return myTextureFile.ToCString();
516}
517
518Standard_Real AIS_TexturedShape::VRepeat() const
519{
520 return myVRepeat;
521}
522Standard_Boolean AIS_TexturedShape::ShowTriangles() const
523{
524 return DoShowTriangles;
525}
526Standard_Real AIS_TexturedShape::TextureUOrigin() const
527{
528 return myUOrigin;
529}
530Standard_Real AIS_TexturedShape::TextureVOrigin() const
531{
532 return myVOrigin;
533}
534Standard_Real AIS_TexturedShape::TextureScaleU() const
535{
536 return myScaleU;
537}
538Standard_Real AIS_TexturedShape::TextureScaleV() const
539{
540 return myScaleV;
541}
542Standard_Boolean AIS_TexturedShape::TextureScale() const
543{
544 return DoSetTextureScale;
545}
546Standard_Boolean AIS_TexturedShape::TextureOrigin() const
547{
548 return DoSetTextureOrigin;
549}
550Standard_Boolean AIS_TexturedShape::TextureModulate() const
551{
552 return myModulate;
553}