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" 12 class SubdivisionNode:
public SurfacePoint
14 typedef SubdivisionNode* node_pointer;
18 template <
class Po
inter>
19 SubdivisionNode(Pointer p):
25 template <
class Po
inter,
class Parameter>
26 SubdivisionNode(Pointer p, Parameter param):
27 SurfacePoint(p, param),
34 double& distance_from_source(){
return m_distance;};
35 node_pointer& previous(){
return m_previous;};
36 unsigned& source_index(){
return m_source_index;};
40 m_distance = GEODESIC_INF;
44 bool operator()(node_pointer
const s1, node_pointer
const s2)
const 50 if(s1->distance_from_source() != s2->distance_from_source())
52 return s1->distance_from_source() < s2->distance_from_source();
62 if(s1->x() != s2->x())
64 return s1->x() < s2->x();
66 if(s1->y() != s2->y())
68 return s1->y() < s2->y();
70 if(s1->z() != s2->z())
72 return s1->z() < s2->z();
79 SurfacePoint& surface_point(){
return static_cast<SurfacePoint&
>(*this);};
83 unsigned m_source_index;
84 node_pointer m_previous;
87 class GeodesicAlgorithmSubdivision:
public GeodesicAlgorithmGraphBase<SubdivisionNode>
89 typedef SubdivisionNode Node;
91 GeodesicAlgorithmSubdivision(geodesic::Mesh* mesh = NULL,
92 unsigned subdivision_level = 0):
93 GeodesicAlgorithmGraphBase<Node>(mesh)
97 m_nodes.reserve(mesh->vertices().size());
98 for(
unsigned i=0; i<mesh->vertices().size(); ++i)
100 vertex_pointer v = &mesh->vertices()[i];
101 m_nodes.push_back(Node(v));
104 set_subdivision_level(subdivision_level);
107 ~GeodesicAlgorithmSubdivision(){};
109 unsigned subdivision_level(){
return m_subdivision_level;};
111 void set_subdivision_level(
unsigned subdivision_level)
113 m_subdivision_level = subdivision_level;
115 m_nodes.resize(m_mesh->vertices().size());
116 m_nodes.reserve(m_mesh->vertices().size() +
117 m_mesh->edges().size()*subdivision_level);
119 for(
unsigned i=0; i<m_mesh->edges().size(); ++i)
121 edge_pointer e = &m_mesh->edges()[i];
122 for(
unsigned i=0; i<subdivision_level; ++i)
124 double offset = (double)(i+1)/(double)(subdivision_level+1);
125 m_nodes.push_back(Node(e, offset));
131 void list_nodes_visible_from_source(MeshElementBase* p,
132 std::vector<node_pointer>& storage);
134 void list_nodes_visible_from_node(node_pointer node,
135 std::vector<node_pointer>& storage,
136 std::vector<double>& distances,
137 double threshold_distance);
139 unsigned node_indexx(edge_pointer e)
141 return e->id()*m_subdivision_level + m_mesh->vertices().size();
145 void list_nodes(MeshElementBase* p,
146 std::vector<node_pointer>& storage,
147 double threshold_distance = -1.0);
149 unsigned m_subdivision_level;
152 inline void GeodesicAlgorithmSubdivision::list_nodes(MeshElementBase* p,
153 std::vector<node_pointer>& storage,
154 double threshold_distance)
156 FEASSERT(p->type() != UNDEFINED_POINT);
158 if(p->type() == VERTEX)
160 vertex_pointer v =
static_cast<vertex_pointer
>(p);
161 node_pointer node = &m_nodes[node_index(v)];
162 if(node->distance_from_source() > threshold_distance)
164 storage.push_back(node);
167 else if(p->type() == EDGE)
169 edge_pointer e =
static_cast<edge_pointer
>(p);
170 unsigned node_index = node_indexx(e);
171 for(
unsigned i=0; i<m_subdivision_level; ++i)
173 node_pointer node = &m_nodes[node_index++];
174 if(node->distance_from_source() > threshold_distance)
176 storage.push_back(node);
183 void GeodesicAlgorithmSubdivision::list_nodes_visible_from_source(MeshElementBase* p,
184 std::vector<node_pointer>& storage)
186 FEASSERT(p->type() != UNDEFINED_POINT);
188 if(p->type() == FACE)
190 face_pointer f =
static_cast<face_pointer
>(p);
191 for(
unsigned i=0; i<3; ++i)
193 list_nodes(f->adjacent_vertices()[i],storage);
194 list_nodes(f->adjacent_edges()[i],storage);
197 else if(p->type() == EDGE)
199 list_nodes(p,storage);
200 list_nodes(p->adjacent_vertices()[0],storage);
201 list_nodes(p->adjacent_vertices()[1],storage);
205 list_nodes(p,storage);
209 void GeodesicAlgorithmSubdivision::list_nodes_visible_from_node(node_pointer node,
210 std::vector<node_pointer>& storage,
211 std::vector<double>& distances,
212 double threshold_distance)
214 MeshElementBase* p = node->base_element();
215 FEASSERT(p->type() != UNDEFINED_POINT);
216 FEASSERT(storage.size() == distances.size());
218 if(p->type() == VERTEX)
220 vertex_pointer v =
static_cast<vertex_pointer
>(p);
222 for(
unsigned i=0; i<v->adjacent_edges().size(); ++i)
224 edge_pointer e = v->adjacent_edges()[i];
225 vertex_pointer v_opposite = e->opposite_vertex(v);
226 list_nodes(e, storage, threshold_distance);
227 list_nodes(v_opposite, storage, threshold_distance);
229 for(
unsigned i=0; i<v->adjacent_faces().size(); ++i)
231 face_pointer f = v->adjacent_faces()[i];
232 edge_pointer e = f->opposite_edge(v);
233 list_nodes(e, storage, threshold_distance);
236 else if(p->type() == EDGE)
238 edge_pointer e =
static_cast<edge_pointer
>(p);
240 vertex_pointer v0 = e->adjacent_vertices()[0];
241 vertex_pointer v1 = e->adjacent_vertices()[1];
242 list_nodes(v0, storage, threshold_distance);
243 list_nodes(v1, storage, threshold_distance);
245 for(
unsigned i=0; i<e->adjacent_faces().size(); ++i)
247 face_pointer f = e->adjacent_faces()[i];
249 list_nodes(f->next_edge(e,v0), storage, threshold_distance);
250 list_nodes(f->next_edge(e,v1), storage, threshold_distance);
251 list_nodes(f->opposite_vertex(e), storage, threshold_distance);
259 unsigned index = distances.size();
260 distances.resize(storage.size());
261 for(; index<storage.size(); ++index)
263 distances[index] = node->distance(&storage[index]->surface_point());
269 #endif //GEODESIC_ALGORITHM_SUBDIVISION_122806 Definition: geodesic_cpp_03_02_2008/geodesic_algorithm_base.h:11