5 #include <cgv/utils/progression.h>
6 #include <cgv/math/fvec.h>
7 #include <cgv/math/mfunc.h>
8 #include <cgv/media/axis_aligned_box.h>
9 #include <cgv/media/mesh/streaming_mesh.h>
11 #include <cgv/media/lib_begin.h>
17 extern CGV_API
int get_nr_cube_triangles(
int idx);
18 extern CGV_API
void put_cube_triangle(
int idx,
int t,
int& vi,
int& vj,
int& vk);
25 unsigned int resx, resy;
26 std::vector<T> values;
27 std::vector<bool> flags;
28 std::vector<int> indices;
30 slice_info(
unsigned int _resx,
unsigned int _resy) : resx(_resx), resy(_resy) {
31 unsigned int n = resx*resy;
34 indices.resize(4 * n);
39 for (
int i = 0; i < 4 * n; ++i)
43 bool flag(
int x,
int y)
const {
return flags[y*resx + x]; }
45 int get_bit_code(
int x,
int y,
int step = 1)
const {
47 return (flags[i] ? 1 : 0) + (flags[i + step] ? 2 : 0) +
48 (flags[i + step*(resx + 1)] ? 4 : 0) + (flags[i + step*resx] ? 8 : 0);
51 const T& value(
int x,
int y)
const {
return values[y*resx + x]; }
52 T& value(
int x,
int y) {
return values[y*resx + x]; }
54 void set_value(
int x,
int y, T value, T iso_value) {
57 flags[i] = value > iso_value;
60 const int& index(
int x,
int y,
int e)
const {
return indices[4 * (y*resx + x) + e]; }
61 int& index(
int x,
int y,
int e) {
return indices[4 * (y*resx + x) + e]; }
63 const int& snap_index(
int x,
int y)
const {
return indices[4 * (y*resx + x) + 3]; }
64 int& snap_index(
int x,
int y) {
return indices[4 * (y*resx + x) + 3]; }
68 template <
typename X,
typename T>
87 const X& _grid_epsilon = 0.01f,
88 const X& _epsilon = 1e-6f) : epsilon(_epsilon), grid_epsilon(_grid_epsilon)
97 T v_1 = info_ptr_1->value(i_1, j_1);
98 T v_2 = info_ptr_2->value(i_2, j_2);
100 X f = (fabs(v_2 - v_1) > epsilon) ? (X)(iso_value - v_1) / (v_2 - v_1) : (X) 0.5;
104 if (f < grid_epsilon) {
105 int vj = info_ptr_1->snap_index(i_1, j_1);
107 info_ptr_1->index(i_1, j_1, e) = vj;
110 info_ptr_1->snap_index(i_1, j_1) = vi;
113 else if (1 - f < grid_epsilon) {
114 int vj = info_ptr_2->snap_index(i_2, j_2);
116 info_ptr_1->index(i_1, j_1, e) = vj;
119 info_ptr_2->snap_index(i_2, j_2) = vi;
122 q(e) -= (1 - f)*d(e);
124 info_ptr_1->index(i_1, j_1, e) = vi;
129 template <
typename Eval,
typename Val
id>
132 unsigned int resx,
unsigned int resy,
unsigned int resz,
133 const Eval& eval,
const Valid& valid,
bool show_progress =
false)
138 d(0) /= (resx - 1); d(1) /= (resy - 1); d(2) /= (resz - 1);
139 iso_value = _iso_value;
143 if (show_progress) prog.init(
"extraction", resz, 10);
146 slice_info<T> slice_info_1(resx, resy), slice_info_2(resx, resy);
147 slice_info<T> *slice_info_ptrs[2] = { &slice_info_1, &slice_info_2 };
150 unsigned int nr_vertices[3] = { 0, 0, 0 };
151 unsigned int i, j, k, n;
152 for (k = 0; k < resz; ++k, p(2) += d(2)) {
157 for (j = 0, p(1) = box.
get_min_pnt()(1); j < resy; ++j, p(1) += d(1))
158 for (i = 0, p(0) = box.
get_min_pnt()(0); i < resx; ++i, p(0) += d(0)) {
159 T v = eval(i, j, k, p);
162 if (i > 0 && info_ptr->flag(i - 1, j) != info_ptr->flag(i, j) && valid(info_ptr->value(i - 1, j)))
164 if (j > 0 && info_ptr->flag(i, j - 1) != info_ptr->flag(i, j) && valid(info_ptr->value(i, j - 1)))
176 for (j = 0, p(1) = box.
get_min_pnt()(1); j < resy; ++j, p(1) += d(1))
177 for (i = 0, p(0) = box.
get_min_pnt()(0); i < resx; ++i, p(0) += d(0))
178 if (prev_info_ptr->flag(i, j) != info_ptr->flag(i, j) && valid(prev_info_ptr->value(i, j)) && valid(info_ptr->value(i, j)))
182 for (j = 0; j < resy - 1; ++j) {
183 for (i = 0; i < resx - 1; ++i) {
185 int idx = prev_info_ptr->get_bit_code(i, j) +
186 16 * info_ptr->get_bit_code(i, j);
188 if (idx == 0 || idx == 255)
192 prev_info_ptr->index(i, j, 0),
193 prev_info_ptr->index(i + 1, j, 1),
194 prev_info_ptr->index(i, j + 1, 0),
195 prev_info_ptr->index(i, j, 1),
196 info_ptr->index(i, j, 0),
197 info_ptr->index(i + 1, j, 1),
198 info_ptr->index(i, j + 1, 0),
199 info_ptr->index(i, j, 1),
200 prev_info_ptr->index(i, j, 2),
201 prev_info_ptr->index(i + 1, j, 2),
202 prev_info_ptr->index(i, j + 1, 2),
203 prev_info_ptr->index(i + 1, j + 1, 2)
206 int n = get_nr_cube_triangles(idx);
207 for (
int t = 0; t < n; ++t) {
209 put_cube_triangle(idx, t, vi, vj, vk);
213 if (vi == -1 || vj == -1 || vk == -1)
215 if ((vi != vj) && (vi != vk) && (vj != vk))
222 nr_vertices[k % 3] = n;
223 n = nr_vertices[(k + 2) % 3];
230 template <
typename T>
233 bool operator () (
const T& v)
const {
return true; }
238 template <
typename T>
241 bool operator () (
const T& v)
const {
return v != std::numeric_limits<T>::max(); }
244 template <
typename T>
247 bool operator () (
const T& v)
const {
return !std::isnan(v); }
251 template <
typename X,
typename T>
267 const X& _grid_epsilon = 0.01f,
268 const X& _epsilon = 1e-6f) :
marching_cubes_base<X, T>(_smcbh, _grid_epsilon, _epsilon), func(_func)
271 T operator () (
unsigned i,
unsigned j,
unsigned k,
const pnt_type& p)
const {
274 void extract(
const T& _iso_value,
276 unsigned int resx,
unsigned int resy,
unsigned int resz,
277 bool show_progress =
false)
279 always_valid<T> valid;
280 this->
extract_impl(_iso_value, box, resx, resy, resz, *
this, valid, show_progress);
288 #include <cgv/config/lib_end.h>