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(
|
||||
const indexed_triangle_set &mesh,
|
||||
// Unscaled Zs
|
||||
const std::vector<float> &zs,
|
||||
const MeshSlicingParams ¶ms,
|
||||
std::function<void()> throw_on_cancel)
|
||||
{
|
||||
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<float> scaled_zs(zs);
|
||||
for (float &z : scaled_zs)
|
||||
z = scaled<float>(z);
|
||||
|
||||
std::vector<stl_vertex> v_scaled_shared(mesh.vertices);
|
||||
for (stl_vertex &v : v_scaled_shared)
|
||||
v *= float(1. / SCALING_FACTOR);
|
||||
|
||||
std::vector<Vec3i> facets_edges = create_face_neighbors_index(mesh);
|
||||
lines = params.trafo.matrix() == Transform3f::Identity().matrix() ?
|
||||
slice_make_lines(v_scaled_shared, [](const Vec3f &p) { return p; }, mesh.indices, facets_edges, scaled_zs, throw_on_cancel) :
|
||||
slice_make_lines(v_scaled_shared, [¶ms](const Vec3f &p) { return params.trafo * p; }, mesh.indices, facets_edges, scaled_zs, throw_on_cancel);
|
||||
throw_on_cancel();
|
||||
const bool identity = params.trafo.matrix() == Transform3d::Identity().matrix();
|
||||
static constexpr const double s = 1. / SCALING_FACTOR;
|
||||
if (zs.size() <= 1) {
|
||||
// It likely is not worthwile to copy the vertices. Apply the transformation in place.
|
||||
if (identity)
|
||||
lines = slice_make_lines(
|
||||
mesh.vertices, [](const Vec3f &p) { return Vec3f(scaled<float>(p.x()), scaled<float>(p.y()), p.z()); },
|
||||
mesh.indices, facets_edges, zs, throw_on_cancel);
|
||||
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>();
|
||||
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);
|
||||
|
||||
@ -1154,16 +1151,13 @@ std::vector<ExPolygons> slice_mesh_ex(
|
||||
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{});
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<size_t>(0, layers_p.size()),
|
||||
[&layers_p, ¶ms, &layers, throw_on_cancel]
|
||||
(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 %zu (slice_z = %.2f):\n", layer_id, z[layer_id]);
|
||||
#endif
|
||||
throw_on_cancel();
|
||||
ExPolygons &expolygons = layers[layer_id];
|
||||
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);
|
||||
}
|
||||
});
|
||||
BOOST_LOG_TRIVIAL(debug) << "slice_mesh make_expolygons in parallel - end";
|
||||
// BOOST_LOG_TRIVIAL(debug) << "slice_mesh make_expolygons in parallel - end";
|
||||
|
||||
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.
|
||||
SlicingMode mode_below { SlicingMode::Regular };
|
||||
// Transforming faces during the slicing.
|
||||
Transform3f trafo { Transform3f::Identity() };
|
||||
Transform3d trafo { Transform3d::Identity() };
|
||||
};
|
||||
|
||||
struct MeshSlicingParamsEx : public MeshSlicingParams
|
||||
|
@ -77,7 +77,7 @@ void MeshClipper::recalculate_triangles()
|
||||
|
||||
// Now do the cutting
|
||||
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());
|
||||
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