FIX:fix bugs of non manifold edge
Jira: STUDIO-5267 Change-Id: I8ac9a2cf96da0bc07ee00b309e65611b92fd174d
This commit is contained in:
parent
7f43532615
commit
099756fc1a
|
@ -447,6 +447,11 @@ const ModelObjectPtrs &Cut::perform_by_contour(std::vector<Part> parts, int dowe
|
|||
if (m_attributes.has(ModelObjectCutAttribute::KeepLower))
|
||||
cut_mo->clone_for_cut(&lower);
|
||||
|
||||
if (upper && lower) {
|
||||
upper->name = upper->name + "_A";
|
||||
lower->name = lower->name + "_B";
|
||||
}
|
||||
|
||||
const size_t cut_parts_cnt = parts.size();
|
||||
bool has_modifiers = false;
|
||||
|
||||
|
|
|
@ -47,9 +47,12 @@ bool is_equal(float lh, float rh)
|
|||
return abs(lh - rh) <= epson;
|
||||
}
|
||||
|
||||
bool is_less(float lh, float rh)
|
||||
{
|
||||
return lh + epson < rh;
|
||||
bool is_equal_for_sort(float lh, float rh) {
|
||||
return abs(lh - rh) <= 1e-8;
|
||||
}
|
||||
|
||||
bool is_equal(const Vec3f &lh, const Vec3f &rh) {
|
||||
return is_equal(lh[0], rh[0]) && is_equal(lh[1], rh[1]) && is_equal(lh[2], rh[2]);
|
||||
}
|
||||
|
||||
class IntersectionReference
|
||||
|
@ -170,7 +173,7 @@ static FacetSliceType slice_facet(
|
|||
// (external on the right of the line)
|
||||
for (int j = 0; j < 3; ++ j) { // loop through facet edges
|
||||
int edge_id;
|
||||
const stl_vertex *a, *b;
|
||||
const stl_vertex *a, *b, *c;
|
||||
int a_id, b_id;
|
||||
{
|
||||
int k = (idx_vertex_lowest + j) % 3;
|
||||
|
@ -180,10 +183,11 @@ static FacetSliceType slice_facet(
|
|||
a = vertices + k;
|
||||
b_id = indices[l];
|
||||
b = vertices + l;
|
||||
c = vertices + (k + 2) % 3;
|
||||
}
|
||||
|
||||
// Is edge or face aligned with the cutting plane?
|
||||
if (a->z() == slice_z && b->z() == slice_z) {
|
||||
if (is_equal(a->z(), slice_z) && is_equal(b->z() ,slice_z)) {
|
||||
// Edge is horizontal and belongs to the current layer.
|
||||
// The following rotation of the three vertices may not be efficient, but this branch happens rarely.
|
||||
const stl_vertex &v0 = vertices[0];
|
||||
|
@ -204,7 +208,7 @@ static FacetSliceType slice_facet(
|
|||
} else {
|
||||
// Two vertices are aligned with the cutting plane, the third vertex is below or above the cutting plane.
|
||||
// Is the third vertex below the cutting plane?
|
||||
bool third_below = v0.z() < slice_z || v1.z() < slice_z || v2.z() < slice_z;
|
||||
bool third_below = c->z() < slice_z;
|
||||
// Two vertices on the cutting plane, the third vertex is below the plane. Consider the edge to be part of the slice
|
||||
// only if it is the upper edge.
|
||||
// (the bottom most edge resp. vertex of a triangle is not owned by the triangle, but the top most edge resp. vertex is part of the triangle
|
||||
|
@ -227,7 +231,7 @@ static FacetSliceType slice_facet(
|
|||
return result;
|
||||
}
|
||||
|
||||
if (a->z() == slice_z) {
|
||||
if (is_equal(a->z() ,slice_z)) {
|
||||
// Only point a alings with the cutting plane.
|
||||
if (point_on_layer == size_t(-1) || points[point_on_layer].point_id != a_id) {
|
||||
point_on_layer = num_points;
|
||||
|
@ -236,7 +240,7 @@ static FacetSliceType slice_facet(
|
|||
point.y() = a->y();
|
||||
point.point_id = a_id;
|
||||
}
|
||||
} else if (b->z() == slice_z) {
|
||||
} else if (is_equal(b->z() , slice_z)) {
|
||||
// Only point b alings with the cutting plane.
|
||||
if (point_on_layer == size_t(-1) || points[point_on_layer].point_id != b_id) {
|
||||
point_on_layer = num_points;
|
||||
|
@ -336,7 +340,7 @@ void slice_facet_at_zs(
|
|||
// find layer extents
|
||||
auto min_layer = std::lower_bound(zs.begin(), zs.end(), min_z); // first layer whose slice_z is >= min_z
|
||||
auto max_layer = std::upper_bound(min_layer, zs.end(), max_z); // first layer whose slice_z is > max_z
|
||||
int idx_vertex_lowest = (vertices[1].z() == min_z) ? 1 : ((vertices[2].z() == min_z) ? 2 : 0);
|
||||
int idx_vertex_lowest = is_equal(vertices[1].z(), min_z) ? 1 : (is_equal(vertices[2].z() , min_z) ? 2 : 0);
|
||||
|
||||
for (auto it = min_layer; it != max_layer; ++ it) {
|
||||
IntersectionLine il;
|
||||
|
@ -392,7 +396,7 @@ static inline IntersectionLines slice_make_lines(
|
|||
const float min_z = fminf(vertices[0].z(), fminf(vertices[1].z(), vertices[2].z()));
|
||||
const float max_z = fmaxf(vertices[0].z(), fmaxf(vertices[1].z(), vertices[2].z()));
|
||||
assert(min_z <= plane_z && max_z >= plane_z);
|
||||
int idx_vertex_lowest = (vertices[1].z() == min_z) ? 1 : ((vertices[2].z() == min_z) ? 2 : 0);
|
||||
int idx_vertex_lowest = is_equal(vertices[1].z(), min_z) ? 1 : (is_equal(vertices[2].z(), min_z) ? 2 : 0);
|
||||
IntersectionLine il;
|
||||
// Ignore horizontal triangles. Any valid horizontal triangle must have a vertical triangle connected, otherwise the part has zero volume.
|
||||
if (!is_equal(min_z, max_z) && slice_facet(plane_z, vertices, indices, face_edge_ids[face_idx], idx_vertex_lowest, false, il) == FacetSliceType::Slicing) {
|
||||
|
@ -447,8 +451,8 @@ void slice_facet_with_slabs(
|
|||
// find facet extents
|
||||
const float min_z = fminf(vertices[0].z(), fminf(vertices[1].z(), vertices[2].z()));
|
||||
const float max_z = fmaxf(vertices[0].z(), fmaxf(vertices[1].z(), vertices[2].z()));
|
||||
const bool horizontal = min_z == max_z;
|
||||
|
||||
const bool horizontal = is_equal(min_z , max_z);
|
||||
|
||||
// find layer extents
|
||||
auto min_layer = std::lower_bound(zs.begin(), zs.end(), min_z); // first layer whose slice_z is >= min_z
|
||||
auto max_layer = std::upper_bound(min_layer, zs.end(), max_z); // first layer whose slice_z is > max_z
|
||||
|
@ -537,7 +541,7 @@ void slice_facet_with_slabs(
|
|||
}
|
||||
} else {
|
||||
// The triangle is not horizontal and at least a single slicing plane intersects the triangle.
|
||||
int idx_vertex_lowest = (vertices[1].z() == min_z) ? 1 : ((vertices[2].z() == min_z) ? 2 : 0);
|
||||
int idx_vertex_lowest = is_equal(vertices[1].z(), min_z) ? 1 : (is_equal(vertices[2].z() , min_z) ? 2 : 0);
|
||||
IntersectionLine il_prev;
|
||||
for (auto it = min_layer; it != max_layer; ++ it) {
|
||||
IntersectionLine il;
|
||||
|
@ -1997,15 +2001,16 @@ void slice_mesh_slabs(
|
|||
|
||||
// Remove duplicates of slice_vertices, optionally triangulate the cut.
|
||||
static void triangulate_slice(
|
||||
indexed_triangle_set &its,
|
||||
IntersectionLines &lines,
|
||||
indexed_triangle_set &its,
|
||||
IntersectionLines &lines,
|
||||
std::vector<int> &slice_vertices,
|
||||
// Vertices of the original (unsliced) mesh. Newly added vertices are those on the slice.
|
||||
int num_original_vertices,
|
||||
// Z height of the slice.
|
||||
float z,
|
||||
bool triangulate,
|
||||
bool normals_down)
|
||||
float z,
|
||||
bool triangulate,
|
||||
bool normals_down,
|
||||
const std::map<int, Vec3f*> §ion_vertices_map)
|
||||
{
|
||||
sort_remove_duplicates(slice_vertices);
|
||||
|
||||
|
@ -2015,11 +2020,12 @@ static void triangulate_slice(
|
|||
map_vertex_to_index.reserve(slice_vertices.size());
|
||||
for (int i : slice_vertices)
|
||||
map_vertex_to_index.emplace_back(to_2d(its.vertices[i]), i);
|
||||
std::sort(map_vertex_to_index.begin(), map_vertex_to_index.end(),
|
||||
[](const std::pair<Vec2f, int> &l, const std::pair<Vec2f, int> &r) {
|
||||
return is_less(l.first.x(), r.first.x()) ||
|
||||
(is_equal(l.first.x(), r.first.x()) && (is_less(l.first.y(), r.first.y()) ||
|
||||
(is_equal(l.first.y(), r.first.y()) && l.second < r.second))); });
|
||||
std::sort(map_vertex_to_index.begin(), map_vertex_to_index.end(),
|
||||
[](const std::pair<Vec2f, int> &l, const std::pair<Vec2f, int> &r) {
|
||||
return l.first.x() < r.first.x() ||
|
||||
(is_equal_for_sort(l.first.x(), r.first.x()) && (l.first.y()< r.first.y() ||
|
||||
(is_equal_for_sort(l.first.y(), r.first.y()) && l.second < r.second)));
|
||||
});
|
||||
|
||||
// 2) Discover duplicate points on the slice. Remap duplicate vertices to a vertex with a lowest index.
|
||||
// Remove denegerate triangles, if they happen to be created by merging duplicate vertices.
|
||||
|
@ -2068,14 +2074,40 @@ static void triangulate_slice(
|
|||
stl_triangle_vertex_indices facet;
|
||||
for (size_t j = 0; j < 3; ++ j) {
|
||||
Vec3f v = triangles[i ++].cast<float>();
|
||||
auto it = lower_bound_by_predicate(map_vertex_to_index.begin(), map_vertex_to_index.end(),
|
||||
auto it = lower_bound_by_predicate(map_vertex_to_index.begin(), map_vertex_to_index.end(),
|
||||
[&v](const std::pair<Vec2f, int> &l) {
|
||||
return is_less(l.first.x(), v.x()) || (is_equal(l.first.x(), v.x()) && is_less(l.first.y(), v.y()));
|
||||
return l.first.x() < v.x() || (is_equal_for_sort(l.first.x(), v.x()) && l.first.y() < v.y());
|
||||
});
|
||||
int idx = -1;
|
||||
if (it != map_vertex_to_index.end() && is_equal(it->first.x(), v.x()) && is_equal(it->first.y(), v.y()))
|
||||
idx = it->second;
|
||||
else {
|
||||
bool exist = false;
|
||||
for (auto i = section_vertices_map.begin(); i != section_vertices_map.end(); i++) {
|
||||
if (is_equal(v, *i->second)) {
|
||||
idx = i->first;
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// go on finding
|
||||
if (!exist) {
|
||||
for (; it != map_vertex_to_index.end(); it++) {
|
||||
if (is_equal(it->first.x(), v.x()) && is_equal(it->first.y(), v.y())) {
|
||||
idx = it->second;
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// go on finding
|
||||
if (!exist) {
|
||||
for (; it != map_vertex_to_index.begin(); it--) {
|
||||
if (is_equal(it->first.x(), v.x()) && is_equal(it->first.y(), v.y())) {
|
||||
idx = it->second;
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!exist){
|
||||
// Try to find the vertex in the list of newly added vertices. Those vertices are not matched on the cut and they shall be rare.
|
||||
for (size_t k = idx_vertex_new_first; k < its.vertices.size(); ++ k)
|
||||
if (its.vertices[k] == v) {
|
||||
|
@ -2156,16 +2188,22 @@ void cut_mesh(const indexed_triangle_set& mesh, float z, indexed_triangle_set* u
|
|||
IntersectionLines upper_lines, lower_lines;
|
||||
std::vector<int> upper_slice_vertices, lower_slice_vertices;
|
||||
std::vector<Vec3i> facets_edge_ids = its_face_edge_ids(mesh);
|
||||
std::map<int, Vec3f *> section_vertices_map;
|
||||
|
||||
for (int facet_idx = 0; facet_idx < int(mesh.indices.size()); ++ facet_idx) {
|
||||
const stl_triangle_vertex_indices &facet = mesh.indices[facet_idx];
|
||||
Vec3f vertices[3] { mesh.vertices[facet(0)], mesh.vertices[facet(1)], mesh.vertices[facet(2)] };
|
||||
float min_z = std::min(vertices[0].z(), std::min(vertices[1].z(), vertices[2].z()));
|
||||
float max_z = std::max(vertices[0].z(), std::max(vertices[1].z(), vertices[2].z()));
|
||||
|
||||
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
if (is_equal(z, vertices[i].z()) && section_vertices_map[facet(i)] == nullptr) {
|
||||
section_vertices_map[facet(i)] = new Vec3f(vertices[i].x(), vertices[i].y(), vertices[i].z());
|
||||
}
|
||||
}
|
||||
// intersect facet with cutting plane
|
||||
IntersectionLine line;
|
||||
int idx_vertex_lowest = (vertices[1].z() == min_z) ? 1 : ((vertices[2].z() == min_z) ? 2 : 0);
|
||||
int idx_vertex_lowest = is_equal(vertices[1].z(), min_z) ? 1 : (is_equal(vertices[2].z() , min_z) ? 2 : 0);
|
||||
FacetSliceType slice_type = FacetSliceType::NoSlice;
|
||||
if (z > min_z - EPSILON && z < max_z + EPSILON) {
|
||||
Vec3f vertices_scaled[3];
|
||||
|
@ -2176,7 +2214,7 @@ void cut_mesh(const indexed_triangle_set& mesh, float z, indexed_triangle_set* u
|
|||
dst.y() = scale_(src.y());
|
||||
dst.z() = src.z();
|
||||
}
|
||||
slice_type = slice_facet(z, vertices_scaled, mesh.indices[facet_idx], facets_edge_ids[facet_idx], idx_vertex_lowest, min_z == max_z, line);
|
||||
slice_type = slice_facet(z, vertices_scaled, mesh.indices[facet_idx], facets_edge_ids[facet_idx], idx_vertex_lowest, is_equal(min_z , max_z), line);
|
||||
}
|
||||
|
||||
if (slice_type != FacetSliceType::NoSlice) {
|
||||
|
@ -2194,12 +2232,12 @@ void cut_mesh(const indexed_triangle_set& mesh, float z, indexed_triangle_set* u
|
|||
upper_lines.emplace_back(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (min_z > z || (min_z == z && max_z > z)) {
|
||||
|
||||
if (min_z > z || (is_equal(min_z , z) && max_z > z)) {
|
||||
// facet is above the cut plane and does not belong to it
|
||||
if (upper != nullptr)
|
||||
upper->indices.emplace_back(facet);
|
||||
} else if (max_z < z || (max_z == z && min_z < z)) {
|
||||
} else if (max_z < z || (is_equal(max_z, z) && min_z < z)) {
|
||||
// facet is below the cut plane and does not belong to it
|
||||
if (lower != nullptr)
|
||||
lower->indices.emplace_back(facet);
|
||||
|
@ -2211,21 +2249,56 @@ void cut_mesh(const indexed_triangle_set& mesh, float z, indexed_triangle_set* u
|
|||
assert(line.edge_b_id != -1);
|
||||
|
||||
// look for the vertex on whose side of the slicing plane there are no other vertices
|
||||
int isolated_vertex =
|
||||
(vertices[0].z() > z) == (vertices[1].z() > z) ? 2 :
|
||||
(vertices[1].z() > z) == (vertices[2].z() > z) ? 0 : 1;
|
||||
|
||||
// get vertices starting from the isolated one
|
||||
int iv = isolated_vertex;
|
||||
stl_vertex v0v1, v2v0;
|
||||
assert(facets_edge_ids[facet_idx](iv) == line.edge_a_id || facets_edge_ids[facet_idx](iv) == line.edge_b_id);
|
||||
if (facets_edge_ids[facet_idx](iv) == line.edge_a_id) {
|
||||
// Unscale to doubles first, then to floats to reach the same accuracy as triangulate_expolygons_2d().
|
||||
v0v1 = to_3d(unscaled<double>(line.a).cast<float>().eval(), z);
|
||||
v2v0 = to_3d(unscaled<double>(line.b).cast<float>().eval(), z);
|
||||
int isolated_vertex, isolated_vertex_option = -1;
|
||||
std::vector<int> list{0, 1, 2};
|
||||
auto get_third = [&list](int isolated_vertex, int temp) {// not use vertex data
|
||||
for (size_t i = 0; i < list.size(); i++) {
|
||||
if (list[i] != isolated_vertex && list[i] != temp) {
|
||||
return list[i];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
if (is_equal(vertices[0].z(), z)) {
|
||||
isolated_vertex = vertices[1].z() > z ? 1 : 2;
|
||||
isolated_vertex_option = get_third(isolated_vertex, 0);
|
||||
} else if (is_equal(vertices[1].z(), z)) {
|
||||
isolated_vertex = vertices[2].z() > z ? 2 : 0;
|
||||
isolated_vertex_option = get_third(isolated_vertex, 1);
|
||||
} else if (is_equal(vertices[2].z(), z)) {
|
||||
isolated_vertex = vertices[0].z() > z ? 0 : 1;
|
||||
isolated_vertex_option = get_third(isolated_vertex, 2);
|
||||
} else {
|
||||
v0v1 = to_3d(unscaled<double>(line.b).cast<float>().eval(), z);
|
||||
v2v0 = to_3d(unscaled<double>(line.a).cast<float>().eval(), z);
|
||||
isolated_vertex = (vertices[0].z() > z) == (vertices[1].z() > z) ? 2 : (vertices[1].z() > z) == (vertices[2].z() > z) ? 0 : 1;
|
||||
}
|
||||
// get vertices starting from the isolated one
|
||||
stl_vertex v0v1, v2v0;
|
||||
auto calc_isolated_vertex = [&v0v1, &v2v0, &line, &facet_idx, &facets_edge_ids, &z](int iv, bool &is_find) {
|
||||
assert(facets_edge_ids[facet_idx](iv) == line.edge_a_id || facets_edge_ids[facet_idx](iv) == line.edge_b_id);
|
||||
is_find = true;
|
||||
if (facets_edge_ids[facet_idx](iv) == line.edge_a_id) {
|
||||
// Unscale to doubles first, then to floats to reach the same accuracy as triangulate_expolygons_2d().
|
||||
v0v1 = to_3d(unscaled<double>(line.a).cast<float>().eval(), z);
|
||||
v2v0 = to_3d(unscaled<double>(line.b).cast<float>().eval(), z);
|
||||
} else if (facets_edge_ids[facet_idx](iv) == line.edge_b_id) {
|
||||
v0v1 = to_3d(unscaled<double>(line.b).cast<float>().eval(), z);
|
||||
v2v0 = to_3d(unscaled<double>(line.a).cast<float>().eval(), z);
|
||||
} else {
|
||||
is_find = false;
|
||||
}
|
||||
};
|
||||
bool find_isolated_vertex;
|
||||
int iv;
|
||||
calc_isolated_vertex(isolated_vertex, find_isolated_vertex);
|
||||
if (!find_isolated_vertex && isolated_vertex_option != -1) {
|
||||
calc_isolated_vertex(isolated_vertex_option, find_isolated_vertex);
|
||||
if (!find_isolated_vertex) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "cut_mesh:error:could not find isolated_vertex";
|
||||
continue;
|
||||
}
|
||||
iv = isolated_vertex_option;
|
||||
} else {
|
||||
iv = isolated_vertex;
|
||||
}
|
||||
const stl_vertex &v0 = vertices[iv];
|
||||
const int iv0 = facet[iv];
|
||||
|
@ -2239,48 +2312,71 @@ void cut_mesh(const indexed_triangle_set& mesh, float z, indexed_triangle_set* u
|
|||
const int iv2 = facet[iv];
|
||||
|
||||
// intersect v0-v1 and v2-v0 with cutting plane and make new vertices
|
||||
auto new_vertex = [upper, lower, &upper_slice_vertices, &lower_slice_vertices](const Vec3f &a, const int ia, const Vec3f &b, const int ib, const Vec3f &c) {
|
||||
auto new_vertex = [upper, lower, &upper_slice_vertices, &lower_slice_vertices](const Vec3f &a, const int ia, const Vec3f &b, const int ib, const Vec3f &c,
|
||||
const int ic, const Vec3f &new_pt, bool &is_new_vertex) {
|
||||
int iupper, ilower;
|
||||
if (c == a)
|
||||
is_new_vertex = false;
|
||||
if (is_equal(new_pt, a))
|
||||
iupper = ilower = ia;
|
||||
else if (c == b)
|
||||
else if (is_equal(new_pt, b))
|
||||
iupper = ilower = ib;
|
||||
else if (is_equal(new_pt, c))
|
||||
iupper = ilower = ic;
|
||||
else {
|
||||
// Insert a new vertex into upper / lower.
|
||||
is_new_vertex = true;
|
||||
if (upper) {
|
||||
iupper = int(upper->vertices.size());
|
||||
upper->vertices.emplace_back(c);
|
||||
upper->vertices.emplace_back(new_pt);
|
||||
upper_slice_vertices.emplace_back(iupper);
|
||||
}
|
||||
if (lower) {
|
||||
ilower = int(lower->vertices.size());
|
||||
lower->vertices.emplace_back(c);
|
||||
lower->vertices.emplace_back(new_pt);
|
||||
lower_slice_vertices.emplace_back(ilower);
|
||||
}
|
||||
}
|
||||
return std::make_pair(iupper, ilower);
|
||||
};
|
||||
auto [iv0v1_upper, iv0v1_lower] = new_vertex(v1, iv1, v0, iv0, v0v1);
|
||||
auto [iv2v0_upper, iv2v0_lower] = new_vertex(v2, iv2, v0, iv0, v2v0);
|
||||
auto new_face = [](indexed_triangle_set *its, int i, int j, int k) {
|
||||
if (its != nullptr && i != j && i != k && j != k)
|
||||
its->indices.emplace_back(i, j, k);
|
||||
bool is_new_vertex_v0v1;
|
||||
bool is_new_vertex_v2v0;
|
||||
auto [iv0v1_upper, iv0v1_lower] = new_vertex(v1, iv1, v0, iv0, v2, iv2, v0v1, is_new_vertex_v0v1);
|
||||
auto [iv2v0_upper, iv2v0_lower] = new_vertex(v2, iv2, v0, iv0, v1, iv1, v2v0, is_new_vertex_v2v0);
|
||||
auto new_face = [](indexed_triangle_set *its, int i, int j, int k) {
|
||||
if (its != nullptr && i != j && i != k && j != k) its->indices.emplace_back(i, j, k);
|
||||
};
|
||||
|
||||
if (v0.z() > z) {
|
||||
new_face(upper, iv0, iv0v1_upper, iv2v0_upper);
|
||||
new_face(lower, iv1, iv2, iv0v1_lower);
|
||||
new_face(lower, iv2, iv2v0_lower, iv0v1_lower);
|
||||
} else {
|
||||
new_face(upper, iv1, iv2, iv0v1_upper);
|
||||
new_face(upper, iv2, iv2v0_upper, iv0v1_upper);
|
||||
new_face(lower, iv0, iv0v1_lower, iv2v0_lower);
|
||||
if (is_new_vertex_v0v1 && is_new_vertex_v2v0) {
|
||||
if (v0.z() > z) {
|
||||
new_face(upper, iv0, iv0v1_upper, iv2v0_upper);
|
||||
new_face(lower, iv1, iv2, iv0v1_lower);
|
||||
new_face(lower, iv2, iv2v0_lower, iv0v1_lower);
|
||||
} else {
|
||||
new_face(upper, iv1, iv2, iv0v1_upper);
|
||||
new_face(upper, iv2, iv2v0_upper, iv0v1_upper);
|
||||
new_face(lower, iv0, iv0v1_lower, iv2v0_lower);
|
||||
}
|
||||
} else if (is_new_vertex_v0v1) {
|
||||
if (v0.z() > z) {
|
||||
new_face(upper, iv0, iv0v1_upper, iv2);
|
||||
new_face(lower, iv1, iv2, iv0v1_lower);
|
||||
} else {
|
||||
new_face(lower, iv0, iv0v1_lower, iv2);
|
||||
new_face(upper, iv1, iv2, iv0v1_upper);
|
||||
}
|
||||
} else if (is_new_vertex_v2v0) {
|
||||
if (v0.z() > z) {
|
||||
new_face(upper, iv0, iv1, iv2v0_upper);
|
||||
new_face(lower, iv1, iv2, iv2v0_lower);
|
||||
} else {
|
||||
new_face(lower, iv0, iv1, iv2v0_lower);
|
||||
new_face(upper, iv1, iv2, iv2v0_upper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (upper != nullptr) {
|
||||
triangulate_slice(*upper, upper_lines, upper_slice_vertices, int(mesh.vertices.size()), z, triangulate_caps, NORMALS_DOWN);
|
||||
triangulate_slice(*upper, upper_lines, upper_slice_vertices, int(mesh.vertices.size()), z, triangulate_caps, NORMALS_DOWN, section_vertices_map);
|
||||
#ifndef NDEBUG
|
||||
if (triangulate_caps) {
|
||||
size_t num_open_edges_new = its_num_open_edges(*upper);
|
||||
|
@ -2290,7 +2386,7 @@ void cut_mesh(const indexed_triangle_set& mesh, float z, indexed_triangle_set* u
|
|||
}
|
||||
|
||||
if (lower != nullptr) {
|
||||
triangulate_slice(*lower, lower_lines, lower_slice_vertices, int(mesh.vertices.size()), z, triangulate_caps, NORMALS_UP);
|
||||
triangulate_slice(*lower, lower_lines, lower_slice_vertices, int(mesh.vertices.size()), z, triangulate_caps, NORMALS_UP, section_vertices_map);
|
||||
#ifndef NDEBUG
|
||||
if (triangulate_caps) {
|
||||
size_t num_open_edges_new = its_num_open_edges(*lower);
|
||||
|
@ -2298,6 +2394,7 @@ void cut_mesh(const indexed_triangle_set& mesh, float z, indexed_triangle_set* u
|
|||
}
|
||||
#endif // NDEBUG
|
||||
}
|
||||
std::map<int, Vec3f*>().swap(section_vertices_map);
|
||||
}
|
||||
|
||||
// BBS: implement plane cut with cgal
|
||||
|
|
Loading…
Reference in New Issue