Tech ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS - Enable detection of collision with circular printbed in backend

This commit is contained in:
enricoturri1966 2021-09-30 14:51:09 +02:00
parent 430c7a69b3
commit 13ef817a99
6 changed files with 111 additions and 53 deletions

View File

@ -26,6 +26,37 @@
namespace Slic3r {
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const Polygon& obj_hull_2d, double obj_min_z, double obj_max_z)
{
static const double Z_TOLERANCE = -1e10;
const Polygons intersection_polys = intersection(printbed_shape, obj_hull_2d);
const bool contained_xy = !intersection_polys.empty() && Geometry::are_approx(intersection_polys.front(), obj_hull_2d);
const bool contained_z = Z_TOLERANCE < obj_min_z && obj_max_z < print_volume_height;
if (contained_xy && contained_z)
return ModelInstancePVS_Inside;
const bool intersects_xy = !contained_xy && !intersection_polys.empty();
const bool intersects_z = !contained_z && obj_min_z < print_volume_height&& Z_TOLERANCE < obj_max_z;
if (intersects_xy || intersects_z)
return ModelInstancePVS_Partly_Outside;
return ModelInstancePVS_Fully_Outside;
}
ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const BoundingBoxf3& box)
{
const Polygon box_hull_2d({
{ scale_(box.min.x()), scale_(box.min.y()) },
{ scale_(box.max.x()), scale_(box.min.y()) },
{ scale_(box.max.x()), scale_(box.max.y()) },
{ scale_(box.min.x()), scale_(box.max.y()) }
});
return printbed_collision_state(printbed_shape, print_volume_height, box_hull_2d, box.min.z(), box.max.z());
}
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
Model& Model::assign_copy(const Model &rhs)
{
this->copy_id(rhs);
@ -330,13 +361,23 @@ BoundingBoxf3 Model::bounding_box() const
return bb;
}
unsigned int Model::update_print_volume_state(const BoundingBoxf3 &print_volume)
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
unsigned int Model::update_print_volume_state(const Polygon& printbed_shape, double print_volume_height)
{
unsigned int num_printable = 0;
for (ModelObject* model_object : this->objects)
num_printable += model_object->check_instances_print_volume_state(printbed_shape, print_volume_height);
return num_printable;
}
#else
unsigned int Model::update_print_volume_state(const BoundingBoxf3 &print_volume)
{
unsigned int num_printable = 0;
for (ModelObject *model_object : this->objects)
num_printable += model_object->check_instances_print_volume_state(print_volume);
return num_printable;
}
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
bool Model::center_instances_around_point(const Vec2d &point)
{
@ -1513,6 +1554,40 @@ double ModelObject::get_instance_max_z(size_t instance_idx) const
return max_z + inst->get_offset(Z);
}
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
unsigned int ModelObject::check_instances_print_volume_state(const Polygon& printbed_shape, double print_volume_height)
{
unsigned int num_printable = 0;
enum {
INSIDE = 1,
OUTSIDE = 2
};
for (ModelInstance* model_instance : this->instances) {
unsigned int inside_outside = 0;
for (const ModelVolume* vol : this->volumes)
if (vol->is_model_part()) {
#if ENABLE_FIX_SINKING_OBJECT_OUT_OF_BED_DETECTION
const BoundingBoxf3 bb = vol->mesh().transformed_bounding_box(model_instance->get_matrix() * vol->get_matrix(), 0.0);
#else
const BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(model_instance->get_matrix() * vol->get_matrix());
#endif // ENABLE_FIX_SINKING_OBJECT_OUT_OF_BED_DETECTION
ModelInstanceEPrintVolumeState state = printbed_collision_state(printbed_shape, print_volume_height, bb);
if (state == ModelInstancePVS_Inside)
inside_outside |= INSIDE;
else if (state == ModelInstancePVS_Fully_Outside)
inside_outside |= OUTSIDE;
else
inside_outside |= INSIDE | OUTSIDE;
}
model_instance->print_volume_state =
(inside_outside == (INSIDE | OUTSIDE)) ? ModelInstancePVS_Partly_Outside :
(inside_outside == INSIDE) ? ModelInstancePVS_Inside : ModelInstancePVS_Fully_Outside;
if (inside_outside == INSIDE)
++num_printable;
}
return num_printable;
}
#else
unsigned int ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
{
unsigned int num_printable = 0;
@ -1544,6 +1619,7 @@ unsigned int ModelObject::check_instances_print_volume_state(const BoundingBoxf3
}
return num_printable;
}
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
void ModelObject::print_info() const
{

View File

@ -367,7 +367,11 @@ public:
double get_instance_max_z(size_t instance_idx) const;
// Called by Print::validate() from the UI thread.
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
unsigned int check_instances_print_volume_state(const Polygon& printbed_shape, double print_volume_height);
#else
unsigned int check_instances_print_volume_state(const BoundingBoxf3& print_volume);
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
// Print object statistics to console.
void print_info() const;
@ -904,6 +908,14 @@ enum ModelInstanceEPrintVolumeState : unsigned char
ModelInstanceNum_BedStates
};
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
// return the state of the given object's volume (extrusion along z of obj_hull_2d from obj_min_z to obj_max_z)
// with respect to the given print volume (extrusion along z of printbed_shape from zero to print_volume_height)
ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const Polygon& obj_hull_2d, double obj_min_z, double obj_max_z);
// return the state of the given box
// with respect to the given print volume (extrusion along z of printbed_shape from zero to print_volume_height)
ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const BoundingBoxf3& box);
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
// A single instance of a ModelObject.
// Knows the affine transformation of an object.
@ -1109,8 +1121,12 @@ public:
BoundingBoxf3 bounding_box() const;
// Set the print_volume_state of PrintObject::instances,
// return total number of printable objects.
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
unsigned int update_print_volume_state(const Polygon& printbed_shape, double print_volume_height);
#else
unsigned int update_print_volume_state(const BoundingBoxf3 &print_volume);
// Returns true if any ModelObject was modified.
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
// Returns true if any ModelObject was modified.
bool center_instances_around_point(const Vec2d &point);
void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); }
TriangleMesh mesh() const;

View File

@ -67,37 +67,6 @@ void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char
namespace Slic3r {
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const Polygon& obj_hull_2d, double obj_min_z, double obj_max_z)
{
static const double Z_TOLERANCE = -1e10;
const Polygons intersection_polys = intersection(printbed_shape, obj_hull_2d);
const bool contained_xy = !intersection_polys.empty() && Geometry::are_approx(intersection_polys.front(), obj_hull_2d);
const bool contained_z = Z_TOLERANCE < obj_min_z && obj_max_z < print_volume_height;
if (contained_xy && contained_z)
return ModelInstancePVS_Inside;
const bool intersects_xy = !contained_xy && !intersection_polys.empty();
const bool intersects_z = !contained_z && obj_min_z < print_volume_height && Z_TOLERANCE < obj_max_z;
if (intersects_xy || intersects_z)
return ModelInstancePVS_Partly_Outside;
return ModelInstancePVS_Fully_Outside;
}
ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const BoundingBoxf3& box)
{
const Polygon box_hull_2d({
{ scale_(box.min.x()), scale_(box.min.y()) },
{ scale_(box.max.x()), scale_(box.min.y()) },
{ scale_(box.max.x()), scale_(box.max.y()) },
{ scale_(box.min.x()), scale_(box.max.y()) }
});
return printbed_collision_state(printbed_shape, print_volume_height, box_hull_2d, box.min.z(), box.max.z());
}
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
#if ENABLE_SMOOTH_NORMALS
static void smooth_normals_corner(TriangleMesh& mesh, std::vector<stl_normal>& normals)
{

View File

@ -41,15 +41,6 @@ enum ModelInstanceEPrintVolumeState : unsigned char;
// Return appropriate color based on the ModelVolume.
std::array<float, 4> color_from_model_volume(const ModelVolume& model_volume);
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
// return the state of given object volume (extrusion along z of obj_hull_2d by obj_height)
// with respect to the given print volume (extrusion along z of printbed_shape by print_volume_height)
ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const Polygon& obj_hull_2d, double obj_min_z, double obj_max_z);
// return the state of given box
// with respect to the given print volume (extrusion along z of printbed_shape by print_volume_height)
ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const BoundingBoxf3& box);
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
// A container for interleaved arrays of 3D vertices and normals,
// possibly indexed by triangles and / or quads.
class GLIndexedVertexArray {

View File

@ -5014,17 +5014,16 @@ void GLCanvas3D::_render_background() const
use_error_color &= _is_any_volume_outside();
else {
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(m_config->option("bed_shape"));
const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast<float>(scale_(BedEpsilon))).front();
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());
// const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box();
// Polygon paths_hull_2d;
// paths_hull_2d.append({ scale_(paths_volume.min.x()), scale_(paths_volume.min.y()) });
// paths_hull_2d.append({ scale_(paths_volume.max.x()), scale_(paths_volume.min.y()) });
// paths_hull_2d.append({ scale_(paths_volume.max.x()), scale_(paths_volume.max.y()) });
// paths_hull_2d.append({ scale_(paths_volume.min.x()), scale_(paths_volume.max.y()) });
// const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, paths_hull_2d, paths_volume.min.z(), paths_volume.max.z());
ModelInstanceEPrintVolumeState state;
if (m_gcode_viewer.has_data()) {
const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(m_config->option("bed_shape"));
const Polygon bed_poly = offset(Polygon::new_scale(opt->values), 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
state = ModelInstancePVS_Inside;
use_error_color &= state != ModelInstancePVS_Inside;
#else
const BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3();

View File

@ -2946,12 +2946,19 @@ void Plater::priv::schedule_background_process()
void Plater::priv::update_print_volume_state()
{
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(this->config->option("bed_shape"));
const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast<float>(scale_(BedEpsilon))).front();
const float bed_height = this->config->opt_float("max_print_height");
this->q->model().update_print_volume_state(bed_poly, bed_height);
#else
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(this->config->opt<ConfigOptionPoints>("bed_shape")->values));
BoundingBoxf3 print_volume(unscale(bed_box_2D.min(0), bed_box_2D.min(1), 0.0), unscale(bed_box_2D.max(0), bed_box_2D.max(1), scale_(this->config->opt_float("max_print_height"))));
// Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced.
print_volume.offset(BedEpsilon);
print_volume.min(2) = -1e10;
this->q->model().update_print_volume_state(print_volume);
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
}