5#include <cgv/utils/progression.h>
6#include <cgv/math/qem.h>
7#include <cgv/math/mfunc.h>
8#include <cgv/media/axis_aligned_box.h>
9#include "streaming_mesh.h"
28 unsigned int resx, resy;
29 std::vector<T> values;
30 std::vector<bool> flags;
31 std::vector<int> indices;
34 std::vector<cell_info<T> > cell_infos;
36 dc_slice_info(
unsigned int _resx,
unsigned int _resy) : resx(_resx), resy(_resy) {
37 unsigned int n = resx*resy;
46 for (
int i=0; i<n; ++i) {
49 cell_infos[i].count = 0;
54 bool flag(
int x,
int y)
const {
return flags[y*resx+x]; }
56 const T& value(
int x,
int y)
const {
return values[y*resx+x]; }
57 T& value(
int x,
int y) {
return values[y*resx+x]; }
59 void set_value(
int x,
int y, T value, T iso_value) {
62 flags[i] = value>iso_value;
65 const int& index(
int x,
int y)
const {
return indices[y*resx+x]; }
66 int& index(
int x,
int y) {
return indices[y*resx+x]; }
68 const qem_type& get_qem(
int x,
int y)
const {
return cell_infos[y*resx+x].Q; }
69 qem_type& ref_qem(
int x,
int y) {
return cell_infos[y*resx+x].Q; }
71 int count(
int x,
int y)
const {
return cell_infos[y*resx+x].count; }
72 int& count(
int x,
int y) {
return cell_infos[y*resx+x].count; }
74 const pnt_type& center(
int x,
int y)
const {
return cell_infos[y*resx+x].center; }
75 pnt_type& center(
int x,
int y) {
return cell_infos[y*resx+x].center; }
77 const cell_info<T>& info(
int x,
int y)
const {
return cell_infos[y*resx+x]; }
78 cell_info<T>& info(
int x,
int y) {
return cell_infos[y*resx+x]; }
82template <
typename X,
typename T>
97 unsigned int resx, resy, resz;
103 unsigned int max_nr_iters;
104 X consistency_threshold;
109 const X& _consistency_threshold = 0.01f,
unsigned int _max_nr_iters = 10,
110 const X& _epsilon = 1e-6f) :
111 func(_func), max_nr_iters(_max_nr_iters), consistency_threshold(_consistency_threshold), epsilon(_epsilon)
118 if (info_ptr->count(i,j) == 0) {
119 info_ptr->index(i,j) = -1;
122 pnt_type p_ref = info_ptr->center(i,j) / X(info_ptr->count(i,j));
128 void generate_quad(
unsigned int vi,
unsigned int vj,
unsigned int vk,
unsigned int vl,
bool reorient)
136 void compute_edge_point(
const T& _v_1,
const T& _v_2,
int e,
const pnt_type& p,
const vec_type& d,
144 unsigned int nr_iters = 0;
146 X ref = consistency_threshold*fabs(v_2-v_1);
151 if (fabs(v_2-v_1) > epsilon) {
153 alpha = (X)(iso_value-v_1)/(v_2-v_1);
158 q(e) = p_end(e) - (1-alpha)*de;
165 if (++nr_iters >= max_nr_iters)
169 if (alpha < 0 || alpha > 1) {
170 std::cout <<
"invalid alpha = " << alpha << std::endl;
172 X f_e = (v_2 - v_1) / de;
173 if (fabs(f_e - n(e)) > consistency_threshold*f_e) {
175 if (fabs(v-iso_value) > ref) {
176 if ((v > iso_value) == (v_2 > iso_value)) {
191 std::cout <<
"not converged after " << nr_iters <<
" iterations" << std::endl;
193 if (n.length() < 1e-6) {
196 n(e) = T((v_1 < v_2) ? 1 : 0);
207 compute_edge_point(v_1, v_2, e, p, d, q, n);
211 if (C1) {
if (C1->count == 0) { C1->Q = Q; C1->center = q; }
else { C1->Q += Q; C1->center += q; } ++C1->count; }
212 if (C2) {
if (C2->count == 0) { C2->Q = Q; C2->center = q; }
else { C2->Q += Q; C2->center += q; } ++C2->count; }
213 if (C3) {
if (C3->count == 0) { C3->Q = Q; C3->center = q; }
else { C3->Q += Q; C3->center += q; } ++C3->count; }
214 if (C4) {
if (C4->count == 0) { C4->Q = Q; C4->center = q; }
else { C4->Q += Q; C4->center += q; } ++C4->count; }
221 for (j = 0, p(1) = minp(1); j < resy; ++j, p(1) += d(1))
222 for (i = 0, p(0) = minp(0); i < resx; ++i, p(0)+=d(0)) {
226 if (i > 0 && info_ptr->flag(i-1,j) != info_ptr->flag(i,j))
228 info_ptr->value(i,j), 0,
229 &info_ptr->info(i-1,j),
230 j > 0 ? &info_ptr->info(i-1,j-1) : 0,
231 prev_info_ptr ? &prev_info_ptr->info(i-1,j) : 0,
232 (j > 0 && prev_info_ptr) ? &prev_info_ptr->info(i-1,j-1) : 0);
233 if (j > 0 && info_ptr->flag(i,j-1) != info_ptr->flag(i,j))
235 info_ptr->value(i,j), 1,
236 &info_ptr->info(i,j-1),
237 i > 0 ? &info_ptr->info(i-1,j-1) : 0,
238 prev_info_ptr ? &prev_info_ptr->info(i,j-1) : 0,
239 (i > 0 && prev_info_ptr) ? &prev_info_ptr->info(i-1,j-1) : 0);
246 for (j = 0, p(1) = minp(1); j < resy; ++j, p(1) += d(1))
247 for (i = 0, p(0) = minp(0); i < resx; ++i, p(0)+=d(0)) {
249 if (info_ptr_1->flag(i,j) != info_ptr_2->flag(i,j))
251 info_ptr_2->value(i,j), 2,
252 &info_ptr_1->info(i,j),
253 j > 0 ? &info_ptr_1->info(i,j-1) : 0,
254 i > 0 ? &info_ptr_1->info(i-1,j) : 0,
255 (i > 0 && j > 0) ? &info_ptr_1->info(i-1,j-1) : 0);
261 for (j = 1, p(1) = minp(1)+d(1); j < resy-1; ++j, p(1) += d(1))
262 for (i = 1, p(0) = minp(0)+d(0); i < resx-1; ++i, p(0)+=d(0))
263 if (info_ptr_1->flag(i,j) != info_ptr_2->flag(i,j))
265 info_ptr_1->index(i-1,j),
266 info_ptr_1->index(i-1,j-1),
267 info_ptr_1->index(i,j-1),
268 info_ptr_1->flag(i,j));
271 void generate_slice_quads(dc_slice_info<T> *info_ptr_1, dc_slice_info<T> *info_ptr_2)
274 for (j = 1, p(1) = minp(1)+d(1); j < resy-1; ++j, p(1) += d(1))
275 for (i = 1, p(0) = minp(0)+d(0); i < resx-1; ++i, p(0)+=d(0)) {
276 if (info_ptr_2->flag(i-1,j) != info_ptr_2->flag(i,j))
278 info_ptr_2->index(i-1,j),
279 info_ptr_2->index(i-1,j-1),
280 info_ptr_1->index(i-1,j-1),
281 info_ptr_2->flag(i-1,j));
282 if (info_ptr_2->flag(i,j-1) != info_ptr_2->flag(i,j))
284 info_ptr_1->index(i-1,j-1),
285 info_ptr_2->index(i-1,j-1),
286 info_ptr_2->index(i,j-1),
287 info_ptr_2->flag(i,j-1));
293 unsigned int _resx,
unsigned int _resy,
unsigned int _resz,
294 bool show_progress =
false)
297 resx = _resx; resy = _resy; resz = _resz;
300 d(0) /= (resx-1); d(1) /= (resy-1); d(2) /= (resz-1);
301 iso_value = _iso_value;
305 if (show_progress) prog.
init(
"extraction", resz, 10);
308 dc_slice_info<T> slice_info_1(resx,resy), slice_info_2(resx,resy), slice_info_3(resx,resy);
309 dc_slice_info<T> *slice_info_ptrs[3] = { &slice_info_1, &slice_info_2, &slice_info_3 };
312 unsigned int nr_vertices[4] = { 0, 0, 0, 0 };
318 process_slab(slice_info_ptrs[0], slice_info_ptrs[1]);
325 for (k=2; k<resz; ++k, p(2) += d(2)) {
332 process_slab(info_ptr_1, info_ptr_2);
333 generate_slice_quads(info_ptr_0, info_ptr_1);
336 nr_vertices[k%4] = n;
337 n = nr_vertices[(k+3)%4];
A vector with zero based index.
T length() const
length of the vector L2-Norm
vec< T > to_vec() const
conversion to vector type
virtual vec_type evaluate_gradient(const pnt_type &p) const
interface for evaluation of the gradient of the multivariate function.
virtual T evaluate(const pnt_type &p) const =0
interface for evaluation of the multivariate function
dimension independent implementation of quadric error metrics
vec< T > minarg(const vec< T > &p_ref, T relative_epsilon, T max_distance=-1, T epsilon=1e-10) const
compute point that minimizes distance to qem and is inside the sphere of radius max_distance around p...
specialization of a multivariate function to three independent variables, which only reimplements the...
unsigned size() const
number of elements
T * data()
cast into non const array
progression provides a simple possibility to show progression of process in console.
void step()
next iteration
void init(const std::string &process, size_t total, int count)
reinitialize