bool Delaunay2dMesh::buildMesh( const std::vector<CCVector2>& points2D, size_t pointCountToUse/*=0*/, 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::Triangulation_data_structure_2<Vb> Tds; typedef CGAL::Delaunay_triangulation_2<K, Tds> DT; typedef DT::Point cgalPoint; std::vector< std::pair<cgalPoint, size_t > > pts; size_t pointCount = points2D.size(); //we will use at most 'pointCountToUse' points (if not 0) if (pointCountToUse > 0 && pointCountToUse < pointCount) { pointCount = pointCountToUse; } if (pointCount < 3) { if (outputErrorStr) strcpy(outputErrorStr, "Not enough points"); return false; } try { pts.reserve(pointCount); } catch (const std::bad_alloc&) { if (outputErrorStr) strcpy(outputErrorStr, "Not enough memory"); return false; }; m_numberOfTriangles = 0; if (m_triIndexes) { delete[] m_triIndexes; m_triIndexes = 0; } for(size_t i = 0; i < pointCount; ++i) { const CCVector2 * pt = &points2D[i]; pts.push_back(std::make_pair(cgalPoint(pt->x, pt->y), i)); } //The delaunay triangulation is built according to the 2D point cloud DT dt(pts.begin(), pts.end()); m_numberOfTriangles = static_cast<unsigned >(dt.number_of_faces()); m_triIndexes = new int[dt.number_of_faces()*3]; //The cgal data structure is converted into CC one if (m_numberOfTriangles > 0) { int faceCount = 0; for (DT::Face_iterator face = dt.faces_begin(); face != dt.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, size_t pointCountToUse/*=0*/, char* outputErrorStr/*=0*/) { #if defined(USE_TRIANGLE_LIB) size_t pointCount = points2D.size(); //we will use at most 'pointCountToUse' points (if not 0) if (pointCountToUse > 0 && pointCountToUse < pointCount) { pointCount = pointCountToUse; } if (pointCount < 3) { if (outputErrorStr) strcpy(outputErrorStr, "Not enough points"); return false; } //reset m_numberOfTriangles = 0; if (m_triIndexes) { delete[] m_triIndexes; m_triIndexes = 0; } //we use the external library 'Triangle' triangulateio in; memset(&in,0,sizeof(triangulateio)); in.numberofpoints = static_cast<int>(pointCount); in.pointlist = (REAL*)(&points2D[0]); //set static variable for 'triunsuitable' (for Triangle lib with '-u' option) //s_maxSquareEdgeLength = maxEdgeLength*maxEdgeLength; //DGM: doesn't work this way --> triangle lib will simply add new points! try { triangulate ( "zQN", &in, &in, 0 ); } catch (std::exception& e) { if (outputErrorStr) strcpy(outputErrorStr,e.what()); return false; } catch (...) { if (outputErrorStr) strcpy(outputErrorStr,"Unknown error"); return false; } m_numberOfTriangles = in.numberoftriangles; if (m_numberOfTriangles > 0) m_triIndexes = in.trianglelist; 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::Triangulation_data_structure_2<Vb> Tds; typedef CGAL::Delaunay_triangulation_2<K, Tds> DT; typedef DT::Point cgalPoint; std::vector< std::pair<cgalPoint, size_t > > pts; size_t pointCount = points2D.size(); //we will use at most 'pointCountToUse' points (if not 0) if (pointCountToUse > 0 && pointCountToUse < pointCount) { pointCount = pointCountToUse; } if (pointCount < 3) { if (outputErrorStr) strcpy(outputErrorStr, "Not enough points"); return false; } try { pts.reserve(pointCount); } catch (const std::bad_alloc&) { if (outputErrorStr) strcpy(outputErrorStr, "Not enough memory"); return false; }; m_numberOfTriangles = 0; if (m_triIndexes) { delete[] m_triIndexes; m_triIndexes = 0; } for(size_t i = 0; i < pointCount; ++i) { const CCVector2 * pt = &points2D[i]; pts.push_back(std::make_pair(cgalPoint(pt->x, pt->y), i)); } //The delaunay triangulation is built according to the 2D point cloud DT dt(pts.begin(), pts.end()); m_numberOfTriangles = static_cast<unsigned >(dt.number_of_faces()); m_triIndexes = new int[dt.number_of_faces()*3]; //The cgal data structure is converted into CC one if (m_numberOfTriangles > 0) { int faceCount = 0; for (DT::Face_iterator face = dt.faces_begin(); face != dt.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, "Please link CC lib with either Triangle or CGAL"); return false; #endif }