mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-22 06:04:01 -06:00
Renamed create_face_neighbors_index() to its_face_edge_ids().
Renamed its_create_neighbors_index() / its_create_neighbors_index_par() to its_face_neighbors() / its_face_neighbors_par(). New variant of its_face_edge_ids() to create edge IDs from face neighbors. Fixed some incorrect use of _NDEBUG, it should be NDEBUG. PrintObject::slice_support_volumes() returns newly Polygons, which are cheaper than ExPolygons. Updated SeamPlacer and SupportMaterial to use regions defined as Polygons, not ExPolygons. TriangleSelector::get_facets_strict() returning a patch with T-joints retriangulated. New slice_mesh_slabs() - slicing projections of a triangle patch into top / bottom layers of slices, for MMU top / bottom segmentation. TriangleMeshSlicer - use 64 mutexes instead of one when scattering sliced triangles into layers. This makes a big difference on modern many core desktop computers. When applying MM segmented regions to input regions, the split regions are now re-merged with 10x higher positive offset epsilon to avoid creating gaps. When testing for existence of paint-on supports or seam, use a more efficient has_facets() test, which does not deserialize into the expensive TriangleSelector tree structure. GLIndexedVertexArray newly uses Eigen::AlignedBox<float, 3> for efficiency instead of our double based BoundingBoxf3. Improved MMU painting refresh speed by optimizing generation of the vertex buffers. Refactored MMU segmentation - projection of painted surfaces from top / bottom. 1) Parallelized. 2) Using the new slice_mesh_slabs() instead of projecting one triangle by the other and merging them with Clipper.
This commit is contained in:
parent
d08a70478e
commit
0d70a2be69
23 changed files with 1357 additions and 489 deletions
|
@ -3,9 +3,9 @@
|
|||
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
#ifndef _NDEBUG
|
||||
#ifndef NDEBUG
|
||||
#define EXPENSIVE_DEBUG_CHECKS
|
||||
#endif // _NDEBUG
|
||||
#endif // NDEBUG
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -19,7 +19,7 @@ static inline Vec3i root_neighbors(const TriangleMesh &mesh, int triangle_id)
|
|||
return neighbors;
|
||||
}
|
||||
|
||||
#ifndef _NDEBUG
|
||||
#ifndef NDEBUG
|
||||
bool TriangleSelector::verify_triangle_midpoints(const Triangle &tr) const
|
||||
{
|
||||
for (int i = 0; i < 3; ++ i) {
|
||||
|
@ -57,7 +57,7 @@ bool TriangleSelector::verify_triangle_neighbors(const Triangle &tr, const Vec3i
|
|||
}
|
||||
return true;
|
||||
}
|
||||
#endif // _NDEBUG
|
||||
#endif // NDEBUG
|
||||
|
||||
// sides_to_split==-1 : just restore previous split
|
||||
void TriangleSelector::Triangle::set_division(int sides_to_split, int special_side_idx)
|
||||
|
@ -308,12 +308,12 @@ int TriangleSelector::triangle_midpoint_or_allocate(int itriangle, int vertexi,
|
|||
}
|
||||
assert(m_vertices[midpoint].ref_cnt == 0);
|
||||
} else {
|
||||
#ifndef _NDEBUG
|
||||
#ifndef NDEBUG
|
||||
Vec3f c1 = 0.5f * (m_vertices[vertexi].v + m_vertices[vertexj].v);
|
||||
Vec3f c2 = m_vertices[midpoint].v;
|
||||
float d = (c2 - c1).norm();
|
||||
assert(std::abs(d) < EPSILON);
|
||||
#endif // _NDEBUG
|
||||
#endif // NDEBUG
|
||||
assert(m_vertices[midpoint].ref_cnt > 0);
|
||||
}
|
||||
return midpoint;
|
||||
|
@ -810,19 +810,23 @@ int TriangleSelector::push_triangle(int a, int b, int c, int source_triangle, co
|
|||
void TriangleSelector::perform_split(int facet_idx, const Vec3i &neighbors, EnforcerBlockerType old_state)
|
||||
{
|
||||
// Reserve space for the new triangles upfront, so that the reference to this triangle will not change.
|
||||
m_triangles.reserve(m_triangles.size() + m_triangles[facet_idx].number_of_split_sides() + 1);
|
||||
{
|
||||
size_t num_triangles_new = m_triangles.size() + m_triangles[facet_idx].number_of_split_sides() + 1;
|
||||
if (m_triangles.capacity() < num_triangles_new)
|
||||
m_triangles.reserve(next_highest_power_of_2(num_triangles_new));
|
||||
}
|
||||
|
||||
Triangle &tr = m_triangles[facet_idx];
|
||||
assert(tr.is_split());
|
||||
|
||||
// indices of triangle vertices
|
||||
#ifdef _NDEBUG
|
||||
#ifdef NDEBUG
|
||||
boost::container::small_vector<int, 6> verts_idxs;
|
||||
#else // _NDEBUG
|
||||
#else // NDEBUG
|
||||
// For easier debugging.
|
||||
std::vector<int> verts_idxs;
|
||||
verts_idxs.reserve(6);
|
||||
#endif // _NDEBUG
|
||||
#endif // NDEBUG
|
||||
for (int j=0, idx = tr.special_side(); j<3; ++j, idx = next_idx_modulo(idx, 3))
|
||||
verts_idxs.push_back(tr.verts_idxs[idx]);
|
||||
|
||||
|
@ -861,13 +865,13 @@ void TriangleSelector::perform_split(int facet_idx, const Vec3i &neighbors, Enfo
|
|||
break;
|
||||
}
|
||||
|
||||
#ifndef _NDEBUG
|
||||
#ifndef NDEBUG
|
||||
assert(this->verify_triangle_neighbors(tr, neighbors));
|
||||
for (int i = 0; i <= tr.number_of_split_sides(); ++i) {
|
||||
Vec3i n = this->child_neighbors(tr, neighbors, i);
|
||||
assert(this->verify_triangle_neighbors(m_triangles[tr.children[i]], n));
|
||||
}
|
||||
#endif // _NDEBUG
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
bool TriangleSelector::has_facets(EnforcerBlockerType state) const
|
||||
|
@ -918,7 +922,7 @@ indexed_triangle_set TriangleSelector::get_facets_strict(EnforcerBlockerType sta
|
|||
++ num_vertices;
|
||||
out.vertices.reserve(num_vertices);
|
||||
std::vector<int> vertex_map(m_vertices.size(), -1);
|
||||
for (int i = 0; i < m_vertices.size(); ++ i)
|
||||
for (size_t i = 0; i < m_vertices.size(); ++ i)
|
||||
if (const Vertex &v = m_vertices[i]; v.ref_cnt > 0) {
|
||||
vertex_map[i] = int(out.vertices.size());
|
||||
out.vertices.emplace_back(v.v);
|
||||
|
@ -958,10 +962,13 @@ void TriangleSelector::get_facets_split_by_tjoints(const Vec3i vertices, const V
|
|||
this->triangle_midpoint(neighbors(1), vertices(2), vertices(1)),
|
||||
this->triangle_midpoint(neighbors(2), vertices(0), vertices(2)));
|
||||
int splits = (midpoints(0) != -1) + (midpoints(1) != -1) + (midpoints(2) != -1);
|
||||
if (splits == 0) {
|
||||
switch (splits) {
|
||||
case 0:
|
||||
// Just emit this triangle.
|
||||
out_triangles.emplace_back(vertices(0), midpoints(0), midpoints(2));
|
||||
} else if (splits == 1) {
|
||||
out_triangles.emplace_back(vertices(0), vertices(1), vertices(2));
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
// Split to two triangles
|
||||
int i = midpoints(0) != -1 ? 2 : midpoints(1) != -1 ? 0 : 1;
|
||||
int j = next_idx_modulo(i, 3);
|
||||
|
@ -969,16 +976,19 @@ void TriangleSelector::get_facets_split_by_tjoints(const Vec3i vertices, const V
|
|||
this->get_facets_split_by_tjoints(
|
||||
{ vertices(i), vertices(j), midpoints(j) },
|
||||
{ neighbors(i),
|
||||
this->neighbor_child(neighbors(j), vertices(j), vertices(k), Partition::Second),
|
||||
this->neighbor_child(neighbors(j), vertices(k), vertices(j), Partition::Second),
|
||||
-1 },
|
||||
out_triangles);
|
||||
this->get_facets_split_by_tjoints(
|
||||
{ midpoints(j), vertices(j), vertices(k) },
|
||||
{ this->neighbor_child(neighbors(j), vertices(j), vertices(k), Partition::First),
|
||||
{ midpoints(j), vertices(k), vertices(i) },
|
||||
{ this->neighbor_child(neighbors(j), vertices(k), vertices(j), Partition::First),
|
||||
neighbors(k),
|
||||
-1 },
|
||||
out_triangles);
|
||||
} else if (splits == 2) {
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// Split to three triangles.
|
||||
int i = midpoints(0) == -1 ? 2 : midpoints(1) == -1 ? 0 : 1;
|
||||
int j = next_idx_modulo(i, 3);
|
||||
|
@ -1000,7 +1010,10 @@ void TriangleSelector::get_facets_split_by_tjoints(const Vec3i vertices, const V
|
|||
this->neighbor_child(neighbors(k), vertices(i), vertices(k), Partition::Second),
|
||||
-1 },
|
||||
out_triangles);
|
||||
} else if (splits == 4) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(splits == 3);
|
||||
// Split to 4 triangles.
|
||||
this->get_facets_split_by_tjoints(
|
||||
{ vertices(0), midpoints(0), midpoints(2) },
|
||||
|
@ -1021,6 +1034,7 @@ void TriangleSelector::get_facets_split_by_tjoints(const Vec3i vertices, const V
|
|||
-1 },
|
||||
out_triangles);
|
||||
out_triangles.emplace_back(midpoints);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1106,6 +1120,13 @@ void TriangleSelector::deserialize(const std::pair<std::vector<std::pair<int, in
|
|||
{
|
||||
reset(); // dump any current state
|
||||
|
||||
// Reserve number of triangles as if each triangle was saved with 4 bits.
|
||||
// With MMU painting this estimate may be somehow low, but better than nothing.
|
||||
m_triangles.reserve(std::max(m_mesh->its.indices.size(), data.second.size() / 4));
|
||||
// Number of triangles is twice the number of vertices on a large manifold mesh of genus zero.
|
||||
// Here the triangles count account for both the nodes and leaves, thus the following line may overestimate.
|
||||
m_vertices.reserve(std::max(m_mesh->its.vertices.size(), m_triangles.size() / 2));
|
||||
|
||||
// Vector to store all parents that have offsprings.
|
||||
struct ProcessingInfo {
|
||||
int facet_id = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue