New BuildVolume class was created, which detects build volume type (rectangular,
circular, convex, concave) and performs efficient collision detection agains these build volumes. As of now, collision detection is performed against a convex hull of a concave build volume for efficency. GCodeProcessor::Result renamed out of GCodeProcessor to GCodeProcessorResult, so it could be forward declared. Plater newly exports BuildVolume, not Bed3D. Bed3D is a rendering class, while BuildVolume is a purely geometric class. Reduced usage of global wxGetApp, the Bed3D is passed as a parameter to View3D/Preview/GLCanvas. Convex hull code was extracted from Geometry.cpp/hpp to Geometry/ConvexHulll.cpp,hpp. New test inside_convex_polygon(). New efficent point inside polygon test: Decompose convex hull to bottom / top parts and use the decomposition to detect point inside a convex polygon in O(log n). decompose_convex_polygon_top_bottom(), inside_convex_polygon(). New Circle constructing functions: circle_ransac() and circle_taubin_newton(). New polygon_is_convex() test with unit tests.
This commit is contained in:
parent
b431fd1f7e
commit
cc44089440
51 changed files with 1544 additions and 1594 deletions
src/libslic3r
|
@ -1,8 +1,9 @@
|
|||
#include "libslic3r.h"
|
||||
#include "BuildVolume.hpp"
|
||||
#include "Exception.hpp"
|
||||
#include "Model.hpp"
|
||||
#include "ModelArrange.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include "Geometry/ConvexHull.hpp"
|
||||
#include "MTUtils.hpp"
|
||||
#include "TriangleMeshSlicer.hpp"
|
||||
#include "TriangleSelector.hpp"
|
||||
|
@ -26,39 +27,6 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||
// Using rotating callipers to check for collision of two convex polygons. Thus both printbed_shape and obj_hull_2d are convex polygons.
|
||||
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)
|
||||
{
|
||||
if (!Geometry::convex_polygons_intersect(printbed_shape, obj_hull_2d))
|
||||
return ModelInstancePVS_Fully_Outside;
|
||||
|
||||
bool contained_xy = true;
|
||||
for (const Point& p : obj_hull_2d) {
|
||||
if (!printbed_shape.contains(p)) {
|
||||
contained_xy = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const bool contained_z = -1e10 < obj_min_z && obj_max_z <= print_volume_height;
|
||||
return (contained_xy && contained_z) ? ModelInstancePVS_Inside : ModelInstancePVS_Partly_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);
|
||||
|
@ -363,24 +331,13 @@ BoundingBoxf3 Model::bounding_box() const
|
|||
return bb;
|
||||
}
|
||||
|
||||
#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||
// printbed_shape is convex polygon
|
||||
unsigned int Model::update_print_volume_state(const Polygon& printbed_shape, double print_volume_height)
|
||||
unsigned int Model::update_print_volume_state(const BuildVolume &build_volume)
|
||||
{
|
||||
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);
|
||||
num_printable += model_object->update_instances_print_volume_state(build_volume);
|
||||
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)
|
||||
{
|
||||
|
@ -1572,9 +1529,7 @@ 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
|
||||
// printbed_shape is convex polygon
|
||||
unsigned int ModelObject::check_instances_print_volume_state(const Polygon& printbed_shape, double print_volume_height)
|
||||
unsigned int ModelObject::update_instances_print_volume_state(const BuildVolume &build_volume)
|
||||
{
|
||||
unsigned int num_printable = 0;
|
||||
enum {
|
||||
|
@ -1586,16 +1541,10 @@ unsigned int ModelObject::check_instances_print_volume_state(const Polygon& prin
|
|||
for (const ModelVolume* vol : this->volumes)
|
||||
if (vol->is_model_part()) {
|
||||
const Transform3d matrix = model_instance->get_matrix() * vol->get_matrix();
|
||||
const BoundingBoxf3 bb = vol->mesh().transformed_bounding_box(matrix, 0.0);
|
||||
if (!bb.defined) {
|
||||
// this may happen if the part is fully below the printbed, leading to a crash in the following call to its_convex_hull_2d_above()
|
||||
continue;
|
||||
}
|
||||
const Polygon volume_hull_2d = its_convex_hull_2d_above(vol->mesh().its, matrix.cast<float>(), 0.0f);
|
||||
ModelInstanceEPrintVolumeState state = printbed_collision_state(printbed_shape, print_volume_height, volume_hull_2d, bb.min.z(), bb.max.z());
|
||||
if (state == ModelInstancePVS_Inside)
|
||||
BuildVolume::ObjectState state = build_volume.object_state(vol->mesh().its, matrix.cast<float>(), true /* may be below print bed */);
|
||||
if (state == BuildVolume::ObjectState::Inside)
|
||||
inside_outside |= INSIDE;
|
||||
else if (state == ModelInstancePVS_Fully_Outside)
|
||||
else if (state == BuildVolume::ObjectState::Outside)
|
||||
inside_outside |= OUTSIDE;
|
||||
else
|
||||
inside_outside |= INSIDE | OUTSIDE;
|
||||
|
@ -1608,35 +1557,6 @@ unsigned int ModelObject::check_instances_print_volume_state(const Polygon& prin
|
|||
}
|
||||
return num_printable;
|
||||
}
|
||||
#else
|
||||
unsigned int ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
|
||||
{
|
||||
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()) {
|
||||
BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(model_instance->get_matrix() * vol->get_matrix());
|
||||
if (print_volume.contains(bb))
|
||||
inside_outside |= INSIDE;
|
||||
else if (print_volume.intersects(bb))
|
||||
inside_outside |= INSIDE | OUTSIDE;
|
||||
else
|
||||
inside_outside |= 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;
|
||||
}
|
||||
#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS
|
||||
|
||||
void ModelObject::print_info() const
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue