Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2020-03-23 20:51:10 +0300
committerbubnikv <bubnikv@gmail.com>2020-03-23 21:20:54 +0300
commit580d739d6f377fcf76456051e1816aae2fb35bad (patch)
tree9c266d187679ba812cd0bc132ffc27fc36ab3c5c /src/libslic3r/TriangleMesh.cpp
parent22d9fcb27f0fba76e4fffe86fde4034ea0b8e32f (diff)
parentd5bcddeed333e6be567de517bc22c69fc5559b7e (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.cpp98
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;
}
}