bool Delaunay2dMesh::buildMesh( const std::vector<CCVector2>& points2D, const std::vector<int>& segments2D, char* outputErrorStr/*=0*/) { #if defined(USE_CGAL_LIB) //CGAL boilerplate typedef CGAL::Exact_predicates_inexact_constructions_kernel K; //We define a vertex_base with info. The "info" (size_t) allow us to keep track of the original point index. typedef CGAL::Triangulation_vertex_base_with_info_2<size_t, K> Vb; typedef CGAL::Constrained_triangulation_face_base_2<K> Fb; typedef CGAL::No_intersection_tag Itag; //This tag could ben changed if we decide to handle intersection typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds; typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds, Itag> CDT; typedef CDT::Point cgalPoint; std::vector< std::pair<cgalPoint, size_t > > constraints; size_t constrCount = segments2D.size(); try { constraints.reserve(constrCount); } catch (const std::bad_alloc&) { if (outputErrorStr) strcpy(outputErrorStr, "Not enough memory"); return false; }; //We create the Constrained Delaunay Triangulation (CDT) CDT cdt; //We build the constraints for(size_t i = 0; i < constrCount; ++i) { const CCVector2 * pt = &points2D[segments2D[i]]; constraints.push_back(std::make_pair(cgalPoint(pt->x, pt->y), segments2D[i])); } //The CDT is built according to the constraints cdt.insert(constraints.begin(), constraints.end()); m_numberOfTriangles = static_cast<unsigned >(cdt.number_of_faces()); m_triIndexes = new int[cdt.number_of_faces()*3]; //The cgal data structure is converted into CC one if (m_numberOfTriangles > 0) { int faceCount = 0; for (CDT::Face_iterator face = cdt.faces_begin(); face != cdt.faces_end(); ++face, faceCount+=3) { m_triIndexes[0+faceCount] = static_cast<int>(face->vertex(0)->info()); m_triIndexes[1+faceCount] = static_cast<int>(face->vertex(1)->info()); m_triIndexes[2+faceCount] = static_cast<int>(face->vertex(2)->info()); }; } m_globalIterator = m_triIndexes; m_globalIteratorEnd = m_triIndexes + 3*m_numberOfTriangles; return true; #else if (outputErrorStr) strcpy(outputErrorStr, "CGAL library not supported"); return false; #endif }
bool Delaunay2dMesh::buildMesh( const std::vector<CCVector2>& points2D, const std::vector<int>& segments2D, char* outputErrorStr/*=0*/) { #if defined(USE_TRIANGLE_LIB) //we use the external library 'Triangle' triangulateio in; memset(&in,0,sizeof(triangulateio)); in.numberofpoints = static_cast<int>(points2D.size()); in.pointlist = (REAL*)(&points2D[0]); in.segmentlist = (int*)(&segments2D[0]); assert((segments2D.size() & 1) == 0); in.numberofsegments = static_cast<int>(segments2D.size()/2); triangulateio out; memset(&out,0,sizeof(triangulateio)); try { triangulate ( "pczBPNIOQY", &in, &out, 0 ); } catch (std::exception& e) { if (outputErrorStr) strcpy(outputErrorStr,e.what()); return false; } catch (...) { if (outputErrorStr) strcpy(outputErrorStr,"Unknown error"); return false; } m_numberOfTriangles = out.numberoftriangles; if (m_numberOfTriangles > 0) { m_triIndexes = out.trianglelist; //remove non existing points int* _tri = out.trianglelist; for (int i=0; i<out.numberoftriangles; ) { if ( _tri[0] >= in.numberofpoints || _tri[1] >= in.numberofpoints || _tri[2] >= in.numberofpoints) { int lasTriIndex = (out.numberoftriangles-1) * 3; _tri[0] = out.trianglelist[lasTriIndex + 0]; _tri[1] = out.trianglelist[lasTriIndex + 1]; _tri[2] = out.trianglelist[lasTriIndex + 2]; --out.numberoftriangles; } else { _tri += 3; ++i; } } //Reduce memory size if (out.numberoftriangles < static_cast<int>(m_numberOfTriangles)) { assert(out.numberoftriangles > 0); realloc(m_triIndexes, sizeof(int)*out.numberoftriangles*3); m_numberOfTriangles = out.numberoftriangles; } } trifree(out.segmentmarkerlist); trifree(out.segmentlist); m_globalIterator = m_triIndexes; m_globalIteratorEnd = m_triIndexes + 3*m_numberOfTriangles; return true; #elif defined(USE_CGAL_LIB) //CGAL boilerplate typedef CGAL::Exact_predicates_inexact_constructions_kernel K; //We define a vertex_base with info. The "info" (size_t) allow us to keep track of the original point index. typedef CGAL::Triangulation_vertex_base_with_info_2<size_t, K> Vb; typedef CGAL::Constrained_triangulation_face_base_2<K> Fb; typedef CGAL::No_intersection_tag Itag; //This tag could ben changed if we decide to handle intersection typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds; typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds, Itag> CDT; typedef CDT::Point cgalPoint; std::vector< std::pair<cgalPoint, size_t > > constraints; size_t constrCount = segments2D.size(); try { constraints.reserve(constrCount); } catch (const std::bad_alloc&) { if (outputErrorStr) strcpy(outputErrorStr, "Not enough memory"); return false; }; //We create the Constrained Delaunay Triangulation (CDT) CDT cdt; //We build the constraints for(size_t i = 0; i < constrCount; ++i) { const CCVector2 * pt = &points2D[segments2D[i]]; constraints.push_back(std::make_pair(cgalPoint(pt->x, pt->y), segments2D[i])); } //The CDT is built according to the constraints cdt.insert(constraints.begin(), constraints.end()); m_numberOfTriangles = static_cast<unsigned >(cdt.number_of_faces()); m_triIndexes = new int[cdt.number_of_faces()*3]; //The cgal data structure is converted into CC one if (m_numberOfTriangles > 0) { int faceCount = 0; for (CDT::Face_iterator face = cdt.faces_begin(); face != cdt.faces_end(); ++face, faceCount+=3) { m_triIndexes[0+faceCount] = static_cast<int>(face->vertex(0)->info()); m_triIndexes[1+faceCount] = static_cast<int>(face->vertex(1)->info()); m_triIndexes[2+faceCount] = static_cast<int>(face->vertex(2)->info()); }; } m_globalIterator = m_triIndexes; m_globalIteratorEnd = m_triIndexes + 3*m_numberOfTriangles; return true; #else if (outputErrorStr) strcpy(outputErrorStr, "Triangle library not supported"); return false; #endif }