TriangleMeshSlicer: Optimized out unnecessary transformations.
This commit is contained in:
parent
70b4915f9c
commit
78c0199523
@ -1047,58 +1047,55 @@ static void make_expolygons(const Polygons &loops, const float closing_radius, c
|
|||||||
|
|
||||||
std::vector<Polygons> slice_mesh(
|
std::vector<Polygons> slice_mesh(
|
||||||
const indexed_triangle_set &mesh,
|
const indexed_triangle_set &mesh,
|
||||||
|
// Unscaled Zs
|
||||||
const std::vector<float> &zs,
|
const std::vector<float> &zs,
|
||||||
const MeshSlicingParams ¶ms,
|
const MeshSlicingParams ¶ms,
|
||||||
std::function<void()> throw_on_cancel)
|
std::function<void()> throw_on_cancel)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(debug) << "slice_mesh to polygons";
|
BOOST_LOG_TRIVIAL(debug) << "slice_mesh to polygons";
|
||||||
|
|
||||||
/*
|
|
||||||
This method gets called with a list of unscaled Z coordinates and outputs
|
|
||||||
a vector pointer having the same number of items as the original list.
|
|
||||||
Each item is a vector of polygons created by slicing our mesh at the
|
|
||||||
given heights.
|
|
||||||
|
|
||||||
This method should basically combine the behavior of the existing
|
|
||||||
Perl methods defined in lib/Slic3r/TriangleMesh.pm:
|
|
||||||
|
|
||||||
- analyze(): this creates the 'facets_edges' and the 'edges_facets'
|
|
||||||
tables (we don't need the 'edges' table)
|
|
||||||
|
|
||||||
- slice_facet(): this has to be done for each facet. It generates
|
|
||||||
intersection lines with each plane identified by the Z list.
|
|
||||||
The get_layer_range() binary search used to identify the Z range
|
|
||||||
of the facet is already ported to C++ (see Object.xsp)
|
|
||||||
|
|
||||||
- make_loops(): this has to be done for each layer. It creates polygons
|
|
||||||
from the lines generated by the previous step.
|
|
||||||
|
|
||||||
At the end, we free the tables generated by analyze() as we don't
|
|
||||||
need them anymore.
|
|
||||||
|
|
||||||
NOTE: this method accepts a vector of floats because the mesh coordinate
|
|
||||||
type is float.
|
|
||||||
*/
|
|
||||||
|
|
||||||
std::vector<IntersectionLines> lines;
|
std::vector<IntersectionLines> lines;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::vector<float> scaled_zs(zs);
|
std::vector<Vec3i> facets_edges = create_face_neighbors_index(mesh);
|
||||||
for (float &z : scaled_zs)
|
const bool identity = params.trafo.matrix() == Transform3d::Identity().matrix();
|
||||||
z = scaled<float>(z);
|
static constexpr const double s = 1. / SCALING_FACTOR;
|
||||||
|
if (zs.size() <= 1) {
|
||||||
std::vector<stl_vertex> v_scaled_shared(mesh.vertices);
|
// It likely is not worthwile to copy the vertices. Apply the transformation in place.
|
||||||
for (stl_vertex &v : v_scaled_shared)
|
if (identity)
|
||||||
v *= float(1. / SCALING_FACTOR);
|
lines = slice_make_lines(
|
||||||
|
mesh.vertices, [](const Vec3f &p) { return Vec3f(scaled<float>(p.x()), scaled<float>(p.y()), p.z()); },
|
||||||
std::vector<Vec3i> facets_edges = create_face_neighbors_index(mesh);
|
mesh.indices, facets_edges, zs, throw_on_cancel);
|
||||||
lines = params.trafo.matrix() == Transform3f::Identity().matrix() ?
|
else {
|
||||||
slice_make_lines(v_scaled_shared, [](const Vec3f &p) { return p; }, mesh.indices, facets_edges, scaled_zs, throw_on_cancel) :
|
// Transform the vertices, scale up in XY, not in Y.
|
||||||
slice_make_lines(v_scaled_shared, [¶ms](const Vec3f &p) { return params.trafo * p; }, mesh.indices, facets_edges, scaled_zs, throw_on_cancel);
|
auto t = params.trafo;
|
||||||
throw_on_cancel();
|
t.prescale(Vec3d(s, s, 1.));
|
||||||
|
auto tf = t.cast<float>();
|
||||||
|
slice_make_lines(mesh.vertices, [tf](const Vec3f &p) { return tf * p; }, mesh.indices, facets_edges, zs, throw_on_cancel);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Copy and scale vertices in XY, don't scale in Z.
|
||||||
|
// Possibly apply the transformation.
|
||||||
|
std::vector<stl_vertex> vertices(mesh.vertices);
|
||||||
|
if (identity) {
|
||||||
|
for (stl_vertex &v : vertices) {
|
||||||
|
// Scale just XY, leave Z unscaled.
|
||||||
|
v.x() *= float(s);
|
||||||
|
v.y() *= float(s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Transform the vertices, scale up in XY, not in Y.
|
||||||
|
auto t = params.trafo;
|
||||||
|
t.prescale(Vec3d(s, s, 1.));
|
||||||
|
auto tf = t.cast<float>();
|
||||||
|
for (stl_vertex &v : vertices)
|
||||||
|
v = tf * v;
|
||||||
|
}
|
||||||
|
lines = slice_make_lines(vertices, [](const Vec3f &p) { return p; }, mesh.indices, facets_edges, zs, throw_on_cancel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// v_scaled_shared could be freed here
|
throw_on_cancel();
|
||||||
|
|
||||||
std::vector<Polygons> layers = make_loops(lines, params, throw_on_cancel);
|
std::vector<Polygons> layers = make_loops(lines, params, throw_on_cancel);
|
||||||
|
|
||||||
@ -1154,16 +1151,13 @@ std::vector<ExPolygons> slice_mesh_ex(
|
|||||||
layers_p = slice_mesh(mesh, zs, slicing_params, throw_on_cancel);
|
layers_p = slice_mesh(mesh, zs, slicing_params, throw_on_cancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "slice_mesh make_expolygons in parallel - start";
|
// BOOST_LOG_TRIVIAL(debug) << "slice_mesh make_expolygons in parallel - start";
|
||||||
std::vector<ExPolygons> layers(layers_p.size(), ExPolygons{});
|
std::vector<ExPolygons> layers(layers_p.size(), ExPolygons{});
|
||||||
tbb::parallel_for(
|
tbb::parallel_for(
|
||||||
tbb::blocked_range<size_t>(0, layers_p.size()),
|
tbb::blocked_range<size_t>(0, layers_p.size()),
|
||||||
[&layers_p, ¶ms, &layers, throw_on_cancel]
|
[&layers_p, ¶ms, &layers, throw_on_cancel]
|
||||||
(const tbb::blocked_range<size_t>& range) {
|
(const tbb::blocked_range<size_t>& range) {
|
||||||
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
|
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
|
||||||
#ifdef SLIC3R_TRIANGLEMESH_DEBUG
|
|
||||||
printf("Layer %zu (slice_z = %.2f):\n", layer_id, z[layer_id]);
|
|
||||||
#endif
|
|
||||||
throw_on_cancel();
|
throw_on_cancel();
|
||||||
ExPolygons &expolygons = layers[layer_id];
|
ExPolygons &expolygons = layers[layer_id];
|
||||||
Slic3r::make_expolygons(layers_p[layer_id], params.closing_radius, params.extra_offset, &expolygons);
|
Slic3r::make_expolygons(layers_p[layer_id], params.closing_radius, params.extra_offset, &expolygons);
|
||||||
@ -1173,7 +1167,7 @@ std::vector<ExPolygons> slice_mesh_ex(
|
|||||||
keep_largest_contour_only(expolygons);
|
keep_largest_contour_only(expolygons);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
BOOST_LOG_TRIVIAL(debug) << "slice_mesh make_expolygons in parallel - end";
|
// BOOST_LOG_TRIVIAL(debug) << "slice_mesh make_expolygons in parallel - end";
|
||||||
|
|
||||||
return layers;
|
return layers;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ struct MeshSlicingParams
|
|||||||
// Mode to apply below slicing_mode_normal_below_layer. Ignored if slicing_mode_nromal_below_layer == 0.
|
// Mode to apply below slicing_mode_normal_below_layer. Ignored if slicing_mode_nromal_below_layer == 0.
|
||||||
SlicingMode mode_below { SlicingMode::Regular };
|
SlicingMode mode_below { SlicingMode::Regular };
|
||||||
// Transforming faces during the slicing.
|
// Transforming faces during the slicing.
|
||||||
Transform3f trafo { Transform3f::Identity() };
|
Transform3d trafo { Transform3d::Identity() };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MeshSlicingParamsEx : public MeshSlicingParams
|
struct MeshSlicingParamsEx : public MeshSlicingParams
|
||||||
|
@ -77,7 +77,7 @@ void MeshClipper::recalculate_triangles()
|
|||||||
|
|
||||||
// Now do the cutting
|
// Now do the cutting
|
||||||
MeshSlicingParamsEx slicing_params;
|
MeshSlicingParamsEx slicing_params;
|
||||||
slicing_params.trafo.rotate(Eigen::Quaternion<double, Eigen::DontAlign>::FromTwoVectors(up, Vec3d::UnitZ()).cast<float>());
|
slicing_params.trafo.rotate(Eigen::Quaternion<double, Eigen::DontAlign>::FromTwoVectors(up, Vec3d::UnitZ()));
|
||||||
|
|
||||||
assert(m_mesh->has_shared_vertices());
|
assert(m_mesh->has_shared_vertices());
|
||||||
std::vector<ExPolygons> list_of_expolys = slice_mesh_ex(m_mesh->its, std::vector<float>{height_mesh}, slicing_params);
|
std::vector<ExPolygons> list_of_expolys = slice_mesh_ex(m_mesh->its, std::vector<float>{height_mesh}, slicing_params);
|
||||||
|
Loading…
Reference in New Issue
Block a user