2 #ifndef GEODESIC_MESH_20071231 3 #define GEODESIC_MESH_20071231 12 #include "geodesic_mesh_elements.h" 13 #include "geodesic_memory.h" 14 #include "geodesic_constants_and_simple_functions.h" 18 struct edge_visible_from_source
32 template<
class Po
ints,
class Faces>
33 void initialize_mesh_data(
unsigned num_vertices,
38 template<
class Po
ints,
class Faces>
39 void initialize_mesh_data(Points& p, Faces& tri);
41 std::vector<Vertex>& vertices(){
return m_vertices;};
42 std::vector<Edge>& edges(){
return m_edges;};
43 std::vector<Face>& faces(){
return m_faces;};
45 unsigned closest_vertices(SurfacePoint* p,
46 std::vector<vertex_pointer>* storage = NULL);
50 void build_adjacencies();
53 typedef void* void_pointer;
54 void_pointer allocate_pointers(
unsigned n)
56 return m_pointer_allocator.allocate(n);
59 std::vector<Vertex> m_vertices;
60 std::vector<Edge> m_edges;
61 std::vector<Face> m_faces;
63 SimlpeMemoryAllocator<void_pointer> m_pointer_allocator;
66 inline unsigned Mesh::closest_vertices(SurfacePoint* p,
67 std::vector<vertex_pointer>* storage)
69 assert(p->type() != UNDEFINED_POINT);
71 if(p->type() == VERTEX)
75 storage->push_back(static_cast<vertex_pointer>(p->base_element()));
79 else if(p->type() == FACE)
83 vertex_pointer* vp= p->base_element()->adjacent_vertices().begin();
84 storage->push_back(*vp);
85 storage->push_back(*(vp+1));
86 storage->push_back(*(vp+2));
90 else if(p->type() == EDGE)
92 edge_pointer edge =
static_cast<edge_pointer
>(p->base_element());
96 storage->push_back(edge->adjacent_vertices()[0]);
97 storage->push_back(edge->adjacent_vertices()[1]);
99 for(
unsigned i = 0; i < edge->adjacent_faces().size(); ++i)
101 face_pointer face = edge->adjacent_faces()[i];
102 storage->push_back(face->opposite_vertex(edge));
105 return 2 + edge->adjacent_faces().size();
112 template<
class Po
ints,
class Faces>
113 void Mesh::initialize_mesh_data(Points& p, Faces& tri)
115 assert(p.size() % 3 == 0);
116 unsigned const num_vertices = p.size() / 3;
117 assert(tri.size() % 3 == 0);
118 unsigned const num_faces = tri.size() / 3;
120 initialize_mesh_data(num_vertices, p, num_faces, tri);
123 template<
class Po
ints,
class Faces>
124 void Mesh::initialize_mesh_data(
unsigned num_vertices,
129 unsigned const approximate_number_of_internal_pointers = (num_vertices + num_faces)*4;
130 unsigned const max_number_of_pointer_blocks = 100;
131 m_pointer_allocator.reset(approximate_number_of_internal_pointers,
132 max_number_of_pointer_blocks);
134 m_vertices.resize(num_vertices);
135 for(
unsigned i=0; i<num_vertices; ++i)
137 Vertex& v = m_vertices[i];
140 unsigned shift = 3*i;
142 v.y() = p[shift + 1];
143 v.z() = p[shift + 2];
146 m_faces.resize(num_faces);
147 for(
unsigned i=0; i<num_faces; ++i)
149 Face& f = m_faces[i];
151 f.adjacent_vertices().set_allocation(allocate_pointers(3),3);
153 unsigned shift = 3*i;
154 for(
unsigned j=0; j<3; ++j)
156 unsigned vertex_index = tri[shift + j];
157 assert(vertex_index < num_vertices);
158 f.adjacent_vertices()[j] = &m_vertices[vertex_index];
165 inline void Mesh::build_adjacencies()
168 std::vector<unsigned> count(m_vertices.size());
169 for(
unsigned i=0; i<m_faces.size(); ++i)
171 Face& f = m_faces[i];
172 for(
unsigned j=0; j<3; ++j)
174 unsigned vertex_id = f.adjacent_vertices()[j]->id();
175 assert(vertex_id < m_vertices.size());
180 for(
unsigned i=0; i<m_vertices.size(); ++i)
182 Vertex& v = m_vertices[i];
183 unsigned num_adjacent_faces = count[i];
185 v.adjacent_faces().set_allocation(allocate_pointers(num_adjacent_faces),
189 std::fill(count.begin(), count.end(), 0);
190 for(
unsigned i=0; i<m_faces.size(); ++i)
192 Face& f = m_faces[i];
193 for(
unsigned j=0; j<3; ++j)
195 vertex_pointer v = f.adjacent_vertices()[j];
196 v->adjacent_faces()[count[v->id()]++] = &f;
202 std::vector<HalfEdge> half_edges(m_faces.size()*3);
204 for(
unsigned i=0; i<m_faces.size(); ++i)
206 Face& f = m_faces[i];
207 for(
unsigned j=0; j<3; ++j)
209 half_edges[k].face_id = i;
210 unsigned vertex_id_1 = f.adjacent_vertices()[j]->id();
211 unsigned vertex_id_2 = f.adjacent_vertices()[(j+1) % 3]->
id();
212 half_edges[k].vertex_0 = std::min(vertex_id_1, vertex_id_2);
213 half_edges[k].vertex_1 = std::max(vertex_id_1, vertex_id_2);
218 std::sort(half_edges.begin(), half_edges.end());
220 unsigned number_of_edges = 1;
221 for(
unsigned i=1; i<half_edges.size(); ++i)
223 if(half_edges[i] != half_edges[i-1])
229 if(i<half_edges.size()-1)
231 assert(half_edges[i] != half_edges[i+1]);
237 m_edges.resize(number_of_edges);
238 unsigned edge_id = 0;
239 for(
unsigned i=0; i<half_edges.size();)
241 Edge& e = m_edges[edge_id];
244 e.adjacent_vertices().set_allocation(allocate_pointers(2),2);
246 e.adjacent_vertices()[0] = &m_vertices[half_edges[i].vertex_0];
247 e.adjacent_vertices()[1] = &m_vertices[half_edges[i].vertex_1];
249 e.length() = e.adjacent_vertices()[0]->distance(e.adjacent_vertices()[1]);
250 assert(e.length() > 1e-100);
252 if(i != half_edges.size()-1 && half_edges[i] == half_edges[i+1])
254 e.adjacent_faces().set_allocation(allocate_pointers(2),2);
255 e.adjacent_faces()[0] = &m_faces[half_edges[i].face_id];
256 e.adjacent_faces()[1] = &m_faces[half_edges[i+1].face_id];
261 e.adjacent_faces().set_allocation(allocate_pointers(1),1);
262 e.adjacent_faces()[0] = &m_faces[half_edges[i].face_id];
268 std::fill(count.begin(), count.end(), 0);
269 for(
unsigned i=0; i<m_edges.size(); ++i)
271 Edge& e = m_edges[i];
272 assert(e.adjacent_vertices().size()==2);
273 count[e.adjacent_vertices()[0]->id()]++;
274 count[e.adjacent_vertices()[1]->id()]++;
276 for(
unsigned i=0; i<m_vertices.size(); ++i)
278 m_vertices[i].adjacent_edges().set_allocation(allocate_pointers(count[i]),
281 std::fill(count.begin(), count.end(), 0);
282 for(
unsigned i=0; i<m_edges.size(); ++i)
284 Edge& e = m_edges[i];
285 for(
unsigned j=0; j<2; ++j)
287 vertex_pointer v = e.adjacent_vertices()[j];
288 v->adjacent_edges()[count[v->id()]++] = &e;
293 for(
unsigned i=0; i<m_faces.size(); ++i)
295 m_faces[i].adjacent_edges().set_allocation(allocate_pointers(3),3);
298 count.resize(m_faces.size());
299 std::fill(count.begin(), count.end(), 0);
300 for(
unsigned i=0; i<m_edges.size(); ++i)
302 Edge& e = m_edges[i];
303 for(
unsigned j=0; j<e.adjacent_faces().size(); ++j)
305 face_pointer f = e.adjacent_faces()[j];
306 assert(count[f->id()]<3);
307 f->adjacent_edges()[count[f->id()]++] = &e;
312 for(
unsigned i=0; i<m_faces.size(); ++i)
314 Face& f = m_faces[i];
317 for(
unsigned j=0; j<3; ++j)
319 for(
unsigned k=0; k<3; ++k)
321 vertex_pointer v = f.adjacent_vertices()[(j + k)%3];
322 abc[k] = f.opposite_edge(v)->length();
325 double angle = angle_from_edges(abc[0], abc[1], abc[2]);
328 f.corner_angles()[j] = angle;
331 assert(std::abs(sum - M_PI) < 1e-5);
335 std::vector<double> total_vertex_angle(m_vertices.size());
336 for(
unsigned i=0; i<m_faces.size(); ++i)
338 Face& f = m_faces[i];
339 for(
unsigned j=0; j<3; ++j)
341 vertex_pointer v = f.adjacent_vertices()[j];
342 total_vertex_angle[v->id()] += f.corner_angles()[j];
346 for(
unsigned i=0; i<m_vertices.size(); ++i)
348 Vertex& v = m_vertices[i];
349 v.saddle_or_boundary() = (total_vertex_angle[v.id()] > 2.0*M_PI - 1e-5);
352 for(
unsigned i=0; i<m_edges.size(); ++i)
354 Edge& e = m_edges[i];
357 e.adjacent_vertices()[0]->saddle_or_boundary() =
true;
358 e.adjacent_vertices()[1]->saddle_or_boundary() =
true;
365 inline bool Mesh::verify()
367 std::cout << std::endl;
370 std::vector<bool> map(m_vertices.size(),
false);
371 for(
unsigned i=0; i<m_edges.size(); ++i)
373 edge_pointer e = &m_edges[i];
374 map[e->adjacent_vertices()[0]->id()] =
true;
375 map[e->adjacent_vertices()[1]->id()] =
true;
377 assert(std::find(map.begin(), map.end(),
false) == map.end());
381 std::vector<face_pointer> stack(1,&m_faces[0]);
382 stack.reserve(m_faces.size());
384 map.resize(m_faces.size());
385 std::fill(map.begin(), map.end(),
false);
388 while(!stack.empty())
390 face_pointer f = stack.back();
393 for(
unsigned i=0; i<3; ++i)
395 edge_pointer e = f->adjacent_edges()[i];
396 face_pointer f_adjacent = e->opposite_face(f);
397 if(f_adjacent && !map[f_adjacent->id()])
399 map[f_adjacent->id()] =
true;
400 stack.push_back(f_adjacent);
404 assert(std::find(map.begin(), map.end(),
false) == map.end());
407 std::cout <<
"mesh has " << m_vertices.size()
408 <<
" vertices, " << m_faces.size()
409 <<
" faces, " << m_edges.size()
412 unsigned total_boundary_edges = 0;
413 double longest_edge = 0;
414 double shortest_edge = 1e100;
415 for(
unsigned i=0; i<m_edges.size(); ++i)
417 Edge& e = m_edges[i];
418 total_boundary_edges += e.is_boundary() ? 1 : 0;
419 longest_edge = std::max(longest_edge, e.length());
420 shortest_edge = std::min(shortest_edge, e.length());
422 std::cout << total_boundary_edges <<
" edges are boundary edges\n";
423 std::cout <<
"shortest/longest edges are " 424 << shortest_edge <<
"/" 425 << longest_edge <<
" = " 426 << shortest_edge/longest_edge
430 double maxx = -1e100;
432 double maxy = -1e100;
434 double maxz = -1e100;
435 for(
unsigned i=0; i<m_vertices.size(); ++i)
437 Vertex& v = m_vertices[i];
438 minx = std::min(minx, v.x());
439 maxx = std::max(maxx, v.x());
440 miny = std::min(miny, v.y());
441 maxy = std::max(maxy, v.y());
442 minz = std::min(minz, v.z());
443 maxz = std::max(maxz, v.z());
445 std::cout <<
"enclosing XYZ box:" 446 <<
" X[" << minx <<
"," << maxx <<
"]" 447 <<
" Y[" << miny <<
"," << maxy <<
"]" 448 <<
" Z[" << minz <<
"," << maxz <<
"]" 451 double dx = maxx - minx;
452 double dy = maxy - miny;
453 double dz = maxz - minz;
454 std::cout <<
"approximate diameter of the mesh is " 455 << sqrt(dx*dx + dy*dy + dz*dz)
458 double min_angle = 1e100;
459 double max_angle = -1e100;
460 for(
unsigned i=0; i<m_faces.size(); ++i)
462 Face& f = m_faces[i];
463 for(
unsigned j=0; j<3; ++j)
465 double angle = f.corner_angles()[j];
466 min_angle = std::min(min_angle, angle);
467 max_angle = std::max(max_angle, angle);
470 std::cout <<
"min/max face angles are " 471 << min_angle/M_PI*180.0 <<
"/" 472 << max_angle/M_PI*180.0
475 std::cout << std::endl;
479 inline void fill_surface_point_structure(geodesic::SurfacePoint* point,
484 unsigned type = (unsigned) data[3];
485 unsigned id = (unsigned) data[4];
490 point->base_element() = &mesh->vertices()[id];
494 point->base_element() = &mesh->edges()[id];
498 point->base_element() = &mesh->faces()[id];
502 inline void fill_surface_point_double(geodesic::SurfacePoint* point,
506 data[0] = point->x();
507 data[1] = point->y();
508 data[2] = point->z();
509 data[4] = point->base_element()->id();
511 if(point->type() == VERTEX)
515 else if(point->type() == EDGE)
Definition: geodesic_cpp_03_02_2008/geodesic_algorithm_base.h:11