void Geometry::Face2BVHMesh(const TopoDS_Face &face, BVHMeshPtr model) { TopLoc_Location loc; Handle_Poly_Triangulation tri = BRep_Tool::Triangulation(face,loc); if ( ! tri.IsNull() ) { const TColgp_Array1OfPnt& nodes = tri->Nodes(); // set mesh triangles and vertice indices std::vector<fcl::Vec3f> vertices; //index from 1 for (int i=1;i<=nodes.Length();i++){ fcl::Vec3f v(nodes(i).X(),nodes(i).Y(),nodes(i).Z()); vertices.push_back(v); } const Poly_Array1OfTriangle& triangleInices = tri->Triangles(); // code to set the vertices and triangles std::vector<fcl::Triangle> triangles; for (int i=1;i<=triangleInices.Length();i++){ int i1=0, i2=0, i3=0; triangleInices(i).Get(i1,i2,i3); fcl::Triangle t(i1,i2,i3); triangles.push_back(t); } model->addSubModel(vertices, triangles); } }
void Surface::tessellate() { TopLoc_Location loc; Handle_Poly_Triangulation triangulation = BRep_Tool::Triangulation( m_face, loc ); if ( triangulation.IsNull() ) { return; } int num_triangles = triangulation->NbTriangles(); const TColgp_Array1OfPnt& nodes = triangulation->Nodes(); const Poly_Array1OfTriangle& triangles = triangulation->Triangles(); const TColgp_Array1OfPnt2d& uvNodes = triangulation->UVNodes(); m_surfaceUVRep.resize( 2 * 3 * num_triangles ); m_surfacePointIndecies.resize( 3 * num_triangles ); Standard_Integer n1, n2, n3 = 0; Standard_Integer num_invalid_triangles = 0; Standard_Integer current_triangle = 0; for ( Standard_Integer i = 0; i < num_triangles; i++ ) { Poly_Triangle triangle = triangles( i + 1 ); bool face_reversed = (m_face.Orientation() == TopAbs_REVERSED); if ( face_reversed ) triangle.Get( n1, n3, n2 ); else triangle.Get( n1, n2, n3 ); if (triangleIsValid(nodes(n1), nodes(n2), nodes(n3))) { gp_Pnt2d uv1 = uvNodes.Value(n1); gp_Pnt2d uv2 = uvNodes.Value(n2); gp_Pnt2d uv3 = uvNodes.Value(n3); m_surfacePointIndecies.push_back( 3 * current_triangle + 0 ); m_surfaceUVRep[ 6 * current_triangle + 0 ] = uv1.X(); m_surfaceUVRep[ 6 * current_triangle + 1 ] = uv1.Y(); m_surfacePointIndecies.push_back( 3 * current_triangle + 1 ); m_surfaceUVRep[ 6 * current_triangle + 2 ] = uv2.X(); m_surfaceUVRep[ 6 * current_triangle + 3 ] = uv2.Y(); m_surfacePointIndecies.push_back( 3 * current_triangle + 2 ); m_surfaceUVRep[ 6 * current_triangle + 4 ] = uv3.X(); m_surfaceUVRep[ 6 * current_triangle + 5 ] = uv3.Y(); current_triangle++; } else { num_invalid_triangles++; } } if (num_invalid_triangles > 0) { m_surfaceUVRep.resize(2 * 3 * (num_triangles - num_invalid_triangles)); } }
void DrawFace(TopoDS_Face face,void(*callbackfunc)(const double* x, const double* n), bool just_one_average_normal) { double x[9], n[9]; StdPrs_ToolShadedShape SST; // Get triangulation TopLoc_Location L; Handle_Poly_Triangulation facing = BRep_Tool::Triangulation(face,L); gp_Trsf tr = L; if(facing.IsNull()){ #if 0 BRepAdaptor_Surface surface(face, Standard_True); double u0 = surface.FirstUParameter(); double u1 = surface.LastUParameter(); double v0 = surface.FirstVParameter(); double v1 = surface.LastVParameter(); const int numi = 10; const int numj = 10; for(int i = 0; i<numi; i++) { for(int j = 0; j<numj; j++) { double uA = -1.2 + 2.5 *(double)i / numi; double uB = -1.2 + 2.5 *(double)(i+1) / numi; double vA = 10* (double)j / numj; double vB = 10*(double)(j+1) / numj; gp_Pnt p0, p1, p2, p3; gp_Dir n0 = GetFaceNormalAtUV(face, uA, vA, &p0); gp_Dir n1 = GetFaceNormalAtUV(face, uB, vA, &p1); gp_Dir n2 = GetFaceNormalAtUV(face, uB, vB, &p2); gp_Dir n3 = GetFaceNormalAtUV(face, uA, vB, &p3); x[0] = p0.X(); x[1] = p0.Y(); x[2] = p0.Z(); x[3] = p1.X(); x[4] = p1.Y(); x[5] = p1.Z(); x[6] = p2.X(); x[7] = p2.Y(); x[8] = p2.Z(); n[0] = n0.X(); n[1] = n0.Y(); n[2] = n0.Z(); n[3] = n1.X(); n[4] = n1.Y(); n[5] = n1.Z(); n[6] = n2.X(); n[7] = n2.Y(); n[8] = n2.Z(); (*callbackfunc)(x, n); x[0] = p0.X(); x[1] = p0.Y(); x[2] = p0.Z(); x[3] = p2.X(); x[4] = p2.Y(); x[5] = p2.Z(); x[6] = p3.X(); x[7] = p3.Y(); x[8] = p3.Z(); n[0] = n0.X(); n[1] = n0.Y(); n[2] = n0.Z(); n[3] = n2.X(); n[4] = n2.Y(); n[5] = n2.Z(); n[6] = n3.X(); n[7] = n3.Y(); n[8] = n3.Z(); (*callbackfunc)(x, n); } } #endif } else { Poly_Connect pc(facing); const TColgp_Array1OfPnt& Nodes = facing->Nodes(); const Poly_Array1OfTriangle& triangles = facing->Triangles(); TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper()); SST.Normal(face, pc, myNormal); Standard_Integer nnn = facing->NbTriangles(); // nnn : nombre de triangles Standard_Integer nt, n1, n2, n3 = 0; // nt : triangle courant // ni : sommet i du triangle courant for (nt = 1; nt <= nnn; nt++) { if (SST.Orientation(face) == TopAbs_REVERSED) // si la face est "reversed" triangles(nt).Get(n1,n3,n2); // le triangle est n1,n3,n2 else triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3 if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) ) { gp_Pnt v1 = Nodes(n1).Transformed(tr); gp_Pnt v2 = Nodes(n2).Transformed(tr); gp_Pnt v3 = Nodes(n3).Transformed(tr); x[0] = v1.X(); x[1] = v1.Y(); x[2] = v1.Z(); x[3] = v2.X(); x[4] = v2.Y(); x[5] = v2.Z(); x[6] = v3.X(); x[7] = v3.Y(); x[8] = v3.Z(); if(just_one_average_normal) { gp_Vec V1(v1, v2); gp_Vec V2(v1, v3); extract((V1 ^ V2).Normalized(), n); } else { n[0] = myNormal(n1).X(); n[1] = myNormal(n1).Y(); n[2] = myNormal(n1).Z(); n[3] = myNormal(n2).X(); n[4] = myNormal(n2).Y(); n[5] = myNormal(n2).Z(); n[6] = myNormal(n3).X(); n[7] = myNormal(n3).Y(); n[8] = myNormal(n3).Z(); } (*callbackfunc)(x, n); } } } }
void Tesselate_Presentation::tesselateShape(const TopoDS_Shape& aShape) { // setResultTitle("Tesselate shape"); TCollection_AsciiString aText = ( "/////////////////////////////////////////////////////////////////" EOL "// Tesselate shape." EOL "/////////////////////////////////////////////////////////////////" EOL EOL ) ; Standard_Real aDeflection = DATA[myIndex][0]; Standard_Integer aNumOfFace = (Standard_Integer)DATA[myIndex][1]; Standard_Integer aNumOfEdge = (Standard_Integer)DATA[myIndex][2]; aText += "Standard_Real aDeflection;" EOL "// aDeflection = ... ;" EOL EOL "// removes all the triangulations of the faces ," EOL "//and all the polygons on the triangulations of the edges:" EOL "BRepTools::Clean(aShape);" EOL EOL "// adds a triangulation of the shape aShape with the deflection aDeflection:" EOL "BRepMesh::Mesh(aShape,aDeflection);" EOL EOL "TopExp_Explorer aExpFace,aExpEdge;" EOL "for(aExpFace.Init(aShape,TopAbs_FACE);aExpFace.More();aExpFace.Next())" EOL "{ " EOL " TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());" EOL " TopLoc_Location aLocation;" EOL EOL " // takes the triangulation of the face aFace:" EOL " Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);" EOL EOL " if(!aTr.IsNull()) // if this triangulation is not NULL" EOL " { " EOL " // takes the array of nodes for this triangulation:" EOL " const TColgp_Array1OfPnt& aNodes = aTr->Nodes();" EOL " // takes the array of triangles for this triangulation:" EOL " const Poly_Array1OfTriangle& triangles = aTr->Triangles();" EOL EOL " // create array of node points in absolute coordinate system" EOL " TColgp_Array1OfPnt aPoints(1, aNodes.Length());" EOL " for( Standard_Integer i = 1; i < aNodes.Length()+1; i++)" EOL " aPoints(i) = aNodes(i).Transformed(aLocation);" EOL EOL " // Takes the node points of each triangle of this triangulation." EOL " // takes a number of triangles:" EOL " Standard_Integer nnn = aTr->NbTriangles();" EOL " Standard_Integer nt,n1,n2,n3;" EOL " for( nt = 1 ; nt < nnn+1 ; nt++)" EOL " {" EOL " // takes the node indices of each triangle in n1,n2,n3:" EOL " triangles(nt).Get(n1,n2,n3);" EOL " // takes the node points:" EOL " gp_Pnt aPnt1 = aPoints(n1);" EOL " gp_Pnt aPnt2 = aPoints(n2);" EOL " gp_Pnt aPnt3 = aPoints(n3);" EOL " } " EOL EOL " // Takes the polygon associated to an edge." EOL " aExpEdge.Init(aFace,TopAbs_EDGE);" EOL " TopoDS_Edge aEdge;" EOL " // for example,working with the first edge:" EOL " if(aExpEdge.More())" EOL " aEdge = TopoDS::Edge(aExpEdge.Current());" EOL EOL " if(!aEdge.IsNull()) // if this edge is not NULL" EOL " {" EOL " // takes the polygon associated to the edge aEdge:" EOL " Handle_Poly_PolygonOnTriangulation aPol = " EOL " BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location());" EOL EOL " if(!aPol.IsNull()) // if this polygon is not NULL" EOL " // takes the array of nodes for this polygon" EOL " // (indexes in the array of nodes for triangulation of theFace):" EOL " const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes();" EOL " }" EOL " }" EOL "}" EOL EOL "//==================================================" EOL EOL ; aText += " Result with deflection = "; aText += TCollection_AsciiString(aDeflection); aText += " :" EOL; GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText); // setResultText(aText.ToCString()); //========================================================================== BRepTools::Clean(aShape); BRepMesh::Mesh(aShape,aDeflection); BRep_Builder aBuilder,aBuild1,aBuild2; TopoDS_Compound aCompound,aComp1,aComp2; aBuilder.MakeCompound(aCompound); aBuild1.MakeCompound(aComp1); aBuild2.MakeCompound(aComp2); TopTools_SequenceOfShape aVertices; Standard_Integer aCount = 0; Standard_Integer aNumOfNodes = 0; Standard_Integer aNumOfTriangles = 0; Handle_AIS_InteractiveObject aShowEdge,aShowFace,aShowShape; TopExp_Explorer aExpFace,aExpEdge; for(aExpFace.Init(aShape,TopAbs_FACE);aExpFace.More();aExpFace.Next()) { aCount++; TopoDS_Face aFace = TopoDS::Face(aExpFace.Current()); TopLoc_Location aLocation; Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation); if(!aTr.IsNull()) { const TColgp_Array1OfPnt& aNodes = aTr->Nodes(); aNumOfNodes += aTr->NbNodes(); Standard_Integer aLower = aNodes.Lower(); Standard_Integer anUpper = aNodes.Upper(); const Poly_Array1OfTriangle& triangles = aTr->Triangles(); aNumOfTriangles += aTr->NbTriangles(); if(aCount == aNumOfFace) { Standard_Integer aNbOfNodesOfFace = aTr->NbNodes(); Standard_Integer aNbOfTrianglesOfFace = aTr->NbTriangles(); aExpEdge.Init(aFace,TopAbs_EDGE); TopoDS_Edge aEdge; for( Standard_Integer i = 0; aExpEdge.More() && i < aNumOfEdge ; aExpEdge.Next(), i++) aEdge = TopoDS::Edge(aExpEdge.Current()); if(!aEdge.IsNull()) { Handle_Poly_PolygonOnTriangulation aPol = BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location()); if(!aPol.IsNull()) { const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes(); Standard_Integer aNbOfNodesOfEdge = aPol->NbNodes(); aText += "Number of nodes of the edge = "; aText += TCollection_AsciiString(aNbOfNodesOfEdge) + EOL; aText += "Number of nodes of the face = "; aText += TCollection_AsciiString(aNbOfNodesOfFace) + EOL; aText += "Number of triangles of the face = "; aText += TCollection_AsciiString(aNbOfTrianglesOfFace) + EOL; GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText); // setResultText(aText.ToCString()); Standard_Integer aLower = aNodesOfPol.Lower(), anUpper = aNodesOfPol.Upper(); for( int i = aLower; i < anUpper ; i++) { gp_Pnt aPnt1 = aNodes(aNodesOfPol(i)).Transformed(aLocation); gp_Pnt aPnt2 = aNodes(aNodesOfPol(i+1)).Transformed(aLocation); TopoDS_Vertex aVertex1 = BRepBuilderAPI_MakeVertex (aPnt1); TopoDS_Vertex aVertex2 = BRepBuilderAPI_MakeVertex (aPnt2); if(!aVertex1.IsNull() && !aVertex2.IsNull() && // if vertices are "alive" !BRep_Tool::Pnt(aVertex1).IsEqual( BRep_Tool::Pnt(aVertex2),Precision::Confusion())) // if they are different { aEdge = BRepBuilderAPI_MakeEdge (aVertex1,aVertex2); aBuild2.Add(aComp2,aVertex1); if(!aEdge.IsNull()) aBuild2.Add(aComp2,aEdge); if(i == anUpper-1) aBuild2.Add(aComp2,aVertex2); } } getAISContext()->EraseAll(); aShowShape = drawShape(aShape); if(WAIT_A_SECOND) return; aShowEdge = drawShape(aComp2,Quantity_NOC_GREEN); getAISContext()->Erase(aShowShape); if(WAIT_A_SECOND) return; } } } TopTools_DataMapOfIntegerShape aEdges; TopTools_SequenceOfShape aVertices; for( Standard_Integer i = 1; i < aNodes.Length()+1; i++) { gp_Pnt aPnt = aNodes(i).Transformed(aLocation); TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(aPnt); if(!aVertex.IsNull()) { aBuilder.Add(aCompound,aVertex); if(aCount == aNumOfFace ) aBuild1.Add(aComp1,aVertex); aVertices.Append(aVertex); } } Standard_Integer nnn = aTr->NbTriangles(); Standard_Integer nt,n1,n2,n3; for( nt = 1 ; nt < nnn+1 ; nt++) { triangles(nt).Get(n1,n2,n3); Standard_Integer key[3]; TopoDS_Vertex aV1,aV2; key[0] = _key(n1, n2); if(!aEdges.IsBound(key[0])) { aV1 = TopoDS::Vertex(aVertices(n1)); aV2 = TopoDS::Vertex(aVertices(n2)); if(!aV1.IsNull() && !aV2.IsNull() && !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion())) { TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2); if(!aEdge.IsNull()) { aEdges.Bind(key[0], aEdge); aBuilder.Add(aCompound,aEdges(key[0])); if(aCount == aNumOfFace) aBuild1.Add(aComp1,aEdges(key[0])); } } } key[1] = _key(n2,n3); if(!aEdges.IsBound(key[1])) { aV1 = TopoDS::Vertex(aVertices(n2)); aV2 = TopoDS::Vertex(aVertices(n3)); if(!aV1.IsNull() && !aV2.IsNull() && !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion())) { TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2); if(!aEdge.IsNull()) { aEdges.Bind(key[1],aEdge); aBuilder.Add(aCompound,aEdges(key[1])); if(aCount == aNumOfFace) aBuild1.Add(aComp1,aEdges(key[1])); } } } key[2] = _key(n3,n1); if(!aEdges.IsBound(key[2])) { aV1 = TopoDS::Vertex(aVertices(n3)); aV2 = TopoDS::Vertex(aVertices(n1)); if(!aV1.IsNull() && !aV2.IsNull() && !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion())) { TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2); if(!aEdge.IsNull()) { aEdges.Bind(key[2],aEdge); aBuilder.Add(aCompound,aEdges(key[2])); if(aCount == aNumOfFace) aBuild1.Add(aComp1,aEdges(key[2])); } } } } if(aCount == aNumOfFace) { aShowFace = drawShape(aComp1,Quantity_NOC_GREEN); getAISContext()->Erase(aShowEdge); } } else { aText += "Can't compute a triangulation on face "; aText += TCollection_AsciiString(aCount) + EOL; GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText); // setResultText(aText.ToCString()); } } aText += "Number of nodes of the shape = "; aText += TCollection_AsciiString(aNumOfNodes) + EOL; aText += "Number of triangles of the shape = "; aText += TCollection_AsciiString(aNumOfTriangles) + EOL EOL; GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText); // setResultText(aText.ToCString()); if(WAIT_A_SECOND) return; drawShape(aCompound,Quantity_NOC_GREEN); getAISContext()->Erase(aShowFace); }