Extended Print::validate() to check, whether the objects

are inside the print volume.
This commit is contained in:
bubnikv 2018-03-14 16:11:57 +01:00
parent 523b297738
commit b43a21d1be
4 changed files with 73 additions and 71 deletions

View file

@ -100,31 +100,7 @@ public:
}
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;
return contains(other.min) && contains(other.max);
}
};

View file

@ -233,51 +233,8 @@ BoundingBoxf3 Model::bounding_box() const
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);
}
}
}
}
}
}
bb.merge(obj->tight_bounding_box(false));
return bb;
}
@ -477,6 +434,15 @@ bool Model::fits_print_volume(const DynamicPrintConfig* config) const
return print_volume.contains(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));
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),
@ -607,7 +573,7 @@ void ModelObject::clear_instances()
// Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug.
BoundingBoxf3 ModelObject::bounding_box()
const BoundingBoxf3& ModelObject::bounding_box()
{
if (! m_bounding_box_valid) {
BoundingBoxf3 raw_bbox;
@ -623,6 +589,54 @@ BoundingBoxf3 ModelObject::bounding_box()
return m_bounding_box;
}
BoundingBoxf3 ModelObject::tight_bounding_box(bool include_modifiers) const
{
BoundingBoxf3 bb;
for (const ModelVolume* vol : this->volumes)
{
if (include_modifiers || !vol->modifier)
{
for (const ModelInstance* inst : this->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;
}
// A mesh containing all transformed instances of this object.
TriangleMesh ModelObject::mesh() const
{

View file

@ -102,8 +102,12 @@ public:
// Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug.
BoundingBoxf3 bounding_box();
// This bounding box is being cached.
const BoundingBoxf3& bounding_box();
void invalidate_bounding_box() { m_bounding_box_valid = false; }
// Returns a snug bounding box of the transformed instances.
// This bounding box is not being cached.
BoundingBoxf3 tight_bounding_box(bool include_modifiers) const;
// A mesh containing all transformed instances of this object.
TriangleMesh mesh() const;
@ -278,6 +282,7 @@ public:
// 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(); }
};

View file

@ -508,6 +508,13 @@ bool Print::has_skirt() const
std::string Print::validate() const
{
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));
for (PrintObject *po : this->objects) {
if (! print_volume.contains(po->model_object()->tight_bounding_box(false)))
return "Some objects are outside of the print volume.";
}
if (this->config.complete_objects) {
// Check horizontal clearance.
{