Merge branch 'master' of https://github.com/Prusa3d/PrusaSlicer
This commit is contained in:
commit
ef07644bf2
21 changed files with 2018 additions and 62 deletions
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 31 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 31 KiB |
|
@ -318,7 +318,7 @@ std::string ExtrusionEntity::role_to_string(ExtrusionRole role)
|
|||
case erIroning : return L("Ironing");
|
||||
case erBridgeInfill : return L("Bridge infill");
|
||||
case erGapFill : return L("Gap fill");
|
||||
case erSkirt : return L("Skirt");
|
||||
case erSkirt : return L("Skirt/Brim");
|
||||
case erSupportMaterial : return L("Support material");
|
||||
case erSupportMaterialInterface : return L("Support material interface");
|
||||
case erWipeTower : return L("Wipe tower");
|
||||
|
@ -349,7 +349,7 @@ ExtrusionRole ExtrusionEntity::string_to_role(const std::string_view role)
|
|||
return erBridgeInfill;
|
||||
else if (role == L("Gap fill"))
|
||||
return erGapFill;
|
||||
else if (role == L("Skirt"))
|
||||
else if (role == L("Skirt") || role == L("Skirt/Brim")) // "Skirt" is for backward compatibility with 2.3.1 and earlier
|
||||
return erSkirt;
|
||||
else if (role == L("Support material"))
|
||||
return erSupportMaterial;
|
||||
|
|
|
@ -857,6 +857,12 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
|||
|
||||
m_time_processor.export_remaining_time_enabled = config.remaining_times.value;
|
||||
m_use_volumetric_e = config.use_volumetric_e;
|
||||
|
||||
#if ENABLE_START_GCODE_VISUALIZATION
|
||||
const ConfigOptionFloatOrPercent* first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height");
|
||||
if (first_layer_height != nullptr)
|
||||
m_first_layer_height = std::abs(first_layer_height->value);
|
||||
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||
}
|
||||
|
||||
void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||
|
@ -1035,6 +1041,12 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
|||
const ConfigOptionBool* use_volumetric_e = config.option<ConfigOptionBool>("use_volumetric_e");
|
||||
if (use_volumetric_e != nullptr)
|
||||
m_use_volumetric_e = use_volumetric_e->value;
|
||||
|
||||
#if ENABLE_START_GCODE_VISUALIZATION
|
||||
const ConfigOptionFloatOrPercent* first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height");
|
||||
if (first_layer_height != nullptr)
|
||||
m_first_layer_height = std::abs(first_layer_height->value);
|
||||
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||
}
|
||||
|
||||
void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
|
||||
|
@ -1060,6 +1072,9 @@ void GCodeProcessor::reset()
|
|||
|
||||
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||
m_line_id = 0;
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
m_last_line_id = 0;
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||
m_feedrate = 0.0f;
|
||||
m_width = 0.0f;
|
||||
|
@ -1082,6 +1097,10 @@ void GCodeProcessor::reset()
|
|||
|
||||
m_filament_diameters = std::vector<float>(Min_Extruder_Count, 1.75f);
|
||||
m_extruded_last_z = 0.0f;
|
||||
#if ENABLE_START_GCODE_VISUALIZATION
|
||||
m_first_layer_height = 0.0f;
|
||||
m_processing_start_custom_gcode = false;
|
||||
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||
m_g1_line_id = 0;
|
||||
m_layer_id = 0;
|
||||
m_cp_color.reset();
|
||||
|
@ -1443,6 +1462,13 @@ void GCodeProcessor::process_tags(const std::string_view comment)
|
|||
// extrusion role tag
|
||||
if (boost::starts_with(comment, reserved_tag(ETags::Role))) {
|
||||
m_extrusion_role = ExtrusionEntity::string_to_role(comment.substr(reserved_tag(ETags::Role).length()));
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
if (m_extrusion_role == erExternalPerimeter)
|
||||
m_seams_detector.activate(true);
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
#if ENABLE_START_GCODE_VISUALIZATION
|
||||
m_processing_start_custom_gcode = (m_extrusion_role == erCustom && m_g1_line_id == 0);
|
||||
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2187,7 +2213,11 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
|||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
}
|
||||
|
||||
#if ENABLE_START_GCODE_VISUALIZATION
|
||||
if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f))
|
||||
#else
|
||||
if (type == EMoveType::Extrude && (m_extrusion_role == erCustom || m_width == 0.0f || m_height == 0.0f))
|
||||
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||
type = EMoveType::Travel;
|
||||
|
||||
// time estimate section
|
||||
|
@ -2303,13 +2333,13 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
|||
// Calculate the jerk depending on whether the axis is coasting in the same direction or reversing a direction.
|
||||
float jerk =
|
||||
(v_exit > v_entry) ?
|
||||
(((v_entry > 0.0f) || (v_exit < 0.0f)) ?
|
||||
((v_entry > 0.0f || v_exit < 0.0f) ?
|
||||
// coasting
|
||||
(v_exit - v_entry) :
|
||||
// axis reversal
|
||||
std::max(v_exit, -v_entry)) :
|
||||
// v_exit <= v_entry
|
||||
(((v_entry < 0.0f) || (v_exit > 0.0f)) ?
|
||||
((v_entry < 0.0f || v_exit > 0.0f) ?
|
||||
// coasting
|
||||
(v_entry - v_exit) :
|
||||
// axis reversal
|
||||
|
@ -2330,7 +2360,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
|||
float vmax_junction_threshold = vmax_junction * 0.99f;
|
||||
|
||||
// Not coasting. The machine will stop and start the movements anyway, better to start the segment from start.
|
||||
if ((prev.safe_feedrate > vmax_junction_threshold) && (curr.safe_feedrate > vmax_junction_threshold))
|
||||
if (prev.safe_feedrate > vmax_junction_threshold && curr.safe_feedrate > vmax_junction_threshold)
|
||||
vmax_junction = curr.safe_feedrate;
|
||||
}
|
||||
|
||||
|
@ -2354,6 +2384,31 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
|||
machine.calculate_time(TimeProcessor::Planner::queue_size);
|
||||
}
|
||||
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
// check for seam starting vertex
|
||||
if (type == EMoveType::Extrude && m_extrusion_role == erExternalPerimeter && m_seams_detector.is_active() && !m_seams_detector.has_first_vertex())
|
||||
m_seams_detector.set_first_vertex(m_result.moves.back().position - m_extruder_offsets[m_extruder_id]);
|
||||
// check for seam ending vertex and store the resulting move
|
||||
else if ((type != EMoveType::Extrude || m_extrusion_role != erExternalPerimeter) && m_seams_detector.is_active()) {
|
||||
auto set_end_position = [this](const Vec3f& pos) {
|
||||
m_end_position[X] = pos.x(); m_end_position[Y] = pos.y(); m_end_position[Z] = pos.z();
|
||||
};
|
||||
|
||||
assert(m_seams_detector.has_first_vertex());
|
||||
const Vec3f curr_pos(m_end_position[X], m_end_position[Y], m_end_position[Z]);
|
||||
const Vec3f new_pos = m_result.moves.back().position - m_extruder_offsets[m_extruder_id];
|
||||
const std::optional<Vec3f> first_vertex = m_seams_detector.get_first_vertex();
|
||||
// the threshold value = 0.25 is arbitrary, we may find some smarter condition later
|
||||
if ((new_pos - *first_vertex).norm() < 0.25f) {
|
||||
set_end_position(0.5f * (new_pos + *first_vertex));
|
||||
store_move_vertex(EMoveType::Seam);
|
||||
set_end_position(curr_pos);
|
||||
}
|
||||
|
||||
m_seams_detector.activate(false);
|
||||
}
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
|
||||
// store move
|
||||
store_move_vertex(type);
|
||||
}
|
||||
|
@ -2807,15 +2862,29 @@ void GCodeProcessor::process_T(const std::string_view command)
|
|||
|
||||
void GCodeProcessor::store_move_vertex(EMoveType type)
|
||||
{
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
m_last_line_id = (type == EMoveType::Color_change || type == EMoveType::Pause_Print || type == EMoveType::Custom_GCode) ?
|
||||
m_line_id + 1 :
|
||||
((type == EMoveType::Seam) ? m_last_line_id : m_line_id);
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
|
||||
MoveVertex vertex = {
|
||||
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
m_last_line_id,
|
||||
#else
|
||||
(type == EMoveType::Color_change || type == EMoveType::Pause_Print || type == EMoveType::Custom_GCode) ? m_line_id + 1 : m_line_id,
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||
type,
|
||||
m_extrusion_role,
|
||||
m_extruder_id,
|
||||
m_cp_color.current,
|
||||
#if ENABLE_START_GCODE_VISUALIZATION
|
||||
Vec3f(m_end_position[X], m_end_position[Y], m_processing_start_custom_gcode ? m_first_layer_height : m_end_position[Z]) + m_extruder_offsets[m_extruder_id],
|
||||
#else
|
||||
Vec3f(m_end_position[X], m_end_position[Y], m_end_position[Z]) + m_extruder_offsets[m_extruder_id],
|
||||
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||
m_end_position[E] - m_start_position[E],
|
||||
m_feedrate,
|
||||
m_width,
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
#include <optional>
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -20,6 +23,9 @@ namespace Slic3r {
|
|||
Noop,
|
||||
Retract,
|
||||
Unretract,
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
Seam,
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
Tool_change,
|
||||
Color_change,
|
||||
Pause_Print,
|
||||
|
@ -370,8 +376,7 @@ namespace Slic3r {
|
|||
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
int64_t time{ 0 };
|
||||
void reset()
|
||||
{
|
||||
void reset() {
|
||||
time = 0;
|
||||
moves = std::vector<MoveVertex>();
|
||||
bed_shape = Pointfs();
|
||||
|
@ -380,8 +385,7 @@ namespace Slic3r {
|
|||
settings_ids.reset();
|
||||
}
|
||||
#else
|
||||
void reset()
|
||||
{
|
||||
void reset() {
|
||||
moves = std::vector<MoveVertex>();
|
||||
bed_shape = Pointfs();
|
||||
extruder_colors = std::vector<std::string>();
|
||||
|
@ -391,6 +395,29 @@ namespace Slic3r {
|
|||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
};
|
||||
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
class SeamsDetector
|
||||
{
|
||||
bool m_active{ false };
|
||||
std::optional<Vec3f> m_first_vertex;
|
||||
|
||||
public:
|
||||
void activate(bool active) {
|
||||
if (m_active != active) {
|
||||
m_active = active;
|
||||
if (m_active)
|
||||
m_first_vertex.reset();
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Vec3f> get_first_vertex() const { return m_first_vertex; }
|
||||
void set_first_vertex(const Vec3f& vertex) { m_first_vertex = vertex; }
|
||||
|
||||
bool is_active() const { return m_active; }
|
||||
bool has_first_vertex() const { return m_first_vertex.has_value(); }
|
||||
};
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
struct DataChecker
|
||||
{
|
||||
|
@ -476,6 +503,9 @@ namespace Slic3r {
|
|||
|
||||
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||
unsigned int m_line_id;
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
unsigned int m_last_line_id;
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||
float m_feedrate; // mm/s
|
||||
float m_width; // mm
|
||||
|
@ -490,10 +520,17 @@ namespace Slic3r {
|
|||
ExtruderTemps m_extruder_temps;
|
||||
std::vector<float> m_filament_diameters;
|
||||
float m_extruded_last_z;
|
||||
#if ENABLE_START_GCODE_VISUALIZATION
|
||||
float m_first_layer_height; // mm
|
||||
bool m_processing_start_custom_gcode;
|
||||
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||
unsigned int m_g1_line_id;
|
||||
unsigned int m_layer_id;
|
||||
CpColor m_cp_color;
|
||||
bool m_use_volumetric_e;
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
SeamsDetector m_seams_detector;
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
|
||||
enum class EProducer
|
||||
{
|
||||
|
|
|
@ -639,9 +639,11 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
|
|||
|
||||
float prime_section_width = std::min(0.9f * m_bed_width / tools.size(), 60.f);
|
||||
box_coordinates cleaning_box(Vec2f(0.02f * m_bed_width, 0.01f + m_perimeter_width/2.f), prime_section_width, 100.f);
|
||||
// In case of a circular bed, place it so it goes across the diameter and hope it will fit
|
||||
if (m_bed_shape == CircularBed)
|
||||
cleaning_box.translate(-m_bed_width/2 + m_bed_width * 0.03f, -m_bed_width * 0.12f);
|
||||
if (m_bed_shape == CircularBed) {
|
||||
cleaning_box = box_coordinates(Vec2f(0.f, 0.f), prime_section_width, 100.f);
|
||||
float total_width_half = tools.size() * prime_section_width / 2.f;
|
||||
cleaning_box.translate(-total_width_half, -std::sqrt(std::max(0.f, std::pow(m_bed_width/2, 2.f) - std::pow(1.05f * total_width_half, 2.f))));
|
||||
}
|
||||
else
|
||||
cleaning_box.translate(m_bed_bottom_left);
|
||||
|
||||
|
|
|
@ -833,18 +833,6 @@ indexed_triangle_set ModelObject::raw_indexed_triangle_set() const
|
|||
return out;
|
||||
}
|
||||
|
||||
// Non-transformed (non-rotated, non-scaled, non-translated) sum of all object volumes.
|
||||
TriangleMesh ModelObject::full_raw_mesh() const
|
||||
{
|
||||
TriangleMesh mesh;
|
||||
for (const ModelVolume *v : this->volumes)
|
||||
{
|
||||
TriangleMesh vol_mesh(v->mesh());
|
||||
vol_mesh.transform(v->get_matrix());
|
||||
mesh.merge(vol_mesh);
|
||||
}
|
||||
return mesh;
|
||||
}
|
||||
|
||||
const BoundingBoxf3& ModelObject::raw_mesh_bounding_box() const
|
||||
{
|
||||
|
|
|
@ -289,8 +289,6 @@ public:
|
|||
TriangleMesh raw_mesh() const;
|
||||
// The same as above, but producing a lightweight indexed_triangle_set.
|
||||
indexed_triangle_set raw_indexed_triangle_set() const;
|
||||
// Non-transformed (non-rotated, non-scaled, non-translated) sum of all object volumes.
|
||||
TriangleMesh full_raw_mesh() const;
|
||||
// A transformed snug bounding box around the non-modifier object volumes, without the translation applied.
|
||||
// This bounding box is only used for the actual slicing.
|
||||
const BoundingBoxf3& raw_bounding_box() const;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <functional>
|
||||
#include <limits>
|
||||
#include <cassert>
|
||||
#include <optional>
|
||||
|
||||
namespace Slic3r { namespace opt {
|
||||
|
||||
|
|
|
@ -2207,6 +2207,7 @@ std::vector<ExPolygons> PrintObject::slice_volumes(
|
|||
TriangleMesh vol_mesh(model_volume.mesh());
|
||||
vol_mesh.transform(model_volume.get_matrix(), true);
|
||||
mesh.merge(vol_mesh);
|
||||
mesh.repair(false);
|
||||
}
|
||||
if (mesh.stl.stats.number_of_facets > 0) {
|
||||
mesh.transform(m_trafo, true);
|
||||
|
|
|
@ -59,6 +59,10 @@
|
|||
#define ENABLE_EXTENDED_M73_LINES (1 && ENABLE_VALIDATE_CUSTOM_GCODE)
|
||||
// Enable a modified version of automatic downscale on load of objects too big
|
||||
#define ENABLE_MODIFIED_DOWNSCALE_ON_LOAD_OBJECTS_TOO_BIG (1 && ENABLE_2_4_0_ALPHA0)
|
||||
// Enable visualization of start gcode as regular toolpaths
|
||||
#define ENABLE_START_GCODE_VISUALIZATION (1 && ENABLE_2_4_0_ALPHA0)
|
||||
// Enable visualization of seams in preview
|
||||
#define ENABLE_SEAMS_VISUALIZATION (1 && ENABLE_2_4_0_ALPHA0)
|
||||
|
||||
|
||||
#endif // _prusaslicer_technologies_h_
|
||||
|
|
|
@ -357,10 +357,14 @@ void TriangleMesh::transform(const Transform3d& t, bool fix_left_handed)
|
|||
its_transform(its, t);
|
||||
if (fix_left_handed && t.matrix().block(0, 0, 3, 3).determinant() < 0.) {
|
||||
// Left handed transformation is being applied. It is a good idea to flip the faces and their normals.
|
||||
this->repair(false);
|
||||
stl_reverse_all_facets(&stl);
|
||||
this->its.clear();
|
||||
this->require_shared_vertices();
|
||||
// As for the assert: the repair function would fix the normals, reversing would
|
||||
// break them again. The caller should provide a mesh that does not need repair.
|
||||
// The repair call is left here so things don't break more than they were.
|
||||
assert(this->repaired);
|
||||
this->repair(false);
|
||||
stl_reverse_all_facets(&stl);
|
||||
this->its.clear();
|
||||
this->require_shared_vertices();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,11 +373,12 @@ void TriangleMesh::transform(const Matrix3d& m, bool fix_left_handed)
|
|||
stl_transform(&stl, m);
|
||||
its_transform(its, m);
|
||||
if (fix_left_handed && m.determinant() < 0.) {
|
||||
// Left handed transformation is being applied. It is a good idea to flip the faces and their normals.
|
||||
// See comments in function above.
|
||||
assert(this->repaired);
|
||||
this->repair(false);
|
||||
stl_reverse_all_facets(&stl);
|
||||
this->its.clear();
|
||||
this->require_shared_vertices();
|
||||
this->its.clear();
|
||||
this->require_shared_vertices();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -143,6 +143,9 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const
|
|||
case EMoveType::Custom_GCode:
|
||||
case EMoveType::Retract:
|
||||
case EMoveType::Unretract:
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
case EMoveType::Seam:
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
case EMoveType::Extrude: {
|
||||
// use rounding to reduce the number of generated paths
|
||||
#if ENABLE_SPLITTED_VERTEX_BUFFER
|
||||
|
@ -540,6 +543,9 @@ const std::vector<GCodeViewer::Color> GCodeViewer::Extrusion_Role_Colors {{
|
|||
const std::vector<GCodeViewer::Color> GCodeViewer::Options_Colors {{
|
||||
{ 0.803f, 0.135f, 0.839f }, // Retractions
|
||||
{ 0.287f, 0.679f, 0.810f }, // Unretractions
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
{ 0.900f, 0.900f, 0.900f }, // Seams
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
{ 0.758f, 0.744f, 0.389f }, // ToolChanges
|
||||
{ 0.856f, 0.582f, 0.546f }, // ColorChanges
|
||||
{ 0.322f, 0.942f, 0.512f }, // PausePrints
|
||||
|
@ -582,11 +588,20 @@ GCodeViewer::GCodeViewer()
|
|||
case EMoveType::Pause_Print:
|
||||
case EMoveType::Custom_GCode:
|
||||
case EMoveType::Retract:
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
case EMoveType::Unretract:
|
||||
case EMoveType::Seam: {
|
||||
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Point;
|
||||
buffer.vertices.format = VBuffer::EFormat::Position;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
case EMoveType::Unretract: {
|
||||
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Point;
|
||||
buffer.vertices.format = VBuffer::EFormat::Position;
|
||||
break;
|
||||
}
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
case EMoveType::Wipe:
|
||||
case EMoveType::Extrude: {
|
||||
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle;
|
||||
|
@ -796,10 +811,18 @@ void GCodeViewer::render() const
|
|||
case EMoveType::Pause_Print:
|
||||
case EMoveType::Custom_GCode:
|
||||
case EMoveType::Retract:
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
case EMoveType::Unretract:
|
||||
case EMoveType::Seam: {
|
||||
buffer.shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110";
|
||||
break;
|
||||
}
|
||||
#else
|
||||
case EMoveType::Unretract: {
|
||||
buffer.shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110";
|
||||
break;
|
||||
}
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
case EMoveType::Wipe:
|
||||
case EMoveType::Extrude: {
|
||||
buffer.shader = "gouraud_light";
|
||||
|
@ -938,6 +961,9 @@ unsigned int GCodeViewer::get_options_visibility_flags() const
|
|||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Wipe), is_toolpath_move_type_visible(EMoveType::Wipe));
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Retractions), is_toolpath_move_type_visible(EMoveType::Retract));
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Unretractions), is_toolpath_move_type_visible(EMoveType::Unretract));
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Seams), is_toolpath_move_type_visible(EMoveType::Seam));
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::ToolChanges), is_toolpath_move_type_visible(EMoveType::Tool_change));
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::ColorChanges), is_toolpath_move_type_visible(EMoveType::Color_change));
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::PausePrints), is_toolpath_move_type_visible(EMoveType::Pause_Print));
|
||||
|
@ -958,6 +984,9 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags)
|
|||
set_toolpath_move_type_visible(EMoveType::Wipe, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Wipe)));
|
||||
set_toolpath_move_type_visible(EMoveType::Retract, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Retractions)));
|
||||
set_toolpath_move_type_visible(EMoveType::Unretract, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Unretractions)));
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
set_toolpath_move_type_visible(EMoveType::Seam, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Seams)));
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
set_toolpath_move_type_visible(EMoveType::Tool_change, is_flag_set(static_cast<unsigned int>(Preview::OptionType::ToolChanges)));
|
||||
set_toolpath_move_type_visible(EMoveType::Color_change, is_flag_set(static_cast<unsigned int>(Preview::OptionType::ColorChanges)));
|
||||
set_toolpath_move_type_visible(EMoveType::Pause_Print, is_flag_set(static_cast<unsigned int>(Preview::OptionType::PausePrints)));
|
||||
|
@ -1595,13 +1624,15 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS
|
||||
const std::array<IBufferType, 8> first_seg_v_offsets = convert_vertices_offset(vbuffer_size, { 0, 1, 2, 3, 4, 5, 6, 7 });
|
||||
const std::array<IBufferType, 8> non_first_seg_v_offsets = convert_vertices_offset(vbuffer_size, { -4, 0, -2, 1, 2, 3, 4, 5 });
|
||||
#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS
|
||||
|
||||
bool is_first_segment = (last_path.vertices_count() == 1);
|
||||
if (is_first_segment || vbuffer_size == 0) {
|
||||
#else
|
||||
if (last_path.vertices_count() == 1 || vbuffer_size == 0) {
|
||||
#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS
|
||||
// 1st segment or restart into a new vertex buffer
|
||||
// ===============================================
|
||||
#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS
|
||||
if (last_path.vertices_count() == 1)
|
||||
if (is_first_segment)
|
||||
// starting cap triangles
|
||||
append_starting_cap_triangles(indices, first_seg_v_offsets);
|
||||
#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS
|
||||
|
@ -1679,7 +1710,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
#if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS
|
||||
if (next != nullptr && (curr.type != next->type || !last_path.matches(*next)))
|
||||
// ending cap triangles
|
||||
append_ending_cap_triangles(indices, non_first_seg_v_offsets);
|
||||
append_ending_cap_triangles(indices, is_first_segment ? first_seg_v_offsets : non_first_seg_v_offsets);
|
||||
#endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS
|
||||
|
||||
last_path.sub_paths.back().last = { ibuffer_id, indices.size() - 1, move_id, curr.position };
|
||||
|
@ -1714,7 +1745,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
// for the gcode viewer we need to take in account all moves to correctly size the printbed
|
||||
m_paths_bounding_box.merge(move.position.cast<double>());
|
||||
else {
|
||||
#if ENABLE_START_GCODE_VISUALIZATION
|
||||
if (move.type == EMoveType::Extrude && move.extrusion_role != erCustom && move.width != 0.0f && move.height != 0.0f)
|
||||
#else
|
||||
if (move.type == EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f)
|
||||
#endif // ENABLE_START_GCODE_VISUALIZATION
|
||||
m_paths_bounding_box.merge(move.position.cast<double>());
|
||||
}
|
||||
}
|
||||
|
@ -3163,6 +3198,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||
case EMoveType::Custom_GCode: { color = Options_Colors[static_cast<unsigned int>(EOptionsColors::CustomGCodes)]; break; }
|
||||
case EMoveType::Retract: { color = Options_Colors[static_cast<unsigned int>(EOptionsColors::Retractions)]; break; }
|
||||
case EMoveType::Unretract: { color = Options_Colors[static_cast<unsigned int>(EOptionsColors::Unretractions)]; break; }
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
case EMoveType::Seam: { color = Options_Colors[static_cast<unsigned int>(EOptionsColors::Seams)]; break; }
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
case EMoveType::Extrude: {
|
||||
if (!top_layer_only ||
|
||||
m_sequential_view.current.last == global_endpoints.last ||
|
||||
|
@ -4557,7 +4595,12 @@ void GCodeViewer::render_legend() const
|
|||
available(EMoveType::Pause_Print) ||
|
||||
available(EMoveType::Retract) ||
|
||||
available(EMoveType::Tool_change) ||
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
available(EMoveType::Unretract) ||
|
||||
available(EMoveType::Seam);
|
||||
#else
|
||||
available(EMoveType::Unretract);
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
};
|
||||
|
||||
auto add_option = [this, append_item](EMoveType move_type, EOptionsColors color, const std::string& text) {
|
||||
|
@ -4575,6 +4618,9 @@ void GCodeViewer::render_legend() const
|
|||
// items
|
||||
add_option(EMoveType::Retract, EOptionsColors::Retractions, _u8L("Retractions"));
|
||||
add_option(EMoveType::Unretract, EOptionsColors::Unretractions, _u8L("Deretractions"));
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
add_option(EMoveType::Seam, EOptionsColors::Seams, _u8L("Seams"));
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
add_option(EMoveType::Tool_change, EOptionsColors::ToolChanges, _u8L("Tool changes"));
|
||||
add_option(EMoveType::Color_change, EOptionsColors::ColorChanges, _u8L("Color changes"));
|
||||
add_option(EMoveType::Pause_Print, EOptionsColors::PausePrints, _u8L("Print pauses"));
|
||||
|
|
|
@ -46,6 +46,9 @@ class GCodeViewer
|
|||
{
|
||||
Retractions,
|
||||
Unretractions,
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
Seams,
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
ToolChanges,
|
||||
ColorChanges,
|
||||
PausePrints,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "libslic3r/libslic3r.h"
|
||||
#include "GLCanvas3D.hpp"
|
||||
|
||||
#include "admesh/stl.h"
|
||||
#include "libslic3r/ClipperUtils.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "libslic3r/GCode/ThumbnailData.hpp"
|
||||
|
@ -1682,8 +1681,10 @@ void GLCanvas3D::render()
|
|||
if (m_picking_enabled)
|
||||
m_mouse.scene_position = _mouse_to_3d(m_mouse.position.cast<coord_t>());
|
||||
|
||||
_render_current_gizmo();
|
||||
// sidebar hints need to be rendered before the gizmos because the depth buffer
|
||||
// could be invalidated by the following gizmo render methods
|
||||
_render_selection_sidebar_hints();
|
||||
_render_current_gizmo();
|
||||
#if ENABLE_RENDER_PICKING_PASS
|
||||
}
|
||||
#endif // ENABLE_RENDER_PICKING_PASS
|
||||
|
@ -4998,8 +4999,9 @@ void GLCanvas3D::_render_background() const
|
|||
if (!m_volumes.empty())
|
||||
use_error_color &= _is_any_volume_outside();
|
||||
else {
|
||||
BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
|
||||
use_error_color &= (test_volume.radius() > 0.0) ? !test_volume.contains(m_gcode_viewer.get_paths_bounding_box()) : false;
|
||||
const BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
|
||||
const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box();
|
||||
use_error_color &= (test_volume.radius() > 0.0 && paths_volume.radius() > 0.0) ? !test_volume.contains(paths_volume) : false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2896,7 +2896,8 @@ void ObjectList::update_selections()
|
|||
{
|
||||
const auto item = GetSelection();
|
||||
if (selection.is_single_full_object()) {
|
||||
if (m_objects_model->GetItemType(m_objects_model->GetParent(item)) & itObject)
|
||||
if (m_objects_model->GetItemType(m_objects_model->GetParent(item)) & itObject &&
|
||||
m_objects_model->GetObjectIdByItem(item) == selection.get_object_idx() )
|
||||
return;
|
||||
sels.Add(m_objects_model->GetItemById(selection.get_object_idx()));
|
||||
}
|
||||
|
|
|
@ -235,7 +235,7 @@ bool Preview::init(wxWindow* parent, Model* model)
|
|||
_L("Ironing") + "|1|" +
|
||||
_L("Bridge infill") + "|1|" +
|
||||
_L("Gap fill") + "|1|" +
|
||||
_L("Skirt") + "|1|" +
|
||||
_L("Skirt/Brim") + "|1|" +
|
||||
_L("Support material") + "|1|" +
|
||||
_L("Support material interface") + "|1|" +
|
||||
_L("Wipe tower") + "|1|" +
|
||||
|
@ -250,6 +250,9 @@ bool Preview::init(wxWindow* parent, Model* model)
|
|||
get_option_type_string(OptionType::Wipe) + "|0|" +
|
||||
get_option_type_string(OptionType::Retractions) + "|0|" +
|
||||
get_option_type_string(OptionType::Unretractions) + "|0|" +
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
get_option_type_string(OptionType::Seams) + "|0|" +
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
get_option_type_string(OptionType::ToolChanges) + "|0|" +
|
||||
get_option_type_string(OptionType::ColorChanges) + "|0|" +
|
||||
get_option_type_string(OptionType::PausePrints) + "|0|" +
|
||||
|
@ -1008,6 +1011,9 @@ wxString Preview::get_option_type_string(OptionType type) const
|
|||
case OptionType::Wipe: { return _L("Wipe"); }
|
||||
case OptionType::Retractions: { return _L("Retractions"); }
|
||||
case OptionType::Unretractions: { return _L("Deretractions"); }
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
case OptionType::Seams: { return _L("Seams"); }
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
case OptionType::ToolChanges: { return _L("Tool changes"); }
|
||||
case OptionType::ColorChanges: { return _L("Color changes"); }
|
||||
case OptionType::PausePrints: { return _L("Print pauses"); }
|
||||
|
|
|
@ -116,6 +116,9 @@ public:
|
|||
Wipe,
|
||||
Retractions,
|
||||
Unretractions,
|
||||
#if ENABLE_SEAMS_VISUALIZATION
|
||||
Seams,
|
||||
#endif // ENABLE_SEAMS_VISUALIZATION
|
||||
ToolChanges,
|
||||
ColorChanges,
|
||||
PausePrints,
|
||||
|
|
|
@ -1483,10 +1483,10 @@ void MainFrame::repair_stl()
|
|||
output_file = dlg.GetPath();
|
||||
}
|
||||
|
||||
auto tmesh = new Slic3r::TriangleMesh();
|
||||
tmesh->ReadSTLFile(input_file.ToUTF8().data());
|
||||
tmesh->repair();
|
||||
tmesh->WriteOBJFile(output_file.ToUTF8().data());
|
||||
Slic3r::TriangleMesh tmesh;
|
||||
tmesh.ReadSTLFile(input_file.ToUTF8().data());
|
||||
tmesh.repair();
|
||||
tmesh.WriteOBJFile(output_file.ToUTF8().data());
|
||||
Slic3r::GUI::show_info(this, L("Your file was repaired."), L("Repair"));
|
||||
}
|
||||
|
||||
|
|
|
@ -976,7 +976,6 @@ void Sidebar::sys_color_changed()
|
|||
for (PlaterPresetComboBox* combo : p->combos_filament)
|
||||
combo->msw_rescale();
|
||||
|
||||
p->frequently_changed_parameters->msw_rescale();
|
||||
p->object_list->msw_rescale();
|
||||
p->object_list->sys_color_changed();
|
||||
p->object_manipulation->sys_color_changed();
|
||||
|
@ -5085,6 +5084,30 @@ void Plater::export_stl(bool extended, bool selection_only)
|
|||
if (selection_only && (obj_idx == -1 || selection.is_wipe_tower()))
|
||||
return;
|
||||
|
||||
// Following lambda generates a combined mesh for export with normals pointing outwards.
|
||||
auto mesh_to_export = [](const ModelObject* mo, bool instances) -> TriangleMesh {
|
||||
TriangleMesh mesh;
|
||||
for (const ModelVolume *v : mo->volumes)
|
||||
if (v->is_model_part()) {
|
||||
TriangleMesh vol_mesh(v->mesh());
|
||||
vol_mesh.repair();
|
||||
vol_mesh.transform(v->get_matrix(), true);
|
||||
mesh.merge(vol_mesh);
|
||||
}
|
||||
mesh.repair();
|
||||
if (instances) {
|
||||
TriangleMesh vols_mesh(mesh);
|
||||
mesh = TriangleMesh();
|
||||
for (const ModelInstance *i : mo->instances) {
|
||||
TriangleMesh m = vols_mesh;
|
||||
m.transform(i->get_matrix(), true);
|
||||
mesh.merge(m);
|
||||
}
|
||||
}
|
||||
mesh.repair();
|
||||
return mesh;
|
||||
};
|
||||
|
||||
TriangleMesh mesh;
|
||||
if (p->printer_technology == ptFFF) {
|
||||
if (selection_only) {
|
||||
|
@ -5092,20 +5115,21 @@ void Plater::export_stl(bool extended, bool selection_only)
|
|||
if (selection.get_mode() == Selection::Instance)
|
||||
{
|
||||
if (selection.is_single_full_object())
|
||||
mesh = model_object->mesh();
|
||||
mesh = mesh_to_export(model_object, true);
|
||||
else
|
||||
mesh = model_object->full_raw_mesh();
|
||||
mesh = mesh_to_export(model_object, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
mesh = model_object->volumes[volume->volume_idx()]->mesh();
|
||||
mesh.transform(volume->get_volume_transformation().get_matrix());
|
||||
mesh.transform(volume->get_volume_transformation().get_matrix(), true);
|
||||
mesh.translate(-model_object->origin_translation.cast<float>());
|
||||
}
|
||||
}
|
||||
else {
|
||||
mesh = p->model.mesh();
|
||||
for (const ModelObject *o : p->model.objects)
|
||||
mesh.merge(mesh_to_export(o, true));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1217,7 +1217,7 @@ void Selection::render_center(bool gizmo_is_dragging) const
|
|||
if (!m_valid || is_empty() || m_quadric == nullptr)
|
||||
return;
|
||||
|
||||
Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center();
|
||||
const Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center();
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
|
@ -1286,7 +1286,7 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) const
|
|||
} else {
|
||||
glsafe(::glTranslated(center(0), center(1), center(2)));
|
||||
if (requires_local_axes()) {
|
||||
Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
const Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
glsafe(::glMultMatrixd(orient_matrix.data()));
|
||||
}
|
||||
}
|
||||
|
@ -1976,7 +1976,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co
|
|||
if (pos == std::string::npos)
|
||||
return;
|
||||
|
||||
double min_z = std::stod(field.substr(pos + 1));
|
||||
const double min_z = std::stod(field.substr(pos + 1));
|
||||
|
||||
// extract type
|
||||
field = field.substr(0, pos);
|
||||
|
@ -1984,7 +1984,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co
|
|||
if (pos == std::string::npos)
|
||||
return;
|
||||
|
||||
int type = std::stoi(field.substr(pos + 1));
|
||||
const int type = std::stoi(field.substr(pos + 1));
|
||||
|
||||
const BoundingBoxf3& box = get_bounding_box();
|
||||
|
||||
|
@ -1995,8 +1995,8 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co
|
|||
|
||||
// view dependend order of rendering to keep correct transparency
|
||||
bool camera_on_top = wxGetApp().plater()->get_camera().is_looking_downward();
|
||||
float z1 = camera_on_top ? min_z : max_z;
|
||||
float z2 = camera_on_top ? max_z : min_z;
|
||||
const float z1 = camera_on_top ? min_z : max_z;
|
||||
const float z2 = camera_on_top ? max_z : min_z;
|
||||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
glsafe(::glDisable(GL_CULL_FACE));
|
||||
|
@ -2004,7 +2004,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co
|
|||
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
|
||||
::glBegin(GL_QUADS);
|
||||
if ((camera_on_top && (type == 1)) || (!camera_on_top && (type == 2)))
|
||||
if ((camera_on_top && type == 1) || (!camera_on_top && type == 2))
|
||||
::glColor4f(1.0f, 0.38f, 0.0f, 1.0f);
|
||||
else
|
||||
::glColor4f(0.8f, 0.8f, 0.8f, 0.5f);
|
||||
|
@ -2015,7 +2015,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co
|
|||
glsafe(::glEnd());
|
||||
|
||||
::glBegin(GL_QUADS);
|
||||
if ((camera_on_top && (type == 2)) || (!camera_on_top && (type == 1)))
|
||||
if ((camera_on_top && type == 2) || (!camera_on_top && type == 1))
|
||||
::glColor4f(1.0f, 0.38f, 0.0f, 1.0f);
|
||||
else
|
||||
::glColor4f(0.8f, 0.8f, 0.8f, 0.5f);
|
||||
|
|
Loading…
Reference in a new issue