diff --git a/src/libslic3r/CutSurface.cpp b/src/libslic3r/CutSurface.cpp
index d01a78b8fc..2d39251784 100644
--- a/src/libslic3r/CutSurface.cpp
+++ b/src/libslic3r/CutSurface.cpp
@@ -1,16 +1,23 @@
#include "CutSurface.hpp"
-/// model.off - CGAL model created from index_triangle_set
+/// {M} .. model index
+/// model/model{M}.off - CGAL model created from index_triangle_set
+/// model_neg/model{M}.off - CGAL model created for differenciate (multi volume object)
/// shape.off - CGAL model created from shapes
/// constrained.off - Visualization of inside and outside triangles
/// Green - not along constrained edge
/// Red - sure that are inside
/// Purple - sure that are outside
+/// (only along constrained edge)
/// filled.off - flood fill green triangles inside of red area
/// - Same meaning of color as constrained
/// reduction.off - Visualization of reduced and non-reduced Vertices
-/// aois/cutAOI{N}.obj - Cuted Area of interest from corefined model
+/// {N} .. Order of cutted Area of Interestmodel from model surface
+/// model_AOIs/{M}/cutAOI{N}.obj - Extracted Area of interest from corefined model
+/// model_AOIs/{M}/outline{N}.obj - Outline of Cutted Area
/// cuts/cut{N}.obj - Filtered surface cuts + Reduced vertices made by e2 (text_edge_2)
+///
+/// result_contours/{O}.obj -
#define DEBUG_OUTPUT_DIR std::string("C:/data/temp/cutSurface/")
using namespace Slic3r;
@@ -52,12 +59,40 @@ SurfaceCut Slic3r::merge(SurfaceCuts &&cuts)
#include "Utils.hpp" // next_highest_power_of_2
namespace priv {
+
+using Project = Emboss::IProjection;
+using Project3f = Emboss::IProject3f;
+
+///
+/// Set true for indices out of area of interest
+///
+/// Flag to convert triangle to cgal
+/// model
+/// Convert 2d point to pair of 3d points
+/// 2d bounding box define AOI
+void set_skip_for_out_of_aoi(std::vector &skip_indicies,
+ const indexed_triangle_set &its,
+ const Project &projection,
+ const BoundingBox &shapes_bb);
+
+///
+/// Set true for indicies outward and almost parallel together.
+/// Note: internally calculate normals
+///
+/// Flag to convert triangle to cgal
+/// model
+/// Direction to measure angle
+/// Maximal allowed angle between opposit normal and
+/// projection direction [in DEG]
+void set_skip_by_angle(std::vector &skip_indicies,
+ const indexed_triangle_set &its,
+ const Project3f &projection,
+ double max_angle = 89.);
+
using EpicKernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using CutMesh = CGAL::Surface_mesh;
using CutMeshes = std::vector;
-// using EpecKernel = CGAL::Exact_predicates_exact_constructions_kernel;
-// using CutMesh = CGAL::Surface_mesh;
using DynamicEdgeProperty = CGAL::dynamic_edge_property_t;
using SMPM = boost::property_map::SMPM;
@@ -70,9 +105,6 @@ using FI = CGAL::SM_Face_index;
using P3 = CGAL::Epick::Point_3;
-using Project = Emboss::IProjection;
-using Project3f = Emboss::IProject3f;
-
///
/// IntersectingElement
///
@@ -159,41 +191,6 @@ const std::string face_shape_map_name = "f:IntersectingElement";
// stored in surface source
const std::string vert_shape_map_name = "v:IntersectingElement";
-///
-/// set true to skip map for indicies
-///
-/// Flag to convert triangle to cgal
-/// model
-/// direction
-void set_skip_for_outward_projection(std::vector &skip_indicies,
- const indexed_triangle_set &its,
- const Project3f &projection);
-
-///
-/// Set true for indicies outward and almost parallel together.
-/// Note: internally calculate normals
-///
-/// Flag to convert triangle to cgal
-/// model
-/// Direction to measure angle
-/// Maximal allowed angle between opposit normal and projection direction [in DEG]
-void set_skip_by_angle(std::vector &skip_indicies,
- const indexed_triangle_set &its,
- const Project3f &projection,
- double max_angle = 89.);
-
-///
-/// Set true for indices out of area of interest
-///
-/// Flag to convert triangle to cgal
-/// model
-/// Convert 2d point to pair of 3d points
-/// 2d bounding box define AOI
-void set_skip_for_out_of_aoi(std::vector &skip_indicies,
- const indexed_triangle_set &its,
- const Project &projection,
- const BoundingBox &shapes_bb);
-
///
/// Convert triangle mesh model to CGAL Surface_mesh
/// Filtrate out opposite triangles
@@ -207,14 +204,6 @@ CutMesh to_cgal(const indexed_triangle_set &its,
const std::vector &skip_indicies,
bool flip = false);
-///
-/// Convert triangle mesh model to CGAL Surface_mesh
-///
-/// Input mesh model
-/// It depends on count of opened edge
-/// CGAL mesh - half edge mesh
-CutMesh to_cgal(const indexed_triangle_set &its, size_t edges_count = 0);
-
///
/// Covert 2d shape (e.g. Glyph) to CGAL model
/// NOTE: internaly create
@@ -240,23 +229,6 @@ struct ShapePointId
uint32_t point_index;
};
-///
-/// Keep conversion from ShapePointId to Index and vice versa
-/// ShapePoint .. contour(or hole) poin from ExPolygons
-/// Index .. continous number
-///
-class ShapePoint2index
-{
- std::vector> m_offsets;
- // for check range of index
- uint32_t m_count;
-public:
- ShapePoint2index(const ExPolygons &shapes);
- uint32_t calc_index(const ShapePointId &id) const;
- ShapePointId calc_id(uint32_t index) const;
- uint32_t get_count() const;
-};
-
///
/// Track source of intersection
/// Help for anotate inner and outer faces
@@ -354,6 +326,24 @@ enum class FaceType {
using FaceTypeMap = CutMesh::Property_map;
const std::string face_type_map_name = "f:side";
+///
+/// Keep conversion from ShapePointId to Index and vice versa
+/// ShapePoint .. contour(or hole) poin from ExPolygons
+/// Index .. continous number
+///
+class ShapePoint2index
+{
+ std::vector> m_offsets;
+ // for check range of index
+ uint32_t m_count;
+
+public:
+ ShapePoint2index(const ExPolygons &shapes);
+ uint32_t calc_index(const ShapePointId &id) const;
+ ShapePointId calc_id(uint32_t index) const;
+ uint32_t get_count() const;
+};
+
///
/// Face with constrained edge are inside/outside by type of intersection
/// Other set to not_constrained(still it could be inside/outside)
@@ -371,24 +361,6 @@ void set_face_type(FaceTypeMap &face_type_map,
const CutMesh &shape_mesh,
const ShapePoint2index &shape2index);
-void set_almost_parallel_type(FaceTypeMap &face_type_map,
- const CutMesh &mesh,
- const Project3f &projection);
-
-///
-/// Check if face is almost parallel
-///
-/// Index of triangle (Face index)
-/// Must contain fi
-/// Direction of projection
-/// Value for cos(alpha), must be greater than zero,
-/// where alpha is minimal angle between projection direction and face normal
-/// True when Triangle is almost parallel with direction of projection
-bool is_almost_parallel(FI fi,
- const CutMesh &mesh,
- const Project3f &projection,
- float threshold = static_cast(std::cos(80 * M_PI / 180)));
-
///
/// Change FaceType from not_constrained to inside
/// For neighbor(or neighbor of neighbor of ...) of inside triangles.
@@ -435,31 +407,17 @@ struct ModelCutId
};
///
-/// Keep conversion from VCutAOIs to Index and vice versa
-/// Model_index .. contour(or hole) poin from ExPolygons
-/// Index .. continous number
+/// Create AOIs(area of interest) on model surface
///
-class ModelCut2index
-{
- std::vector m_offsets;
- // for check range of index
- uint32_t m_count;
-public:
- ModelCut2index(const VCutAOIs &cuts);
- uint32_t calc_index(const ModelCutId &id) const;
- ModelCutId calc_id(uint32_t index) const;
- uint32_t get_count() const;
-};
-
-///
-/// Cut surface from model
-///
-/// Input model converted to CGAL
+/// Input model converted to CGAL
+/// NOTE: will be extended by corefine edge
/// 2d contours
/// [const]Model made by shapes
/// NOTE: Can't be definde as const because of corefine function input definition,
-/// but it is. Convert index to shape point from
-/// ExPolygons Patches from model surface
+/// but it is.
+/// Wanted projection distance
+/// Convert index to shape point from ExPolygons
+/// Patches from model surface
CutAOIs cut_from_model(CutMesh &cgal_model,
const ExPolygons &shapes,
/*const*/ CutMesh &cgal_shape,
@@ -511,6 +469,24 @@ struct SurfacePatch
};
using SurfacePatches = std::vector;
+///
+/// Keep conversion from VCutAOIs to Index and vice versa
+/// Model_index .. contour(or hole) poin from ExPolygons
+/// Index .. continous number
+///
+class ModelCut2index
+{
+ std::vector m_offsets;
+ // for check range of index
+ uint32_t m_count;
+
+public:
+ ModelCut2index(const VCutAOIs &cuts);
+ uint32_t calc_index(const ModelCutId &id) const;
+ ModelCutId calc_id(uint32_t index) const;
+ uint32_t get_count() const;
+};
+
///
/// Differenciate other models
///
@@ -633,53 +609,6 @@ void collect_surface_data(std::queue &process,
FaceTypeMap &face_type_map,
const CutMesh &mesh);
-///
-/// Check if contour contain at least 2 unique source contour points
-///
-/// Vector of half edge define outline
-/// For corefine edge vertices know source of intersection
-/// Triangle half edge mesh
-/// Minimal count of unique source points creating outline
-/// True when outline is made by minimal or greater count of unique source point otherwise FALSE
-bool has_minimal_contour_points(const std::vector &outlines,
- const VertexShapeMap &vert_shape_map,
- const CutMesh &mesh,
- size_t min_count = 2);
-
-///
-/// Check orientation of triangle
-///
-/// triangle
-/// Triangle half edge mesh
-/// Direction to check
-/// True when triangle normal is toward projection otherwise FALSE
-bool is_toward_projection(FI fi,
- const CutMesh &mesh,
- const Project3f &projection);
-
-///
-/// Check orientation of triangle defined by vertices a, b, c in CCW order
-///
-/// Trienagle vertex
-/// Trienagle vertex
-/// Trienagle vertex
-/// Direction to check
-/// True when triangle normal is toward projection otherwise FALSE
-bool is_toward_projection(const Vec3f &a,
- const Vec3f &b,
- const Vec3f &c,
- const Project3f &projection);
-///
-/// Check orientation of triangle
-///
-/// triangle indicies into vertices vector
-/// model vertices
-/// Direction to check
-/// True when triangle normal is toward projection otherwise FALSE
-bool is_toward_projection(const stl_triangle_vertex_indices &t,
- const std::vector &vertices,
- const Project3f &projection);
-
///
/// Copy triangles from CGAL mesh into index triangle set
/// NOTE: Skip vertices created by edge in center of Quad.
@@ -745,7 +674,7 @@ void store(const SurfacePatches &patches, const std::string &dir);
void store(const Vec3f &vertex, const Vec3f &normal, const std::string &file, float size = 2.f);
void store(const ProjectionDistances &pds, const VCutAOIs &aois, const CutMeshes &meshes, const std::string &file, float width = 0.2f/* [in mm] */);
void store(const SurfaceCuts &cut, const std::string &dir);
-void store(const SurfaceCut &cut, const std::string &prefix);
+void store(const SurfaceCut &cut, const std::string &file, const std::string &contour_dir);
void store(const std::vector &models, const std::string &obj_filename);
void store(const std::vector&models, const std::string &dir);
@@ -768,15 +697,14 @@ SurfaceCut Slic3r::cut_surface(const ExPolygons &shapes,
// for filter out triangles out of bounding box
BoundingBox shapes_bb = get_extents(shapes);
- Point projection_center = shapes_bb.center();
#ifdef DEBUG_OUTPUT_DIR
+ Point projection_center = shapes_bb.center();
priv::store(projection, projection_center, projection_ratio,
DEBUG_OUTPUT_DIR + "projection_center.obj");
#endif // DEBUG_OUTPUT_DIR
// for filttrate opposite triangles and a little more
- const float max_angle = 89.f;
-
+ const float max_angle = 89.9f;
priv::CutMeshes cgal_models; // source for patch
priv::CutMeshes cgal_neg_models; // model used for differenciate patches
cgal_models.reserve(models.size());
@@ -787,14 +715,11 @@ SurfaceCut Slic3r::cut_surface(const ExPolygons &shapes,
// create model for differenciate cutted patches
bool flip = true;
cgal_neg_models.push_back(priv::to_cgal(its, skip_indicies, flip));
-
- // cut out opposit triangles
- // priv::set_skip_for_outward_projection(skip_indicies, model, projection);
+
// cut out more than only opposit triangles
priv::set_skip_by_angle(skip_indicies, its, projection, max_angle);
cgal_models.push_back(priv::to_cgal(its, skip_indicies));
}
-
#ifdef DEBUG_OUTPUT_DIR
priv::store(cgal_models, DEBUG_OUTPUT_DIR + "model/");// model[0-N].off
priv::store(cgal_neg_models, DEBUG_OUTPUT_DIR + "model_neg/"); // model[0-N].off
@@ -807,7 +732,6 @@ SurfaceCut Slic3r::cut_surface(const ExPolygons &shapes,
// create tool for convert index to shape Point adress and vice versa
priv::ShapePoint2index s2i(shapes);
-
priv::VCutAOIs model_cuts;
// cut shape from each cgal model
for (priv::CutMesh &cgal_model : cgal_models) {
@@ -815,7 +739,7 @@ SurfaceCut Slic3r::cut_surface(const ExPolygons &shapes,
cgal_model, shapes, cgal_shape, projection_ratio, s2i);
#ifdef DEBUG_OUTPUT_DIR
size_t index = &cgal_model - &cgal_models.front();
- priv::store(cutAOIs, cgal_model, DEBUG_OUTPUT_DIR + "aois" + std::to_string(index) + "/"); // only debug
+ priv::store(cutAOIs, cgal_model, DEBUG_OUTPUT_DIR + "model_AOIs/" + std::to_string(index) + "/"); // only debug
#endif // DEBUG_OUTPUT_DIR
model_cuts.push_back(std::move(cutAOIs));
}
@@ -842,92 +766,11 @@ SurfaceCut Slic3r::cut_surface(const ExPolygons &shapes,
std::vector use_patch = priv::select_patches(best_projection, patches, model_cuts);
SurfaceCut result = merge_patches(patches, use_patch);
#ifdef DEBUG_OUTPUT_DIR
- priv::store(result, DEBUG_OUTPUT_DIR + "result");
+ priv::store(result, DEBUG_OUTPUT_DIR + "result.obj", DEBUG_OUTPUT_DIR + "result_contours/");
#endif // DEBUG_OUTPUT_DIR
return result;
}
-indexed_triangle_set Slic3r::cuts2model(const SurfaceCuts &cuts,
- const priv::Project3f &projection)
-{
- indexed_triangle_set result;
- size_t count_vertices = 0;
- size_t count_indices = 0;
- for (const SurfaceCut &cut : cuts) {
- assert(!cut.empty());
- count_indices += cut.indices.size()*2;
- // indices from from zig zag
- for (const auto &c : cut.contours) {
- assert(!c.empty());
- count_indices += c.size() * 2;
- }
- count_vertices += cut.vertices.size()*2;
- }
- result.vertices.reserve(count_vertices);
- result.indices.reserve(count_indices);
-
- size_t indices_offset = 0;
- for (const SurfaceCut &cut : cuts) {
- // front
- for (const auto &v : cut.vertices)
- result.vertices.push_back(v);
- for (const auto &i : cut.indices)
- result.indices.emplace_back(i.x() + indices_offset,
- i.y() + indices_offset,
- i.z() + indices_offset);
-
- // back
- for (const auto &v : cut.vertices) {
- Vec3f v2 = projection.project(v);
- result.vertices.push_back(v2);
- }
- size_t back_offset = indices_offset + cut.vertices.size();
- for (const auto &i : cut.indices) {
- assert(i.x() + back_offset < result.vertices.size());
- assert(i.y() + back_offset < result.vertices.size());
- assert(i.z() + back_offset < result.vertices.size());
- // Y and Z is swapped CCW triangles for back side
- result.indices.emplace_back(i.x() + back_offset,
- i.z() + back_offset,
- i.y() + back_offset);
- }
-
- // zig zag indices
- for (const auto &contour : cut.contours) {
- size_t prev_ci = contour.back();
- size_t prev_front_index = indices_offset + prev_ci;
- size_t prev_back_index = back_offset + prev_ci;
- for (size_t ci : contour) {
- size_t front_index = indices_offset + ci;
- size_t back_index = back_offset + ci;
- assert(front_index < result.vertices.size());
- assert(prev_front_index < result.vertices.size());
- assert(back_index < result.vertices.size());
- assert(prev_back_index < result.vertices.size());
-
- result.indices.emplace_back(
- front_index,
- prev_front_index,
- back_index
- );
- result.indices.emplace_back(
- prev_front_index,
- prev_back_index,
- back_index
- );
- prev_front_index = front_index;
- prev_back_index = back_index;
- }
- }
-
- indices_offset = result.vertices.size();
- }
-
- assert(count_vertices == result.vertices.size());
- assert(count_indices == result.indices.size());
- return result;
-}
-
indexed_triangle_set Slic3r::cut2model(const SurfaceCut &cut,
const priv::Project3f &projection)
{
@@ -991,81 +834,52 @@ indexed_triangle_set Slic3r::cut2model(const SurfaceCut &cut,
return result;
}
-bool priv::is_toward_projection(FI fi,
- const CutMesh &mesh,
- const Project3f &projection)
+// set_skip_for_out_of_aoi helping functions
+namespace priv {
+// define plane
+using PointNormal = std::pair;
+using PointNormals = std::array;
+
+///
+/// Check
+///
+///
+///
+///
+///
+bool is_out_of(const Vec3d &v, const PointNormal &point_normal);
+
+using IsOnSides = std::array, 4>;
+///
+/// Check if triangle t has all vertices out of any plane
+///
+/// Triangle
+/// Flag is vertex index out of plane
+/// True when triangle is out of one of plane
+bool is_all_on_one_side(const Vec3i &t, const IsOnSides is_on_sides);
+
+} // namespace priv
+
+bool priv::is_out_of(const Vec3d &v, const PointNormal &point_normal)
{
- HI hi = mesh.halfedge(fi);
+ const Vec3d& p = point_normal.first;
+ const Vec3d& n = point_normal.second;
+ double signed_distance = (v - p).dot(n);
+ return signed_distance > 1e-5;
+};
- const P3 &a = mesh.point(mesh.source(hi));
- const P3 &b = mesh.point(mesh.target(hi));
- const P3 &c = mesh.point(mesh.target(mesh.next(hi)));
-
- Vec3f a_(a.x(), a.y(), a.z());
- Vec3f p_ = projection.project(a_);
- P3 p{p_.x(), p_.y(), p_.z()};
-
- return CGAL::orientation(a, b, c, p) == CGAL::POSITIVE;
-}
-
-bool priv::is_toward_projection(const stl_triangle_vertex_indices &t,
- const std::vector &vertices,
- const Project3f &projection)
-{
- return is_toward_projection(vertices[t[0]], vertices[t[1]],
- vertices[t[2]], projection);
-}
-
-bool priv::is_toward_projection(const Vec3f &a,
- const Vec3f &b,
- const Vec3f &c,
- const Project3f &projection)
-{
- P3 cgal_a(a.x(), a.y(), a.z());
- P3 cgal_b(b.x(), b.y(), b.z());
- P3 cgal_c(c.x(), c.y(), c.z());
-
- Vec3f p = projection.project(a);
- P3 cgal_p{p.x(), p.y(), p.z()};
-
- // is_toward_projection
- return CGAL::orientation(cgal_a, cgal_b, cgal_c, cgal_p) ==
- CGAL::POSITIVE;
-}
-
-void priv::set_skip_for_outward_projection(std::vector &skip_indicies,
- const indexed_triangle_set &its,
- const Project3f &projection)
-{
- assert(skip_indicies.size() == its.indices.size());
- for (const auto &t : its.indices) {
- size_t index = &t - &its.indices.front();
- if (skip_indicies[index]) continue;
- if (is_toward_projection(t, its.vertices, projection)) continue;
- skip_indicies[index] = true;
- }
-}
-
-void priv::set_skip_by_angle(std::vector &skip_indicies,
- const indexed_triangle_set &its,
- const Project3f &projection,
- double max_angle)
-{
- float threshold = static_cast(cos(max_angle / 180. * M_PI));
- assert(skip_indicies.size() == its.indices.size());
- for (const stl_triangle_vertex_indices& face : its.indices) {
- size_t index = &face - &its.indices.front();
- if (skip_indicies[index]) continue;
- Vec3f n = its_face_normal(its, face);
- const Vec3f v = its.vertices[face[0]];
- // Improve: For Orthogonal Projection it is same for each vertex
- Vec3f projected = projection.project(v);
- Vec3f project_dir = projected - v;
- project_dir.normalize();
- float cos_alpha = project_dir.dot(n);
- if (cos_alpha > threshold) continue;
- skip_indicies[index] = true;
+bool priv::is_all_on_one_side(const Vec3i &t, const IsOnSides is_on_sides) {
+ for (size_t side = 0; side < 4; side++) {
+ bool result = true;
+ for (auto vi : t) {
+ if (!is_on_sides[side][vi]) {
+ result = false;
+ break;
+ }
+ }
+ if (result) return true;
}
+ return false;
}
void priv::set_skip_for_out_of_aoi(std::vector &skip_indicies,
@@ -1096,7 +910,7 @@ void priv::set_skip_for_out_of_aoi(std::vector &skip_indicies,
// 3 .. right
size_t prev_i = 3;
// plane is defined by point and normal
- std::array, 4> point_normals;
+ PointNormals point_normals;
for (size_t i = 0; i < 4; i++) {
const Vec3f &p1 = bb[i].first;
const Vec3f &p2 = bb[i].second;
@@ -1114,79 +928,59 @@ void priv::set_skip_for_out_of_aoi(std::vector &skip_indicies,
point_normals[i] = {p1.cast(), normal};
}
// same meaning as point normal
- std::array, 4> is_on_sides;
+ IsOnSides is_on_sides;
for (size_t side = 0; side < 4; side++)
is_on_sides[side] = std::vector(its.vertices.size(), {false});
-
- auto is_out_of = [&point_normals](int side, const Vec3d &v) -> bool {
- const auto &[p, n] = point_normals[side];
- double signed_distance = (v - p).dot(n);
- return signed_distance > 1e-5;
- };
-
+
// inspect all vertices when it is out of bounding box
for (size_t i = 0; i < its.vertices.size(); i++) {
Vec3d v = its.vertices[i].cast();
// under + above
for (int side : {0, 2}) {
- if (is_out_of(side, v)) {
+ if (is_out_of(v, point_normals[side])) {
is_on_sides[side][i] = true;
+ // when it is under it can't be above
break;
}
}
// left + right
for (int side : {1, 3}) {
- if (is_out_of(side, v)) {
+ if (is_out_of(v, point_normals[side])) {
is_on_sides[side][i] = true;
+ // when it is on left side it can't be on right
break;
}
}
}
- auto is_all_on_one_side = [is_on_sides](const Vec3i &t) -> bool {
- for (size_t side = 0; side < 4; side++) {
- bool result = true;
- for (auto vi : t){
- if (!is_on_sides[side][vi]) {
- result = false;
- break;
- }
- }
- if (result) return true;
- }
- return false;
- };
-
// inspect all triangles, when it is out of bounding box
- for (size_t i = 0; i < its.indices.size(); i++) {
- if (skip_indicies[i]) continue;
- const auto& t = its.indices[i];
- if (is_all_on_one_side(t))
+ for (size_t i = 0; i < its.indices.size(); i++) {
+ if (is_all_on_one_side(its.indices[i], is_on_sides))
skip_indicies[i] = true;
}
}
-priv::CutMesh priv::to_cgal(const indexed_triangle_set &its, size_t edges_count)
+void priv::set_skip_by_angle(std::vector &skip_indicies,
+ const indexed_triangle_set &its,
+ const Project3f &projection,
+ double max_angle)
{
- CutMesh result;
- if (its.empty()) return result;
-
- const std::vector &vertices = its.vertices;
- const std::vector &indices = its.indices;
-
- size_t vertices_count = vertices.size();
- size_t faces_count = indices.size();
- if (edges_count == 0) edges_count = (faces_count * 3) / 2;
- result.reserve(vertices_count, edges_count, faces_count);
-
- for (const stl_vertex &v : vertices)
- result.add_vertex(CutMesh::Point{v.x(), v.y(), v.z()});
-
- for (const stl_triangle_vertex_indices &f : indices)
- result.add_face(static_cast(f[0]), static_cast(f[1]),
- static_cast(f[2]));
-
- return result;
+ assert(max_angle < 90. && max_angle > 89.);
+ assert(skip_indicies.size() == its.indices.size());
+ float threshold = static_cast(cos(max_angle / 180. * M_PI));
+ for (const stl_triangle_vertex_indices& face : its.indices) {
+ size_t index = &face - &its.indices.front();
+ if (skip_indicies[index]) continue;
+ Vec3f n = its_face_normal(its, face);
+ const Vec3f v = its.vertices[face[0]];
+ // Improve: For Orthogonal Projection it is same for each vertex
+ Vec3f projected = projection.project(v);
+ Vec3f project_dir = projected - v;
+ project_dir.normalize();
+ float cos_alpha = project_dir.dot(n);
+ if (cos_alpha > threshold) continue;
+ skip_indicies[index] = true;
+ }
}
priv::CutMesh priv::to_cgal(const indexed_triangle_set &its,
@@ -1337,7 +1131,6 @@ priv::CutMesh priv::to_cgal(const ExPolygons &shapes,
return result;
}
-
priv::CutAOIs priv::cut_from_model(CutMesh &cgal_model,
const ExPolygons &shapes,
CutMesh &cgal_shape,
@@ -1472,55 +1265,6 @@ void priv::set_face_type(FaceTypeMap &face_type_map,
} while (hi != hi_end);
face_type_map[fi] = face_type;
}
-}
-
-void priv::set_almost_parallel_type(FaceTypeMap &face_type_map,
- const CutMesh &mesh,
- const Project3f &projection)
-{
- for (const FI &fi : mesh.faces()) {
- auto &type = face_type_map[fi];
- if (type != FaceType::inside) continue;
- //*
- assert(is_toward_projection(fi, mesh, projection));
- /*/
- if (!is_toward_projection(fi, mesh, projection)) {
- type = FaceType::outside;
- }else
- // */
- if (is_almost_parallel(fi, mesh, projection))
- // change type
- type = FaceType::inside_parallel;
- }
-}
-
-bool priv::is_almost_parallel(FI fi, const CutMesh &mesh, const Project3f &projection, float threshold)
-{
- HI hi = mesh.halfedge(fi);
- std::array vis = {
- mesh.source(hi),
- mesh.target(hi),
- mesh.target(mesh.next(hi))
- };
- std::array vertices;
- for (size_t i = 0; i < 3; i++) {
- const P3 &p3 = mesh.point(vis[i]);
- vertices[i] = Vec3f(p3.x(), p3.y(), p3.z());
- }
-
- Vec3f projected = projection.project(vertices[0]);
- Vec3f project_dir = projected - vertices[0];
- project_dir.normalize();
- Vec3f v1 = vertices[1] - vertices[0];
- v1.normalize();
- Vec3f v2 = vertices[2] - vertices[0];
- v2.normalize();
- // face normal
- Vec3f v_perp = v1.cross(v2);
- v_perp.normalize();
-
- float cos_alpha = project_dir.dot(v_perp);
- return cos_alpha <= threshold;
}
priv::ShapePoint2index::ShapePoint2index(const ExPolygons &shapes) {
@@ -1749,31 +1493,6 @@ void priv::Visitor::new_vertex_added(std::size_t i_id, VI v, const CutMesh &tm)
vert_shape_map[v] = intersection_ptr;
}
-bool priv::has_minimal_contour_points(const std::vector &outlines,
- const VertexShapeMap &vert_shape_map,
- const CutMesh &mesh,
- size_t min_count)
-{
- // unique vector of indicies point from source contour(ExPolygon)
- std::vector point_indicies;
- point_indicies.reserve(min_count);
- for (HI hi : outlines) {
- VI vi = mesh.source(hi);
- const auto& shape = vert_shape_map[vi];
- if (shape == nullptr) continue;
- uint32_t pi = shape->shape_point_index;
- if (pi == std::numeric_limits::max()) continue;
- // is already stored in vector?
- if (std::find(point_indicies.begin(), point_indicies.end(), pi)
- != point_indicies.end())
- continue;
- if (point_indicies.size() == min_count) return true;
- point_indicies.push_back(pi);
- }
- // prevent weird small pieces
- return false;
-}
-
void priv::collect_surface_data(std::queue &process,
std::vector &faces,
std::vector &outlines,
@@ -3911,11 +3630,12 @@ void priv::store(const SurfaceCuts &cut, const std::string &dir) {
}
}
-void priv::store(const SurfaceCut &cut, const std::string &prefix) {
- its_write_obj(cut, (prefix + ".obj").c_str());
+void priv::store(const SurfaceCut &cut, const std::string &file, const std::string &contour_dir) {
+ prepare_dir(contour_dir);
+ its_write_obj(cut, file.c_str());
for (const auto& contour : cut.contours) {
size_t c_index = &contour - &cut.contours.front();
- std::string c_file = prefix + "_contour" + std::to_string(c_index) + ".obj";
+ std::string c_file = contour_dir + std::to_string(c_index) + ".obj";
indexed_triangle_set c_its = create_contour_its(cut, contour);
its_write_obj(c_its, c_file.c_str());
}
diff --git a/src/libslic3r/CutSurface.hpp b/src/libslic3r/CutSurface.hpp
index 5d702d2afc..b0bafd930b 100644
--- a/src/libslic3r/CutSurface.hpp
+++ b/src/libslic3r/CutSurface.hpp
@@ -69,15 +69,6 @@ SurfaceCut cut_surface(const ExPolygons &shapes,
const Emboss::IProjection &projection,
float projection_ratio);
-
-///
-/// Create model from surface cuts by projection
-///
-/// Surfaces from model
-/// Way of emboss
-/// Mesh
-indexed_triangle_set cuts2model(const SurfaceCuts &cuts,
- const Emboss::IProject3f &projection);
///
/// Create model from surface cuts by projection
///
@@ -87,6 +78,5 @@ indexed_triangle_set cuts2model(const SurfaceCuts &cuts,
indexed_triangle_set cut2model(const SurfaceCut &cut,
const Emboss::IProject3f &projection);
-
} // namespace Slic3r
#endif // slic3r_CutSurface_hpp_