2 #ifndef GEODESIC_MESH_20071231
3 #define GEODESIC_MESH_20071231
32 template<
class Po
ints,
class Faces>
36 Faces& tri,
const float* curvature,
int mode,
int strain);
38 template<
class Po
ints,
class Faces>
41 void update_weight(
const float *curvature,
int mode,
double strain,
double sigmo);
43 std::vector<Vertex>&
vertices(){
return m_vertices;};
44 std::vector<Edge>&
edges(){
return m_edges;};
45 std::vector<Face>&
faces(){
return m_faces;};
48 std::vector<vertex_pointer>* storage = NULL);
52 void build_adjacencies(
const float *curvature,
int mode,
int strain);
55 typedef void* void_pointer;
56 void_pointer allocate_pointers(
unsigned n)
58 return m_pointer_allocator.
allocate(n);
61 std::vector<Vertex> m_vertices;
62 std::vector<Edge> m_edges;
63 std::vector<Face> m_faces;
65 SimlpeMemoryAllocator<void_pointer> m_pointer_allocator;
69 std::vector<vertex_pointer>* storage)
86 storage->push_back(*vp);
87 storage->push_back(*(vp+1));
88 storage->push_back(*(vp+2));
114 template<
class Po
ints,
class Faces>
117 assert(p.size() % 3 == 0);
118 unsigned const num_vertices = p.size() / 3;
119 assert(tri.size() % 3 == 0);
120 unsigned const num_faces = tri.size() / 3;
125 template<
class Po
ints,
class Faces>
129 Faces& tri,
const float* curvature,
int mode,
int strain)
133 unsigned const approximate_number_of_internal_pointers = (num_vertices + num_faces)*4;
137 unsigned const max_number_of_pointer_blocks = 100;
138 m_pointer_allocator.
reset(approximate_number_of_internal_pointers,
139 max_number_of_pointer_blocks);
143 m_vertices.resize(num_vertices);
144 for(
unsigned i=0; i<num_vertices; ++i)
146 Vertex& v = m_vertices[i];
149 unsigned shift = 3*i;
151 v.
y() = p[shift + 1];
152 v.
z() = p[shift + 2];
157 m_faces.resize(num_faces);
158 for(
unsigned i=0; i<num_faces; ++i)
161 Face& f = m_faces[i];
165 unsigned shift = 3*i;
166 unsigned vertex_index;
167 for(
unsigned j=0; j<3; ++j)
170 vertex_index = tri[shift + j];
171 assert(vertex_index < num_vertices);
179 build_adjacencies(curvature,mode,strain);
182 inline void Mesh::build_adjacencies(
const float *curvature,
int mode,
int strain)
185 std::vector<unsigned> count(m_vertices.size());
186 for(
unsigned i=0; i<m_faces.size(); ++i)
188 Face& f = m_faces[i];
189 for(
unsigned j=0; j<3; ++j)
197 for(
unsigned i=0; i<m_vertices.size(); ++i)
199 Vertex& v = m_vertices[i];
200 unsigned num_adjacent_faces = count[i];
202 v.adjacent_faces().set_allocation(allocate_pointers(num_adjacent_faces),
206 std::fill(count.begin(), count.end(), 0);
207 for(
unsigned i=0; i<m_faces.size(); ++i)
209 Face& f = m_faces[i];
210 for(
unsigned j=0; j<3; ++j)
213 v->adjacent_faces()[count[v->id()]++] = &f;
219 std::vector<HalfEdge> half_edges(m_faces.size()*3);
221 for(
unsigned i=0; i<m_faces.size(); ++i)
223 Face& f = m_faces[i];
224 for(
unsigned j=0; j<3; ++j)
226 half_edges[k].face_id = i;
227 unsigned vertex_id_1 = f.adjacent_vertices()[j]->id();
228 unsigned vertex_id_2 = f.adjacent_vertices()[(j+1) % 3]->
id();
229 half_edges[k].vertex_0 =
std::min(vertex_id_1, vertex_id_2);
230 half_edges[k].vertex_1 =
std::max(vertex_id_1, vertex_id_2);
235 std::sort(half_edges.begin(), half_edges.end());
237 unsigned number_of_edges = 1;
238 bool last_shared =
false;
240 for(
unsigned i=1; i<half_edges.size(); ++i)
242 if( half_edges[i] != half_edges[i-1] || last_shared )
250 if(i<half_edges.size()-1)
252 if( half_edges[i] == half_edges[i+1])
258 std::cerr <<
"Warning: Duplicate edges. The mesh is malformed: "
259 <<
"some triangles share an edge with more than one "
260 <<
"other triangle.\n";
269 m_edges.resize(number_of_edges);
270 unsigned edge_id = 0;
271 for(
unsigned i=0; i<half_edges.size();)
273 std::cout <<
"\ri: " << i << std::flush;
275 Edge& e = m_edges[edge_id];
278 e.adjacent_vertices().set_allocation(allocate_pointers(2),2);
280 e.adjacent_vertices()[0] = &m_vertices[half_edges[i].vertex_0];
281 e.adjacent_vertices()[1] = &m_vertices[half_edges[i].vertex_1];
295 double a1 = 0.0,a2 = 0.0;
297 if (curvature!= NULL && mode != 0)
302 a1 = pow ((1.0)/(1.0 + exp(-strain*curvature[v1->id()])), 2);
303 a2 = pow ((1.0)/(1.0 + exp(-strain*curvature[v2->id()])), 2);
309 a1 = pow ((1.0)/(1.0 + exp(strain*curvature[v1->id()])), 2);
310 a2 = pow ((1.0)/(1.0 + exp(strain*curvature[v2->id()])), 2);
313 e.length() = (v1->distance(v2) * (a1 + a2));
316 e.length() = e.adjacent_vertices()[0]->distance(e.adjacent_vertices()[1]);
321 if(i != half_edges.size()-1 && half_edges[i] == half_edges[i+1])
323 e.adjacent_faces().set_allocation(allocate_pointers(2),2);
324 e.adjacent_faces()[0] = &m_faces[half_edges[i].face_id];
325 e.adjacent_faces()[1] = &m_faces[half_edges[i+1].face_id];
330 e.adjacent_faces().set_allocation(allocate_pointers(1),1);
331 e.adjacent_faces()[0] = &m_faces[half_edges[i].face_id];
337 std::fill(count.begin(), count.end(), 0);
338 for(
unsigned i=0; i<m_edges.size(); ++i)
340 Edge& e = m_edges[i];
341 assert(e.adjacent_vertices().size()==2);
342 count[e.adjacent_vertices()[0]->id()]++;
343 count[e.adjacent_vertices()[1]->id()]++;
345 for(
unsigned i=0; i<m_vertices.size(); ++i)
347 m_vertices[i].adjacent_edges().set_allocation(allocate_pointers(count[i]),
350 std::fill(count.begin(), count.end(), 0);
351 for(
unsigned i=0; i<m_edges.size(); ++i)
353 Edge& e = m_edges[i];
354 for(
unsigned j=0; j<2; ++j)
357 v->adjacent_edges()[count[v->id()]++] = &e;
362 for(
unsigned i=0; i<m_faces.size(); ++i)
364 m_faces[i].adjacent_edges().set_allocation(allocate_pointers(3),3);
367 count.resize(m_faces.size());
368 std::fill(count.begin(), count.end(), 0);
369 for(
unsigned i=0; i<m_edges.size(); ++i)
371 Edge& e = m_edges[i];
372 for(
unsigned j=0; j<e.adjacent_faces().size(); ++j)
375 assert(count[f->id()]<3);
376 f->adjacent_edges()[count[f->id()]++] = &e;
381 for(
unsigned i=0; i<m_faces.size(); ++i)
383 Face& f = m_faces[i];
386 for(
unsigned j=0; j<3; ++j)
388 for(
unsigned k=0; k<3; ++k)
391 abc[k] = f.opposite_edge(v)->length();
399 f.corner_angles()[j] = angle;
406 std::vector<double> total_vertex_angle(m_vertices.size());
407 for(
unsigned i=0; i<m_faces.size(); ++i)
409 Face& f = m_faces[i];
410 for(
unsigned j=0; j<3; ++j)
413 total_vertex_angle[v->id()] += f.corner_angles()[j];
417 for(
unsigned i=0; i<m_vertices.size(); ++i)
419 Vertex& v = m_vertices[i];
420 v.saddle_or_boundary() = (total_vertex_angle[v.id()] > 2.0*
M_PI - 1e-5);
423 for(
unsigned i=0; i<m_edges.size(); ++i)
425 Edge& e = m_edges[i];
428 e.adjacent_vertices()[0]->saddle_or_boundary() =
true;
429 e.adjacent_vertices()[1]->saddle_or_boundary() =
true;
439 std::vector<unsigned> count(m_vertices.size());
440 for(
unsigned i=0; i<m_faces.size(); ++i)
442 Face& f = m_faces[i];
443 for(
unsigned j=0; j<3; ++j)
446 assert(vertex_id < m_vertices.size());
451 for(
unsigned i=0; i<m_vertices.size(); ++i)
453 Vertex& v = m_vertices[i];
454 unsigned num_adjacent_faces = count[i];
460 std::fill(count.begin(), count.end(), 0);
461 for(
unsigned i=0; i<m_faces.size(); ++i)
463 Face& f = m_faces[i];
464 for(
unsigned j=0; j<3; ++j)
473 std::vector<HalfEdge> half_edges(m_faces.size()*3);
475 for(
unsigned i=0; i<m_faces.size(); ++i)
477 Face& f = m_faces[i];
478 for(
unsigned j=0; j<3; ++j)
480 half_edges[k].face_id = i;
483 half_edges[k].vertex_0 =
std::min(vertex_id_1, vertex_id_2);
484 half_edges[k].vertex_1 =
std::max(vertex_id_1, vertex_id_2);
489 std::sort(half_edges.begin(), half_edges.end());
491 unsigned number_of_edges = 1;
492 for(
unsigned i=1; i<half_edges.size(); ++i)
494 if(half_edges[i] != half_edges[i-1])
500 if(i<half_edges.size()-1)
502 assert(half_edges[i] != half_edges[i+1]);
508 m_edges.resize(number_of_edges);
509 unsigned edge_id = 0;
510 for(
unsigned i=0; i<half_edges.size();)
512 Edge& e = m_edges[edge_id];
532 double a1 = 0.0,a2 = 0.0;
534 if (curvature!= NULL && mode != 0)
539 a1 = pow ((
double)(1.0)/(1.0 + exp(-strain*curvature[v1->
id()])), (
double)sigmo);
540 a2 = pow ((
double)(1.0)/(1.0 + exp(-strain*curvature[v2->
id()])), (
double)sigmo);
546 a1 = pow ((
double)(1.0)/(1.0 + exp(strain*curvature[v1->
id()])), (
double)sigmo);
547 a2 = pow ((
double)(1.0)/(1.0 + exp(strain*curvature[v2->
id()])), (
double)sigmo);
557 if(i != half_edges.size()-1 && half_edges[i] == half_edges[i+1])
573 std::fill(count.begin(), count.end(), 0);
574 for(
unsigned i=0; i<m_edges.size(); ++i)
576 Edge& e = m_edges[i];
581 for(
unsigned i=0; i<m_vertices.size(); ++i)
583 m_vertices[i].adjacent_edges().set_allocation(allocate_pointers(count[i]),
586 std::fill(count.begin(), count.end(), 0);
587 for(
unsigned i=0; i<m_edges.size(); ++i)
589 Edge& e = m_edges[i];
590 for(
unsigned j=0; j<2; ++j)
598 for(
unsigned i=0; i<m_faces.size(); ++i)
600 m_faces[i].adjacent_edges().set_allocation(allocate_pointers(3),3);
603 count.resize(m_faces.size());
604 std::fill(count.begin(), count.end(), 0);
605 for(
unsigned i=0; i<m_edges.size(); ++i)
607 Edge& e = m_edges[i];
611 assert(count[f->
id()]<3);
617 for(
unsigned i=0; i<m_faces.size(); ++i)
619 Face& f = m_faces[i];
622 for(
unsigned j=0; j<3; ++j)
624 for(
unsigned k=0; k<3; ++k)
642 std::vector<double> total_vertex_angle(m_vertices.size());
643 for(
unsigned i=0; i<m_faces.size(); ++i)
645 Face& f = m_faces[i];
646 for(
unsigned j=0; j<3; ++j)
653 for(
unsigned i=0; i<m_vertices.size(); ++i)
655 Vertex& v = m_vertices[i];
659 for(
unsigned i=0; i<m_edges.size(); ++i)
661 Edge& e = m_edges[i];
672 inline bool Mesh::verify()
674 std::cout << std::endl;
677 std::vector<bool> map(m_vertices.size(),
false);
678 for(
unsigned i=0; i<m_edges.size(); ++i)
684 assert(std::find(map.begin(), map.end(),
false) == map.end());
688 std::vector<face_pointer> stack(1,&m_faces[0]);
689 stack.reserve(m_faces.size());
691 map.resize(m_faces.size());
692 std::fill(map.begin(), map.end(),
false);
695 while(!stack.empty())
700 for(
unsigned i=0; i<3; ++i)
704 if(f_adjacent && !map[f_adjacent->id()])
706 map[f_adjacent->id()] =
true;
707 stack.push_back(f_adjacent);
711 assert(std::find(map.begin(), map.end(),
false) == map.end());
714 std::cout <<
"mesh has " << m_vertices.size()
715 <<
" vertices, " << m_faces.size()
716 <<
" faces, " << m_edges.size()
719 unsigned total_boundary_edges = 0;
720 double longest_edge = 0;
721 double shortest_edge = 1e100;
722 for(
unsigned i=0; i<m_edges.size(); ++i)
724 Edge& e = m_edges[i];
725 total_boundary_edges += e.is_boundary() ? 1 : 0;
726 longest_edge =
std::max(longest_edge, e.length());
727 shortest_edge =
std::min(shortest_edge, e.length());
729 std::cout << total_boundary_edges <<
" edges are boundary edges\n";
730 std::cout <<
"shortest/longest edges are "
731 << shortest_edge <<
"/"
732 << longest_edge <<
" = "
733 << shortest_edge/longest_edge
737 double maxx = -1e100;
739 double maxy = -1e100;
741 double maxz = -1e100;
742 for(
unsigned i=0; i<m_vertices.size(); ++i)
744 Vertex& v = m_vertices[i];
752 std::cout <<
"enclosing XYZ box:"
753 <<
" X[" << minx <<
"," << maxx <<
"]"
754 <<
" Y[" << miny <<
"," << maxy <<
"]"
755 <<
" Z[" << minz <<
"," << maxz <<
"]"
758 double dx = maxx - minx;
759 double dy = maxy - miny;
760 double dz = maxz - minz;
761 std::cout <<
"approximate diameter of the mesh is "
762 << sqrt(dx*dx + dy*dy + dz*dz)
765 double min_angle = 1e100;
766 double max_angle = -1e100;
767 for(
unsigned i=0; i<m_faces.size(); ++i)
769 Face& f = m_faces[i];
770 for(
unsigned j=0; j<3; ++j)
772 double angle = f.corner_angles()[j];
773 min_angle =
std::min(min_angle, angle);
774 max_angle =
std::max(max_angle, angle);
777 std::cout <<
"min/max face angles are "
778 << min_angle/
M_PI*180.0 <<
"/"
779 << max_angle/
M_PI*180.0
782 std::cout << std::endl;
791 unsigned type = (unsigned) data[3];
792 unsigned id = (unsigned) data[4];
813 data[0] = point->
x();
814 data[1] = point->
y();
815 data[2] = point->
z();
vertex_pointer opposite_vertex(edge_pointer e)
edge_pointer opposite_edge(vertex_pointer v)
vertex_pointer_vector & adjacent_vertices()
edge_pointer_vector & adjacent_edges()
face_pointer_vector & adjacent_faces()
void update_weight(const float *curvature, int mode, double strain, double sigmo)
void initialize_mesh_data(unsigned num_vertices, Points &p, unsigned num_faces, Faces &tri, const float *curvature, int mode, int strain)
std::vector< Edge > & edges()
std::vector< Vertex > & vertices()
unsigned closest_vertices(SurfacePoint *p, std::vector< vertex_pointer > *storage=NULL)
std::vector< Face > & faces()
void set(double new_x, double new_y, double new_z)
double distance(double *v)
pointer allocate(unsigned const n)
void reset(unsigned block_size, unsigned max_number_of_blocks)
void set_allocation(DataPointer begin, unsigned size)
base_pointer & base_element()
bool & saddle_or_boundary()
float min(float x, float y)
float max(float x, float y)
DataTypeTraits< T >::LongType sum(const Volume< T > &vol)
void fill_surface_point_structure(geodesic::SurfacePoint *point, double *data, Mesh *mesh)
double angle_from_edges(double const a, double const b, double const c)
void fill_surface_point_double(geodesic::SurfacePoint *point, double *data, long)