OCC22199 OpenGL memory leaks in TKOpenGl
[occt.git] / src / AIS / AIS_TexturedShape.cxx
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
55 AIS_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
82 void 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
108 void 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
122 void AIS_TexturedShape::SetTextureMapOn()
123 {
124   DoMapTexture = Standard_True;
125 }
126
127 //=======================================================================
128 //function : SetTextureMapOff
129 //purpose  : 
130 //=======================================================================
131
132 void AIS_TexturedShape::SetTextureMapOff()
133 {
134   DoMapTexture = Standard_False;
135 }
136
137 //=======================================================================
138 //function : SetTextureOrigin
139 //purpose  : 
140 //=======================================================================
141
142 void 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
154 void 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
166 Standard_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
190 void AIS_TexturedShape::ShowTriangles(const Standard_Boolean ShowTrianglesYN)
191 {
192   DoShowTriangles = ShowTrianglesYN;
193 }
194
195 //=======================================================================
196 //function : EnableTextureModulate
197 //purpose  : 
198 //=======================================================================
199
200 void AIS_TexturedShape::EnableTextureModulate()
201 {
202   myModulate = Standard_True;
203 }
204
205 //=======================================================================
206 //function : DisableTextureModulate
207 //purpose  : 
208 //=======================================================================
209
210 void AIS_TexturedShape::DisableTextureModulate()
211 {
212   myModulate = Standard_False;
213 }
214
215 //=======================================================================
216 //function : UpdateAttributes
217 //purpose  : 
218 //=======================================================================
219
220 void 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
258 void 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();
345           {  
346             Handle(Prs3d_ShadingAspect) aPrs3d_ShadingAspect = new Prs3d_ShadingAspect;
347             myAspect = aPrs3d_ShadingAspect->Aspect();
348           }
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
493 Standard_Boolean AIS_TexturedShape::TextureMapState() const
494 {
495   return DoMapTexture;
496 }
497
498 Standard_Real AIS_TexturedShape::URepeat() const
499 {
500   return myURepeat;
501 }
502
503 Standard_Boolean AIS_TexturedShape::TextureRepeat() const
504 {
505   return DoRepeat;
506 }
507
508 Standard_Real AIS_TexturedShape::Deflection() const
509 {
510   return myDeflection;
511 }
512
513 Standard_CString AIS_TexturedShape::TextureFile() const
514 {
515   return myTextureFile.ToCString();
516 }
517
518 Standard_Real AIS_TexturedShape::VRepeat() const
519 {
520   return myVRepeat;
521 }
522 Standard_Boolean AIS_TexturedShape::ShowTriangles() const
523 {
524   return DoShowTriangles;
525 }
526 Standard_Real AIS_TexturedShape::TextureUOrigin() const
527 {
528   return myUOrigin;
529 }
530 Standard_Real AIS_TexturedShape::TextureVOrigin() const
531 {
532   return myVOrigin;
533 }
534 Standard_Real AIS_TexturedShape::TextureScaleU() const
535 {
536   return myScaleU;
537 }
538 Standard_Real AIS_TexturedShape::TextureScaleV() const
539 {
540   return myScaleV;
541 }
542 Standard_Boolean        AIS_TexturedShape::TextureScale() const
543 {
544   return DoSetTextureScale;
545 }
546 Standard_Boolean        AIS_TexturedShape::TextureOrigin() const
547 {
548   return DoSetTextureOrigin;
549 }
550 Standard_Boolean        AIS_TexturedShape::TextureModulate() const
551 {
552   return myModulate;
553 }