mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 01:15:53 +08:00
Optimization: further improvements in measurement initialization
This commit is contained in:
parent
fa0abac952
commit
3277bba8c1
@ -72,7 +72,7 @@ public:
|
|||||||
int get_num_of_planes() const;
|
int get_num_of_planes() const;
|
||||||
const std::vector<int>& get_plane_triangle_indices(int idx) const;
|
const std::vector<int>& get_plane_triangle_indices(int idx) const;
|
||||||
const std::vector<SurfaceFeature>& get_plane_features(unsigned int plane_id);
|
const std::vector<SurfaceFeature>& get_plane_features(unsigned int plane_id);
|
||||||
const TriangleMesh& get_mesh() const;
|
const indexed_triangle_set& get_its() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update_planes();
|
void update_planes();
|
||||||
@ -80,7 +80,7 @@ private:
|
|||||||
|
|
||||||
std::vector<PlaneData> m_planes;
|
std::vector<PlaneData> m_planes;
|
||||||
std::vector<size_t> m_face_to_plane;
|
std::vector<size_t> m_face_to_plane;
|
||||||
TriangleMesh m_mesh;
|
indexed_triangle_set m_its;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
MeasuringImpl::MeasuringImpl(const indexed_triangle_set& its)
|
MeasuringImpl::MeasuringImpl(const indexed_triangle_set& its)
|
||||||
: m_mesh(its)
|
: m_its(its)
|
||||||
{
|
{
|
||||||
update_planes();
|
update_planes();
|
||||||
|
|
||||||
@ -104,14 +104,12 @@ MeasuringImpl::MeasuringImpl(const indexed_triangle_set& its)
|
|||||||
|
|
||||||
void MeasuringImpl::update_planes()
|
void MeasuringImpl::update_planes()
|
||||||
{
|
{
|
||||||
m_planes.clear();
|
|
||||||
|
|
||||||
// Now we'll go through all the facets and append Points of facets sharing the same normal.
|
// Now we'll go through all the facets and append Points of facets sharing the same normal.
|
||||||
// This part is still performed in mesh coordinate system.
|
// This part is still performed in mesh coordinate system.
|
||||||
const size_t num_of_facets = m_mesh.its.indices.size();
|
const size_t num_of_facets = m_its.indices.size();
|
||||||
m_face_to_plane.resize(num_of_facets, size_t(-1));
|
m_face_to_plane.resize(num_of_facets, size_t(-1));
|
||||||
const std::vector<Vec3f> face_normals = its_face_normals(m_mesh.its);
|
const std::vector<Vec3f> face_normals = its_face_normals(m_its);
|
||||||
const std::vector<Vec3i> face_neighbors = its_face_neighbors(m_mesh.its);
|
const std::vector<Vec3i> face_neighbors = its_face_neighbors(m_its);
|
||||||
std::vector<int> facet_queue(num_of_facets, 0);
|
std::vector<int> facet_queue(num_of_facets, 0);
|
||||||
int facet_queue_cnt = 0;
|
int facet_queue_cnt = 0;
|
||||||
const stl_normal* normal_ptr = nullptr;
|
const stl_normal* normal_ptr = nullptr;
|
||||||
@ -121,6 +119,10 @@ void MeasuringImpl::update_planes()
|
|||||||
return (std::abs(a(0) - b(0)) < 0.001 && std::abs(a(1) - b(1)) < 0.001 && std::abs(a(2) - b(2)) < 0.001);
|
return (std::abs(a(0) - b(0)) < 0.001 && std::abs(a(1) - b(1)) < 0.001 && std::abs(a(2) - b(2)) < 0.001);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
m_planes.clear();
|
||||||
|
m_planes.reserve(num_of_facets / 5); // empty plane data object is quite lightweight, let's save the initial reallocations
|
||||||
|
|
||||||
|
|
||||||
// First go through all the triangles and fill in m_planes vector. For each "plane"
|
// First go through all the triangles and fill in m_planes vector. For each "plane"
|
||||||
// detected on the model, it will contain list of facets that are part of it.
|
// detected on the model, it will contain list of facets that are part of it.
|
||||||
// We will also fill in m_face_to_plane, which contains index into m_planes
|
// We will also fill in m_face_to_plane, which contains index into m_planes
|
||||||
@ -132,7 +134,7 @@ void MeasuringImpl::update_planes()
|
|||||||
facet_queue[facet_queue_cnt ++] = seed_facet_idx;
|
facet_queue[facet_queue_cnt ++] = seed_facet_idx;
|
||||||
normal_ptr = &face_normals[seed_facet_idx];
|
normal_ptr = &face_normals[seed_facet_idx];
|
||||||
m_face_to_plane[seed_facet_idx] = m_planes.size();
|
m_face_to_plane[seed_facet_idx] = m_planes.size();
|
||||||
m_planes.emplace_back();
|
m_planes.emplace_back();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (seed_facet_idx == num_of_facets)
|
if (seed_facet_idx == num_of_facets)
|
||||||
@ -160,16 +162,21 @@ void MeasuringImpl::update_planes()
|
|||||||
assert(std::none_of(m_face_to_plane.begin(), m_face_to_plane.end(), [](size_t val) { return val == size_t(-1); }));
|
assert(std::none_of(m_face_to_plane.begin(), m_face_to_plane.end(), [](size_t val) { return val == size_t(-1); }));
|
||||||
|
|
||||||
// Now we will walk around each of the planes and save vertices which form the border.
|
// Now we will walk around each of the planes and save vertices which form the border.
|
||||||
SurfaceMesh sm(m_mesh.its);
|
const SurfaceMesh sm(m_its);
|
||||||
for (int plane_id=0; plane_id < int(m_planes.size()); ++plane_id) {
|
|
||||||
const auto& facets = m_planes[plane_id].facets;
|
const auto& face_to_plane = m_face_to_plane;
|
||||||
m_planes[plane_id].borders.clear();
|
auto& planes = m_planes;
|
||||||
|
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, m_planes.size()),
|
||||||
|
[&planes, &face_to_plane, &face_neighbors, &sm](const tbb::blocked_range<size_t>& range) {
|
||||||
|
for (size_t plane_id = range.begin(); plane_id != range.end(); ++plane_id) {
|
||||||
|
|
||||||
|
const auto& facets = planes[plane_id].facets;
|
||||||
|
planes[plane_id].borders.clear();
|
||||||
std::vector<std::array<bool, 3>> visited(facets.size(), {false, false, false});
|
std::vector<std::array<bool, 3>> visited(facets.size(), {false, false, false});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (int face_id=0; face_id<int(facets.size()); ++face_id) {
|
for (int face_id=0; face_id<int(facets.size()); ++face_id) {
|
||||||
assert(m_face_to_plane[facets[face_id]] == plane_id);
|
assert(face_to_plane[facets[face_id]] == plane_id);
|
||||||
|
|
||||||
for (int edge_id=0; edge_id<3; ++edge_id) {
|
for (int edge_id=0; edge_id<3; ++edge_id) {
|
||||||
// Every facet's edge which has a neighbor from a different plane is
|
// Every facet's edge which has a neighbor from a different plane is
|
||||||
@ -177,7 +184,7 @@ void MeasuringImpl::update_planes()
|
|||||||
int neighbor_idx = face_neighbors[facets[face_id]][edge_id];
|
int neighbor_idx = face_neighbors[facets[face_id]][edge_id];
|
||||||
if (neighbor_idx == -1)
|
if (neighbor_idx == -1)
|
||||||
goto PLANE_FAILURE;
|
goto PLANE_FAILURE;
|
||||||
if (visited[face_id][edge_id] || (int)m_face_to_plane[neighbor_idx] == plane_id) {
|
if (visited[face_id][edge_id] || (int)face_to_plane[neighbor_idx] == plane_id) {
|
||||||
visited[face_id][edge_id] = true;
|
visited[face_id][edge_id] = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -188,8 +195,8 @@ void MeasuringImpl::update_planes()
|
|||||||
|
|
||||||
// he is the first halfedge on the border. Now walk around and append the points.
|
// he is the first halfedge on the border. Now walk around and append the points.
|
||||||
//const Halfedge_index he_orig = he;
|
//const Halfedge_index he_orig = he;
|
||||||
m_planes[plane_id].borders.emplace_back();
|
planes[plane_id].borders.emplace_back();
|
||||||
std::vector<Vec3d>& last_border = m_planes[plane_id].borders.back();
|
std::vector<Vec3d>& last_border = planes[plane_id].borders.back();
|
||||||
last_border.reserve(4);
|
last_border.reserve(4);
|
||||||
last_border.emplace_back(sm.point(sm.source(he)).cast<double>());
|
last_border.emplace_back(sm.point(sm.source(he)).cast<double>());
|
||||||
//Vertex_index target = sm.target(he);
|
//Vertex_index target = sm.target(he);
|
||||||
@ -211,7 +218,7 @@ void MeasuringImpl::update_planes()
|
|||||||
// Remember all halfedges we saw to break out of such infinite loops.
|
// Remember all halfedges we saw to break out of such infinite loops.
|
||||||
boost::container::small_vector<Halfedge_index, 10> he_seen;
|
boost::container::small_vector<Halfedge_index, 10> he_seen;
|
||||||
|
|
||||||
while ( (int)m_face_to_plane[sm.face(he)] == plane_id && he != he_orig) {
|
while ( (int)face_to_plane[sm.face(he)] == plane_id && he != he_orig) {
|
||||||
he_seen.emplace_back(he);
|
he_seen.emplace_back(he);
|
||||||
he = sm.next_around_target(he);
|
he = sm.next_around_target(he);
|
||||||
if (he.is_invalid() || std::find(he_seen.begin(), he_seen.end(), he) != he_seen.end())
|
if (he.is_invalid() || std::find(he_seen.begin(), he_seen.end(), he) != he_seen.end())
|
||||||
@ -242,7 +249,7 @@ void MeasuringImpl::update_planes()
|
|||||||
} while (he != he_start);
|
} while (he != he_start);
|
||||||
|
|
||||||
if (last_border.size() == 1)
|
if (last_border.size() == 1)
|
||||||
m_planes[plane_id].borders.pop_back();
|
planes[plane_id].borders.pop_back();
|
||||||
else {
|
else {
|
||||||
assert(last_border.front() == last_border.back());
|
assert(last_border.front() == last_border.back());
|
||||||
last_border.pop_back();
|
last_border.pop_back();
|
||||||
@ -252,8 +259,9 @@ void MeasuringImpl::update_planes()
|
|||||||
continue; // There was no failure.
|
continue; // There was no failure.
|
||||||
|
|
||||||
PLANE_FAILURE:
|
PLANE_FAILURE:
|
||||||
m_planes[plane_id].borders.clear();
|
planes[plane_id].borders.clear();
|
||||||
}
|
}});
|
||||||
|
m_planes.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -582,9 +590,9 @@ const std::vector<SurfaceFeature>& MeasuringImpl::get_plane_features(unsigned in
|
|||||||
return m_planes[plane_id].surface_features;
|
return m_planes[plane_id].surface_features;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TriangleMesh& MeasuringImpl::get_mesh() const
|
const indexed_triangle_set& MeasuringImpl::get_its() const
|
||||||
{
|
{
|
||||||
return this->m_mesh;
|
return this->m_its;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -627,9 +635,9 @@ const std::vector<SurfaceFeature>& Measuring::get_plane_features(unsigned int pl
|
|||||||
return priv->get_plane_features(plane_id);
|
return priv->get_plane_features(plane_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TriangleMesh& Measuring::get_mesh() const
|
const indexed_triangle_set& Measuring::get_its() const
|
||||||
{
|
{
|
||||||
return priv->get_mesh();
|
return priv->get_its();
|
||||||
}
|
}
|
||||||
|
|
||||||
const AngleAndEdges AngleAndEdges::Dummy = { 0.0, Vec3d::Zero(), { Vec3d::Zero(), Vec3d::Zero() }, { Vec3d::Zero(), Vec3d::Zero() }, 0.0, true };
|
const AngleAndEdges AngleAndEdges::Dummy = { 0.0, Vec3d::Zero(), { Vec3d::Zero(), Vec3d::Zero() }, { Vec3d::Zero(), Vec3d::Zero() }, 0.0, true };
|
||||||
|
@ -109,7 +109,7 @@ public:
|
|||||||
const std::vector<SurfaceFeature>& get_plane_features(unsigned int plane_id) const;
|
const std::vector<SurfaceFeature>& get_plane_features(unsigned int plane_id) const;
|
||||||
|
|
||||||
// Returns the mesh used for measuring
|
// Returns the mesh used for measuring
|
||||||
const TriangleMesh& get_mesh() const;
|
const indexed_triangle_set& get_its() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<MeasuringImpl> priv;
|
std::unique_ptr<MeasuringImpl> priv;
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
#include <tbb/parallel_for.h>
|
||||||
|
|
||||||
#include <wx/clipbrd.h>
|
#include <wx/clipbrd.h>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
@ -650,7 +652,7 @@ void GLGizmoMeasure::on_render()
|
|||||||
const auto [idx, normal, point] = m_curr_feature->get_plane();
|
const auto [idx, normal, point] = m_curr_feature->get_plane();
|
||||||
if (m_last_plane_idx != idx) {
|
if (m_last_plane_idx != idx) {
|
||||||
m_last_plane_idx = idx;
|
m_last_plane_idx = idx;
|
||||||
const indexed_triangle_set& its = m_measuring->get_mesh().its;
|
const indexed_triangle_set& its = m_measuring->get_its();
|
||||||
const std::vector<int>& plane_triangles = m_measuring->get_plane_triangle_indices(idx);
|
const std::vector<int>& plane_triangles = m_measuring->get_plane_triangle_indices(idx);
|
||||||
GLModel::Geometry init_data = init_plane_data(its, plane_triangles);
|
GLModel::Geometry init_data = init_plane_data(its, plane_triangles);
|
||||||
m_plane.reset();
|
m_plane.reset();
|
||||||
@ -1039,10 +1041,18 @@ void GLGizmoMeasure::update_if_needed()
|
|||||||
auto update_plane_models_cache = [this](const indexed_triangle_set& its) {
|
auto update_plane_models_cache = [this](const indexed_triangle_set& its) {
|
||||||
m_plane_models_cache.clear();
|
m_plane_models_cache.clear();
|
||||||
m_plane_models_cache.resize(m_measuring->get_num_of_planes(), GLModel());
|
m_plane_models_cache.resize(m_measuring->get_num_of_planes(), GLModel());
|
||||||
for (int idx = 0; idx < m_measuring->get_num_of_planes(); ++idx) {
|
|
||||||
GLModel::Geometry init_data = init_plane_data(its, m_measuring->get_plane_triangle_indices(idx));
|
auto& plane_models_cache = m_plane_models_cache;
|
||||||
m_plane_models_cache[idx].init_from(std::move(init_data));
|
const auto& measuring = m_measuring;
|
||||||
}
|
|
||||||
|
//for (int idx = 0; idx < m_measuring->get_num_of_planes(); ++idx) {
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, m_measuring->get_num_of_planes()),
|
||||||
|
[&plane_models_cache, &measuring, &its](const tbb::blocked_range<size_t>& range) {
|
||||||
|
for (size_t idx = range.begin(); idx != range.end(); ++idx) {
|
||||||
|
GLModel::Geometry init_data = init_plane_data(its, measuring->get_plane_triangle_indices(idx));
|
||||||
|
plane_models_cache[idx].init_from(std::move(init_data));
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
auto do_update = [this, update_plane_models_cache](const std::vector<VolumeCacheItem>& volumes_cache, const Selection& selection) {
|
auto do_update = [this, update_plane_models_cache](const std::vector<VolumeCacheItem>& volumes_cache, const Selection& selection) {
|
||||||
@ -1061,8 +1071,8 @@ void GLGizmoMeasure::update_if_needed()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_measuring.reset(new Measure::Measuring(composite_mesh.its));
|
m_measuring.reset(new Measure::Measuring(composite_mesh.its));
|
||||||
update_plane_models_cache(m_measuring->get_mesh().its);
|
update_plane_models_cache(m_measuring->get_its());
|
||||||
m_raycaster.reset(new MeshRaycaster(std::make_shared<const TriangleMesh>(m_measuring->get_mesh())));
|
m_raycaster.reset(new MeshRaycaster(std::make_shared<const TriangleMesh>(composite_mesh)));
|
||||||
m_volumes_cache = volumes_cache;
|
m_volumes_cache = volumes_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user