Tech ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS - Reworked detection of collision with printbed. The detection uses now different algorithms in dependence of the printbed type (rectangular, circular, convex) to improve performance.
This commit is contained in:
parent
982172b878
commit
4ff13a5d63
@ -720,6 +720,9 @@ void GCodeProcessor::UsedFilaments::process_caches(GCodeProcessor* processor)
|
|||||||
void GCodeProcessor::Result::reset() {
|
void GCodeProcessor::Result::reset() {
|
||||||
moves = std::vector<GCodeProcessor::MoveVertex>();
|
moves = std::vector<GCodeProcessor::MoveVertex>();
|
||||||
bed_shape = Pointfs();
|
bed_shape = Pointfs();
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
max_print_height = 0.0f;
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
settings_ids.reset();
|
settings_ids.reset();
|
||||||
extruders_count = 0;
|
extruders_count = 0;
|
||||||
extruder_colors = std::vector<std::string>();
|
extruder_colors = std::vector<std::string>();
|
||||||
@ -734,6 +737,9 @@ void GCodeProcessor::Result::reset() {
|
|||||||
moves.clear();
|
moves.clear();
|
||||||
lines_ends.clear();
|
lines_ends.clear();
|
||||||
bed_shape = Pointfs();
|
bed_shape = Pointfs();
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
max_print_height = 0.0f;
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
settings_ids.reset();
|
settings_ids.reset();
|
||||||
extruders_count = 0;
|
extruders_count = 0;
|
||||||
extruder_colors = std::vector<std::string>();
|
extruder_colors = std::vector<std::string>();
|
||||||
@ -883,6 +889,10 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
|||||||
const ConfigOptionFloatOrPercent* first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height");
|
const ConfigOptionFloatOrPercent* first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height");
|
||||||
if (first_layer_height != nullptr)
|
if (first_layer_height != nullptr)
|
||||||
m_first_layer_height = std::abs(first_layer_height->value);
|
m_first_layer_height = std::abs(first_layer_height->value);
|
||||||
|
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
m_result.max_print_height = config.max_print_height;
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||||
@ -1112,6 +1122,12 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
|||||||
const ConfigOptionFloatOrPercent* first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height");
|
const ConfigOptionFloatOrPercent* first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height");
|
||||||
if (first_layer_height != nullptr)
|
if (first_layer_height != nullptr)
|
||||||
m_first_layer_height = std::abs(first_layer_height->value);
|
m_first_layer_height = std::abs(first_layer_height->value);
|
||||||
|
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
const ConfigOptionFloat* max_print_height = config.option<ConfigOptionFloat>("max_print_height");
|
||||||
|
if (max_print_height != nullptr)
|
||||||
|
m_result.max_print_height = max_print_height->value;
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
|
void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
|
||||||
|
@ -351,6 +351,9 @@ namespace Slic3r {
|
|||||||
// Positions of ends of lines of the final G-code this->filename after TimeProcessor::post_process() finalizes the G-code.
|
// Positions of ends of lines of the final G-code this->filename after TimeProcessor::post_process() finalizes the G-code.
|
||||||
std::vector<size_t> lines_ends;
|
std::vector<size_t> lines_ends;
|
||||||
Pointfs bed_shape;
|
Pointfs bed_shape;
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
float max_print_height;
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
SettingsIds settings_ids;
|
SettingsIds settings_ids;
|
||||||
size_t extruders_count;
|
size_t extruders_count;
|
||||||
std::vector<std::string> extruder_colors;
|
std::vector<std::string> extruder_colors;
|
||||||
|
@ -282,9 +282,11 @@ bool Bed3D::is_circle(const Pointfs& shape, Vec2d* center, double* radius)
|
|||||||
|
|
||||||
avg_dist /= vertex_distances.size();
|
avg_dist /= vertex_distances.size();
|
||||||
|
|
||||||
|
double tolerance = avg_dist * 0.01;
|
||||||
|
|
||||||
bool defined_value = true;
|
bool defined_value = true;
|
||||||
for (double el : vertex_distances) {
|
for (double el : vertex_distances) {
|
||||||
if (fabs(el - avg_dist) > 10.0 * SCALED_EPSILON)
|
if (fabs(el - avg_dist) > tolerance)
|
||||||
defined_value = false;
|
defined_value = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -298,6 +300,11 @@ bool Bed3D::is_circle(const Pointfs& shape, Vec2d* center, double* radius)
|
|||||||
return defined_value;
|
return defined_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Bed3D::is_convex(const Pointfs& shape)
|
||||||
|
{
|
||||||
|
return Polygon::new_scale(shape).convex_points().size() == shape.size();
|
||||||
|
}
|
||||||
|
|
||||||
Bed3D::EShapeType Bed3D::detect_shape_type(const Pointfs& shape)
|
Bed3D::EShapeType Bed3D::detect_shape_type(const Pointfs& shape)
|
||||||
{
|
{
|
||||||
if (shape.size() < 3)
|
if (shape.size() < 3)
|
||||||
|
@ -139,6 +139,7 @@ public:
|
|||||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
static bool is_rectangle(const Pointfs& shape, Vec2d* min = nullptr, Vec2d* max = nullptr);
|
static bool is_rectangle(const Pointfs& shape, Vec2d* min = nullptr, Vec2d* max = nullptr);
|
||||||
static bool is_circle(const Pointfs& shape, Vec2d* center = nullptr, double* radius = nullptr);
|
static bool is_circle(const Pointfs& shape, Vec2d* center = nullptr, double* radius = nullptr);
|
||||||
|
static bool is_convex(const Pointfs& shape);
|
||||||
static EShapeType detect_shape_type(const Pointfs& shape);
|
static EShapeType detect_shape_type(const Pointfs& shape);
|
||||||
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
#include "Plater.hpp"
|
#include "Plater.hpp"
|
||||||
#include "BitmapCache.hpp"
|
#include "BitmapCache.hpp"
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
#include "3DBed.hpp"
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
|
||||||
#include "libslic3r/ExtrusionEntity.hpp"
|
#include "libslic3r/ExtrusionEntity.hpp"
|
||||||
#include "libslic3r/ExtrusionEntityCollection.hpp"
|
#include "libslic3r/ExtrusionEntityCollection.hpp"
|
||||||
@ -267,6 +270,12 @@ void GLIndexedVertexArray::render(
|
|||||||
const std::pair<size_t, size_t>& tverts_range,
|
const std::pair<size_t, size_t>& tverts_range,
|
||||||
const std::pair<size_t, size_t>& qverts_range) const
|
const std::pair<size_t, size_t>& qverts_range) const
|
||||||
{
|
{
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
// this method has been called before calling finalize() ?
|
||||||
|
if (this->vertices_and_normals_interleaved_VBO_id == 0 && !this->vertices_and_normals_interleaved.empty())
|
||||||
|
return;
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
|
||||||
assert(this->vertices_and_normals_interleaved_VBO_id != 0);
|
assert(this->vertices_and_normals_interleaved_VBO_id != 0);
|
||||||
assert(this->triangle_indices_VBO_id != 0 || this->quad_indices_VBO_id != 0);
|
assert(this->triangle_indices_VBO_id != 0 || this->quad_indices_VBO_id != 0);
|
||||||
|
|
||||||
@ -879,7 +888,7 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
|||||||
GLVolume& v = *volumes.back();
|
GLVolume& v = *volumes.back();
|
||||||
v.indexed_vertex_array.load_mesh(mesh);
|
v.indexed_vertex_array.load_mesh(mesh);
|
||||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
v.calc_convex_hull_3d();
|
v.set_convex_hull(mesh.convex_hull_3d());
|
||||||
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
|
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
|
||||||
v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0));
|
v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0));
|
||||||
@ -1038,7 +1047,11 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
|||||||
glsafe(::glDisable(GL_BLEND));
|
glsafe(::glDisable(GL_BLEND));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state, bool as_toolpaths) const
|
||||||
|
#else
|
||||||
bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state) const
|
bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state) const
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
{
|
{
|
||||||
if (config == nullptr)
|
if (config == nullptr)
|
||||||
return false;
|
return false;
|
||||||
@ -1050,6 +1063,57 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M
|
|||||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast<float>(scale_(BedEpsilon))).front();
|
const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast<float>(scale_(BedEpsilon))).front();
|
||||||
const float bed_height = config->opt_float("max_print_height");
|
const float bed_height = config->opt_float("max_print_height");
|
||||||
|
const BoundingBox bed_box_2D = get_extents(bed_poly);
|
||||||
|
BoundingBoxf3 print_volume({ unscale<double>(bed_box_2D.min.x()), unscale<double>(bed_box_2D.min.y()), -1e10 },
|
||||||
|
{ unscale<double>(bed_box_2D.max.x()), unscale<double>(bed_box_2D.max.y()), bed_height });
|
||||||
|
|
||||||
|
auto check_against_rectangular_bed = [&print_volume](GLVolume& volume, ModelInstanceEPrintVolumeState& state) {
|
||||||
|
const BoundingBoxf3* const bb = volume.is_sinking() ? &volume.transformed_non_sinking_bounding_box() : &volume.transformed_convex_hull_bounding_box();
|
||||||
|
volume.is_outside = !print_volume.contains(*bb);
|
||||||
|
if (volume.printable) {
|
||||||
|
if (state == ModelInstancePVS_Inside && volume.is_outside)
|
||||||
|
state = ModelInstancePVS_Fully_Outside;
|
||||||
|
if (state == ModelInstancePVS_Fully_Outside && volume.is_outside && print_volume.intersects(*bb))
|
||||||
|
state = ModelInstancePVS_Partly_Outside;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto check_against_circular_bed = [](GLVolume& volume, ModelInstanceEPrintVolumeState& state, const Vec2d& center, double radius) {
|
||||||
|
const TriangleMesh* mesh = volume.is_sinking() ? &GUI::wxGetApp().plater()->model().objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : volume.convex_hull();
|
||||||
|
const Polygon volume_hull_2d = its_convex_hull_2d_above(mesh->its, volume.world_matrix().cast<float>(), 0.0f);
|
||||||
|
size_t outside_count = 0;
|
||||||
|
const double sq_radius = sqr(radius);
|
||||||
|
for (const Point& p : volume_hull_2d.points) {
|
||||||
|
if (sq_radius < (unscale(p) - center).squaredNorm())
|
||||||
|
++outside_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
volume.is_outside = outside_count > 0;
|
||||||
|
if (volume.printable) {
|
||||||
|
if (state == ModelInstancePVS_Inside && volume.is_outside)
|
||||||
|
state = ModelInstancePVS_Fully_Outside;
|
||||||
|
if (state == ModelInstancePVS_Fully_Outside && volume.is_outside && outside_count < volume_hull_2d.size())
|
||||||
|
state = ModelInstancePVS_Partly_Outside;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto check_against_convex_bed = [&bed_poly, bed_height](GLVolume& volume, ModelInstanceEPrintVolumeState& state) {
|
||||||
|
const TriangleMesh* mesh = volume.is_sinking() ? &GUI::wxGetApp().plater()->model().objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : volume.convex_hull();
|
||||||
|
const Polygon volume_hull_2d = its_convex_hull_2d_above(mesh->its, volume.world_matrix().cast<float>(), 0.0f);
|
||||||
|
const BoundingBoxf3* const bb = volume.is_sinking() ? &volume.transformed_non_sinking_bounding_box() : &volume.transformed_convex_hull_bounding_box();
|
||||||
|
ModelInstanceEPrintVolumeState volume_state = printbed_collision_state(bed_poly, bed_height, volume_hull_2d, bb->min.z(), bb->max.z());
|
||||||
|
bool contained = (volume_state == ModelInstancePVS_Inside);
|
||||||
|
bool intersects = (volume_state == ModelInstancePVS_Partly_Outside);
|
||||||
|
|
||||||
|
volume.is_outside = !contained;
|
||||||
|
if (volume.printable) {
|
||||||
|
if (state == ModelInstancePVS_Inside && volume.is_outside)
|
||||||
|
state = ModelInstancePVS_Fully_Outside;
|
||||||
|
|
||||||
|
if (state == ModelInstancePVS_Fully_Outside && volume.is_outside && intersects)
|
||||||
|
state = ModelInstancePVS_Partly_Outside;
|
||||||
|
}
|
||||||
|
};
|
||||||
#else
|
#else
|
||||||
const BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
|
const BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
|
||||||
BoundingBoxf3 print_volume({ unscale<double>(bed_box_2D.min.x()), unscale<double>(bed_box_2D.min.y()), 0.0 },
|
BoundingBoxf3 print_volume({ unscale<double>(bed_box_2D.min.x()), unscale<double>(bed_box_2D.min.y()), 0.0 },
|
||||||
@ -1063,36 +1127,33 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M
|
|||||||
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
|
||||||
ModelInstanceEPrintVolumeState overall_state = ModelInstancePVS_Inside;
|
ModelInstanceEPrintVolumeState overall_state = ModelInstancePVS_Inside;
|
||||||
|
|
||||||
bool contained_min_one = false;
|
bool contained_min_one = false;
|
||||||
|
|
||||||
for (GLVolume* volume : this->volumes) {
|
for (GLVolume* volume : this->volumes) {
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
if (as_toolpaths && !volume->is_extrusion_path)
|
||||||
|
continue;
|
||||||
|
else if (!as_toolpaths && (volume->is_modifier || (!volume->shader_outside_printer_detection_enabled && (volume->is_wipe_tower || volume->composite_id.volume_id < 0))))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (GUI::Bed3D::is_rectangle(opt->values))
|
||||||
|
check_against_rectangular_bed(*volume, overall_state);
|
||||||
|
else {
|
||||||
|
Vec2d center;
|
||||||
|
double radius;
|
||||||
|
if (GUI::Bed3D::is_circle(opt->values, ¢er, &radius))
|
||||||
|
check_against_circular_bed(*volume, overall_state, center, radius);
|
||||||
|
else if (GUI::Bed3D::is_convex(opt->values))
|
||||||
|
check_against_convex_bed(*volume, overall_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
contained_min_one |= !volume->is_outside;
|
||||||
|
#else
|
||||||
if (volume->is_modifier || (!volume->shader_outside_printer_detection_enabled && (volume->is_wipe_tower || volume->composite_id.volume_id < 0)))
|
if (volume->is_modifier || (!volume->shader_outside_printer_detection_enabled && (volume->is_wipe_tower || volume->composite_id.volume_id < 0)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
|
||||||
bool contained = false;
|
|
||||||
bool intersects = false;
|
|
||||||
bool is_aux_volume = volume->is_sla_support() || volume->is_sla_pad() || volume->is_wipe_tower;
|
|
||||||
const BoundingBoxf3 bb = is_aux_volume ? volume->transformed_convex_hull_bounding_box() : volume->transformed_non_sinking_bounding_box();
|
|
||||||
ModelInstanceEPrintVolumeState volume_state;
|
|
||||||
if (is_aux_volume) {
|
|
||||||
if (volume->is_sla_support() || volume->is_wipe_tower) {
|
|
||||||
const Polygon volume_hull_2d = its_convex_hull_2d_above(volume->convex_hull()->its, volume->world_matrix().cast<float>(), 0.0f);
|
|
||||||
volume_state = printbed_collision_state(bed_poly, bed_height, volume_hull_2d, bb.min.z(), bb.max.z());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const TriangleMesh* mesh = volume->is_sinking() ? &GUI::wxGetApp().plater()->model().objects[volume->object_idx()]->volumes[volume->volume_idx()]->mesh() : volume->convex_hull();
|
|
||||||
const Polygon volume_hull_2d = its_convex_hull_2d_above(mesh->its, volume->world_matrix().cast<float>(), 0.0f);
|
|
||||||
volume_state = printbed_collision_state(bed_poly, bed_height, volume_hull_2d, bb.min.z(), bb.max.z());
|
|
||||||
}
|
|
||||||
contained = (volume_state == ModelInstancePVS_Inside);
|
|
||||||
intersects = (volume_state == ModelInstancePVS_Partly_Outside);
|
|
||||||
#else
|
|
||||||
const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box();
|
const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box();
|
||||||
bool contained = print_volume.contains(bb);
|
bool contained = print_volume.contains(bb);
|
||||||
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
|
||||||
|
|
||||||
volume->is_outside = !contained;
|
volume->is_outside = !contained;
|
||||||
if (!volume->printable)
|
if (!volume->printable)
|
||||||
@ -1103,10 +1164,6 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M
|
|||||||
if (overall_state == ModelInstancePVS_Inside && volume->is_outside)
|
if (overall_state == ModelInstancePVS_Inside && volume->is_outside)
|
||||||
overall_state = ModelInstancePVS_Fully_Outside;
|
overall_state = ModelInstancePVS_Fully_Outside;
|
||||||
|
|
||||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
|
||||||
if (overall_state == ModelInstancePVS_Fully_Outside && volume->is_outside && intersects)
|
|
||||||
overall_state = ModelInstancePVS_Partly_Outside;
|
|
||||||
#else
|
|
||||||
if (overall_state == ModelInstancePVS_Fully_Outside && volume->is_outside && print_volume.intersects(bb))
|
if (overall_state == ModelInstancePVS_Fully_Outside && volume->is_outside && print_volume.intersects(bb))
|
||||||
overall_state = ModelInstancePVS_Partly_Outside;
|
overall_state = ModelInstancePVS_Partly_Outside;
|
||||||
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
@ -654,7 +654,11 @@ public:
|
|||||||
|
|
||||||
// returns true if all the volumes are completely contained in the print volume
|
// returns true if all the volumes are completely contained in the print volume
|
||||||
// returns the containment state in the given out_state, if non-null
|
// returns the containment state in the given out_state, if non-null
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
bool check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state, bool as_toolpaths = false) const;
|
||||||
|
#else
|
||||||
bool check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state) const;
|
bool check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state) const;
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
void reset_outside_state();
|
void reset_outside_state();
|
||||||
|
|
||||||
void update_colors_by_extruder(const DynamicPrintConfig* config);
|
void update_colors_by_extruder(const DynamicPrintConfig* config);
|
||||||
|
@ -6,10 +6,11 @@
|
|||||||
#include "libslic3r/Model.hpp"
|
#include "libslic3r/Model.hpp"
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
#include "libslic3r/LocalesUtils.hpp"
|
#include "libslic3r/LocalesUtils.hpp"
|
||||||
|
#include "libslic3r/PresetBundle.hpp"
|
||||||
|
|
||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
#include "MainFrame.hpp"
|
#include "MainFrame.hpp"
|
||||||
#include "Plater.hpp"
|
#include "Plater.hpp"
|
||||||
#include "libslic3r/PresetBundle.hpp"
|
|
||||||
#include "Camera.hpp"
|
#include "Camera.hpp"
|
||||||
#include "I18N.hpp"
|
#include "I18N.hpp"
|
||||||
#include "GUI_Utils.hpp"
|
#include "GUI_Utils.hpp"
|
||||||
@ -19,6 +20,10 @@
|
|||||||
#include "GLToolbar.hpp"
|
#include "GLToolbar.hpp"
|
||||||
#include "GUI_Preview.hpp"
|
#include "GUI_Preview.hpp"
|
||||||
#include "GUI_ObjectManipulation.hpp"
|
#include "GUI_ObjectManipulation.hpp"
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
#include "3DBed.hpp"
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
|
||||||
#include <imgui/imgui_internal.h>
|
#include <imgui/imgui_internal.h>
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
@ -674,6 +679,10 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print&
|
|||||||
if (wxGetApp().is_gcode_viewer())
|
if (wxGetApp().is_gcode_viewer())
|
||||||
m_custom_gcode_per_print_z = gcode_result.custom_gcode_per_print_z;
|
m_custom_gcode_per_print_z = gcode_result.custom_gcode_per_print_z;
|
||||||
|
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
m_max_print_height = gcode_result.max_print_height;
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
|
||||||
load_toolpaths(gcode_result);
|
load_toolpaths(gcode_result);
|
||||||
|
|
||||||
if (m_layers.empty())
|
if (m_layers.empty())
|
||||||
@ -819,6 +828,9 @@ void GCodeViewer::reset()
|
|||||||
|
|
||||||
m_paths_bounding_box = BoundingBoxf3();
|
m_paths_bounding_box = BoundingBoxf3();
|
||||||
m_max_bounding_box = BoundingBoxf3();
|
m_max_bounding_box = BoundingBoxf3();
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
m_max_print_height = 0.0f;
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
m_tool_colors = std::vector<Color>();
|
m_tool_colors = std::vector<Color>();
|
||||||
m_extruders_count = 0;
|
m_extruders_count = 0;
|
||||||
m_extruder_ids = std::vector<unsigned char>();
|
m_extruder_ids = std::vector<unsigned char>();
|
||||||
@ -835,6 +847,9 @@ void GCodeViewer::reset()
|
|||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
m_statistics.reset_all();
|
m_statistics.reset_all();
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
m_contained_in_bed = true;
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeViewer::render()
|
void GCodeViewer::render()
|
||||||
@ -1554,7 +1569,49 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
|
|
||||||
// set approximate max bounding box (take in account also the tool marker)
|
// set approximate max bounding box (take in account also the tool marker)
|
||||||
m_max_bounding_box = m_paths_bounding_box;
|
m_max_bounding_box = m_paths_bounding_box;
|
||||||
m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size()[2] * Vec3d::UnitZ());
|
m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size().z() * Vec3d::UnitZ());
|
||||||
|
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
if (wxGetApp().is_editor()) {
|
||||||
|
const Bed3D::EShapeType bed_type = wxGetApp().plater()->get_bed().get_shape_type();
|
||||||
|
if (bed_type == Bed3D::EShapeType::Rectangle) {
|
||||||
|
BoundingBoxf3 print_volume = wxGetApp().plater()->get_bed().get_bounding_box(false);
|
||||||
|
print_volume.min.z() = -1e10;
|
||||||
|
print_volume.max.z() = m_max_print_height;
|
||||||
|
print_volume.min -= Vec3f(BedEpsilon, BedEpsilon, 0.0f).cast<double>();
|
||||||
|
print_volume.max += Vec3f(BedEpsilon, BedEpsilon, 0.0f).cast<double>();
|
||||||
|
m_contained_in_bed = print_volume.contains(m_paths_bounding_box);
|
||||||
|
}
|
||||||
|
else if (bed_type == Bed3D::EShapeType::Circle) {
|
||||||
|
Vec2d center;
|
||||||
|
double radius;
|
||||||
|
Bed3D::is_circle(wxGetApp().plater()->get_bed().get_shape(), ¢er, &radius);
|
||||||
|
const double sq_radius = sqr(radius);
|
||||||
|
for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) {
|
||||||
|
if (move.type == EMoveType::Extrude && move.extrusion_role != erCustom && move.width != 0.0f && move.height != 0.0f) {
|
||||||
|
if (sq_radius < (Vec2d(move.position.x(), move.position.y()) - center).squaredNorm()) {
|
||||||
|
m_contained_in_bed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bed_type == Bed3D::EShapeType::Custom) {
|
||||||
|
const Pointfs& shape = wxGetApp().plater()->get_bed().get_shape();
|
||||||
|
if (Bed3D::is_convex(shape)) {
|
||||||
|
const Polygon poly = Polygon::new_scale(shape);
|
||||||
|
for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) {
|
||||||
|
if (move.type == EMoveType::Extrude && move.extrusion_role != erCustom && move.width != 0.0f && move.height != 0.0f) {
|
||||||
|
if (!poly.contains(Point::new_scale(Vec2d(move.position.x(), move.position.y())))) {
|
||||||
|
m_contained_in_bed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
|
||||||
#if ENABLE_FIX_SEAMS_SYNCH
|
#if ENABLE_FIX_SEAMS_SYNCH
|
||||||
m_sequential_view.gcode_ids.clear();
|
m_sequential_view.gcode_ids.clear();
|
||||||
|
@ -780,6 +780,9 @@ private:
|
|||||||
BoundingBoxf3 m_paths_bounding_box;
|
BoundingBoxf3 m_paths_bounding_box;
|
||||||
// bounding box of toolpaths + marker tools
|
// bounding box of toolpaths + marker tools
|
||||||
BoundingBoxf3 m_max_bounding_box;
|
BoundingBoxf3 m_max_bounding_box;
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
float m_max_print_height{ 0.0f };
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
std::vector<Color> m_tool_colors;
|
std::vector<Color> m_tool_colors;
|
||||||
Layers m_layers;
|
Layers m_layers;
|
||||||
std::array<unsigned int, 2> m_layers_z_range;
|
std::array<unsigned int, 2> m_layers_z_range;
|
||||||
@ -804,6 +807,10 @@ private:
|
|||||||
|
|
||||||
std::vector<CustomGCode::Item> m_custom_gcode_per_print_z;
|
std::vector<CustomGCode::Item> m_custom_gcode_per_print_z;
|
||||||
|
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
bool m_contained_in_bed{ true };
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GCodeViewer();
|
GCodeViewer();
|
||||||
~GCodeViewer() { reset(); }
|
~GCodeViewer() { reset(); }
|
||||||
@ -832,6 +839,10 @@ public:
|
|||||||
const SequentialView& get_sequential_view() const { return m_sequential_view; }
|
const SequentialView& get_sequential_view() const { return m_sequential_view; }
|
||||||
void update_sequential_view_current(unsigned int first, unsigned int last);
|
void update_sequential_view_current(unsigned int first, unsigned int last);
|
||||||
|
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
bool is_contained_in_bed() const { return m_contained_in_bed; }
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
|
||||||
EViewType get_view_type() const { return m_view_type; }
|
EViewType get_view_type() const { return m_view_type; }
|
||||||
void set_view_type(EViewType type) {
|
void set_view_type(EViewType type) {
|
||||||
if (type == EViewType::Count)
|
if (type == EViewType::Count)
|
||||||
|
@ -1108,10 +1108,18 @@ void GLCanvas3D::reset_volumes()
|
|||||||
_set_warning_notification(EWarning::ObjectOutside, false);
|
_set_warning_notification(EWarning::ObjectOutside, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state(bool as_toolpaths) const
|
||||||
|
#else
|
||||||
ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state() const
|
ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state() const
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
{
|
{
|
||||||
ModelInstanceEPrintVolumeState state;
|
ModelInstanceEPrintVolumeState state;
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
m_volumes.check_outside_state(m_config, &state, as_toolpaths);
|
||||||
|
#else
|
||||||
m_volumes.check_outside_state(m_config, &state);
|
m_volumes.check_outside_state(m_config, &state);
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5016,24 +5024,16 @@ void GLCanvas3D::_render_background() const
|
|||||||
|
|
||||||
if (!m_volumes.empty())
|
if (!m_volumes.empty())
|
||||||
use_error_color &= _is_any_volume_outside();
|
use_error_color &= _is_any_volume_outside();
|
||||||
else {
|
|
||||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
|
||||||
ModelInstanceEPrintVolumeState state;
|
|
||||||
if (m_gcode_viewer.has_data()) {
|
|
||||||
const Polygon bed_poly = offset(Polygon::new_scale(wxGetApp().plater()->get_bed().get_shape()), static_cast<float>(scale_(BedEpsilon))).front();
|
|
||||||
const float bed_height = m_config->opt_float("max_print_height");
|
|
||||||
state = printbed_collision_state(bed_poly, bed_height, m_gcode_viewer.get_paths_bounding_box());
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
state = ModelInstancePVS_Inside;
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
use_error_color &= m_gcode_viewer.has_data() && !m_gcode_viewer.is_contained_in_bed();
|
||||||
use_error_color &= state != ModelInstancePVS_Inside;
|
|
||||||
#else
|
#else
|
||||||
|
{
|
||||||
const BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
|
const BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
|
||||||
const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box();
|
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;
|
use_error_color &= (test_volume.radius() > 0.0 && paths_volume.radius() > 0.0) ? !test_volume.contains(paths_volume) : false;
|
||||||
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
}
|
}
|
||||||
|
|
||||||
glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
@ -6379,18 +6379,7 @@ void GLCanvas3D::_load_sla_shells()
|
|||||||
void GLCanvas3D::_update_toolpath_volumes_outside_state()
|
void GLCanvas3D::_update_toolpath_volumes_outside_state()
|
||||||
{
|
{
|
||||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
const Polygon bed_poly = offset(Polygon::new_scale(wxGetApp().plater()->get_bed().get_shape()), static_cast<float>(scale_(BedEpsilon))).front();
|
check_volumes_outside_state(true);
|
||||||
const float bed_height = m_config->opt_float("max_print_height");
|
|
||||||
for (GLVolume* volume : m_volumes.volumes) {
|
|
||||||
if (volume->is_extrusion_path) {
|
|
||||||
const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box();
|
|
||||||
const Polygon volume_hull_2d = its_convex_hull_2d_above(volume->convex_hull()->its, volume->world_matrix().cast<float>(), 0.0f);
|
|
||||||
const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, volume_hull_2d, bb.min.z(), bb.max.z());
|
|
||||||
volume->is_outside = (state != ModelInstancePVS_Inside);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
volume->is_outside = false;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
|
BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
|
||||||
for (GLVolume* volume : m_volumes.volumes) {
|
for (GLVolume* volume : m_volumes.volumes) {
|
||||||
@ -6402,18 +6391,7 @@ void GLCanvas3D::_update_toolpath_volumes_outside_state()
|
|||||||
void GLCanvas3D::_update_sla_shells_outside_state()
|
void GLCanvas3D::_update_sla_shells_outside_state()
|
||||||
{
|
{
|
||||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
const Polygon bed_poly = offset(Polygon::new_scale(wxGetApp().plater()->get_bed().get_shape()), static_cast<float>(scale_(BedEpsilon))).front();
|
check_volumes_outside_state();
|
||||||
const float bed_height = m_config->opt_float("max_print_height");
|
|
||||||
for (GLVolume* volume : m_volumes.volumes) {
|
|
||||||
if (volume->shader_outside_printer_detection_enabled) {
|
|
||||||
const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box();
|
|
||||||
const Polygon volume_hull_2d = its_convex_hull_2d_above(volume->convex_hull()->its, volume->world_matrix().cast<float>(), 0.0f);
|
|
||||||
const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, volume_hull_2d, bb.min.z(), bb.max.z());
|
|
||||||
volume->is_outside = (state != ModelInstancePVS_Inside);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
volume->is_outside = false;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
|
BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
|
||||||
for (GLVolume* volume : m_volumes.volumes) {
|
for (GLVolume* volume : m_volumes.volumes) {
|
||||||
@ -6431,12 +6409,8 @@ void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning)
|
|||||||
else {
|
else {
|
||||||
if (wxGetApp().is_editor()) {
|
if (wxGetApp().is_editor()) {
|
||||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
if (current_printer_technology() != ptSLA) {
|
if (current_printer_technology() != ptSLA)
|
||||||
const Polygon bed_poly = offset(Polygon::new_scale(wxGetApp().plater()->get_bed().get_shape()), static_cast<float>(scale_(BedEpsilon))).front();
|
show = m_gcode_viewer.has_data() && !m_gcode_viewer.is_contained_in_bed();
|
||||||
const float bed_height = m_config->opt_float("max_print_height");
|
|
||||||
const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, m_gcode_viewer.get_paths_bounding_box());
|
|
||||||
show = state != ModelInstancePVS_Inside;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
|
BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();
|
||||||
const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box();
|
const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box();
|
||||||
@ -6445,6 +6419,7 @@ void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning)
|
|||||||
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_set_warning_notification(warning, show);
|
_set_warning_notification(warning, show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,7 +621,11 @@ public:
|
|||||||
unsigned int get_volumes_count() const;
|
unsigned int get_volumes_count() const;
|
||||||
const GLVolumeCollection& get_volumes() const { return m_volumes; }
|
const GLVolumeCollection& get_volumes() const { return m_volumes; }
|
||||||
void reset_volumes();
|
void reset_volumes();
|
||||||
|
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
ModelInstanceEPrintVolumeState check_volumes_outside_state(bool as_toolpaths = false) const;
|
||||||
|
#else
|
||||||
ModelInstanceEPrintVolumeState check_volumes_outside_state() const;
|
ModelInstanceEPrintVolumeState check_volumes_outside_state() const;
|
||||||
|
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||||
|
|
||||||
#if ENABLE_SEAMS_USING_MODELS
|
#if ENABLE_SEAMS_USING_MODELS
|
||||||
void init_gcode_viewer() { m_gcode_viewer.init(); }
|
void init_gcode_viewer() { m_gcode_viewer.init(); }
|
||||||
|
Loading…
Reference in New Issue
Block a user