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:
Enrico Turri 2018-04-24 09:00:33 +02:00
parent 973060c728
commit 71d9500b2e
11 changed files with 33 additions and 76 deletions

View file

@ -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>

View file

@ -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;

View file

@ -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();

View file

@ -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.";
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -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)

View file

@ -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)