1 // Created on: 2001-07-02
2 // Created by: Mathias BOSSHARD
3 // Copyright (c) 2001-2012 OPEN CASCADE SAS
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.
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.
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.
21 ////////////////////////////////////////////////////////////////////////
24 #include <AIS_TexturedShape.ixx>
25 #include <Standard_ErrorHandler.hxx>
27 #include <BRepTools.hxx>
29 #include <Graphic3d_StructureManager.hxx>
30 #include <Graphic3d_Texture2Dmanual.hxx>
31 #include <Graphic3d_AspectFillArea3d.hxx>
32 #include <AIS_InteractiveContext.hxx>
33 #include <Prs3d_ShadingAspect.hxx>
34 #include <Prs3d_Root.hxx>
35 #include <PrsMgr_PresentationManager3d.hxx>
36 #include <Prs3d_Presentation.hxx>
37 #include <TopExp_Explorer.hxx>
38 #include <StdPrs_WFDeflectionShape.hxx>
39 #include <Graphic3d_Group.hxx>
40 #include <AIS_Drawer.hxx>
41 #include <StdPrs_WFShape.hxx>
42 #include <StdPrs_ShadedShape.hxx>
43 #include <StdPrs_ToolShadedShape.hxx>
44 #include <Precision.hxx>
45 #include <BRepMesh.hxx>
46 #include <Poly_Triangulation.hxx>
47 #include <Poly_Connect.hxx>
48 #include <Graphic3d_Array1OfVertexNT.hxx>
49 #include <Aspect_Array1OfEdge.hxx>
50 #include <TColgp_Array1OfDir.hxx>
51 #include <TColgp_Array1OfPnt2d.hxx>
53 #define MAX2(X, Y) ( Abs(X) > Abs(Y)? Abs(X) : Abs(Y) )
54 #define MAX3(X, Y, Z) ( MAX2 ( MAX2(X,Y) , Z) )
56 //////////////////////////////////////////////////////////////////////
57 // CONSTRUCTOR / DESTRUCTOR
58 //////////////////////////////////////////////////////////////////////
60 //=======================================================================
61 //function : AIS_TexturedShape
63 //=======================================================================
65 AIS_TexturedShape::AIS_TexturedShape(const TopoDS_Shape& ashape):AIS_Shape(ashape),
66 myPredefTexture(Graphic3d_NameOfTexture2D(0)),
68 DoRepeat(Standard_True),
71 DoMapTexture(Standard_True),
72 DoSetTextureOrigin(Standard_True),
75 DoSetTextureScale(Standard_True),
78 DoShowTriangles(Standard_False),
79 myModulate(Standard_True)
83 //////////////////////////////////////////////////////////////////////
84 // TEXTURE MAPPING MANAGEMENT METHODS
85 //////////////////////////////////////////////////////////////////////
87 //=======================================================================
88 //function : SetTextureFileName
90 //=======================================================================
92 void AIS_TexturedShape::SetTextureFileName(const TCollection_AsciiString& TextureFileName)
94 if (TextureFileName.IsIntegerValue())
96 if(TextureFileName.IntegerValue()<Graphic3d_Texture2D::NumberOfTextures() && TextureFileName.IntegerValue()>=0)
97 myPredefTexture = (Graphic3d_NameOfTexture2D)(TextureFileName.IntegerValue());
100 cout << "Texture "<<TextureFileName<<" doesn't exist \n"<< endl;
101 cout << "Using Texture 0 instead ...\n"<< endl;
102 myPredefTexture = (Graphic3d_NameOfTexture2D)(0);
108 myTextureFile = TextureFileName;
109 myPredefTexture = (Graphic3d_NameOfTexture2D)(-1);
113 //=======================================================================
114 //function : SetTextureRepeat
116 //=======================================================================
118 void AIS_TexturedShape::SetTextureRepeat(const Standard_Boolean RepeatYN,
119 const Standard_Real URepeat,
120 const Standard_Real VRepeat)
127 //=======================================================================
128 //function : SetTextureMapOn
130 //=======================================================================
132 void AIS_TexturedShape::SetTextureMapOn()
134 DoMapTexture = Standard_True;
137 //=======================================================================
138 //function : SetTextureMapOff
140 //=======================================================================
142 void AIS_TexturedShape::SetTextureMapOff()
144 DoMapTexture = Standard_False;
147 //=======================================================================
148 //function : SetTextureOrigin
150 //=======================================================================
152 void AIS_TexturedShape::SetTextureOrigin(const Standard_Boolean SetTextureOriginYN, const Standard_Real UOrigin, const Standard_Real VOrigin)
154 DoSetTextureOrigin = SetTextureOriginYN;
159 //=======================================================================
160 //function : SetTextureScale
162 //=======================================================================
164 void AIS_TexturedShape::SetTextureScale(const Standard_Boolean SetTextureScaleYN, const Standard_Real ScaleU, const Standard_Real ScaleV)
166 DoSetTextureScale = SetTextureScaleYN;
171 //=======================================================================
172 //function : TriangleIsValid
174 //=======================================================================
176 Standard_Boolean AIS_TexturedShape::TriangleIsValid(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) const
178 gp_Vec V1(P1,P2); // V1=(P1,P2)
179 gp_Vec V2(P2,P3); // V2=(P2,P3)
180 gp_Vec V3(P3,P1); // V3=(P3,P1)
182 if ((V1.SquareMagnitude() > 1.e-10) && (V2.SquareMagnitude() > 1.e-10) && (V3.SquareMagnitude() > 1.e-10))
184 V1.Cross(V2); // V1 = Normal
185 if (V1.SquareMagnitude() > 1.e-10)
186 return Standard_True;
188 return Standard_False;
191 return Standard_False;
195 //=======================================================================
196 //function : ShowTriangles
198 //=======================================================================
200 void AIS_TexturedShape::ShowTriangles(const Standard_Boolean ShowTrianglesYN)
202 DoShowTriangles = ShowTrianglesYN;
205 //=======================================================================
206 //function : EnableTextureModulate
208 //=======================================================================
210 void AIS_TexturedShape::EnableTextureModulate()
212 myModulate = Standard_True;
215 //=======================================================================
216 //function : DisableTextureModulate
218 //=======================================================================
220 void AIS_TexturedShape::DisableTextureModulate()
222 myModulate = Standard_False;
225 //=======================================================================
226 //function : UpdateAttributes
228 //=======================================================================
230 void AIS_TexturedShape::UpdateAttributes()
232 Handle(Graphic3d_StructureManager) aStrucMana = GetContext()->MainPrsMgr()->StructureManager();
233 myAspect = (new Prs3d_ShadingAspect())->Aspect();
234 Handle(Prs3d_Presentation) aPrs = Presentation();
237 myAspect->SetTextureMapOff();
241 if(myPredefTexture!=-1)
242 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myPredefTexture);
244 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myTextureFile.ToCString());
246 myAspect->SetTextureMapOn();
248 myAspect->SetTextureMap(mytexture);
249 if (!mytexture->IsDone())
251 cout << "An error occured while building texture \n" <<endl;
256 myAspect->SetEdgeOn();
258 myAspect->SetEdgeOff();
260 Prs3d_Root::CurrentGroup(aPrs)->SetGroupPrimitivesAspect(myAspect);
263 //=======================================================================
266 //=======================================================================
268 void AIS_TexturedShape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
269 const Handle(Prs3d_Presentation)& aPrs,
270 const Standard_Integer aMode)
274 if(myshape.IsNull()) return;
276 Standard_Integer TheType;
277 TheType = (Standard_Integer) myshape.ShapeType();
278 if(TheType>4 && TheType<8)
280 aPrs->SetVisual(Graphic3d_TOS_ALL);
281 aPrs->SetDisplayPriority(TheType+2);
284 if (myshape.ShapeType() == TopAbs_COMPOUND)
286 TopExp_Explorer anExplor (myshape, TopAbs_VERTEX);
287 if (!anExplor.More()) {return;}
291 aPrs->SetInfiniteState(Standard_True);
297 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
302 Standard_Real prevangle ;
303 Standard_Real newangle ;
304 Standard_Real prevcoeff ;
305 Standard_Real newcoeff ;
307 if (OwnDeviationAngle(newangle,prevangle) || OwnDeviationCoefficient(newcoeff,prevcoeff))
308 if (Abs (newangle - prevangle) > Precision::Angular() || Abs (newcoeff - prevcoeff) > Precision::Confusion() )
310 BRepTools::Clean(myshape);
312 if ((Standard_Integer) myshape.ShapeType()>4)
313 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
316 myDrawer->SetShadingAspectGlobal(Standard_False);
318 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
324 StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer);
326 catch (Standard_Failure)
328 cout <<"AIS_TexturedShape::Compute() in ShadingMode failed \n" <<endl;
329 StdPrs_WFShape::Add(aPrs,myshape,myDrawer);
336 case 2: // Bounding box
340 StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
344 AIS_Shape::DisplayBox(aPrs,BoundingBox(),myDrawer);
349 case 3: // texture mapping on triangulation
351 BRepTools::Clean(myshape);
352 BRepTools::Update(myshape);
354 Handle(Graphic3d_StructureManager) aStrucMana = GetContext()->MainPrsMgr()->StructureManager();
356 Handle(Prs3d_ShadingAspect) aPrs3d_ShadingAspect = new Prs3d_ShadingAspect;
357 myAspect = aPrs3d_ShadingAspect->Aspect();
361 myAspect->SetTextureMapOff();
364 myAspect->SetTextureMapOn();
366 if(myPredefTexture!=-1)
367 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myPredefTexture);
369 mytexture = new Graphic3d_Texture2Dmanual(aStrucMana, myTextureFile.ToCString());
371 if (!mytexture->IsDone())
373 cout <<"An error occured while building texture \n" <<endl;
377 mytexture->EnableModulate();
379 mytexture->DisableModulate();
381 myAspect->SetTextureMap(mytexture);
383 myAspect->SetEdgeOn();
385 myAspect->SetEdgeOff();
388 mytexture->EnableRepeat();
390 mytexture->DisableRepeat();
392 myDeflection = AIS_Shape::GetDeflection(myshape,myDrawer);
393 BRepMesh::Mesh(myshape,myDeflection);
394 // Adds a triangulation of the shape myshape to its topological data structure.
395 // This triangulation is computed with the deflection myDeflection.
398 cout <<"Deflection = " << myDeflection << "\n" << endl;
401 StdPrs_ToolShadedShape SST;
403 Standard_Integer NumFace;
404 TopExp_Explorer ExpFace;
406 for( NumFace=0,ExpFace.Init(myshape,TopAbs_FACE); ExpFace.More(); ExpFace.Next(),NumFace++ )
408 TopoDS_Face myFace = TopoDS::Face(ExpFace.Current());
409 TopLoc_Location aLocation = myFace.Location();
412 cout << "The face is being processed" << NumFace << "\n" << endl;
414 Handle(Poly_Triangulation) myT = BRep_Tool::Triangulation(myFace, aLocation);
415 // Returns the Triangulation of the face. It is a null handle if there is no triangulation.
420 cout << "Triangulation of the face "<< i <<" is null \n"<< endl;
424 Poly_Connect pc(myT);
425 const TColgp_Array1OfPnt& Nodes = myT->Nodes();
426 const TColgp_Array1OfPnt2d& UVNodes = myT->UVNodes();
427 const Poly_Array1OfTriangle& triangles = myT->Triangles();
428 TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper());
430 SST.Normal(myFace, pc, myNormal);
431 BRepTools::UVBounds(myFace,Umin, Umax, Vmin, Vmax);
432 dUmax = (Umax - Umin);
433 dVmax = (Vmax - Vmin);
434 Handle(Graphic3d_Group) mygroup = Prs3d_Root::CurrentGroup(aPrs);
436 Standard_Integer nnn = myT->NbTriangles(); // nnn : number of triangles
437 Standard_Integer nt, n1, n2, n3 = 0; // nt : current triangle
438 // ni : top i of the current triangle
439 for (nt = 1; nt <= nnn; nt++)
442 cout << "The triangle is being processed: "<< nt <<"\n";
444 if (SST.Orientation(myFace) == TopAbs_REVERSED) // if the face is "reversed"
445 triangles(nt).Get(n1,n3,n2); // the triangle is n1,n3,n2
447 triangles(nt).Get(n1,n2,n3); // the triangle is n1,n2,n3
449 if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
450 { // vertexNT associated to each node
451 Graphic3d_Array1OfVertexNT Points(1,3);
452 Aspect_Array1OfEdge aretes(1,3);
454 mygroup->BeginPrimitives();
456 gp_Pnt p = Nodes(n1).Transformed(aLocation.Transformation());
457 gp_Pnt q = Nodes(n2).Transformed(aLocation.Transformation());
458 gp_Pnt r = Nodes(n3).Transformed(aLocation.Transformation());
460 Points(1).SetCoord(p.X(), p.Y(), p.Z());
461 Points(2).SetCoord(q.X(), q.Y(), q.Z());
462 Points(3).SetCoord(r.X(), r.Y(), r.Z());
464 Points(1).SetNormal(myNormal(n1).X(), myNormal(n1).Y(), myNormal(n1).Z());
465 Points(2).SetNormal(myNormal(n2).X(), myNormal(n2).Y(), myNormal(n2).Z());
466 Points(3).SetNormal(myNormal(n3).X(), myNormal(n3).Y(), myNormal(n3).Z());
468 Points(1).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n1).X()-Umin))/dUmax)/myScaleU,
469 (-myVOrigin+(myVRepeat*(UVNodes(n1).Y()-Vmin))/dVmax)/myScaleV);
470 Points(2).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n2).X()-Umin))/dUmax)/myScaleU,
471 (-myVOrigin+(myVRepeat*(UVNodes(n2).Y()-Vmin))/dVmax)/myScaleV);
472 Points(3).SetTextureCoordinate((-myUOrigin+(myURepeat*(UVNodes(n3).X()-Umin))/dUmax)/myScaleU,
473 (-myVOrigin+(myVRepeat*(UVNodes(n3).Y()-Vmin))/dVmax)/myScaleV);
475 aretes(1).SetValues(1, 2, Aspect_TOE_INVISIBLE);
476 aretes(2).SetValues(2, 3, Aspect_TOE_INVISIBLE);
477 aretes(3).SetValues(3, 1, Aspect_TOE_INVISIBLE);
479 mygroup->EndPrimitives();
480 mygroup->TriangleSet(Points, aretes, Standard_True);
482 } // end of "if the triangle is valid
483 } // end of the "parcours" of the triangles
484 mygroup->SetGroupPrimitivesAspect(myAspect);
485 }// end of the exploration of the shape in faces
490 // aPrs->ReCompute(); // for hidden line recomputation if necessary...
497 /////////////////////////////////////////////////////////
499 /////////////////////////////////////////////////////////
503 Standard_Boolean AIS_TexturedShape::TextureMapState() const
508 Standard_Real AIS_TexturedShape::URepeat() const
513 Standard_Boolean AIS_TexturedShape::TextureRepeat() const
518 Standard_Real AIS_TexturedShape::Deflection() const
523 Standard_CString AIS_TexturedShape::TextureFile() const
525 return myTextureFile.ToCString();
528 Standard_Real AIS_TexturedShape::VRepeat() const
532 Standard_Boolean AIS_TexturedShape::ShowTriangles() const
534 return DoShowTriangles;
536 Standard_Real AIS_TexturedShape::TextureUOrigin() const
540 Standard_Real AIS_TexturedShape::TextureVOrigin() const
544 Standard_Real AIS_TexturedShape::TextureScaleU() const
548 Standard_Real AIS_TexturedShape::TextureScaleV() const
552 Standard_Boolean AIS_TexturedShape::TextureScale() const
554 return DoSetTextureScale;
556 Standard_Boolean AIS_TexturedShape::TextureOrigin() const
558 return DoSetTextureOrigin;
560 Standard_Boolean AIS_TexturedShape::TextureModulate() const