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 FEASSERT(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 FEASSERT(p.size() % 3 == 0);
116 unsigned const num_vertices = p.size() / 3;
117 FEASSERT(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 FEASSERT(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 FEASSERT(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)
232 if(half_edges[i] == half_edges[i+1])
234 feX(
"::geodesic::Mesh::build_adjacencies",
235 "duplicate half edge");
242 m_edges.resize(number_of_edges);
243 unsigned edge_id = 0;
244 for(
unsigned i=0; i<half_edges.size();)
246 Edge& e = m_edges[edge_id];
249 e.adjacent_vertices().set_allocation(allocate_pointers(2),2);
251 e.adjacent_vertices()[0] = &m_vertices[half_edges[i].vertex_0];
252 e.adjacent_vertices()[1] = &m_vertices[half_edges[i].vertex_1];
254 e.length() = e.adjacent_vertices()[0]->distance(e.adjacent_vertices()[1]);
255 FEASSERT(e.length() > 1e-100);
257 if(i != half_edges.size()-1 && half_edges[i] == half_edges[i+1])
259 e.adjacent_faces().set_allocation(allocate_pointers(2),2);
260 e.adjacent_faces()[0] = &m_faces[half_edges[i].face_id];
261 e.adjacent_faces()[1] = &m_faces[half_edges[i+1].face_id];
266 e.adjacent_faces().set_allocation(allocate_pointers(1),1);
267 e.adjacent_faces()[0] = &m_faces[half_edges[i].face_id];
273 std::fill(count.begin(), count.end(), 0);
274 for(
unsigned i=0; i<m_edges.size(); ++i)
276 Edge& e = m_edges[i];
277 FEASSERT(e.adjacent_vertices().size()==2);
278 count[e.adjacent_vertices()[0]->id()]++;
279 count[e.adjacent_vertices()[1]->id()]++;
281 for(
unsigned i=0; i<m_vertices.size(); ++i)
283 m_vertices[i].adjacent_edges().set_allocation(allocate_pointers(count[i]),
286 std::fill(count.begin(), count.end(), 0);
287 for(
unsigned i=0; i<m_edges.size(); ++i)
289 Edge& e = m_edges[i];
290 for(
unsigned j=0; j<2; ++j)
292 vertex_pointer v = e.adjacent_vertices()[j];
293 v->adjacent_edges()[count[v->id()]++] = &e;
298 for(
unsigned i=0; i<m_faces.size(); ++i)
300 m_faces[i].adjacent_edges().set_allocation(allocate_pointers(3),3);
303 count.resize(m_faces.size());
304 std::fill(count.begin(), count.end(), 0);
305 for(
unsigned i=0; i<m_edges.size(); ++i)
307 Edge& e = m_edges[i];
308 for(
unsigned j=0; j<e.adjacent_faces().size(); ++j)
310 face_pointer f = e.adjacent_faces()[j];
311 FEASSERT(count[f->id()]<3);
312 f->adjacent_edges()[count[f->id()]++] = &e;
317 for(
unsigned i=0; i<m_faces.size(); ++i)
319 Face& f = m_faces[i];
322 for(
unsigned j=0; j<3; ++j)
324 for(
unsigned k=0; k<3; ++k)
326 vertex_pointer v = f.adjacent_vertices()[(j + k)%3];
327 abc[k] = f.opposite_edge(v)->length();
330 double angle = angle_from_edges(abc[0], abc[1], abc[2]);
331 FEASSERT(angle>1e-5);
333 f.corner_angles()[j] = angle;
336 FEASSERT(std::abs(sum - M_PI) < 1e-5);
340 std::vector<double> total_vertex_angle(m_vertices.size());
341 for(
unsigned i=0; i<m_faces.size(); ++i)
343 Face& f = m_faces[i];
344 for(
unsigned j=0; j<3; ++j)
346 vertex_pointer v = f.adjacent_vertices()[j];
347 total_vertex_angle[v->id()] += f.corner_angles()[j];
351 for(
unsigned i=0; i<m_vertices.size(); ++i)
353 Vertex& v = m_vertices[i];
354 v.saddle_or_boundary() = (total_vertex_angle[v.id()] > 2.0*M_PI - 1e-5);
357 for(
unsigned i=0; i<m_edges.size(); ++i)
359 Edge& e = m_edges[i];
362 e.adjacent_vertices()[0]->saddle_or_boundary() =
true;
363 e.adjacent_vertices()[1]->saddle_or_boundary() =
true;
367 #if FE_CODEGEN<=FE_DEBUG 372 inline bool Mesh::verify()
374 std::cout << std::endl;
377 std::vector<bool> map(m_vertices.size(),
false);
378 for(
unsigned i=0; i<m_edges.size(); ++i)
380 edge_pointer e = &m_edges[i];
381 map[e->adjacent_vertices()[0]->id()] =
true;
382 map[e->adjacent_vertices()[1]->id()] =
true;
384 FEASSERT(std::find(map.begin(), map.end(),
false) == map.end());
388 std::vector<face_pointer> stack(1,&m_faces[0]);
389 stack.reserve(m_faces.size());
391 map.resize(m_faces.size());
392 std::fill(map.begin(), map.end(),
false);
395 while(!stack.empty())
397 face_pointer f = stack.back();
400 for(
unsigned i=0; i<3; ++i)
402 edge_pointer e = f->adjacent_edges()[i];
403 face_pointer f_adjacent = e->opposite_face(f);
404 if(f_adjacent && !map[f_adjacent->id()])
406 map[f_adjacent->id()] =
true;
407 stack.push_back(f_adjacent);
419 std::cout <<
"::geodesic::Mesh::verify()\n";
421 std::cout <<
"mesh has " << m_vertices.size()
422 <<
" vertices, " << m_faces.size()
423 <<
" faces, " << m_edges.size()
426 unsigned total_boundary_edges = 0;
427 double longest_edge = 0;
428 double shortest_edge = 1e100;
429 for(
unsigned i=0; i<m_edges.size(); ++i)
431 Edge& e = m_edges[i];
432 total_boundary_edges += e.is_boundary() ? 1 : 0;
433 longest_edge = std::max(longest_edge, e.length());
434 shortest_edge = std::min(shortest_edge, e.length());
436 std::cout << total_boundary_edges <<
" edges are boundary edges\n";
437 std::cout <<
"shortest/longest edges are " 438 << shortest_edge <<
"/" 439 << longest_edge <<
" = " 440 << shortest_edge/longest_edge
444 double maxx = -1e100;
446 double maxy = -1e100;
448 double maxz = -1e100;
449 for(
unsigned i=0; i<m_vertices.size(); ++i)
451 Vertex& v = m_vertices[i];
452 minx = std::min(minx, v.x());
453 maxx = std::max(maxx, v.x());
454 miny = std::min(miny, v.y());
455 maxy = std::max(maxy, v.y());
456 minz = std::min(minz, v.z());
457 maxz = std::max(maxz, v.z());
459 std::cout <<
"enclosing XYZ box:" 460 <<
" X[" << minx <<
"," << maxx <<
"]" 461 <<
" Y[" << miny <<
"," << maxy <<
"]" 462 <<
" Z[" << minz <<
"," << maxz <<
"]" 465 double dx = maxx - minx;
466 double dy = maxy - miny;
467 double dz = maxz - minz;
468 std::cout <<
"approximate diameter of the mesh is " 469 << sqrt(dx*dx + dy*dy + dz*dz)
472 double min_angle = 1e100;
473 double max_angle = -1e100;
474 for(
unsigned i=0; i<m_faces.size(); ++i)
476 Face& f = m_faces[i];
477 for(
unsigned j=0; j<3; ++j)
479 double angle = f.corner_angles()[j];
480 min_angle = std::min(min_angle, angle);
481 max_angle = std::max(max_angle, angle);
484 std::cout <<
"min/max face angles are " 485 << min_angle/M_PI*180.0 <<
"/" 486 << max_angle/M_PI*180.0
489 std::cout << std::endl;
493 inline void fill_surface_point_structure(geodesic::SurfacePoint* point,
498 unsigned type = (unsigned) data[3];
499 unsigned id = (unsigned) data[4];
504 point->base_element() = &mesh->vertices()[id];
508 point->base_element() = &mesh->edges()[id];
512 point->base_element() = &mesh->faces()[id];
516 inline void fill_surface_point_double(geodesic::SurfacePoint* point,
520 data[0] = point->x();
521 data[1] = point->y();
522 data[2] = point->z();
523 data[4] = point->base_element()->id();
525 if(point->type() == VERTEX)
529 else if(point->type() == EDGE)
Definition: geodesic_cpp_03_02_2008/geodesic_algorithm_base.h:11