diff options
author | bubnikv <bubnikv@gmail.com> | 2020-03-23 20:51:10 +0300 |
---|---|---|
committer | bubnikv <bubnikv@gmail.com> | 2020-03-23 21:20:54 +0300 |
commit | 580d739d6f377fcf76456051e1816aae2fb35bad (patch) | |
tree | 9c266d187679ba812cd0bc132ffc27fc36ab3c5c /src/libslic3r/TriangleMesh.cpp | |
parent | 22d9fcb27f0fba76e4fffe86fde4034ea0b8e32f (diff) | |
parent | d5bcddeed333e6be567de517bc22c69fc5559b7e (diff) |
Merging version_2.2.0 final into stable
Merge commit 'd5bcddeed333e6be567de517bc22c69fc5559b7e' into stable
Diffstat (limited to 'src/libslic3r/TriangleMesh.cpp')
-rw-r--r-- | src/libslic3r/TriangleMesh.cpp | 98 |
1 files changed, 86 insertions, 12 deletions
diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index c2fcb11bd..ee5e96f3d 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -70,6 +70,34 @@ TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd>& f stl_get_size(&stl); } +TriangleMesh::TriangleMesh(const indexed_triangle_set &M) +{ + stl.stats.type = inmemory; + + // count facets and allocate memory + stl.stats.number_of_facets = uint32_t(M.indices.size()); + stl.stats.original_num_facets = int(stl.stats.number_of_facets); + stl_allocate(&stl); + + for (uint32_t i = 0; i < stl.stats.number_of_facets; ++ i) { + stl_facet facet; + facet.vertex[0] = M.vertices[size_t(M.indices[i](0))]; + facet.vertex[1] = M.vertices[size_t(M.indices[i](1))]; + facet.vertex[2] = M.vertices[size_t(M.indices[i](2))]; + facet.extra[0] = 0; + facet.extra[1] = 0; + + stl_normal normal; + stl_calculate_normal(normal, &facet); + stl_normalize_vector(normal); + facet.normal = normal; + + stl.facet_start[i] = facet; + } + + stl_get_size(&stl); +} + // #define SLIC3R_TRACE_REPAIR void TriangleMesh::repair(bool update_shared_vertices) @@ -236,7 +264,7 @@ bool TriangleMesh::needed_repair() const || this->stl.stats.backwards_edges > 0; } -void TriangleMesh::WriteOBJFile(const char* output_file) +void TriangleMesh::WriteOBJFile(const char* output_file) const { its_write_obj(this->its, output_file); } @@ -593,6 +621,16 @@ TriangleMesh TriangleMesh::convex_hull_3d() const return output_mesh; } +std::vector<ExPolygons> TriangleMesh::slice(const std::vector<double> &z) +{ + // convert doubles to floats + std::vector<float> z_f(z.begin(), z.end()); + TriangleMeshSlicer mslicer(this); + std::vector<ExPolygons> layers; + mslicer.slice(z_f, SlicingMode::Regular, 0.0004f, &layers, [](){}); + return layers; +} + void TriangleMesh::require_shared_vertices() { BOOST_LOG_TRIVIAL(trace) << "TriangleMeshSlicer::require_shared_vertices - start"; @@ -738,7 +776,7 @@ void TriangleMeshSlicer::set_up_direction(const Vec3f& up) -void TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<Polygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const +void TriangleMeshSlicer::slice(const std::vector<float> &z, SlicingMode mode, std::vector<Polygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const { BOOST_LOG_TRIVIAL(debug) << "TriangleMeshSlicer::slice"; @@ -793,11 +831,38 @@ void TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<Polygons layers->resize(z.size()); tbb::parallel_for( tbb::blocked_range<size_t>(0, z.size()), - [&lines, &layers, throw_on_cancel, this](const tbb::blocked_range<size_t>& range) { + [&lines, &layers, mode, throw_on_cancel, this](const tbb::blocked_range<size_t>& range) { for (size_t line_idx = range.begin(); line_idx < range.end(); ++ line_idx) { if ((line_idx & 0x0ffff) == 0) throw_on_cancel(); - this->make_loops(lines[line_idx], &(*layers)[line_idx]); + + Polygons &polygons = (*layers)[line_idx]; + this->make_loops(lines[line_idx], &polygons); + + if (! polygons.empty()) { + if (mode == SlicingMode::Positive) { + // Reorient all loops to be CCW. + for (Polygon& p : polygons) + p.make_counter_clockwise(); + } else if (mode == SlicingMode::PositiveLargestContour) { + // Keep just the largest polygon, make it CCW. + double max_area = 0.; + Polygon* max_area_polygon = nullptr; + for (Polygon& p : polygons) { + double a = p.area(); + if (std::abs(a) > std::abs(max_area)) { + max_area = a; + max_area_polygon = &p; + } + } + assert(max_area_polygon != nullptr); + if (max_area < 0.) + max_area_polygon->reverse(); + Polygon p(std::move(*max_area_polygon)); + polygons.clear(); + polygons.emplace_back(std::move(p)); + } + } } } ); @@ -875,22 +940,25 @@ void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vector<IntersectionLin } } -void TriangleMeshSlicer::slice(const std::vector<float> &z, const float closing_radius, std::vector<ExPolygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const +void TriangleMeshSlicer::slice(const std::vector<float> &z, SlicingMode mode, const float closing_radius, std::vector<ExPolygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const { std::vector<Polygons> layers_p; - this->slice(z, &layers_p, throw_on_cancel); + this->slice(z, (mode == SlicingMode::PositiveLargestContour) ? SlicingMode::Positive : mode, &layers_p, throw_on_cancel); BOOST_LOG_TRIVIAL(debug) << "TriangleMeshSlicer::make_expolygons in parallel - start"; layers->resize(z.size()); tbb::parallel_for( tbb::blocked_range<size_t>(0, z.size()), - [&layers_p, closing_radius, layers, throw_on_cancel, this](const tbb::blocked_range<size_t>& range) { + [&layers_p, mode, closing_radius, layers, throw_on_cancel, this](const tbb::blocked_range<size_t>& range) { for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) { #ifdef SLIC3R_TRIANGLEMESH_DEBUG printf("Layer " PRINTF_ZU " (slice_z = %.2f):\n", layer_id, z[layer_id]); #endif throw_on_cancel(); - this->make_expolygons(layers_p[layer_id], closing_radius, &(*layers)[layer_id]); + ExPolygons &expolygons = (*layers)[layer_id]; + this->make_expolygons(layers_p[layer_id], closing_radius, &expolygons); + if (mode == SlicingMode::PositiveLargestContour) + keep_largest_contour_only(expolygons); } }); BOOST_LOG_TRIVIAL(debug) << "TriangleMeshSlicer::make_expolygons in parallel - end"; @@ -1861,7 +1929,8 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower) } // Generate the vertex list for a cube solid of arbitrary size in X/Y/Z. -TriangleMesh make_cube(double x, double y, double z) { +TriangleMesh make_cube(double x, double y, double z) +{ Vec3d pv[8] = { Vec3d(x, y, 0), Vec3d(x, 0, 0), Vec3d(0, 0, 0), Vec3d(0, y, 0), Vec3d(x, y, z), Vec3d(0, y, z), @@ -1878,7 +1947,8 @@ TriangleMesh make_cube(double x, double y, double z) { Pointf3s vertices(&pv[0], &pv[0]+8); TriangleMesh mesh(vertices ,facets); - return mesh; + mesh.repair(); + return mesh; } // Generate the mesh for a cylinder and return it, using @@ -1922,7 +1992,9 @@ TriangleMesh make_cylinder(double r, double h, double fa) facets.emplace_back(Vec3crd(id, 2, 3)); facets.emplace_back(Vec3crd(id, id - 1, 2)); - return TriangleMesh(std::move(vertices), std::move(facets)); + TriangleMesh mesh(std::move(vertices), std::move(facets)); + mesh.repair(); + return mesh; } // Generates mesh for a sphere centered about the origin, using the generated angle @@ -1978,7 +2050,9 @@ TriangleMesh make_sphere(double radius, double fa) k2 = k2_next; } } - return TriangleMesh(std::move(vertices), std::move(facets)); + TriangleMesh mesh(std::move(vertices), std::move(facets)); + mesh.repair(); + return mesh; } } |