2 #ifndef GEODESIC_ALGORITHM_SUBDIVISION_122806 3 #define GEODESIC_ALGORITHM_SUBDIVISION_122806 5 #include "geodesic_algorithm_graph_base.h" 6 #include "geodesic_mesh_elements.h" 13 class SubdivisionNode:
public SurfacePoint
15 typedef SubdivisionNode* node_pointer;
19 template <
class Po
inter>
20 SubdivisionNode(Pointer p):
26 template <
class Po
inter,
class Parameter>
27 SubdivisionNode(Pointer p, Parameter param):
28 SurfacePoint(p, param),
35 double& distance_from_source(){
return m_distance;};
36 node_pointer& previous(){
return m_previous;};
37 unsigned& source_index(){
return m_source_index;};
41 m_distance = GEODESIC_INF;
45 bool operator()(node_pointer
const s1, node_pointer
const s2)
const 51 if(s1->distance_from_source() != s2->distance_from_source())
53 return s1->distance_from_source() < s2->distance_from_source();
63 if(s1->x() != s2->x())
65 return s1->x() < s2->x();
67 if(s1->y() != s2->y())
69 return s1->y() < s2->y();
71 if(s1->z() != s2->z())
73 return s1->z() < s2->z();
80 SurfacePoint& surface_point(){
return static_cast<SurfacePoint&
>(*this);};
84 unsigned m_source_index;
85 node_pointer m_previous;
88 class GeodesicAlgorithmSubdivision:
public GeodesicAlgorithmGraphBase<SubdivisionNode>
90 typedef SubdivisionNode Node;
92 GeodesicAlgorithmSubdivision(geodesic::Mesh* mesh = NULL,
93 unsigned subdivision_level = 0):
94 GeodesicAlgorithmGraphBase<Node>(mesh)
98 m_nodes.reserve(mesh->vertices().size());
99 for(
unsigned i=0; i<mesh->vertices().size(); ++i)
101 vertex_pointer v = &mesh->vertices()[i];
102 m_nodes.push_back(Node(v));
105 set_subdivision_level(subdivision_level);
108 ~GeodesicAlgorithmSubdivision(){};
110 unsigned subdivision_level(){
return m_subdivision_level;};
112 void set_subdivision_level(
unsigned subdivision_level)
114 m_subdivision_level = subdivision_level;
116 m_nodes.resize(m_mesh->vertices().size());
117 m_nodes.reserve(m_mesh->vertices().size() +
118 m_mesh->edges().size()*subdivision_level);
120 for(
unsigned i=0; i<m_mesh->edges().size(); ++i)
122 edge_pointer e = &m_mesh->edges()[i];
123 for(
unsigned i=0; i<subdivision_level; ++i)
125 double offset = (double)(i+1)/(double)(subdivision_level+1);
126 m_nodes.push_back(Node(e, offset));
132 void list_nodes_visible_from_source(MeshElementBase* p,
133 std::vector<node_pointer>& storage);
135 void list_nodes_visible_from_node(node_pointer node,
136 std::vector<node_pointer>& storage,
137 std::vector<double>& distances,
138 double threshold_distance);
140 unsigned node_indexx(edge_pointer e)
142 return e->id()*m_subdivision_level + m_mesh->vertices().size();
146 void list_nodes(MeshElementBase* p,
147 std::vector<node_pointer>& storage,
148 double threshold_distance = -1.0);
150 unsigned m_subdivision_level;
153 inline void GeodesicAlgorithmSubdivision::list_nodes(MeshElementBase* p,
154 std::vector<node_pointer>& storage,
155 double threshold_distance)
157 assert(p->type() != UNDEFINED_POINT);
159 if(p->type() == VERTEX)
161 vertex_pointer v =
static_cast<vertex_pointer
>(p);
162 node_pointer node = &m_nodes[node_index(v)];
163 if(node->distance_from_source() > threshold_distance)
165 storage.push_back(node);
168 else if(p->type() == EDGE)
170 edge_pointer e =
static_cast<edge_pointer
>(p);
171 unsigned node_index = node_indexx(e);
172 for(
unsigned i=0; i<m_subdivision_level; ++i)
174 node_pointer node = &m_nodes[node_index++];
175 if(node->distance_from_source() > threshold_distance)
177 storage.push_back(node);
184 void GeodesicAlgorithmSubdivision::list_nodes_visible_from_source(MeshElementBase* p,
185 std::vector<node_pointer>& storage)
187 assert(p->type() != UNDEFINED_POINT);
189 if(p->type() == FACE)
191 face_pointer f =
static_cast<face_pointer
>(p);
192 for(
unsigned i=0; i<3; ++i)
194 list_nodes(f->adjacent_vertices()[i],storage);
195 list_nodes(f->adjacent_edges()[i],storage);
198 else if(p->type() == EDGE)
200 list_nodes(p,storage);
201 list_nodes(p->adjacent_vertices()[0],storage);
202 list_nodes(p->adjacent_vertices()[1],storage);
206 list_nodes(p,storage);
210 void GeodesicAlgorithmSubdivision::list_nodes_visible_from_node(node_pointer node,
211 std::vector<node_pointer>& storage,
212 std::vector<double>& distances,
213 double threshold_distance)
215 MeshElementBase* p = node->base_element();
216 assert(p->type() != UNDEFINED_POINT);
217 assert(storage.size() == distances.size());
219 if(p->type() == VERTEX)
221 vertex_pointer v =
static_cast<vertex_pointer
>(p);
223 for(
unsigned i=0; i<v->adjacent_edges().size(); ++i)
225 edge_pointer e = v->adjacent_edges()[i];
226 vertex_pointer v_opposite = e->opposite_vertex(v);
227 list_nodes(e, storage, threshold_distance);
228 list_nodes(v_opposite, storage, threshold_distance);
230 for(
unsigned i=0; i<v->adjacent_faces().size(); ++i)
232 face_pointer f = v->adjacent_faces()[i];
233 edge_pointer e = f->opposite_edge(v);
234 list_nodes(e, storage, threshold_distance);
237 else if(p->type() == EDGE)
239 edge_pointer e =
static_cast<edge_pointer
>(p);
241 vertex_pointer v0 = e->adjacent_vertices()[0];
242 vertex_pointer v1 = e->adjacent_vertices()[1];
243 list_nodes(v0, storage, threshold_distance);
244 list_nodes(v1, storage, threshold_distance);
246 for(
unsigned i=0; i<e->adjacent_faces().size(); ++i)
248 face_pointer f = e->adjacent_faces()[i];
250 list_nodes(f->next_edge(e,v0), storage, threshold_distance);
251 list_nodes(f->next_edge(e,v1), storage, threshold_distance);
252 list_nodes(f->opposite_vertex(e), storage, threshold_distance);
260 unsigned index = distances.size();
261 distances.resize(storage.size());
262 for(; index<storage.size(); ++index)
264 distances[index] = node->distance(&storage[index]->surface_point());
270 #endif //GEODESIC_ALGORITHM_SUBDIVISION_122806 Definition: geodesic_cpp_03_02_2008/geodesic_algorithm_base.h:11