TriangleSelector - some memory optimization.
Don't store traingle normal, but reference the source triangle, which stores its normal.
This commit is contained in:
parent
74ab3e108e
commit
6bade1b24a
5 changed files with 49 additions and 59 deletions
|
@ -112,8 +112,9 @@ void TriangleSelector::seed_fill_select_triangles(const Vec3f& hit, int facet_st
|
|||
assert(neighbor_idx >= 0);
|
||||
if (neighbor_idx >= 0 && !visited[neighbor_idx]) {
|
||||
// Check if neighbour_facet_idx is satisfies angle in seed_fill_angle and append it to facet_queue if it do.
|
||||
double dot_product = m_triangles[neighbor_idx].normal.dot(m_triangles[current_facet].normal);
|
||||
if (std::clamp(dot_product, 0., 1.) >= facet_angle_limit)
|
||||
const Vec3f &n1 = m_mesh->stl.facet_start[m_triangles[neighbor_idx].source_triangle].normal;
|
||||
const Vec3f &n2 = m_mesh->stl.facet_start[m_triangles[current_facet].source_triangle].normal;
|
||||
if (std::clamp(n1.dot(n2), 0.f, 1.f) >= facet_angle_limit)
|
||||
facet_queue.push(neighbor_idx);
|
||||
}
|
||||
}
|
||||
|
@ -201,6 +202,8 @@ void TriangleSelector::set_facet(int facet_idx, EnforcerBlockerType state)
|
|||
m_triangles[facet_idx].set_state(state);
|
||||
}
|
||||
|
||||
// called by select_patch()->select_triangle()
|
||||
// to decide which sides of the traingle to split and to actually split it calling set_division() and perform_split().
|
||||
void TriangleSelector::split_triangle(int facet_idx)
|
||||
{
|
||||
if (m_triangles[facet_idx].is_split()) {
|
||||
|
@ -475,8 +478,7 @@ void TriangleSelector::reset(const EnforcerBlockerType reset_state)
|
|||
m_triangles.reserve(m_mesh->its.indices.size());
|
||||
for (size_t i=0; i<m_mesh->its.indices.size(); ++i) {
|
||||
const stl_triangle_vertex_indices& ind = m_mesh->its.indices[i];
|
||||
const Vec3f& normal = m_mesh->stl.facet_start[i].normal;
|
||||
push_triangle(ind[0], ind[1], ind[2], normal, reset_state);
|
||||
push_triangle(ind[0], ind[1], ind[2], i, reset_state);
|
||||
}
|
||||
m_orig_size_vertices = m_vertices.size();
|
||||
m_orig_size_indices = m_triangles.size();
|
||||
|
@ -503,20 +505,20 @@ void TriangleSelector::set_edge_limit(float edge_limit)
|
|||
|
||||
|
||||
|
||||
void TriangleSelector::push_triangle(int a, int b, int c, const Vec3f& normal, const EnforcerBlockerType state)
|
||||
void TriangleSelector::push_triangle(int a, int b, int c, int source_triangle, const EnforcerBlockerType state)
|
||||
{
|
||||
for (int i : {a, b, c}) {
|
||||
assert(i >= 0 && i < int(m_vertices.size()));
|
||||
++m_vertices[i].ref_cnt;
|
||||
}
|
||||
m_triangles.emplace_back(a, b, c, normal, state);
|
||||
m_triangles.emplace_back(a, b, c, source_triangle, state);
|
||||
}
|
||||
|
||||
|
||||
// called by deserialize() and select_patch()->select_triangle()->split_triangle()
|
||||
void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_state)
|
||||
{
|
||||
Triangle* tr = &m_triangles[facet_idx];
|
||||
const Vec3f normal = tr->normal;
|
||||
int source_triangle = tr->source_triangle;
|
||||
|
||||
assert(tr->is_split());
|
||||
|
||||
|
@ -524,7 +526,7 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat
|
|||
int sides_to_split = tr->number_of_split_sides();
|
||||
|
||||
// indices of triangle vertices
|
||||
std::vector<int> verts_idxs;
|
||||
boost::container::small_vector<int, 6> verts_idxs;
|
||||
int idx = tr->special_side();
|
||||
for (int j=0; j<3; ++j) {
|
||||
verts_idxs.push_back(tr->verts_idxs[idx++]);
|
||||
|
@ -537,8 +539,8 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat
|
|||
m_vertices.emplace_back((m_vertices[verts_idxs[1]].v + m_vertices[verts_idxs[2]].v)/2.);
|
||||
verts_idxs.insert(verts_idxs.begin()+2, m_vertices.size() - 1);
|
||||
|
||||
push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[2], normal);
|
||||
push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[0], normal);
|
||||
push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[2], source_triangle);
|
||||
push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[0], source_triangle);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
@ -548,9 +550,9 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat
|
|||
m_vertices.emplace_back((m_vertices[verts_idxs[0]].v + m_vertices[verts_idxs[3]].v)/2.);
|
||||
verts_idxs.insert(verts_idxs.begin()+4, m_vertices.size() - 1);
|
||||
|
||||
push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[4], normal);
|
||||
push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[4], normal);
|
||||
push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[4], normal);
|
||||
push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[4], source_triangle);
|
||||
push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[4], source_triangle);
|
||||
push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[4], source_triangle);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
@ -561,10 +563,10 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat
|
|||
m_vertices.emplace_back((m_vertices[verts_idxs[4]].v + m_vertices[verts_idxs[0]].v)/2.);
|
||||
verts_idxs.insert(verts_idxs.begin()+5, m_vertices.size() - 1);
|
||||
|
||||
push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[5], normal);
|
||||
push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[3], normal);
|
||||
push_triangle(verts_idxs[3], verts_idxs[4], verts_idxs[5], normal);
|
||||
push_triangle(verts_idxs[1], verts_idxs[3], verts_idxs[5], normal);
|
||||
push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[5], source_triangle);
|
||||
push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[3], source_triangle);
|
||||
push_triangle(verts_idxs[3], verts_idxs[4], verts_idxs[5], source_triangle);
|
||||
push_triangle(verts_idxs[1], verts_idxs[3], verts_idxs[5], source_triangle);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -694,6 +696,7 @@ void TriangleSelector::deserialize(const std::pair<std::vector<std::pair<int, in
|
|||
int processed_children = 0;
|
||||
int total_children = 0;
|
||||
};
|
||||
// Depth-first queue of a source mesh triangle and its childern.
|
||||
// kept outside of the loop to avoid re-allocating inside the loop.
|
||||
std::vector<ProcessingInfo> parents;
|
||||
|
||||
|
|
|
@ -76,19 +76,21 @@ protected:
|
|||
public:
|
||||
// Use TriangleSelector::push_triangle to create a new triangle.
|
||||
// It increments/decrements reference counter on vertices.
|
||||
Triangle(int a, int b, int c, const Vec3f& normal_, const EnforcerBlockerType init_state)
|
||||
Triangle(int a, int b, int c, int source_triangle, const EnforcerBlockerType init_state)
|
||||
: verts_idxs{a, b, c},
|
||||
normal{normal_},
|
||||
state{init_state},
|
||||
number_of_splits{0},
|
||||
special_side_idx{0},
|
||||
old_number_of_splits{0}
|
||||
{}
|
||||
source_triangle{source_triangle},
|
||||
state{init_state}
|
||||
{
|
||||
// Initialize bit fields. Default member initializers are not supported by C++17.
|
||||
m_selected_by_seed_fill = false;
|
||||
m_valid = true;
|
||||
old_number_of_splits = 0;
|
||||
}
|
||||
// Indices into m_vertices.
|
||||
std::array<int, 3> verts_idxs;
|
||||
|
||||
// Triangle normal (a shader might need it).
|
||||
Vec3f normal;
|
||||
// Index of the source triangle at the initial (unsplit) mesh.
|
||||
int source_triangle;
|
||||
|
||||
// Children triangles.
|
||||
std::array<int, 4> children;
|
||||
|
@ -118,16 +120,20 @@ protected:
|
|||
private:
|
||||
friend TriangleSelector;
|
||||
|
||||
int number_of_splits;
|
||||
int special_side_idx;
|
||||
// Packing the rest of member variables into 4 bytes, aligned to 4 bytes boundary.
|
||||
char number_of_splits { 0 };
|
||||
// Index of a vertex opposite to the split edge (for number_of_splits == 1)
|
||||
// or index of a vertex shared by the two split edges (for number_of_splits == 2).
|
||||
// For number_of_splits == 3, special_side_idx is always zero.
|
||||
char special_side_idx { 0 };
|
||||
EnforcerBlockerType state;
|
||||
bool m_selected_by_seed_fill = false;
|
||||
bool m_selected_by_seed_fill : 1;
|
||||
// Is this triangle valid or marked to be removed?
|
||||
bool m_valid{true};
|
||||
bool m_valid : 1;
|
||||
|
||||
// How many children were spawned during last split?
|
||||
// Is not reset on remerging the triangle.
|
||||
int old_number_of_splits;
|
||||
char old_number_of_splits : 2;
|
||||
};
|
||||
|
||||
struct Vertex {
|
||||
|
@ -185,7 +191,7 @@ private:
|
|||
void remove_useless_children(int facet_idx); // No hidden meaning. Triangles are meant.
|
||||
bool is_pointer_in_triangle(int facet_idx) const;
|
||||
bool is_edge_inside_cursor(int facet_idx) const;
|
||||
void push_triangle(int a, int b, int c, const Vec3f &normal, const EnforcerBlockerType state = EnforcerBlockerType{0});
|
||||
void push_triangle(int a, int b, int c, int source_triangle, const EnforcerBlockerType state = EnforcerBlockerType{0});
|
||||
void perform_split(int facet_idx, EnforcerBlockerType old_state);
|
||||
};
|
||||
|
||||
|
|
|
@ -154,8 +154,9 @@ public:
|
|||
push_geometry(float(x), float(y), float(z), float(nx), float(ny), float(nz));
|
||||
}
|
||||
|
||||
inline void push_geometry(const Vec3d& p, const Vec3d& n) {
|
||||
push_geometry(p(0), p(1), p(2), n(0), n(1), n(2));
|
||||
template<typename Derived, typename Derived2>
|
||||
inline void push_geometry(const Eigen::MatrixBase<Derived>& p, const Eigen::MatrixBase<Derived2>& n) {
|
||||
push_geometry(float(p(0)), float(p(1)), float(p(2)), float(n(0)), float(n(1)), float(n(2)));
|
||||
}
|
||||
|
||||
inline void push_triangle(int idx1, int idx2, int idx3) {
|
||||
|
|
|
@ -434,12 +434,7 @@ void TriangleSelectorMmuGui::render(ImGuiWrapper *imgui)
|
|||
continue;
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
m_iva_colors[color_idx].push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]),
|
||||
double(m_vertices[tr.verts_idxs[i]].v[1]),
|
||||
double(m_vertices[tr.verts_idxs[i]].v[2]),
|
||||
double(tr.normal[0]),
|
||||
double(tr.normal[1]),
|
||||
double(tr.normal[2]));
|
||||
m_iva_colors[color_idx].push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal);
|
||||
m_iva_colors[color_idx].push_triangle(color_cnt[color_idx], color_cnt[color_idx] + 1, color_cnt[color_idx] + 2);
|
||||
color_cnt[color_idx] += 3;
|
||||
}
|
||||
|
@ -449,12 +444,7 @@ void TriangleSelectorMmuGui::render(ImGuiWrapper *imgui)
|
|||
if (!tr.valid() || tr.is_split() || !tr.is_selected_by_seed_fill()) continue;
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
m_iva_seed_fill.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]),
|
||||
double(m_vertices[tr.verts_idxs[i]].v[1]),
|
||||
double(m_vertices[tr.verts_idxs[i]].v[2]),
|
||||
double(tr.normal[0]),
|
||||
double(tr.normal[1]),
|
||||
double(tr.normal[2]));
|
||||
m_iva_seed_fill.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal);
|
||||
m_iva_seed_fill.push_triangle(seed_fill_cnt, seed_fill_cnt + 1, seed_fill_cnt + 2);
|
||||
seed_fill_cnt += 3;
|
||||
}
|
||||
|
|
|
@ -598,12 +598,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
|
|||
: blc_cnt;
|
||||
|
||||
for (int i=0; i<3; ++i)
|
||||
va.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]),
|
||||
double(m_vertices[tr.verts_idxs[i]].v[1]),
|
||||
double(m_vertices[tr.verts_idxs[i]].v[2]),
|
||||
double(tr.normal[0]),
|
||||
double(tr.normal[1]),
|
||||
double(tr.normal[2]));
|
||||
va.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal);
|
||||
va.push_triangle(cnt, cnt + 1, cnt + 2);
|
||||
cnt += 3;
|
||||
}
|
||||
|
@ -613,12 +608,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
|
|||
continue;
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
m_iva_seed_fill.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]),
|
||||
double(m_vertices[tr.verts_idxs[i]].v[1]),
|
||||
double(m_vertices[tr.verts_idxs[i]].v[2]),
|
||||
double(tr.normal[0]),
|
||||
double(tr.normal[1]),
|
||||
double(tr.normal[2]));
|
||||
m_iva_seed_fill.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal);
|
||||
m_iva_seed_fill.push_triangle(seed_fill_cnt, seed_fill_cnt + 1, seed_fill_cnt + 2);
|
||||
seed_fill_cnt += 3;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue