mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 06:55:53 +08:00
New gcode visualization integration - Fixed in export toolpaths to obj
This commit is contained in:
parent
5534e7f849
commit
8eba25889b
@ -1799,7 +1799,9 @@ public:
|
||||
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);
|
||||
|
||||
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) {
|
||||
const libvgcode::PathVertex& curr = m_viewer.get_vertex_at(i);
|
||||
const libvgcode::PathVertex& next = m_viewer.get_vertex_at(i + 1);
|
||||
@ -1809,11 +1811,11 @@ public:
|
||||
unsigned char flags = 0;
|
||||
if (curr.gcode_id == next.gcode_id)
|
||||
flags |= Flag_First;
|
||||
if (!nextnext.is_extrusion())
|
||||
if (i + 1 == visible_range[1] || !nextnext.is_extrusion())
|
||||
flags |= Flag_Last;
|
||||
else
|
||||
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);
|
||||
}
|
||||
@ -1825,21 +1827,18 @@ private:
|
||||
static const unsigned char Flag_First = 0x01;
|
||||
static const unsigned char Flag_Last = 0x02;
|
||||
static const unsigned char Flag_Internal = 0x04;
|
||||
unsigned char m_flags{ 0 };
|
||||
static const float Cap_Rounding_Factor;
|
||||
|
||||
struct SegmentLocalSystem
|
||||
struct SegmentLocalAxes
|
||||
{
|
||||
Vec3f forward;
|
||||
Vec3f right;
|
||||
Vec3f up;
|
||||
};
|
||||
|
||||
SegmentLocalSystem segment_local_system(const Vec3f& v1, const Vec3f& v2) {
|
||||
SegmentLocalSystem ret;
|
||||
const Vec3f line = v2 - v1;
|
||||
const float line_sqlen = line.squaredNorm();
|
||||
ret.forward = (line_sqlen < 1e-4) ? Vec3f::UnitX() : line.normalized();
|
||||
SegmentLocalAxes segment_local_axes(const Vec3f& v1, const Vec3f& v2) {
|
||||
SegmentLocalAxes ret;
|
||||
ret.forward = (v2 - v1).normalized();
|
||||
ret.right = ret.forward.cross(Vec3f::UnitZ()).normalized();
|
||||
ret.up = ret.right.cross(ret.forward);
|
||||
return ret;
|
||||
@ -1851,7 +1850,7 @@ private:
|
||||
Vec3f normal;
|
||||
};
|
||||
|
||||
struct VertexCrossSection
|
||||
struct CrossSection
|
||||
{
|
||||
Vertex right;
|
||||
Vertex top;
|
||||
@ -1859,8 +1858,8 @@ private:
|
||||
Vertex bottom;
|
||||
};
|
||||
|
||||
VertexCrossSection cross_section(const Vec3f& v, const Vec3f& right, const Vec3f& up, float width, float height) {
|
||||
VertexCrossSection ret;
|
||||
CrossSection cross_section(const Vec3f& v, const Vec3f& right, const Vec3f& up, float width, float height) {
|
||||
CrossSection ret;
|
||||
const Vec3f w_shift = 0.5f * width * right;
|
||||
const Vec3f h_shift = 0.5f * height * up;
|
||||
ret.right.position = v + w_shift;
|
||||
@ -1874,7 +1873,7 @@ private:
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1885,7 +1884,7 @@ private:
|
||||
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) {
|
||||
if (std::abs(std::abs(axes1.forward.dot(axes2.forward)) - 1.0f) < EPSILON)
|
||||
corner_type = CornerType::Straight;
|
||||
@ -1897,23 +1896,23 @@ private:
|
||||
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 v2_pos = libvgcode::convert(v2.position);
|
||||
const Vec3f v3_pos = libvgcode::convert(v3.position);
|
||||
const SegmentLocalSystem v1_v2 = segment_local_system(v1_pos, v2_pos);
|
||||
const SegmentLocalSystem v2_v3 = segment_local_system(v2_pos, v3_pos);
|
||||
const SegmentLocalAxes v1_v2 = segment_local_axes(v1_pos, v2_pos);
|
||||
const SegmentLocalAxes v2_v3 = segment_local_axes(v2_pos, v3_pos);
|
||||
|
||||
// starting cap
|
||||
if ((flags & Flag_First) > 0) {
|
||||
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, ncs.right); // 1
|
||||
export_vertex(f, ncs.top); // 2
|
||||
export_vertex(f, ncs.left); // 3
|
||||
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(2), vertex_id(3));
|
||||
export_triangle(f, vertex_id(0), vertex_id(3), vertex_id(4));
|
||||
@ -1923,13 +1922,13 @@ private:
|
||||
// segment body + ending cap
|
||||
if ((flags & Flag_Last) > 0) {
|
||||
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, ncs.right); // 1
|
||||
export_vertex(f, ncs.top); // 2
|
||||
export_vertex(f, ncs.left); // 3
|
||||
export_vertex(f, ncs.bottom); // 4
|
||||
export_material(f, color_id(v2));
|
||||
export_material(f, color_id(v1_id + 1));
|
||||
// segment body
|
||||
export_triangle(f, vertex_id(-4), vertex_id(1), vertex_id(2));
|
||||
export_triangle(f, vertex_id(-4), vertex_id(2), vertex_id(-3));
|
||||
@ -1948,15 +1947,15 @@ private:
|
||||
}
|
||||
else {
|
||||
CornerType corner_type;
|
||||
const VertexCrossSection 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 VertexCrossSection ncs23 = normal_cross_section(v2_pos, v2_v3, v2.width, v2.height);
|
||||
const CrossSection ccs = corner_cross_section(v2_pos, v1_v2, v2_v3, v2.width, v2.height, corner_type);
|
||||
const CrossSection ncs12 = normal_cross_section(v2_pos, v1_v2, v2.width, v2.height);
|
||||
const CrossSection ncs23 = normal_cross_section(v2_pos, v2_v3, v2.width, v2.height);
|
||||
if (corner_type == CornerType::Straight) {
|
||||
export_vertex(f, ncs12.right); // 0
|
||||
export_vertex(f, ncs12.top); // 1
|
||||
export_vertex(f, ncs12.left); // 2
|
||||
export_vertex(f, ncs12.bottom); // 3
|
||||
export_material(f, color_id(v2));
|
||||
export_material(f, color_id(v1_id + 1));
|
||||
// segment body
|
||||
export_triangle(f, vertex_id(-4), vertex_id(0), vertex_id(1));
|
||||
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, ncs23.left); // 4
|
||||
export_vertex(f, ncs12.bottom); // 5
|
||||
export_material(f, color_id(v2));
|
||||
export_material(f, color_id(v1_id + 1));
|
||||
// segment body
|
||||
export_triangle(f, vertex_id(-4), vertex_id(2), 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, ccs.left); // 4
|
||||
export_vertex(f, ncs12.bottom); // 5
|
||||
export_material(f, color_id(v2));
|
||||
export_material(f, color_id(v1_id + 1));
|
||||
// segment body
|
||||
export_triangle(f, vertex_id(-4), vertex_id(0), vertex_id(3));
|
||||
export_triangle(f, vertex_id(-4), vertex_id(3), vertex_id(-3));
|
||||
@ -2041,14 +2040,19 @@ private:
|
||||
fprintf(&f, "\nnewmtl material_%zu\n", ++materials_counter);
|
||||
fprintf(&f, "Ka 1 1 1\n");
|
||||
fprintf(&f, "Kd %g %g %g\n", static_cast<float>(color[0]) * inv_255,
|
||||
static_cast<float>(color[1]) * inv_255,
|
||||
static_cast<float>(color[2]) * inv_255);
|
||||
static_cast<float>(color[1]) * inv_255,
|
||||
static_cast<float>(color[2]) * inv_255);
|
||||
fprintf(&f, "Ks 0 0 0\n");
|
||||
}
|
||||
}
|
||||
|
||||
size_t color_id(const libvgcode::PathVertex& v) {
|
||||
const libvgcode::Color color = m_viewer.get_vertex_color(v);
|
||||
size_t color_id(size_t vertex_id) {
|
||||
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; });
|
||||
if (color_it == m_colors.end()) {
|
||||
m_colors.emplace_back(color);
|
||||
|
@ -47,6 +47,8 @@ public:
|
||||
bool is_top_layer_only_view_range() const;
|
||||
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;
|
||||
float get_layer_z(size_t layer_id) const;
|
||||
std::vector<float> get_layers_zs() const;
|
||||
@ -171,6 +173,7 @@ public:
|
||||
|
||||
float get_travels_radius() const;
|
||||
void set_travels_radius(float radius);
|
||||
|
||||
float get_wipes_radius() const;
|
||||
void set_wipes_radius(float radius);
|
||||
|
||||
|
@ -87,6 +87,11 @@ bool Viewer::is_top_layer_only_view_range() const
|
||||
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)
|
||||
{
|
||||
m_impl->set_top_layer_only_view_range(top_layer_only_view_range);
|
||||
|
@ -697,7 +697,7 @@ void ViewerImpl::update_colors()
|
||||
{
|
||||
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];
|
||||
std::vector<float> colors(m_vertices.size());
|
||||
for (size_t i = 0; i < m_vertices.size(); ++i) {
|
||||
|
@ -84,6 +84,8 @@ public:
|
||||
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);
|
||||
|
||||
bool is_spiral_vase_mode() const { return m_settings.spiral_vase_mode; }
|
||||
|
||||
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); }
|
||||
std::vector<float> get_layers_zs() const { return m_layers.get_zs(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user