Extended Print::validate() to check, whether the objects
are inside the print volume.
This commit is contained in:
parent
523b297738
commit
b43a21d1be
4 changed files with 73 additions and 71 deletions
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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(); }
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue