More robust fix for 3D view and GUI buttons not in synch when object's size is almost identical to print volume's size
This commit is contained in:
parent
973060c728
commit
71d9500b2e
@ -1396,7 +1396,7 @@ sub Render {
|
||||
if ($self->enable_picking) {
|
||||
$self->mark_volumes_for_layer_height;
|
||||
$self->volumes->set_print_box($self->bed_bounding_box->x_min, $self->bed_bounding_box->y_min, 0.0, $self->bed_bounding_box->x_max, $self->bed_bounding_box->y_max, $self->{config}->get('max_print_height'));
|
||||
$self->volumes->update_outside_state($self->{config}, 0);
|
||||
$self->volumes->check_outside_state($self->{config});
|
||||
# do not cull backfaces to show broken geometry, if any
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
|
@ -1921,7 +1921,7 @@ sub object_list_changed {
|
||||
}
|
||||
|
||||
my $export_in_progress = $self->{export_gcode_output_file} || $self->{send_gcode_file};
|
||||
my $model_fits = $self->{model}->fits_print_volume($self->{config});
|
||||
my $model_fits = $self->{canvas3D} ? $self->{canvas3D}->volumes->check_outside_state($self->{config}) : 1;
|
||||
my $method = ($have_objects && ! $export_in_progress && $model_fits) ? 'Enable' : 'Disable';
|
||||
$self->{"btn_$_"}->$method
|
||||
for grep $self->{"btn_$_"}, qw(reslice export_gcode print send_gcode);
|
||||
|
@ -222,13 +222,14 @@ sub reload_scene {
|
||||
# checks for geometry outside the print volume to render it accordingly
|
||||
if (scalar @{$self->volumes} > 0)
|
||||
{
|
||||
if (!$self->{model}->fits_print_volume($self->{config})) {
|
||||
my $contained = $self->volumes->check_outside_state($self->{config});
|
||||
if (!$contained) {
|
||||
$self->set_warning_enabled(1);
|
||||
Slic3r::GUI::_3DScene::generate_warning_texture(L("Detected object outside print volume"));
|
||||
$self->on_enable_action_buttons->(0) if ($self->on_enable_action_buttons);
|
||||
} else {
|
||||
$self->set_warning_enabled(0);
|
||||
$self->volumes->update_outside_state($self->{config}, 1);
|
||||
$self->volumes->reset_outside_state();
|
||||
Slic3r::GUI::_3DScene::reset_warning_texture();
|
||||
$self->on_enable_action_buttons->(1) if ($self->on_enable_action_buttons);
|
||||
}
|
||||
|
@ -147,31 +147,6 @@ public:
|
||||
BoundingBoxf3() : BoundingBox3Base<Pointf3>() {};
|
||||
BoundingBoxf3(const Pointf3 &pmin, const Pointf3 &pmax) : BoundingBox3Base<Pointf3>(pmin, pmax) {};
|
||||
BoundingBoxf3(const std::vector<Pointf3> &points) : BoundingBox3Base<Pointf3>(points) {};
|
||||
|
||||
// check if the given point is contained inside this bounding box
|
||||
// all quantities are compared after being quantized to try to reduce instability due to float imprecision
|
||||
bool contains_quantized(const Pointf3& point) const {
|
||||
struct Helper
|
||||
{
|
||||
static coordf_t quantize(coordf_t value)
|
||||
{
|
||||
static const coordf_t INV_EPSILON = 1.0 / EPSILON;
|
||||
return round(value * INV_EPSILON + 0.5) * EPSILON;
|
||||
}
|
||||
};
|
||||
|
||||
coordf_t x = Helper::quantize(point.x);
|
||||
coordf_t y = Helper::quantize(point.y);
|
||||
coordf_t z = Helper::quantize(point.z);
|
||||
|
||||
return (Helper::quantize(min.x) <= x) && (x <= Helper::quantize(max.x))
|
||||
&& (Helper::quantize(min.y) <= y) && (y <= Helper::quantize(max.y))
|
||||
&& (Helper::quantize(min.z) <= z) && (z <= Helper::quantize(max.z));
|
||||
}
|
||||
|
||||
bool contains_quantized(const BoundingBoxf3& other) const {
|
||||
return contains_quantized(other.min) && contains_quantized(other.max);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename VT>
|
||||
|
@ -447,36 +447,6 @@ void Model::adjust_min_z()
|
||||
}
|
||||
}
|
||||
|
||||
bool Model::fits_print_volume(const DynamicPrintConfig* config) const
|
||||
{
|
||||
if (config == nullptr)
|
||||
return false;
|
||||
|
||||
if (objects.empty())
|
||||
return true;
|
||||
|
||||
const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config->option("bed_shape"));
|
||||
if (opt == nullptr)
|
||||
return false;
|
||||
|
||||
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
|
||||
BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config->opt_float("max_print_height")));
|
||||
// Allow the objects to protrude below the print bed
|
||||
print_volume.min.z = -1e10;
|
||||
return print_volume.contains_quantized(transformed_bounding_box());
|
||||
}
|
||||
|
||||
bool Model::fits_print_volume(const FullPrintConfig &config) const
|
||||
{
|
||||
if (objects.empty())
|
||||
return true;
|
||||
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(config.bed_shape.values));
|
||||
BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config.max_print_height));
|
||||
// Allow the objects to protrude below the print bed
|
||||
print_volume.min.z = -1e10;
|
||||
return print_volume.contains_quantized(transformed_bounding_box());
|
||||
}
|
||||
|
||||
unsigned int Model::get_auto_extruder_id()
|
||||
{
|
||||
unsigned int id = s_auto_extruder_id;
|
||||
|
@ -285,10 +285,6 @@ public:
|
||||
// Ensures that the min z of the model is not negative
|
||||
void adjust_min_z();
|
||||
|
||||
// Returs true if this model is contained into the print volume defined inside the given config
|
||||
bool fits_print_volume(const DynamicPrintConfig* config) const;
|
||||
bool fits_print_volume(const FullPrintConfig &config) const;
|
||||
|
||||
void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); }
|
||||
|
||||
static unsigned int get_auto_extruder_id();
|
||||
|
@ -522,7 +522,7 @@ std::string Print::validate() const
|
||||
// Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced.
|
||||
print_volume.min.z = -1e10;
|
||||
for (PrintObject *po : this->objects) {
|
||||
if (!print_volume.contains_quantized(po->model_object()->tight_bounding_box(false)))
|
||||
if (!print_volume.contains(po->model_object()->tight_bounding_box(false)))
|
||||
return "Some objects are outside of the print volume.";
|
||||
}
|
||||
|
||||
|
@ -643,29 +643,40 @@ void GLVolumeCollection::render_legacy() const
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void GLVolumeCollection::update_outside_state(const DynamicPrintConfig* config, bool all_inside)
|
||||
bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config)
|
||||
{
|
||||
if (config == nullptr)
|
||||
return;
|
||||
return false;
|
||||
|
||||
const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config->option("bed_shape"));
|
||||
if (opt == nullptr)
|
||||
return;
|
||||
return false;
|
||||
|
||||
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
|
||||
BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config->opt_float("max_print_height")));
|
||||
// Allow the objects to protrude below the print bed
|
||||
print_volume.min.z = -1e10;
|
||||
|
||||
bool contained = true;
|
||||
for (GLVolume* volume : this->volumes)
|
||||
{
|
||||
if (all_inside)
|
||||
if (volume != nullptr)
|
||||
{
|
||||
volume->is_outside = false;
|
||||
continue;
|
||||
bool state = print_volume.contains(volume->transformed_bounding_box());
|
||||
contained &= state;
|
||||
volume->is_outside = !state;
|
||||
}
|
||||
}
|
||||
|
||||
volume->is_outside = !print_volume.contains_quantized(volume->transformed_bounding_box());
|
||||
return contained;
|
||||
}
|
||||
|
||||
void GLVolumeCollection::reset_outside_state()
|
||||
{
|
||||
for (GLVolume* volume : this->volumes)
|
||||
{
|
||||
if (volume != nullptr)
|
||||
volume->is_outside = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -422,7 +422,9 @@ public:
|
||||
print_box_max[0] = max_x; print_box_max[1] = max_y; print_box_max[2] = max_z;
|
||||
}
|
||||
|
||||
void update_outside_state(const DynamicPrintConfig* config, bool all_inside);
|
||||
bool check_outside_state(const DynamicPrintConfig* config);
|
||||
void reset_outside_state();
|
||||
|
||||
void update_colors_by_extruder(const DynamicPrintConfig* config);
|
||||
|
||||
// Returns a vector containing the sorted list of all the print_zs of the volumes contained in this collection
|
||||
|
@ -104,7 +104,12 @@
|
||||
void release_geometry();
|
||||
|
||||
void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z);
|
||||
void update_outside_state(DynamicPrintConfig* config, bool all_inside);
|
||||
bool check_outside_state(DynamicPrintConfig* config)
|
||||
%code%{
|
||||
RETVAL = THIS->check_outside_state(config);
|
||||
%};
|
||||
|
||||
void reset_outside_state();
|
||||
void update_colors_by_extruder(DynamicPrintConfig* config);
|
||||
|
||||
bool move_volume_up(int idx)
|
||||
|
@ -99,9 +99,6 @@
|
||||
|
||||
void print_info() const;
|
||||
|
||||
bool fits_print_volume(DynamicPrintConfig* config) const
|
||||
%code%{ RETVAL = THIS->fits_print_volume(config); %};
|
||||
|
||||
bool store_stl(char *path, bool binary)
|
||||
%code%{ TriangleMesh mesh = THIS->mesh(); RETVAL = Slic3r::store_stl(path, &mesh, binary); %};
|
||||
bool store_amf(char *path, Print* print, bool export_print_config)
|
||||
|
Loading…
Reference in New Issue
Block a user