int main() { CDT cdt; Vertex_handle va = cdt.insert(Point(-2,0,1)); Vertex_handle vb = cdt.insert(Point(0,-2,1)); Vertex_handle vc = cdt.insert(Point(2,0,1)); Vertex_handle vd = cdt.insert(Point(0,1,1)); cdt.insert(Point(2, 0.6,1)); cdt.insert_constraint(va, vb); cdt.insert_constraint(vb, vc); cdt.insert_constraint(vc, vd); cdt.insert_constraint(vd, va); std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; std::cout << "Meshing..." << std::endl; Mesher mesher(cdt); mesher.set_criteria(Criteria(0.125, 0.05)); mesher.refine_mesh(); std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; std::cout << "Run Lloyd optimization..."; CGAL::lloyd_optimize_mesh_2(cdt, CGAL::parameters::max_iteration_number = 10); std::cout << " done." << std::endl; std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; }
int main() { CDT cdt; Vertex_handle va = cdt.insert(Point(-4,0)); Vertex_handle vb = cdt.insert(Point(0,-1)); Vertex_handle vc = cdt.insert(Point(4,0)); Vertex_handle vd = cdt.insert(Point(0,1)); cdt.insert(Point(2, 0.6)); cdt.insert_constraint(va, vb); cdt.insert_constraint(vb, vc); cdt.insert_constraint(vc, vd); cdt.insert_constraint(vd, va); std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; std::cout << "Meshing the triangulation with default criterias..." << std::endl; Mesher mesher(cdt); mesher.refine_mesh(); std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; std::cout << "Meshing with new criterias..." << std::endl; // 0.125 is the default shape bound. It corresponds to abound 20.6 degree. // 0.5 is the upper bound on the length of the longuest edge. // See reference manual for Delaunay_mesh_size_traits_2<K>. mesher.set_criteria(Criteria(0.125, 0.5)); mesher.refine_mesh(); std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; }
void insert_polygon( CDT& cdt, const Polygon_2& polygon ) { if (polygon.is_empty()) return; CDT::Vertex_handle v_prev = cdt.insert( *CGAL::cpp0x::prev( polygon.vertices_end() ) ); for (Polygon_2::Vertex_iterator vit = polygon.vertices_begin(); vit != polygon.vertices_end(); ++vit) { CDT::Vertex_handle vh = cdt.insert(*vit); cdt.insert_constraint(vh, v_prev); v_prev = vh; } }
int main() { CDT cdt; std::vector<std::pair<Vertex_handle, Vertex_handle> > constraints; std::vector<std::pair<Point,Point> > segments; segments.push_back(std::make_pair(Point(212.69651243, 168.58113131, 0), Point(212.69487813, 169.35340097, 0))); segments.push_back(std::make_pair(Point( 211.49303932, 161.00812931, 0), Point(211.49303932, 172.95244391, 0))); segments.push_back(std::make_pair(Point( 210.13500000, 169.20200000, 0), Point(232.65300000, 167.91200000, 0))); segments.push_back(std::make_pair(Point( 210.13500000, 169.20200000, 0), Point(232.69100000, 189.32500000, 0))); Point p, q; for(unsigned int i=0;i< segments.size(); i++){ p = segments[i].first; q = segments[i].second; Vertex_handle v = cdt.insert(p); Vertex_handle w = cdt.insert(q); constraints.push_back(std::make_pair(v,w)); } for(unsigned int i=0; i < constraints.size(); ++i){ std::cerr << i << std::endl; cdt.insert_constraint(constraints[i].first, constraints[i].second); } std::cerr << "done" << std::endl; return 0; }
int test_T2(const FT eps) { std::cout << "test_T2 (tolerance: " << eps << ")" << std::endl; std::vector<Point_2> points; Polygon_2 polygon1; polygon1.push_back(Point_2(0,0)); polygon1.push_back(Point_2(2,0)); polygon1.push_back(Point_2(2,2)); polygon1.push_back(Point_2(0,2)); // Insert the constraint... CDT cdt; cdt.insert_constraint(polygon1.vertices_begin(), polygon1.vertices_end(), true); // ... and four points outside the box to create faces outside the domain cdt.insert(Point_2(-1,-1)); cdt.insert(Point_2(3,-1)); cdt.insert(Point_2(3,3)); cdt.insert(Point_2(-1,3)); // Refine the triangulation CGAL::refine_Delaunay_mesh_2(cdt, Mesh_2_criteria(0.125, 0.5)); CGAL::Random_points_in_triangle_mesh_2<Point_2, CDT> g(cdt); std::copy_n(g, 300, std::back_inserter(points)); for(std::size_t i=0; i<points.size(); ++i) { Point_2 p = points[i]; for(int j=0; j<2; ++j) { double coords[2] = {p.x(), p.y()}; if(coords[j] > 2.0 + eps || coords[j] < -eps) { std::cerr << "ERROR : Generated point (" << p << ") is not on a face of the domain." << std::endl; return 0; } } } return 1; }
std::list< CgalTrian> erGeometryExtractTrianglesWithMesh( InputSegmentIterator debut, InputSegmentIterator fin,double mesh_angle=0.125,double mesh_size=4.) { CgalDT cgadt ; for( InputSegmentIterator icg=debut;icg!=fin;icg++) { cgadt.insert_constraint(icg->source(),icg->target()); }; CGAL::refine_Delaunay_mesh_2(cgadt, Criteria(mesh_angle,mesh_size)); CgalDT::Finite_edges_iterator bed,nif; // std::cout << "Nbre de noeuds:" << cgadt.number_of_vertices() << std::endl; // int i; // std::cin >> i; bed=cgadt.finite_edges_begin(); nif=cgadt.finite_edges_end(); CDT cdt; for(;bed!=nif;bed++) { CDT::Vertex_handle va = cdt.insert(bed->first->vertex(cgadt.cw(bed->second))->point()); CDT::Vertex_handle vb = cdt.insert(bed->first->vertex(cgadt.ccw(bed->second))->point()); if(cgadt.is_constrained(*bed)) { cdt.insert_constraint(va,vb); } } initializeID(cdt); discoverComponents(cdt); std::list<CgalTrian> triangs; CDT::All_faces_iterator deb=cdt.all_faces_begin(); for(;deb!=cdt.all_faces_end();deb++) { if(deb->is_in_domain()) { CgalTrian tri=cdt.triangle(deb); triangs.push_back(tri); } }; return triangs; };
int main() { CDT cdt; Vertex_handle va = cdt.insert(Point(-4,0)); Vertex_handle vb = cdt.insert(Point(0,-1)); Vertex_handle vc = cdt.insert(Point(4,0)); Vertex_handle vd = cdt.insert(Point(0,1)); cdt.insert(Point(2, 0.6)); cdt.insert_constraint(va, vb); cdt.insert_constraint(vb, vc); cdt.insert_constraint(vc, vd); cdt.insert_constraint(vd, va); std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; std::cout << "Meshing the triangulation..." << std::endl; CGAL::refine_Delaunay_mesh_2(cdt, Criteria(0.125, 0.5)); std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; }
int main() { CDT cdt; cdt.insert_constraint(Point(2, 5), Point(8, 5)); cdt.insert(Point(5, 6)); cdt.insert(Point(5, 4)); std::pair<Vertex_handle,Vertex_handle> p; for(CDT::Subconstraint_iterator sit = cdt.subconstraints_begin(); sit != cdt.subconstraints_end(); ++sit){ p = (*sit).first; Vertex_handle vh1 = p.first; Vertex_handle vh2 = p.second; std::cerr << "subconstraint: " << vh1->point() << " -- " << vh2->point() << std::endl; } std::cerr << "\nMake Gabriel" << std::endl; CGAL::make_conforming_Gabriel_2(cdt); int counter = 0; for(CDT::Subconstraint_iterator sit = cdt.subconstraints_begin(); sit != cdt.subconstraints_end(); ++sit){ ++counter; p = (*sit).first; Vertex_handle vh1 = p.first; Vertex_handle vh2 = p.second; std::cerr << "subconstraint: " << vh1->point() << " -- " << vh2->point() << std::endl; } assert(counter>1); return 0; }
void FixedPlaneMesh::TrianglatePolygon(const double3& normal, std::vector<Point3D>& pts, ListOfvertices& results) { if (pts.size() < 3) return ; if (pts.size() ==3) { VertexInfo vi1(pts[0], normal, mColor); VertexInfo vi2(pts[1], normal, mColor); VertexInfo vi3(pts[2], normal, mColor); results.push_back(vi1); results.push_back(vi2); results.push_back(vi3); return ; } typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Triangulation_vertex_base_2<K> Vb; typedef CGAL::Constrained_triangulation_face_base_2<K> Fb; typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS; //typedef CGAL::Exact_predicates_tag Itag; typedef CGAL::Constrained_Delaunay_triangulation_2<K, TDS, CGAL::No_intersection_tag> CDT; vec3<double> origin = pts[0]; vec3<double> N = normal; vec3<double> U = normalize(pts[1] - origin); vec3<double> V = cross(N, U); CDT cdt; CDT::Vertex_handle vh1, vh2, vh3; vec3<double> v0 = PosToLocal(U, V, N, origin, pts[0]); CDT::Point p0(v0.x, v0.y); vh1 = vh3 = cdt.insert(p0); for ( int i = 1; i< pts.size() ; i++) { vec3<double> v1 = PosToLocal(U, V, N, origin, pts[i]); CDT::Point p1(v1.x, v1.y); vh2 = cdt.insert(p1); cdt.insert_constraint(vh1, vh2); vh1 = vh2; } cdt.insert_constraint(vh2, vh3); int count = cdt.number_of_faces() ; results.reserve(count*3); for (CDT::Finite_faces_iterator fit = cdt.finite_faces_begin(); fit != cdt.finite_faces_end(); ++fit) { vec2<double> v0(fit->vertex(2)->point().x(),fit->vertex(2)->point().y() ); vec2<double> v1(fit->vertex(1)->point().x(),fit->vertex(1)->point().y() ); vec2<double> v2(fit->vertex(0)->point().x(),fit->vertex(0)->point().y() ); if (IsEqual(cross(v0- v2, v1-v2), (double)0., (double)EPSF )) continue; // vec3<double > p0(v0, 0.0); vec3<double > p1(v1, 0.0); vec3<double > p2(v2, 0.0); p0 = PosToGlobal(U, V, N, origin, p0); p1 = PosToGlobal(U, V, N, origin, p1); p2 = PosToGlobal(U, V, N, origin, p2); VertexInfo vi1(p0, N, mColor); VertexInfo vi2(p1, N, mColor); VertexInfo vi3(p2, N, mColor); results.push_back(vi1); results.push_back(vi2); results.push_back(vi3); } }
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 }
void triangulate(const Polygon_2& polygon, Cut_iter cuts_begin, Cut_iter cuts_end, const boost::unordered_map<Point_3, boost::unordered_set<Segment_3_undirected> >& point2edges, Out_iter triangles) { typedef CGAL::Triangulation_vertex_base_2<Kernel> Vb; typedef CGAL::Triangulation_vertex_base_with_info_2<Point_3, Kernel, Vb> Info; typedef CGAL::Constrained_triangulation_face_base_2<Kernel> Fb; typedef CGAL::Triangulation_data_structure_2<Info,Fb> TDS; typedef CGAL::Exact_predicates_tag Itag; typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, TDS, Itag> CDT; typedef CDT::Vertex_handle Vertex_handle; static log4cplus::Logger logger = log4cplus::Logger::getInstance("polygon_utils"); Polygon_2 p(polygon); LOG4CPLUS_TRACE(logger, "Triangulating " << pp(p)); if (p.size() < 3) return; bool vertical = is_vertical(p); if (vertical) { LOG4CPLUS_TRACE(logger, "Polygon is vertical. Rotating."); p = yz_swap_neg(p); } bool reverse = !p.is_counterclockwise_oriented(); if (reverse) p.reverse_orientation(); CDT cdt; boost::unordered_map<Point_3, Vertex_handle> point2handle; for (Polygon_2::Vertex_iterator it = p.vertices_begin(); it != p.vertices_end(); ++it) { Vertex_handle h = cdt.insert(*it); point2handle[*it] = h; h->info() = *it;//it->z(); } Polygon_2::Vertex_circulator start = p.vertices_circulator(); Polygon_2::Vertex_circulator c = start; Polygon_2::Vertex_circulator n = c; ++n; do { Vertex_handle ch = point2handle[*c];//cdt.insert(*c); Vertex_handle nh = point2handle[*n];//cdt.insert(*n); // ch->info() = c->z(); // nh->info() = n->z(); // cdt.insert_constraint(*c, *n); cdt.insert_constraint(ch, nh); ++c; ++n; } while (c != start); for (Cut_iter c_it = cuts_begin; c_it != cuts_end; ++c_it) { Polyline_2 cut = *c_it; LOG4CPLUS_TRACE(logger, "Adding cut: " << pp(cut)); if (vertical) cut = yz_swap_neg(cut); for (Polyline_2::const_iterator c = cut.begin(); c != cut.end(); ++c) { Polyline_2::const_iterator n = c; ++n; if (n != cut.end()) { const Point_3& cp = *c; const Point_3& np = *n; if (point2handle.find(cp) == point2handle.end()) { Vertex_handle h = cdt.insert(cp); point2handle[cp] = h; h->info() = cp;//cp.z(); } if (point2handle.find(np) == point2handle.end()) { Vertex_handle h = cdt.insert(np); point2handle[np] = h; h->info() = np;//np.z(); } Vertex_handle ch = point2handle[*c];//cdt.insert(*c); Vertex_handle nh = point2handle[*n];//cdt.insert(*n); // ch->info() = c->z(); // nh->info() = n->z(); // cdt.insert_constraint(*c, *n); cdt.insert_constraint(ch, nh); LOG4CPLUS_TRACE(logger, " " << pp(Segment_2(*c, *n))); } } } // Loop through the triangulation and store the vertices of each triangle for (CDT::Finite_faces_iterator ffi = cdt.finite_faces_begin(); ffi != cdt.finite_faces_end(); ++ffi) { Triangle t; Point_3 center = centroid(ffi->vertex(0)->info(), ffi->vertex(1)->info(), ffi->vertex(2)->info()); if (p.has_on_bounded_side(center) && is_legal(ffi->vertex(0)->info(), ffi->vertex(1)->info(), ffi->vertex(2)->info(), point2edges)) { for (int i = 0; i < 3; ++i) { int idx = reverse ? 2-i : i; if (!vertical) { // Point_3 p(ffi->vertex(i)->point()); // p = Point_3(p.x(), p.y(), ffi->vertex(i)->info()); Point_3 p(ffi->vertex(i)->info()); t[idx] = p; } else { // Point_3 p(ffi->vertex(i)->point()); // p = Point_3(p.x(), p.y(), ffi->vertex(i)->info()); Point_3 p(ffi->vertex(i)->info()); t[idx] = yz_swap_pos(p); } } LOG4CPLUS_TRACE(logger, "Adding tile: " << pp_tri(t)); *triangles++ = t; } } }
/* * BuildCutLinesInDEM * * This routine builds horizontal and vertical lines in a DEM via constraints. * Useful for cutting over on a rectangularly mapped texture. * * The DEM points that are used are removed from the mesh to keep them from getting hit multiple times. * */ void BuildCutLinesInDEM( DEMGeo& ioDem, CDT& outMesh, int segments) // Number of cuts per dim, 1 means no action taken! { CDT::Face_handle local; int x_interval = (ioDem.mWidth-1) / segments; int y_interval = (ioDem.mHeight-1) / segments; vector<CDT::Vertex_handle> junctions; junctions.resize((segments+1)*(segments+1)); // First, there will be some crossing points - add every one of them to the triangulation. int x, y, dx, dy; for (y = 0; y < ioDem.mHeight; y += y_interval) for (x = 0; x < ioDem.mWidth; x += x_interval) { float h = ioDem(x,y); if (h != NO_DATA) { // gMeshPoints.push_back(Point_2(ioDem.x_to_lon(x),ioDem.y_to_lat(y))); #if !NO_TRIANGULATE CDT::Vertex_handle vv = outMesh.insert(CDT::Point(ioDem.x_to_lon(x),ioDem.y_to_lat(y)), local); vv->info().height = h; local = vv->face(); #endif junctions[(x / x_interval) + (y / y_interval) * (segments+1)] = vv; } else AssertPrintf("Needed DEM point AWOL - %d,%d.\n",x,y); } // Next, add the vertical segments. Run through each vertical stripe except the edges, // for every horizontal one except the top. This is each vertical band we must add. for (y = y_interval; y < ioDem.mHeight; y += y_interval) for (x = x_interval; x < (ioDem.mWidth-x_interval); x += x_interval) { CDT::Vertex_handle v1, v2; v1 = junctions[(x / x_interval) + ((y-y_interval) / y_interval) * (segments+1)]; for (dy = y - y_interval + 1; dy < y; ++dy) { float h = ioDem(x,dy); if (h != NO_DATA) { // gMeshPoints.push_back(Point_2(ioDem.x_to_lon(x),ioDem.y_to_lat(dy))); #if !NO_TRIANGULATE v2 = outMesh.insert(CDT::Point(ioDem.x_to_lon(x),ioDem.y_to_lat(dy)), local); v2->info().height = h; local = v2->face(); outMesh.insert_constraint(v1, v2); v2 = v1; #endif } } v2 = junctions[(x / x_interval) + (y / y_interval) * (segments+1)]; outMesh.insert_constraint(v1, v2); } // Same thing but horizontal-like. for (y = y_interval; y < (ioDem.mHeight-y_interval); y += y_interval) for (x = x_interval; x < ioDem.mWidth; x += x_interval) { CDT::Vertex_handle v1, v2; v1 = junctions[((x-x_interval) / x_interval) + (y / y_interval) * (segments+1)]; for (dx = x - x_interval + 1; dx < x; ++dx) { float h = ioDem(dx,y); if (h != NO_DATA) { // gMeshPoints.push_back(Point_2(ioDem.x_to_lon(dx),ioDem.y_to_lat(y))); #if !NO_TRIANGULATE v2 = outMesh.insert(CDT::Point(ioDem.x_to_lon(dx),ioDem.y_to_lat(y)), local); v2->info().height = h; local = v2->face(); outMesh.insert_constraint(v1, v2); v2 = v1; #endif } } v2 = junctions[(x / x_interval) + (y / y_interval) * (segments+1)]; outMesh.insert_constraint(v1, v2); } }
int main() { typedef viennagrid::plc_2d_mesh mesh_type; mesh_type mesh; typedef viennagrid::result_of::point<mesh_type>::type point_type; typedef viennagrid::result_of::element<mesh_type, viennagrid::vertex_tag>::type vertex_type; typedef viennagrid::result_of::handle<mesh_type, viennagrid::vertex_tag>::type vertex_handle_type; typedef viennagrid::result_of::element<mesh_type, viennagrid::line_tag>::type line_type; typedef viennagrid::result_of::handle<mesh_type, viennagrid::line_tag>::type line_handle_type; typedef viennagrid::result_of::element<mesh_type, viennagrid::plc_tag>::type plc_type; typedef viennagrid::result_of::handle<mesh_type, viennagrid::plc_tag>::type plc_handle_type; plc_handle_type plc_handle; { std::vector<vertex_handle_type> v; v.push_back( viennagrid::make_vertex( mesh, point_type(0, 0) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(10, 0) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(20, 10) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(20, 20) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(10, 20) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(0, 10) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(5, 5) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(10, 10) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(12, 10) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(10, 12) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(8, 10) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(15, 15) ) ); std::vector<line_handle_type> lines; { std::vector<vertex_handle_type>::iterator start = v.begin(); std::vector<vertex_handle_type>::iterator end = v.begin() + 7; std::vector<vertex_handle_type>::iterator it1 = start; std::vector<vertex_handle_type>::iterator it2 = it1; ++it2; for (; it2 != end; ++it1, ++it2) lines.push_back( viennagrid::make_line(mesh, *it1, *it2) ); lines.push_back( viennagrid::make_line(mesh, *it1, *start) ); } { std::vector<vertex_handle_type>::iterator start = v.begin() + 7; std::vector<vertex_handle_type>::iterator end = v.begin() + 10; std::vector<vertex_handle_type>::iterator it1 = start; std::vector<vertex_handle_type>::iterator it2 = it1; ++it2; for (; it2 != end; ++it1, ++it2) lines.push_back( viennagrid::make_line(mesh, *it1, *it2) ); lines.push_back( viennagrid::make_line(mesh, *it1, *start) ); } lines.push_back( viennagrid::make_element<line_type>( mesh, v.begin() + 9, v.begin() + 11 ) ); vertex_handle_type point = v[11]; std::vector<point_type> hole_points; hole_points.push_back( point_type(10.5, 10.5) ); plc_handle = viennagrid::make_plc( mesh, lines.begin(), lines.end(), &point, &point + 1, hole_points.begin(), hole_points.end() ); } plc_type & plc = viennagrid::dereference_handle(mesh, plc_handle); typedef viennagrid::result_of::element_range<plc_type, viennagrid::vertex_tag>::type vertex_range_type; typedef viennagrid::result_of::iterator<vertex_range_type>::type vertex_range_iterator; typedef viennagrid::result_of::element_range<plc_type, viennagrid::line_tag>::type line_range_type; typedef viennagrid::result_of::iterator<line_range_type>::type line_range_iterator; typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Triangulation_vertex_base_2<Kernel> VertexBase; typedef CGAL::Delaunay_mesh_face_base_2<Kernel> FaceBase; typedef CGAL::Triangulation_data_structure_2<VertexBase, FaceBase> Triangulation_structure; typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, Triangulation_structure> CDT; typedef CGAL::Delaunay_mesh_size_criteria_2<CDT> Criteria; typedef CDT::Vertex_handle Vertex_handle; typedef CDT::Point Point; CDT cdt; std::map<vertex_handle_type, Vertex_handle> vertex_handle_map; vertex_range_type vertices = viennagrid::elements<viennagrid::vertex_tag>(plc); for (vertex_range_iterator it = vertices.begin(); it != vertices.end(); ++it) { vertex_handle_type const & vtx_handle = it.handle(); vertex_type const & vtx = *it; point_type const & vgrid_point = viennagrid::point( mesh, vtx ); Vertex_handle handle = cdt.insert( Point(vgrid_point[0], vgrid_point[1]) ); vertex_handle_map[vtx_handle] = handle; } line_range_type lines = viennagrid::elements<viennagrid::line_tag>(plc); for (line_range_iterator it = lines.begin(); it != lines.end(); ++it) { line_type & line = *it; vertex_handle_type vgrid_v0 = viennagrid::elements<viennagrid::vertex_tag>(line).handle_at(0); vertex_handle_type vgrid_v1 = viennagrid::elements<viennagrid::vertex_tag>(line).handle_at(1); Vertex_handle cgal_v0 = vertex_handle_map[vgrid_v0]; Vertex_handle cgal_v1 = vertex_handle_map[vgrid_v1]; cdt.insert_constraint(cgal_v0, cgal_v1); } std::vector<point_type> & vgrid_list_of_holes = viennagrid::hole_points(plc); std::list<Point> cgal_list_of_holes; for (std::vector<point_type>::iterator it = vgrid_list_of_holes.begin(); it != vgrid_list_of_holes.end(); ++it) cgal_list_of_holes.push_back( Point( (*it)[0], (*it)[1] ) ); CGAL::refine_Delaunay_mesh_2(cdt, cgal_list_of_holes.begin(), cgal_list_of_holes.end(), Criteria()); std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; std::cout << "Number of finite faces: " << cdt.number_of_faces() << std::endl; typedef viennagrid::triangular_2d_mesh triangle_mesh_type; triangle_mesh_type triangle_mesh; typedef viennagrid::result_of::point<triangle_mesh_type>::type triangle_point_type; typedef viennagrid::result_of::element<triangle_mesh_type, viennagrid::vertex_tag>::type triangle_vertex_type; typedef viennagrid::result_of::handle<triangle_mesh_type, viennagrid::vertex_tag>::type triangle_vertex_handle_type; typedef viennagrid::result_of::element<triangle_mesh_type, viennagrid::line_tag>::type triangle_line_type; typedef viennagrid::result_of::handle<triangle_mesh_type, viennagrid::line_tag>::type triangle_line_handle_type; typedef viennagrid::result_of::element<triangle_mesh_type, viennagrid::triangle_tag>::type triangle_triangle_type; typedef viennagrid::result_of::handle<triangle_mesh_type, viennagrid::triangle_tag>::type triangle_triangle__handle_type; std::map<Point, triangle_vertex_handle_type> points; int mesh_faces_counter = 0; for(CDT::Finite_faces_iterator fit = cdt.finite_faces_begin(); fit != cdt.finite_faces_end(); ++fit) { if(fit->is_in_domain()) { typedef CDT::Triangle Triangle; Triangle tri = cdt.triangle(fit); triangle_vertex_handle_type vgrid_vtx[3]; for (int i = 0; i < 3; ++i) { std::map<Point, triangle_vertex_handle_type>::iterator pit = points.find( tri[i] ); if (pit == points.end()) { vgrid_vtx[i] = viennagrid::make_vertex( triangle_mesh, triangle_point_type(tri[i].x(), tri[i].y()) ); points[ tri[i] ] = vgrid_vtx[i]; } else vgrid_vtx[i] = pit->second; } viennagrid::make_element<triangle_triangle_type>( triangle_mesh, vgrid_vtx, vgrid_vtx+3 ); std::cout << tri << std::endl; ++mesh_faces_counter; } } std::cout << "Number of faces in the mesh mesh: " << mesh_faces_counter << std::endl; std::copy( viennagrid::elements<triangle_triangle_type>(triangle_mesh).begin(), viennagrid::elements<triangle_triangle_type>(triangle_mesh).end(), std::ostream_iterator<triangle_triangle_type>(std::cout, "\n") ); viennagrid::io::vtk_writer<triangle_mesh_type> vtk_writer; vtk_writer(triangle_mesh, "test"); }
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 }