#ifndef CGAL_MARCHING_CUBES_3_OLD_H #define CGAL_MARCHING_CUBES_3_OLD_H #include #include #include #include namespace CGAL { namespace Isosurfacing { template void marching_cubes_cell_old(const std::size_t x, const std::size_t y, const std::size_t z, const Domain_& domain, const typename Domain_::FT iso_value, PointRange& points, PolygonRange& polygons, std::mutex& mutex) { typedef std::array Idx_3; typedef typename Domain_::FT FT; typedef typename Domain_::Point_3 Point_3; const Idx_3 idx0 = {x + 0, y + 1, z + 0}; const Idx_3 idx1 = {x + 1, y + 1, z + 0}; const Idx_3 idx2 = {x + 1, y + 0, z + 0}; const Idx_3 idx3 = {x + 0, y + 0, z + 0}; const Idx_3 idx4 = {x + 0, y + 1, z + 1}; const Idx_3 idx5 = {x + 1, y + 1, z + 1}; const Idx_3 idx6 = {x + 1, y + 0, z + 1}; const Idx_3 idx7 = {x + 0, y + 0, z + 1}; const Point_3 pos0 = domain.position(idx0[0], idx0[1], idx0[2]); const Point_3 pos1 = domain.position(idx1[0], idx1[1], idx1[2]); const Point_3 pos2 = domain.position(idx2[0], idx2[1], idx2[2]); const Point_3 pos3 = domain.position(idx3[0], idx3[1], idx3[2]); const Point_3 pos4 = domain.position(idx4[0], idx4[1], idx4[2]); const Point_3 pos5 = domain.position(idx5[0], idx5[1], idx5[2]); const Point_3 pos6 = domain.position(idx6[0], idx6[1], idx6[2]); const Point_3 pos7 = domain.position(idx7[0], idx7[1], idx7[2]); const FT dist0 = domain.value(idx0[0], idx0[1], idx0[2]); const FT dist1 = domain.value(idx1[0], idx1[1], idx1[2]); const FT dist2 = domain.value(idx2[0], idx2[1], idx2[2]); const FT dist3 = domain.value(idx3[0], idx3[1], idx3[2]); const FT dist4 = domain.value(idx4[0], idx4[1], idx4[2]); const FT dist5 = domain.value(idx5[0], idx5[1], idx5[2]); const FT dist6 = domain.value(idx6[0], idx6[1], idx6[2]); const FT dist7 = domain.value(idx7[0], idx7[1], idx7[2]); unsigned int cubeindex = 0; // set bit if corresponding corner is below iso cubeindex |= (dist0 < iso_value) << 0; cubeindex |= (dist1 < iso_value) << 1; cubeindex |= (dist2 < iso_value) << 2; cubeindex |= (dist3 < iso_value) << 3; cubeindex |= (dist4 < iso_value) << 4; cubeindex |= (dist5 < iso_value) << 5; cubeindex |= (dist6 < iso_value) << 6; cubeindex |= (dist7 < iso_value) << 7; Point_3 vertlist[12]; // bitmap of edges that intersect the iso-plane(s) const int edges = edgeTable[cubeindex]; if (edges == 0) { return; } // interpolation of vertices incident to the edge, according to diagram if (edges & (1 << 0)) { vertlist[0] = vertex_interpolation(pos0, pos1, dist0, dist1, iso_value); } if (edges & (1 << 1)) { vertlist[1] = vertex_interpolation(pos1, pos2, dist1, dist2, iso_value); } if (edges & (1 << 2)) { vertlist[2] = vertex_interpolation(pos2, pos3, dist2, dist3, iso_value); } if (edges & (1 << 3)) { vertlist[3] = vertex_interpolation(pos3, pos0, dist3, dist0, iso_value); } if (edges & (1 << 4)) { vertlist[4] = vertex_interpolation(pos4, pos5, dist4, dist5, iso_value); } if (edges & (1 << 5)) { vertlist[5] = vertex_interpolation(pos5, pos6, dist5, dist6, iso_value); } if (edges & (1 << 6)) { vertlist[6] = vertex_interpolation(pos6, pos7, dist6, dist7, iso_value); } if (edges & (1 << 7)) { vertlist[7] = vertex_interpolation(pos7, pos4, dist7, dist4, iso_value); } if (edges & (1 << 8)) { vertlist[8] = vertex_interpolation(pos0, pos4, dist0, dist4, iso_value); } if (edges & (1 << 9)) { vertlist[9] = vertex_interpolation(pos1, pos5, dist1, dist5, iso_value); } if (edges & (1 << 10)) { vertlist[10] = vertex_interpolation(pos2, pos6, dist2, dist6, iso_value); } if (edges & (1 << 11)) { vertlist[11] = vertex_interpolation(pos3, pos7, dist3, dist7, iso_value); } // std::lock_guard lock(mutex); for (int i = 0; triTable[cubeindex][i] != -1; i += 3) { const Point_3& p0 = vertlist[triTable[cubeindex][i + 0]]; const Point_3& p1 = vertlist[triTable[cubeindex][i + 1]]; const Point_3& p2 = vertlist[triTable[cubeindex][i + 2]]; const std::size_t p0_idx = points.size(); // TODO: not allowed points.push_back(p0); points.push_back(p1); points.push_back(p2); polygons.push_back({}); auto& triangle = polygons.back(); triangle.push_back(p0_idx + 0); triangle.push_back(p0_idx + 1); triangle.push_back(p0_idx + 2); } } template void marching_cubes_cell_RG(const std::size_t x, const std::size_t y, const std::size_t z, const Domain_& domain, const typename Domain_::FT iso_value, PointRange& points, PolygonRange& polygons, std::mutex& mutex, std::unordered_map& vertex_map) { typedef typename Domain_::FT FT; typedef typename Domain_::Point_3 Point; /// The structure _Vertex_ represents a vertex by giving its unique global index and the unique index of the edge. struct Vertex { std::size_t g_idx; // vertices; // slice hex // collect function values and build index FT values[8]; Point corners[8]; int vi = 0; std::bitset<8> index = 0; for (int kl = 0; kl <= 1; kl++) { for (int jl = 0; jl <= 1; jl++) { for (int il = 0; il <= 1; il++) { // collect scalar values and computex index corners[vi] = domain.position(x + il, y + jl, z + kl); values[vi] = domain.value(x + il, y + jl, z + kl); if (values[vi] >= iso_value) { // index.set(VertexMapping[vi]); index.set(vi); } // next cell vertex vi++; } } } // collect edges from table and // interpolate triangle vertex positon const int i_case = int(index.to_ullong()); // compute for this case the vertices ushort flag = 1; for (int edge = 0; edge < 12; edge++) { if (flag & Cube_table::intersected_edges[i_case]) { // the edge global index is given by the vertex global index + the edge offset const std::size_t ix = x + Cube_table::global_edge_id[edge][0]; const std::size_t iy = y + Cube_table::global_edge_id[edge][1]; const std::size_t iz = z + Cube_table::global_edge_id[edge][2]; const std::size_t global_index = (iz * domain.size_y() * domain.size_x() + iy * domain.size_x() + ix); vertices[edge].g_edg = cell_shift_factor * global_index + Cube_table::global_edge_id[edge][3]; // generate vertex here, do not care at this point if vertex already exist // interpolation weight const int v0 = Cube_table::edge_to_vertex[edge][0]; const int v1 = Cube_table::edge_to_vertex[edge][1]; const FT l = (iso_value - values[v0]) / (values[v1] - values[v0]); // interpolate vertex const FT px = (1 - l) * corners[v0][0] + l * corners[v1][0]; const FT py = (1 - l) * corners[v0][1] + l * corners[v1][1]; const FT pz = (1 - l) * corners[v0][2] + l * corners[v1][2]; const Point position(px, py, pz); // std::lock_guard lock(mutex); // set vertex index // const auto s_index = vertex_map.find(vertices[edge].g_edg); // if (s_index == vertex_map.end()) { // index not found! Add index to hash map const std::size_t g_idx = points.size(); // vertex_map[vertices[edge].g_edg] = g_idx; vertices[edge].g_idx = g_idx; points.push_back(position); //} else { // vertices[edge].g_idx = s_index->second; // this is vertex global index g_idx //} } flag <<= 1; } // std::lock_guard lock(mutex); // construct triangles for (int t = 0; t < 16; t += 3) { const int t_index = i_case * 16 + t; // if (e_tris_list[t_index] == 0x7f) if (Cube_table::triangle_cases[t_index] == -1) break; const int eg0 = Cube_table::triangle_cases[t_index]; const int eg1 = Cube_table::triangle_cases[t_index + 1]; const int eg2 = Cube_table::triangle_cases[t_index + 2]; // insert new triangle in list polygons.push_back({}); auto& triangle = polygons.back(); triangle.push_back(vertices[eg0].g_idx); triangle.push_back(vertices[eg1].g_idx); triangle.push_back(vertices[eg2].g_idx); } } template void make_triangle_mesh_using_marching_cubes_old(const Domain_& domain, const typename Domain_::FT iso_value, PointRange& points, PolygonRange& polygons) { std::mutex mutex; const std::size_t size_k = domain.size_z(); const std::size_t size_j = domain.size_y(); const std::size_t size_i = domain.size_x(); const std::size_t blocking_size = 100; // TODO: look at polygon mesh processing for tbb (also linking) // compute a unique global index for vertices // use as key the unique edge number std::unordered_map v_map; for (std::size_t bj = 0; bj < size_j - 1; bj += blocking_size) { //#pragma omp parallel for for (std::size_t k = 0; k < size_k - 1; k++) { const std::size_t j_start = bj; const std::size_t j_end = std::min(size_j - 1, bj + blocking_size); for (std::size_t j = j_start; j < j_end; j++) { for (std::size_t i = 0; i < size_i - 1; i++) { // internal::marching_cubes_cell_old(i, j, k, domain, iso_value, points, polygons, mutex); internal::marching_cubes_cell_RG(i, j, k, domain, iso_value, points, polygons, mutex, v_map); } } } } } } // namespace Isosurfacing } // namespace CGAL #endif // CGAL_MARCHING_CUBES_3_OLD_H