New gcode visualization integration - Fixed in export toolpaths to obj

This commit is contained in:
enricoturri1966 2023-12-18 11:06:23 +01:00 committed by Lukas Matena
parent 5534e7f849
commit 8eba25889b
5 changed files with 47 additions and 33 deletions

View File

@ -1799,7 +1799,9 @@ public:
fprintf(f_mat.f, "# G-Code Toolpaths Materials\n"); fprintf(f_mat.f, "# G-Code Toolpaths Materials\n");
fprintf(f_mat.f, "# Generated by %s-%s based on Slic3r\n", SLIC3R_APP_NAME, SLIC3R_VERSION); fprintf(f_mat.f, "# Generated by %s-%s based on Slic3r\n", SLIC3R_APP_NAME, SLIC3R_VERSION);
const libvgcode::Interval& visible_range = m_viewer.get_view_visible_range(); libvgcode::Interval visible_range = m_viewer.get_view_visible_range();
if (m_viewer.is_top_layer_only_view_range())
visible_range[0] = m_viewer.get_view_full_range()[0];
for (size_t i = visible_range[0]; i <= visible_range[1]; ++i) { for (size_t i = visible_range[0]; i <= visible_range[1]; ++i) {
const libvgcode::PathVertex& curr = m_viewer.get_vertex_at(i); const libvgcode::PathVertex& curr = m_viewer.get_vertex_at(i);
const libvgcode::PathVertex& next = m_viewer.get_vertex_at(i + 1); const libvgcode::PathVertex& next = m_viewer.get_vertex_at(i + 1);
@ -1809,11 +1811,11 @@ public:
unsigned char flags = 0; unsigned char flags = 0;
if (curr.gcode_id == next.gcode_id) if (curr.gcode_id == next.gcode_id)
flags |= Flag_First; flags |= Flag_First;
if (!nextnext.is_extrusion()) if (i + 1 == visible_range[1] || !nextnext.is_extrusion())
flags |= Flag_Last; flags |= Flag_Last;
else else
flags |= Flag_Internal; flags |= Flag_Internal;
export_segment(*f_geo.f, flags, curr, next, nextnext); export_segment(*f_geo.f, flags, i, curr, next, nextnext);
} }
export_materials(*f_mat.f); export_materials(*f_mat.f);
} }
@ -1825,21 +1827,18 @@ private:
static const unsigned char Flag_First = 0x01; static const unsigned char Flag_First = 0x01;
static const unsigned char Flag_Last = 0x02; static const unsigned char Flag_Last = 0x02;
static const unsigned char Flag_Internal = 0x04; static const unsigned char Flag_Internal = 0x04;
unsigned char m_flags{ 0 };
static const float Cap_Rounding_Factor; static const float Cap_Rounding_Factor;
struct SegmentLocalSystem struct SegmentLocalAxes
{ {
Vec3f forward; Vec3f forward;
Vec3f right; Vec3f right;
Vec3f up; Vec3f up;
}; };
SegmentLocalSystem segment_local_system(const Vec3f& v1, const Vec3f& v2) { SegmentLocalAxes segment_local_axes(const Vec3f& v1, const Vec3f& v2) {
SegmentLocalSystem ret; SegmentLocalAxes ret;
const Vec3f line = v2 - v1; ret.forward = (v2 - v1).normalized();
const float line_sqlen = line.squaredNorm();
ret.forward = (line_sqlen < 1e-4) ? Vec3f::UnitX() : line.normalized();
ret.right = ret.forward.cross(Vec3f::UnitZ()).normalized(); ret.right = ret.forward.cross(Vec3f::UnitZ()).normalized();
ret.up = ret.right.cross(ret.forward); ret.up = ret.right.cross(ret.forward);
return ret; return ret;
@ -1851,7 +1850,7 @@ private:
Vec3f normal; Vec3f normal;
}; };
struct VertexCrossSection struct CrossSection
{ {
Vertex right; Vertex right;
Vertex top; Vertex top;
@ -1859,8 +1858,8 @@ private:
Vertex bottom; Vertex bottom;
}; };
VertexCrossSection cross_section(const Vec3f& v, const Vec3f& right, const Vec3f& up, float width, float height) { CrossSection cross_section(const Vec3f& v, const Vec3f& right, const Vec3f& up, float width, float height) {
VertexCrossSection ret; CrossSection ret;
const Vec3f w_shift = 0.5f * width * right; const Vec3f w_shift = 0.5f * width * right;
const Vec3f h_shift = 0.5f * height * up; const Vec3f h_shift = 0.5f * height * up;
ret.right.position = v + w_shift; ret.right.position = v + w_shift;
@ -1874,7 +1873,7 @@ private:
return ret; return ret;
} }
VertexCrossSection normal_cross_section(const Vec3f& v, const SegmentLocalSystem& axes, float width, float height) { CrossSection normal_cross_section(const Vec3f& v, const SegmentLocalAxes& axes, float width, float height) {
return cross_section(v, axes.right, axes.up, width, height); return cross_section(v, axes.right, axes.up, width, height);
} }
@ -1885,7 +1884,7 @@ private:
Straight Straight
}; };
VertexCrossSection corner_cross_section(const Vec3f& v, const SegmentLocalSystem& axes1, const SegmentLocalSystem& axes2, CrossSection corner_cross_section(const Vec3f& v, const SegmentLocalAxes& axes1, const SegmentLocalAxes& axes2,
float width, float height, CornerType& corner_type) { float width, float height, CornerType& corner_type) {
if (std::abs(std::abs(axes1.forward.dot(axes2.forward)) - 1.0f) < EPSILON) if (std::abs(std::abs(axes1.forward.dot(axes2.forward)) - 1.0f) < EPSILON)
corner_type = CornerType::Straight; corner_type = CornerType::Straight;
@ -1897,23 +1896,23 @@ private:
return cross_section(v, right, axes1.up, width, height); return cross_section(v, right, axes1.up, width, height);
} }
void export_segment(FILE& f, unsigned char flags, const libvgcode::PathVertex& v1, const libvgcode::PathVertex& v2, const libvgcode::PathVertex& v3) { void export_segment(FILE& f, unsigned char flags, size_t v1_id, const libvgcode::PathVertex& v1, const libvgcode::PathVertex& v2, const libvgcode::PathVertex& v3) {
const Vec3f v1_pos = libvgcode::convert(v1.position); const Vec3f v1_pos = libvgcode::convert(v1.position);
const Vec3f v2_pos = libvgcode::convert(v2.position); const Vec3f v2_pos = libvgcode::convert(v2.position);
const Vec3f v3_pos = libvgcode::convert(v3.position); const Vec3f v3_pos = libvgcode::convert(v3.position);
const SegmentLocalSystem v1_v2 = segment_local_system(v1_pos, v2_pos); const SegmentLocalAxes v1_v2 = segment_local_axes(v1_pos, v2_pos);
const SegmentLocalSystem v2_v3 = segment_local_system(v2_pos, v3_pos); const SegmentLocalAxes v2_v3 = segment_local_axes(v2_pos, v3_pos);
// starting cap // starting cap
if ((flags & Flag_First) > 0) { if ((flags & Flag_First) > 0) {
const Vertex v0 = { v1_pos - Cap_Rounding_Factor * v1.width * v1_v2.forward, -v1_v2.forward }; const Vertex v0 = { v1_pos - Cap_Rounding_Factor * v1.width * v1_v2.forward, -v1_v2.forward };
const VertexCrossSection ncs = normal_cross_section(v1_pos, v1_v2, v1.width, v1.height); const CrossSection ncs = normal_cross_section(v1_pos, v1_v2, v1.width, v1.height);
export_vertex(f, v0); // 0 export_vertex(f, v0); // 0
export_vertex(f, ncs.right); // 1 export_vertex(f, ncs.right); // 1
export_vertex(f, ncs.top); // 2 export_vertex(f, ncs.top); // 2
export_vertex(f, ncs.left); // 3 export_vertex(f, ncs.left); // 3
export_vertex(f, ncs.bottom); // 4 export_vertex(f, ncs.bottom); // 4
export_material(f, color_id(v1)); export_material(f, color_id(v1_id));
export_triangle(f, vertex_id(0), vertex_id(1), vertex_id(2)); export_triangle(f, vertex_id(0), vertex_id(1), vertex_id(2));
export_triangle(f, vertex_id(0), vertex_id(2), vertex_id(3)); export_triangle(f, vertex_id(0), vertex_id(2), vertex_id(3));
export_triangle(f, vertex_id(0), vertex_id(3), vertex_id(4)); export_triangle(f, vertex_id(0), vertex_id(3), vertex_id(4));
@ -1923,13 +1922,13 @@ private:
// segment body + ending cap // segment body + ending cap
if ((flags & Flag_Last) > 0) { if ((flags & Flag_Last) > 0) {
const Vertex v0 = { v2_pos + Cap_Rounding_Factor * v2.width * v1_v2.forward, v1_v2.forward }; const Vertex v0 = { v2_pos + Cap_Rounding_Factor * v2.width * v1_v2.forward, v1_v2.forward };
const VertexCrossSection ncs = normal_cross_section(v2_pos, v1_v2, v2.width, v2.height); const CrossSection ncs = normal_cross_section(v2_pos, v1_v2, v2.width, v2.height);
export_vertex(f, v0); // 0 export_vertex(f, v0); // 0
export_vertex(f, ncs.right); // 1 export_vertex(f, ncs.right); // 1
export_vertex(f, ncs.top); // 2 export_vertex(f, ncs.top); // 2
export_vertex(f, ncs.left); // 3 export_vertex(f, ncs.left); // 3
export_vertex(f, ncs.bottom); // 4 export_vertex(f, ncs.bottom); // 4
export_material(f, color_id(v2)); export_material(f, color_id(v1_id + 1));
// segment body // segment body
export_triangle(f, vertex_id(-4), vertex_id(1), vertex_id(2)); export_triangle(f, vertex_id(-4), vertex_id(1), vertex_id(2));
export_triangle(f, vertex_id(-4), vertex_id(2), vertex_id(-3)); export_triangle(f, vertex_id(-4), vertex_id(2), vertex_id(-3));
@ -1948,15 +1947,15 @@ private:
} }
else { else {
CornerType corner_type; CornerType corner_type;
const VertexCrossSection ccs = corner_cross_section(v2_pos, v1_v2, v2_v3, v2.width, v2.height, corner_type); const CrossSection ccs = corner_cross_section(v2_pos, v1_v2, v2_v3, v2.width, v2.height, corner_type);
const VertexCrossSection ncs12 = normal_cross_section(v2_pos, v1_v2, v2.width, v2.height); const CrossSection ncs12 = normal_cross_section(v2_pos, v1_v2, v2.width, v2.height);
const VertexCrossSection ncs23 = normal_cross_section(v2_pos, v2_v3, v2.width, v2.height); const CrossSection ncs23 = normal_cross_section(v2_pos, v2_v3, v2.width, v2.height);
if (corner_type == CornerType::Straight) { if (corner_type == CornerType::Straight) {
export_vertex(f, ncs12.right); // 0 export_vertex(f, ncs12.right); // 0
export_vertex(f, ncs12.top); // 1 export_vertex(f, ncs12.top); // 1
export_vertex(f, ncs12.left); // 2 export_vertex(f, ncs12.left); // 2
export_vertex(f, ncs12.bottom); // 3 export_vertex(f, ncs12.bottom); // 3
export_material(f, color_id(v2)); export_material(f, color_id(v1_id + 1));
// segment body // segment body
export_triangle(f, vertex_id(-4), vertex_id(0), vertex_id(1)); export_triangle(f, vertex_id(-4), vertex_id(0), vertex_id(1));
export_triangle(f, vertex_id(-4), vertex_id(1), vertex_id(-3)); export_triangle(f, vertex_id(-4), vertex_id(1), vertex_id(-3));
@ -1975,7 +1974,7 @@ private:
export_vertex(f, ncs12.top); // 3 export_vertex(f, ncs12.top); // 3
export_vertex(f, ncs23.left); // 4 export_vertex(f, ncs23.left); // 4
export_vertex(f, ncs12.bottom); // 5 export_vertex(f, ncs12.bottom); // 5
export_material(f, color_id(v2)); export_material(f, color_id(v1_id + 1));
// segment body // segment body
export_triangle(f, vertex_id(-4), vertex_id(2), vertex_id(3)); export_triangle(f, vertex_id(-4), vertex_id(2), vertex_id(3));
export_triangle(f, vertex_id(-4), vertex_id(3), vertex_id(-3)); export_triangle(f, vertex_id(-4), vertex_id(3), vertex_id(-3));
@ -1999,7 +1998,7 @@ private:
export_vertex(f, ncs12.top); // 3 export_vertex(f, ncs12.top); // 3
export_vertex(f, ccs.left); // 4 export_vertex(f, ccs.left); // 4
export_vertex(f, ncs12.bottom); // 5 export_vertex(f, ncs12.bottom); // 5
export_material(f, color_id(v2)); export_material(f, color_id(v1_id + 1));
// segment body // segment body
export_triangle(f, vertex_id(-4), vertex_id(0), vertex_id(3)); export_triangle(f, vertex_id(-4), vertex_id(0), vertex_id(3));
export_triangle(f, vertex_id(-4), vertex_id(3), vertex_id(-3)); export_triangle(f, vertex_id(-4), vertex_id(3), vertex_id(-3));
@ -2047,8 +2046,13 @@ private:
} }
} }
size_t color_id(const libvgcode::PathVertex& v) { size_t color_id(size_t vertex_id) {
const libvgcode::Color color = m_viewer.get_vertex_color(v); const libvgcode::PathVertex& v = m_viewer.get_vertex_at(vertex_id);
const size_t top_layer_id = m_viewer.is_top_layer_only_view_range() ? m_viewer.get_layers_view_range()[1] : 0;
const bool color_top_layer_only = m_viewer.get_view_full_range()[1] != m_viewer.get_view_visible_range()[1];
const libvgcode::Color color = (color_top_layer_only && v.layer_id < top_layer_id &&
(!m_viewer.is_spiral_vase_mode() || vertex_id != m_viewer.get_view_enabled_range()[0])) ?
libvgcode::Dummy_Color : m_viewer.get_vertex_color(v);
auto color_it = std::find_if(m_colors.begin(), m_colors.end(), [&color](const libvgcode::Color& m) { return m == color; }); auto color_it = std::find_if(m_colors.begin(), m_colors.end(), [&color](const libvgcode::Color& m) { return m == color; });
if (color_it == m_colors.end()) { if (color_it == m_colors.end()) {
m_colors.emplace_back(color); m_colors.emplace_back(color);

View File

@ -47,6 +47,8 @@ public:
bool is_top_layer_only_view_range() const; bool is_top_layer_only_view_range() const;
void set_top_layer_only_view_range(bool top_layer_only_view_range); void set_top_layer_only_view_range(bool top_layer_only_view_range);
bool is_spiral_vase_mode() const;
size_t get_layers_count() const; size_t get_layers_count() const;
float get_layer_z(size_t layer_id) const; float get_layer_z(size_t layer_id) const;
std::vector<float> get_layers_zs() const; std::vector<float> get_layers_zs() const;
@ -171,6 +173,7 @@ public:
float get_travels_radius() const; float get_travels_radius() const;
void set_travels_radius(float radius); void set_travels_radius(float radius);
float get_wipes_radius() const; float get_wipes_radius() const;
void set_wipes_radius(float radius); void set_wipes_radius(float radius);

View File

@ -87,6 +87,11 @@ bool Viewer::is_top_layer_only_view_range() const
return m_impl->is_top_layer_only_view_range(); return m_impl->is_top_layer_only_view_range();
} }
bool Viewer::is_spiral_vase_mode() const
{
return m_impl->is_spiral_vase_mode();
}
void Viewer::set_top_layer_only_view_range(bool top_layer_only_view_range) void Viewer::set_top_layer_only_view_range(bool top_layer_only_view_range)
{ {
m_impl->set_top_layer_only_view_range(top_layer_only_view_range); m_impl->set_top_layer_only_view_range(top_layer_only_view_range);

View File

@ -697,7 +697,7 @@ void ViewerImpl::update_colors()
{ {
update_color_ranges(); update_color_ranges();
const uint32_t top_layer_id = m_settings.top_layer_only_view_range ? m_layers.get_view_range()[1] : 0; const size_t top_layer_id = m_settings.top_layer_only_view_range ? m_layers.get_view_range()[1] : 0;
const bool color_top_layer_only = m_view_range.get_full()[1] != m_view_range.get_visible()[1]; const bool color_top_layer_only = m_view_range.get_full()[1] != m_view_range.get_visible()[1];
std::vector<float> colors(m_vertices.size()); std::vector<float> colors(m_vertices.size());
for (size_t i = 0; i < m_vertices.size(); ++i) { for (size_t i = 0; i < m_vertices.size(); ++i) {

View File

@ -84,6 +84,8 @@ public:
bool is_top_layer_only_view_range() const { return m_settings.top_layer_only_view_range; } bool is_top_layer_only_view_range() const { return m_settings.top_layer_only_view_range; }
void set_top_layer_only_view_range(bool top_layer_only_view_range); void set_top_layer_only_view_range(bool top_layer_only_view_range);
bool is_spiral_vase_mode() const { return m_settings.spiral_vase_mode; }
size_t get_layers_count() const { return m_layers.count(); } size_t get_layers_count() const { return m_layers.count(); }
float get_layer_z(size_t layer_id) const { return m_layers.get_layer_z(layer_id); } float get_layer_z(size_t layer_id) const { return m_layers.get_layer_z(layer_id); }
std::vector<float> get_layers_zs() const { return m_layers.get_zs(); } std::vector<float> get_layers_zs() const { return m_layers.get_zs(); }