1 // ============================================================================= 2 // PROJECT CHRONO - http://projectchrono.org 3 // 4 // Copyright (c) 2014 projectchrono.org 5 // All rights reserved. 6 // 7 // Use of this source code is governed by a BSD-style license that can be found 8 // in the LICENSE file at the top level of the distribution and at 9 // http://projectchrono.org/license-chrono.txt. 10 // 11 // ============================================================================= 12 // Authors: Alessandro Tasora 13 // ============================================================================= 14 15 #ifndef CHIRRCASCADEMESHTOOLS_H 16 #define CHIRRCASCADEMESHTOOLS_H 17 18 19 #include <irrlicht.h> 20 21 #include "chrono_cascade/ChCascadeDoc.h" 22 #include "chrono_cascade/ChCascadeMeshTools.h" 23 24 #include <TopoDS_Shape.hxx> 25 #include <TopoDS.hxx> 26 #include <TopoDS_HShape.hxx> 27 #include <TopoDS_Edge.hxx> 28 #include <TopoDS_Face.hxx> 29 #include <TopoDS_Compound.hxx> 30 #include <BRep_Builder.hxx> 31 #include <BRepTools.hxx> 32 #include <BRep_Tool.hxx> 33 #include <BRepBuilderAPI_MakeEdge.hxx> 34 #include <BRepBuilderAPI_MakeVertex.hxx> 35 #include <TopExp_Explorer.hxx> 36 #include <TopLoc_Location.hxx> 37 #include <TopoDS_Iterator.hxx> 38 #include <BRepAdaptor_HSurface.hxx> 39 #include <Poly.hxx> 40 #include <Poly_Connect.hxx> 41 #include <Poly_Triangle.hxx> 42 #include <Poly_Triangulation.hxx> 43 #include <TColgp_Array1OfDir.hxx> 44 #include <BRepMesh_IncrementalMesh.hxx> 45 #include <TShort_Array1OfShortReal.hxx> 46 47 namespace irr { 48 namespace scene { 49 50 /// @addtogroup cascade_module 51 /// @{ 52 53 /// Tools to convert an OpenCASCADE shapes into 54 /// 'Irrlicht' triangle meshes. 55 56 class ChIrrCascadeMeshTools { 57 public: 58 //--------------------------------------------------------------------------------- 59 // CONVERSION TO 'IRRLICHT' MESHES 60 61 /// Function to use to convert a OpenCASCADE face into a Irrlicht mesh, 62 /// so that it can be used for visualizing it. 63 64 static void fillIrrlichtMeshFromCascadeFace(scene::IMesh* pMesh, 65 const TopoDS_Face& F, 66 video::SColor clr = video::SColor(255, 255, 255, 255)) { 67 BRepAdaptor_Surface BS(F, Standard_False); 68 Handle(BRepAdaptor_HSurface) gFace = new BRepAdaptor_HSurface(BS); 69 70 Handle(Poly_Triangulation) T; 71 TopLoc_Location theLocation; 72 T = BRep_Tool::Triangulation(F, theLocation); 73 74 if (!T.IsNull()) { 75 76 irr::scene::SMeshBuffer* buffer = new irr::scene::SMeshBuffer(); 77 78 buffer->Vertices.set_used(T->NbNodes()); 79 buffer->Indices.set_used(T->NbTriangles() * 3); 80 81 const TColgp_Array1OfPnt& mNodes = T->Nodes(); 82 83 Poly::ComputeNormals(T); 84 const TShort_Array1OfShortReal& mNormals = T->Normals(); 85 86 87 int ivert = 0; 88 for (int j = mNodes.Lower(); j <= mNodes.Upper(); j++) { 89 gp_Pnt p; 90 gp_Dir pn; 91 p = mNodes(j).Transformed(theLocation.Transformation()); 92 93 chrono::ChVector<> pos(p.X(), p.Y(), p.Z()); 94 chrono::ChVector<> nor(mNormals((j-1)*3+1), mNormals((j-1)*3+2), mNormals((j-1)*3+3)); 95 if (F.Orientation() == TopAbs_REVERSED) 96 nor*= -1; 97 98 buffer->Vertices[ivert] = 99 irr::video::S3DVertex((irr::f32)pos.x(), (irr::f32)pos.y(), (irr::f32)pos.z(), (irr::f32)nor.x(), 100 (irr::f32)nor.y(), (irr::f32)nor.z(), clr, 0, 0); 101 ivert++; 102 } 103 104 int itri = 0; 105 for (int j = T->Triangles().Lower(); j <= T->Triangles().Upper(); j++) { 106 Standard_Integer n[3]; 107 if (F.Orientation() == TopAbs_REVERSED) 108 T->Triangles()(j).Get(n[0], n[2], n[1]); 109 else 110 T->Triangles()(j).Get(n[0], n[1], n[2]); 111 int ia = (n[0]) - 1; 112 int ib = (n[1]) - 1; 113 int ic = (n[2]) - 1; 114 115 buffer->Indices[itri * 3 + 0] = ia; 116 buffer->Indices[itri * 3 + 1] = ib; 117 buffer->Indices[itri * 3 + 2] = ic; 118 119 itri++; 120 } 121 122 irr::scene::SMesh* mmesh = dynamic_cast<irr::scene::SMesh*>(pMesh); 123 mmesh->addMeshBuffer(buffer); 124 mmesh->recalculateBoundingBox(); 125 } 126 127 } 128 129 /// Function to use to convert a OpenCASCADE shape into a Irrlicht mesh, 130 /// so that it can be used for visualizing it. 131 132 static void fillIrrlichtMeshFromCascade(scene::IMesh* pMesh, 133 const TopoDS_Shape& mshape, 134 double deflection = 1, 135 bool relative_deflection = false, 136 double angulardeflection = 0.5, 137 video::SColor clr = video::SColor(255, 255, 255, 255)) { 138 BRepTools::Clean(mshape); 139 BRepMesh_IncrementalMesh M(mshape, deflection, relative_deflection , angulardeflection,true); 140 // GetLog() << " ..tesselation done \n"; 141 142 // Loop on faces.. 143 TopExp_Explorer ex; 144 for (ex.Init(mshape, TopAbs_FACE); ex.More(); ex.Next()) { 145 const TopoDS_Face& F = TopoDS::Face(ex.Current()); 146 fillIrrlichtMeshFromCascadeFace(pMesh, F, clr); 147 } 148 } 149 }; 150 151 /// @} cascade_module 152 153 } // END_OF_NAMESPACE____ 154 } // END_OF_NAMESPACE____ 155 156 #endif // END of header 157