Out of bed detection - 1st installment

This commit is contained in:
Enrico Turri 2018-03-09 10:40:42 +01:00
parent 83a2d2af4b
commit bdd2d725c8
15 changed files with 689 additions and 188 deletions

View file

@ -94,6 +94,38 @@ public:
void translate(const Pointf3 &pos) { this->translate(pos.x, pos.y, pos.z); }
void offset(coordf_t delta);
PointClass center() const;
bool contains(const PointClass &point) const {
return BoundingBoxBase<PointClass>::contains(point) && point.z >= this->min.z && point.z <= this->max.z;
}
bool contains(const BoundingBox3Base<PointClass>& other) const {
if (!contains(other.min))
return false;
if (!contains(PointClass(other.max.x, other.min.y, other.min.z)))
return false;
if (!contains(PointClass(other.max.x, other.max.y, other.min.z)))
return false;
if (!contains(PointClass(other.min.x, other.max.y, other.min.z)))
return false;
if (!contains(PointClass(other.min.x, other.min.y, other.max.z)))
return false;
if (!contains(PointClass(other.max.x, other.min.y, other.max.z)))
return false;
if (!contains(other.max))
return false;
if (!contains(PointClass(other.min.x, other.max.y, other.max.z)))
return false;
return true;
}
};
class BoundingBox : public BoundingBoxBase<Point>

View file

@ -222,7 +222,7 @@ bool Model::add_default_instances()
}
// this returns the bounding box of the *transformed* instances
BoundingBoxf3 Model::bounding_box()
BoundingBoxf3 Model::bounding_box() const
{
BoundingBoxf3 bb;
for (ModelObject *o : this->objects)
@ -230,6 +230,57 @@ BoundingBoxf3 Model::bounding_box()
return bb;
}
BoundingBoxf3 Model::transformed_bounding_box() const
{
BoundingBoxf3 bb;
for (const ModelObject* obj : this->objects)
{
for (const ModelVolume* vol : obj->volumes)
{
if (!vol->modifier)
{
for (const ModelInstance* inst : obj->instances)
{
double c = cos(inst->rotation);
double s = sin(inst->rotation);
for (int f = 0; f < vol->mesh.stl.stats.number_of_facets; ++f)
{
const stl_facet& facet = vol->mesh.stl.facet_start[f];
for (int i = 0; i < 3; ++i)
{
// original point
const stl_vertex& v = facet.vertex[i];
Pointf3 p((double)v.x, (double)v.y, (double)v.z);
// scale
p.x *= inst->scaling_factor;
p.y *= inst->scaling_factor;
p.z *= inst->scaling_factor;
// rotate Z
double x = p.x;
double y = p.y;
p.x = c * x - s * y;
p.y = s * x + c * y;
// translate
p.x += inst->offset.x;
p.y += inst->offset.y;
bb.merge(p);
}
}
}
}
}
}
return bb;
}
void Model::center_instances_around_point(const Pointf &point)
{
// BoundingBoxf3 bb = this->bounding_box();
@ -409,6 +460,23 @@ void Model::convert_multipart_object()
this->objects.push_back(object);
}
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")));
return print_volume.contains(transformed_bounding_box());
}
ModelObject::ModelObject(Model *model, const ModelObject &other, bool copy_volumes) :
name(other.name),
input_file(other.input_file),
@ -671,7 +739,7 @@ void ModelObject::transform(const float* matrix3x4)
v->mesh.transform(matrix3x4);
}
origin_translation = Pointf3(0.0f, 0.0f, 0.0f);
origin_translation = Pointf3(0.0, 0.0, 0.0);
invalidate_bounding_box();
}

View file

@ -260,7 +260,10 @@ public:
void delete_material(t_model_material_id material_id);
void clear_materials();
bool add_default_instances();
BoundingBoxf3 bounding_box();
// Returns approximate axis aligned bounding box of this model
BoundingBoxf3 bounding_box() const;
// Returns tight axis aligned bounding box of this model
BoundingBoxf3 transformed_bounding_box() const;
void center_instances_around_point(const Pointf &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;
@ -273,6 +276,9 @@ public:
bool looks_like_multipart_object() const;
void convert_multipart_object();
// Returs true if this model is contained into the print volume defined inside the given config
bool fits_print_volume(const DynamicPrintConfig* config) const;
void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); }
};

View file

@ -120,6 +120,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"layer_gcode",
"min_fan_speed",
"max_fan_speed",
"max_print_height",
"min_print_speed",
"max_print_speed",
"max_volumetric_speed",

View file

@ -803,6 +803,13 @@ PrintConfigDef::PrintConfigDef()
def->min = 0;
def->default_value = new ConfigOptionFloats { 0. };
def = this->add("max_print_height", coFloat);
def->label = L("Max print height");
def->tooltip = L("Set this to the maximum height that can be reached by your extruder while printing.");
def->sidetext = L("mm");
def->cli = "max-print-height=f";
def->default_value = new ConfigOptionFloat(200.0);
def = this->add("max_print_speed", coFloat);
def->label = L("Max print speed");
def->tooltip = L("When setting other speed settings to 0 Slic3r will autocalculate the optimal speed "

View file

@ -583,6 +583,7 @@ public:
ConfigOptionFloats max_layer_height;
ConfigOptionInts min_fan_speed;
ConfigOptionFloats min_layer_height;
ConfigOptionFloat max_print_height;
ConfigOptionFloats min_print_speed;
ConfigOptionFloat min_skirt_length;
ConfigOptionString notes;
@ -647,6 +648,7 @@ protected:
OPT_PTR(max_layer_height);
OPT_PTR(min_fan_speed);
OPT_PTR(min_layer_height);
OPT_PTR(max_print_height);
OPT_PTR(min_print_speed);
OPT_PTR(min_skirt_length);
OPT_PTR(notes);