Replacing french comments by english one
[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         myAspect = (new Prs3d_ShadingAspect())->Aspect();
347         if (!DoMapTexture)
348           {
349             myAspect->SetTextureMapOff();
350             return;
351           }
352         myAspect->SetTextureMapOn();
353         
354         if(myPredefTexture!=-1)
355           mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myPredefTexture);
356         else
357           mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myTextureFile.ToCString());
358
359         if (!mytexture->IsDone())
360           {
361             cout <<"An error occured while building texture \n" <<endl;
362             return;
363           }
364         if (myModulate)
365           mytexture->EnableModulate();
366         else
367           mytexture->DisableModulate();
368
369         myAspect->SetTextureMap(mytexture);
370         if (DoShowTriangles)
371           myAspect->SetEdgeOn();
372         else
373           myAspect->SetEdgeOff();
374
375         if (DoRepeat)
376           mytexture->EnableRepeat();
377         else
378           mytexture->DisableRepeat();
379
380         myDeflection = AIS_Shape::GetDeflection(myshape,myDrawer);
381         BRepMesh::Mesh(myshape,myDeflection);
382         // Adds a triangulation of the shape myshape to its topological data structure.
383         // This triangulation is computed with the deflection myDeflection.
384
385 #ifdef DEBUG
386         cout <<"Deflection =  " << myDeflection << "\n" << endl;
387 #endif
388
389         StdPrs_ToolShadedShape SST;
390
391         Standard_Integer NumFace;
392         TopExp_Explorer ExpFace;
393
394         for( NumFace=0,ExpFace.Init(myshape,TopAbs_FACE); ExpFace.More(); ExpFace.Next(),NumFace++ )
395           {
396             TopoDS_Face         myFace          = TopoDS::Face(ExpFace.Current());
397             TopLoc_Location aLocation   = myFace.Location();
398
399 #ifdef DEBUG
400             cout << "J\'explore actuellement la face " << NumFace << "\n" << endl;
401 #endif
402             Handle(Poly_Triangulation) myT = BRep_Tool::Triangulation(myFace, aLocation);
403             // Returns  the Triangulation of  the  face. It  is a null handle if there is no triangulation.
404
405             if (myT.IsNull())
406               {
407 #ifdef DEBUG
408                 cout << "Triangulation of the face "<< i <<" is null \n"<< endl;
409 #endif
410                 return;
411               }
412             Poly_Connect pc(myT);       
413             const TColgp_Array1OfPnt& Nodes = myT->Nodes();
414             const TColgp_Array1OfPnt2d& UVNodes = myT->UVNodes();
415             const Poly_Array1OfTriangle& triangles = myT->Triangles();
416             TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper());
417             
418             SST.Normal(myFace, pc, myNormal);
419             BRepTools::UVBounds(myFace,Umin, Umax, Vmin, Vmax);
420             dUmax = (Umax - Umin);
421             dVmax = (Vmax - Vmin);
422             Handle(Graphic3d_Group) mygroup = Prs3d_Root::CurrentGroup(aPrs);
423
424             Standard_Integer nnn = myT->NbTriangles();                                  // nnn : number of triangles
425             Standard_Integer nt, n1, n2, n3 = 0;                                                // nt  : current triangle
426             // ni  : top i of the current triangle
427             for (nt = 1; nt <= nnn; nt++)                                       
428               {
429 #ifdef DEBUG
430                 cout << "On traite actuellement le triangle : "<< nt <<"\n";
431 #endif                                          
432                 if (SST.Orientation(myFace) == TopAbs_REVERSED)                 // if the face is "reversed"
433                   triangles(nt).Get(n1,n3,n2);                                          // the triangle is n1,n3,n2
434                 else 
435                   triangles(nt).Get(n1,n2,n3);                                          // the triangle is n1,n2,n3
436
437                 if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
438                   {     // Associates vertexNT to each node
439                     Graphic3d_Array1OfVertexNT Points(1,3);
440                     Aspect_Array1OfEdge aretes(1,3);
441
442                     mygroup->BeginPrimitives();
443                     {
444                       gp_Pnt p = Nodes(n1).Transformed(aLocation.Transformation());
445                       gp_Pnt q = Nodes(n2).Transformed(aLocation.Transformation());
446                       gp_Pnt r = Nodes(n3).Transformed(aLocation.Transformation());
447
448                       Points(1).SetCoord(p.X(), p.Y(), p.Z());
449                       Points(2).SetCoord(q.X(), q.Y(), q.Z());
450                       Points(3).SetCoord(r.X(), r.Y(), r.Z());
451
452                       Points(1).SetNormal(myNormal(n1).X(), myNormal(n1).Y(), myNormal(n1).Z());
453                       Points(2).SetNormal(myNormal(n2).X(), myNormal(n2).Y(), myNormal(n2).Z());
454                       Points(3).SetNormal(myNormal(n3).X(), myNormal(n3).Y(), myNormal(n3).Z());
455
456                       Points(1).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n1).X()-Umin))/dUmax)/myScaleU,
457                                                      (-myVOrigin+(myVRepeat*(UVNodes(n1).Y()-Vmin))/dVmax)/myScaleV);
458                       Points(2).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n2).X()-Umin))/dUmax)/myScaleU,
459                                                      (-myVOrigin+(myVRepeat*(UVNodes(n2).Y()-Vmin))/dVmax)/myScaleV);
460                       Points(3).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n3).X()-Umin))/dUmax)/myScaleU,
461                                                      (-myVOrigin+(myVRepeat*(UVNodes(n3).Y()-Vmin))/dVmax)/myScaleV);
462                       
463                       aretes(1).SetValues(1, 2, Aspect_TOE_INVISIBLE);
464                       aretes(2).SetValues(2, 3, Aspect_TOE_INVISIBLE);
465                       aretes(3).SetValues(3, 1, Aspect_TOE_INVISIBLE);
466                     }
467                     mygroup->EndPrimitives();
468                     mygroup->TriangleSet(Points, aretes, Standard_True);        
469
470                   } // end of "if the triangle is valid
471               } // end of the "parcours" of the triangles
472             mygroup->SetGroupPrimitivesAspect(myAspect);
473           }// end of the exploration of the shape in faces
474         break;
475       }// end case 3
476
477     } // end switch
478   //  aPrs->ReCompute(); // for hidden line recomputation if necessary...
479 }
480
481
482
483
484
485 /////////////////////////////////////////////////////////
486 //              QUERY METHODS
487 /////////////////////////////////////////////////////////
488
489
490
491 Standard_Boolean AIS_TexturedShape::TextureMapState() const
492 {
493   return DoMapTexture;
494 }
495
496 Standard_Real AIS_TexturedShape::URepeat() const
497 {
498   return myURepeat;
499 }
500
501 Standard_Boolean AIS_TexturedShape::TextureRepeat() const
502 {
503   return DoRepeat;
504 }
505
506 Standard_Real AIS_TexturedShape::Deflection() const
507 {
508   return myDeflection;
509 }
510
511 Standard_CString AIS_TexturedShape::TextureFile() const
512 {
513   return myTextureFile.ToCString();
514 }
515
516 Standard_Real AIS_TexturedShape::VRepeat() const
517 {
518   return myVRepeat;
519 }
520 Standard_Boolean AIS_TexturedShape::ShowTriangles() const
521 {
522   return DoShowTriangles;
523 }
524 Standard_Real AIS_TexturedShape::TextureUOrigin() const
525 {
526   return myUOrigin;
527 }
528 Standard_Real AIS_TexturedShape::TextureVOrigin() const
529 {
530   return myVOrigin;
531 }
532 Standard_Real AIS_TexturedShape::TextureScaleU() const
533 {
534   return myScaleU;
535 }
536 Standard_Real AIS_TexturedShape::TextureScaleV() const
537 {
538   return myScaleV;
539 }
540 Standard_Boolean        AIS_TexturedShape::TextureScale() const
541 {
542   return DoSetTextureScale;
543 }
544 Standard_Boolean        AIS_TexturedShape::TextureOrigin() const
545 {
546   return DoSetTextureOrigin;
547 }
548 Standard_Boolean        AIS_TexturedShape::TextureModulate() const
549 {
550   return myModulate;
551 }