Refactoring of functions thick_lines_to_indexed_vertex_array() to reduce the amount of produced vertices while reducing visual artifacts in gcode toolpaths due to averaged normals

This commit is contained in:
Enrico Turri 2019-07-08 15:30:59 +02:00
parent 9ba5568539
commit 4ba7dfb6dd
3 changed files with 22 additions and 13 deletions

View file

@ -849,6 +849,7 @@ static void thick_lines_to_indexed_vertex_array(
int idx_initial[4] = { -1, -1, -1, -1 };
double width_initial = 0.;
double bottom_z_initial = 0.0;
double len_prev = 0.0;
// loop once more in case of closed loops
size_t lines_end = closed ? (lines.size() + 1) : lines.size();
@ -864,6 +865,7 @@ static void thick_lines_to_indexed_vertex_array(
bool is_closing = closed && is_last;
Vec2d v = unscale(line.vector()).normalized();
double len = unscale<double>(line.length());
Vec2d a = unscale(line.a);
Vec2d b = unscale(line.b);
@ -927,7 +929,14 @@ static void thick_lines_to_indexed_vertex_array(
// Continuing a previous segment.
// Share left / right vertices if possible.
double v_dot = v_prev.dot(v);
bool sharp = v_dot < 0.9999; // v_dot < 0.9999; // cos(1 degree)
// To reduce gpu memory usage, we try to reuse vertices
// To reduce the visual artifacts, due to averaged normals, we allow to reuse vertices only when any of two adjacent edges
// is longer than a fixed threshold.
// The following value is arbitrary, it comes from tests made on a bunch of models showing the visual artifacts
double len_threshold = 2.5;
// Generate new vertices if the angle between adjacent edges is greater than 45 degrees or thresholds conditions are met
bool sharp = (v_dot < 0.707) || (len_prev > len_threshold) || (len > len_threshold);
if (sharp) {
if (!bottom_z_different)
{
@ -1003,6 +1012,7 @@ static void thick_lines_to_indexed_vertex_array(
bottom_z_prev = bottom_z;
b1_prev = b1;
v_prev = v;
len_prev = len;
if (bottom_z_different && (closed || (!is_first && !is_last)))
{
@ -1056,6 +1066,7 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
int idx_initial[4] = { -1, -1, -1, -1 };
int idx_prev[4] = { -1, -1, -1, -1 };
double z_prev = 0.0;
double len_prev = 0.0;
Vec3d n_right_prev = Vec3d::Zero();
Vec3d n_top_prev = Vec3d::Zero();
Vec3d unit_v_prev = Vec3d::Zero();
@ -1077,6 +1088,7 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
double width = widths[i];
Vec3d unit_v = unscale(line.vector()).normalized();
double len = unscale<double>(line.length());
Vec3d n_top = Vec3d::Zero();
Vec3d n_right = Vec3d::Zero();
@ -1153,9 +1165,16 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
// Continuing a previous segment.
// Share left / right vertices if possible.
double v_dot = unit_v_prev.dot(unit_v);
bool is_sharp = v_dot < 0.9999; // v_dot < 0.9999; // cos(1 degree)
bool is_right_turn = n_top_prev.dot(unit_v_prev.cross(unit_v)) > 0.0;
// To reduce gpu memory usage, we try to reuse vertices
// To reduce the visual artifacts, due to averaged normals, we allow to reuse vertices only when any of two adjacent edges
// is longer than a fixed threshold.
// The following value is arbitrary, it comes from tests made on a bunch of models showing the visual artifacts
double len_threshold = 2.5;
// Generate new vertices if the angle between adjacent edges is greater than 45 degrees or thresholds conditions are met
bool is_sharp = (v_dot < 0.707) || (len_prev > len_threshold) || (len > len_threshold);
if (is_sharp)
{
// Allocate new left / right points for the start of this segment as these points will receive their own normals to indicate a sharp turn.
@ -1234,6 +1253,7 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
n_right_prev = n_right;
n_top_prev = n_top;
unit_v_prev = unit_v;
len_prev = len;
if (!closed)
{
@ -1495,9 +1515,6 @@ void GLModel::set_scale(const Vec3d& scale)
void GLModel::reset()
{
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// m_volume.release_geometry();
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
m_filename = "";
}

View file

@ -74,9 +74,7 @@ public:
quad_indices_VBO_id(0)
{}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
~GLIndexedVertexArray() { release_geometry(); }
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
GLIndexedVertexArray& operator=(const GLIndexedVertexArray &rhs)
{

View file

@ -1356,9 +1356,6 @@ void GLCanvas3D::reset_volumes()
if (!m_volumes.empty())
{
m_selection.clear();
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// m_volumes.release_geometry();
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
m_volumes.clear();
m_dirty = true;
}
@ -1920,9 +1917,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
assert(volume_idx_wipe_tower_old == -1);
volume_idx_wipe_tower_old = (int)volume_id;
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// volume->release_geometry();
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
if (! m_reload_delayed)
delete volume;
} else {