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
11 ////////////////////////////////////////////////////////////////////////
14 #include <AIS_TexturedShape.ixx>
15 #include <Standard_ErrorHandler.hxx>
17 #include <BRepTools.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>
43 #define MAX2(X, Y) ( Abs(X) > Abs(Y)? Abs(X) : Abs(Y) )
44 #define MAX3(X, Y, Z) ( MAX2 ( MAX2(X,Y) , Z) )
46 //////////////////////////////////////////////////////////////////////
47 // CONSTRUCTOR / DESTRUCTOR
48 //////////////////////////////////////////////////////////////////////
50 //=======================================================================
51 //function : AIS_TexturedShape
53 //=======================================================================
55 AIS_TexturedShape::AIS_TexturedShape(const TopoDS_Shape& ashape):AIS_Shape(ashape),
56 myPredefTexture(Graphic3d_NameOfTexture2D(0)),
58 DoRepeat(Standard_True),
61 DoMapTexture(Standard_True),
62 DoSetTextureOrigin(Standard_True),
65 DoSetTextureScale(Standard_True),
68 DoShowTriangles(Standard_False),
69 myModulate(Standard_True)
73 //////////////////////////////////////////////////////////////////////
74 // TEXTURE MAPPING MANAGEMENT METHODS
75 //////////////////////////////////////////////////////////////////////
77 //=======================================================================
78 //function : SetTextureFileName
80 //=======================================================================
82 void AIS_TexturedShape::SetTextureFileName(const TCollection_AsciiString& TextureFileName)
84 if (TextureFileName.IsIntegerValue())
86 if(TextureFileName.IntegerValue()<Graphic3d_Texture2D::NumberOfTextures() && TextureFileName.IntegerValue()>=0)
87 myPredefTexture = (Graphic3d_NameOfTexture2D)(TextureFileName.IntegerValue());
90 cout << "Texture "<<TextureFileName<<" doesn't exist \n"<< endl;
91 cout << "Using Texture 0 instead ...\n"<< endl;
92 myPredefTexture = (Graphic3d_NameOfTexture2D)(0);
98 myTextureFile = TextureFileName;
99 myPredefTexture = (Graphic3d_NameOfTexture2D)(-1);
103 //=======================================================================
104 //function : SetTextureRepeat
106 //=======================================================================
108 void AIS_TexturedShape::SetTextureRepeat(const Standard_Boolean RepeatYN,
109 const Standard_Real URepeat,
110 const Standard_Real VRepeat)
117 //=======================================================================
118 //function : SetTextureMapOn
120 //=======================================================================
122 void AIS_TexturedShape::SetTextureMapOn()
124 DoMapTexture = Standard_True;
127 //=======================================================================
128 //function : SetTextureMapOff
130 //=======================================================================
132 void AIS_TexturedShape::SetTextureMapOff()
134 DoMapTexture = Standard_False;
137 //=======================================================================
138 //function : SetTextureOrigin
140 //=======================================================================
142 void AIS_TexturedShape::SetTextureOrigin(const Standard_Boolean SetTextureOriginYN, const Standard_Real UOrigin, const Standard_Real VOrigin)
144 DoSetTextureOrigin = SetTextureOriginYN;
149 //=======================================================================
150 //function : SetTextureScale
152 //=======================================================================
154 void AIS_TexturedShape::SetTextureScale(const Standard_Boolean SetTextureScaleYN, const Standard_Real ScaleU, const Standard_Real ScaleV)
156 DoSetTextureScale = SetTextureScaleYN;
161 //=======================================================================
162 //function : TriangleIsValid
164 //=======================================================================
166 Standard_Boolean AIS_TexturedShape::TriangleIsValid(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) const
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)
172 if ((V1.SquareMagnitude() > 1.e-10) && (V2.SquareMagnitude() > 1.e-10) && (V3.SquareMagnitude() > 1.e-10))
174 V1.Cross(V2); // V1 = Normal
175 if (V1.SquareMagnitude() > 1.e-10)
176 return Standard_True;
178 return Standard_False;
181 return Standard_False;
185 //=======================================================================
186 //function : ShowTriangles
188 //=======================================================================
190 void AIS_TexturedShape::ShowTriangles(const Standard_Boolean ShowTrianglesYN)
192 DoShowTriangles = ShowTrianglesYN;
195 //=======================================================================
196 //function : EnableTextureModulate
198 //=======================================================================
200 void AIS_TexturedShape::EnableTextureModulate()
202 myModulate = Standard_True;
205 //=======================================================================
206 //function : DisableTextureModulate
208 //=======================================================================
210 void AIS_TexturedShape::DisableTextureModulate()
212 myModulate = Standard_False;
215 //=======================================================================
216 //function : UpdateAttributes
218 //=======================================================================
220 void AIS_TexturedShape::UpdateAttributes()
222 Handle(Graphic3d_StructureManager) aStrucMana = GetContext()->MainPrsMgr()->StructureManager();
223 myAspect = (new Prs3d_ShadingAspect())->Aspect();
224 Handle(Prs3d_Presentation) aPrs = Presentation();
227 myAspect->SetTextureMapOff();
231 if(myPredefTexture!=-1)
232 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myPredefTexture);
234 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myTextureFile.ToCString());
236 myAspect->SetTextureMapOn();
238 myAspect->SetTextureMap(mytexture);
239 if (!mytexture->IsDone())
241 cout << "An error occured while building texture \n" <<endl;
246 myAspect->SetEdgeOn();
248 myAspect->SetEdgeOff();
250 Prs3d_Root::CurrentGroup(aPrs)->SetGroupPrimitivesAspect(myAspect);
253 //=======================================================================
256 //=======================================================================
258 void AIS_TexturedShape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
259 const Handle(Prs3d_Presentation)& aPrs,
260 const Standard_Integer aMode)
264 if(myshape.IsNull()) return;
266 Standard_Integer TheType;
267 TheType = (Standard_Integer) myshape.ShapeType();
268 if(TheType>4 && TheType<8)
270 aPrs->SetVisual(Graphic3d_TOS_ALL);
271 aPrs->SetDisplayPriority(TheType+2);
274 if (myshape.ShapeType() == TopAbs_COMPOUND)
276 TopExp_Explorer anExplor (myshape, TopAbs_VERTEX);
277 if (!anExplor.More()) {return;}
281 aPrs->SetInfiniteState(Standard_True);
287 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
292 Standard_Real prevangle ;
293 Standard_Real newangle ;
294 Standard_Real prevcoeff ;
295 Standard_Real newcoeff ;
297 if (OwnDeviationAngle(newangle,prevangle) || OwnDeviationCoefficient(newcoeff,prevcoeff))
298 if (Abs (newangle - prevangle) > Precision::Angular() || Abs (newcoeff - prevcoeff) > Precision::Confusion() )
300 BRepTools::Clean(myshape);
302 if ((Standard_Integer) myshape.ShapeType()>4)
303 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
306 myDrawer->SetShadingAspectGlobal(Standard_False);
308 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
314 StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer);
316 catch (Standard_Failure)
318 cout <<"AIS_TexturedShape::Compute() in ShadingMode failed \n" <<endl;
319 StdPrs_WFShape::Add(aPrs,myshape,myDrawer);
326 case 2: // Bounding box
330 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
334 AIS_Shape::DisplayBox(aPrs,BoundingBox(),myDrawer);
339 case 3: // texture mapping on triangulation
341 BRepTools::Clean(myshape);
342 BRepTools::Update(myshape);
344 Handle(Graphic3d_StructureManager) aStrucMana = GetContext()->MainPrsMgr()->StructureManager();
346 Handle(Prs3d_ShadingAspect) aPrs3d_ShadingAspect = new Prs3d_ShadingAspect;
347 myAspect = aPrs3d_ShadingAspect->Aspect();
351 myAspect->SetTextureMapOff();
354 myAspect->SetTextureMapOn();
356 if(myPredefTexture!=-1)
357 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myPredefTexture);
359 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myTextureFile.ToCString());
361 if (!mytexture->IsDone())
363 cout <<"An error occured while building texture \n" <<endl;
367 mytexture->EnableModulate();
369 mytexture->DisableModulate();
371 myAspect->SetTextureMap(mytexture);
373 myAspect->SetEdgeOn();
375 myAspect->SetEdgeOff();
378 mytexture->EnableRepeat();
380 mytexture->DisableRepeat();
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.
388 cout <<"Deflection = " << myDeflection << "\n" << endl;
391 StdPrs_ToolShadedShape SST;
393 Standard_Integer NumFace;
394 TopExp_Explorer ExpFace;
396 for( NumFace=0,ExpFace.Init(myshape,TopAbs_FACE); ExpFace.More(); ExpFace.Next(),NumFace++ )
398 TopoDS_Face myFace = TopoDS::Face(ExpFace.Current());
399 TopLoc_Location aLocation = myFace.Location();
402 cout << "The face is being processed" << NumFace << "\n" << endl;
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.
410 cout << "Triangulation of the face "<< i <<" is null \n"<< endl;
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());
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);
426 Standard_Integer nnn = myT->NbTriangles(); // nnn : number of triangles
427 Standard_Integer nt, n1, n2, n3 = 0; // nt : current triangle
428 // ni : top i of the current triangle
429 for (nt = 1; nt <= nnn; nt++)
432 cout << "The triangle is being processed: "<< nt <<"\n";
434 if (SST.Orientation(myFace) == TopAbs_REVERSED) // if the face is "reversed"
435 triangles(nt).Get(n1,n3,n2); // the triangle is n1,n3,n2
437 triangles(nt).Get(n1,n2,n3); // the triangle is n1,n2,n3
439 if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
440 { // vertexNT associated to each node
441 Graphic3d_Array1OfVertexNT Points(1,3);
442 Aspect_Array1OfEdge aretes(1,3);
444 mygroup->BeginPrimitives();
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());
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());
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());
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);
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);
469 mygroup->EndPrimitives();
470 mygroup->TriangleSet(Points, aretes, Standard_True);
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
480 // aPrs->ReCompute(); // for hidden line recomputation if necessary...
487 /////////////////////////////////////////////////////////
489 /////////////////////////////////////////////////////////
493 Standard_Boolean AIS_TexturedShape::TextureMapState() const
498 Standard_Real AIS_TexturedShape::URepeat() const
503 Standard_Boolean AIS_TexturedShape::TextureRepeat() const
508 Standard_Real AIS_TexturedShape::Deflection() const
513 Standard_CString AIS_TexturedShape::TextureFile() const
515 return myTextureFile.ToCString();
518 Standard_Real AIS_TexturedShape::VRepeat() const
522 Standard_Boolean AIS_TexturedShape::ShowTriangles() const
524 return DoShowTriangles;
526 Standard_Real AIS_TexturedShape::TextureUOrigin() const
530 Standard_Real AIS_TexturedShape::TextureVOrigin() const
534 Standard_Real AIS_TexturedShape::TextureScaleU() const
538 Standard_Real AIS_TexturedShape::TextureScaleV() const
542 Standard_Boolean AIS_TexturedShape::TextureScale() const
544 return DoSetTextureScale;
546 Standard_Boolean AIS_TexturedShape::TextureOrigin() const
548 return DoSetTextureOrigin;
550 Standard_Boolean AIS_TexturedShape::TextureModulate() const