mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 16:57:53 -06:00
Use of bounding box of rotated 3D convex hull for out of print volume detection
This commit is contained in:
parent
211790f8c3
commit
4d98d32199
12 changed files with 276 additions and 141 deletions
|
@ -17,6 +17,11 @@
|
|||
#include "SVG.hpp"
|
||||
#include <Eigen/Dense>
|
||||
|
||||
static const float UNIT_MATRIX[] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f };
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
unsigned int Model::s_auto_extruder_id = 1;
|
||||
|
@ -235,14 +240,6 @@ BoundingBoxf3 Model::bounding_box() const
|
|||
return bb;
|
||||
}
|
||||
|
||||
BoundingBoxf3 Model::transformed_bounding_box() const
|
||||
{
|
||||
BoundingBoxf3 bb;
|
||||
for (const ModelObject* obj : this->objects)
|
||||
bb.merge(obj->tight_bounding_box(false));
|
||||
return bb;
|
||||
}
|
||||
|
||||
void Model::center_instances_around_point(const Pointf &point)
|
||||
{
|
||||
// BoundingBoxf3 bb = this->bounding_box();
|
||||
|
@ -623,54 +620,6 @@ const BoundingBoxf3& ModelObject::bounding_box() const
|
|||
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
|
||||
{
|
||||
|
@ -755,15 +704,22 @@ void ModelObject::center_around_origin()
|
|||
void ModelObject::translate(coordf_t x, coordf_t y, coordf_t z)
|
||||
{
|
||||
for (ModelVolume *v : this->volumes)
|
||||
{
|
||||
v->mesh.translate(float(x), float(y), float(z));
|
||||
if (m_bounding_box_valid)
|
||||
v->m_convex_hull.translate(float(x), float(y), float(z));
|
||||
}
|
||||
|
||||
if (m_bounding_box_valid)
|
||||
m_bounding_box.translate(x, y, z);
|
||||
}
|
||||
|
||||
void ModelObject::scale(const Pointf3 &versor)
|
||||
{
|
||||
for (ModelVolume *v : this->volumes)
|
||||
{
|
||||
v->mesh.scale(versor);
|
||||
v->m_convex_hull.scale(versor);
|
||||
}
|
||||
// reset origin translation since it doesn't make sense anymore
|
||||
this->origin_translation = Pointf3(0,0,0);
|
||||
this->invalidate_bounding_box();
|
||||
|
@ -774,6 +730,7 @@ void ModelObject::rotate(float angle, const Axis &axis)
|
|||
for (ModelVolume *v : this->volumes)
|
||||
{
|
||||
v->mesh.rotate(angle, axis);
|
||||
v->m_convex_hull.rotate(angle, axis);
|
||||
}
|
||||
|
||||
center_around_origin();
|
||||
|
@ -790,6 +747,7 @@ void ModelObject::transform(const float* matrix3x4)
|
|||
for (ModelVolume* v : volumes)
|
||||
{
|
||||
v->mesh.transform(matrix3x4);
|
||||
v->m_convex_hull.transform(matrix3x4);
|
||||
}
|
||||
|
||||
origin_translation = Pointf3(0.0, 0.0, 0.0);
|
||||
|
@ -799,8 +757,12 @@ void ModelObject::transform(const float* matrix3x4)
|
|||
void ModelObject::mirror(const Axis &axis)
|
||||
{
|
||||
for (ModelVolume *v : this->volumes)
|
||||
{
|
||||
v->mesh.mirror(axis);
|
||||
this->origin_translation = Pointf3(0,0,0);
|
||||
v->m_convex_hull.mirror(axis);
|
||||
}
|
||||
|
||||
this->origin_translation = Pointf3(0, 0, 0);
|
||||
this->invalidate_bounding_box();
|
||||
}
|
||||
|
||||
|
@ -904,45 +866,20 @@ void ModelObject::split(ModelObjectPtrs* new_objects)
|
|||
|
||||
void ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
|
||||
{
|
||||
for (ModelVolume* vol : this->volumes)
|
||||
for (const ModelVolume* vol : this->volumes)
|
||||
{
|
||||
if (!vol->modifier)
|
||||
{
|
||||
for (ModelInstance* inst : this->instances)
|
||||
{
|
||||
BoundingBoxf3 bb;
|
||||
std::vector<float> world_mat(UNIT_MATRIX, std::end(UNIT_MATRIX));
|
||||
Eigen::Transform<float, 3, Eigen::Affine> m = Eigen::Transform<float, 3, Eigen::Affine>::Identity();
|
||||
m.translate(Eigen::Vector3f((float)inst->offset.x, (float)inst->offset.y, 0.0f));
|
||||
m.rotate(Eigen::AngleAxisf(inst->rotation, Eigen::Vector3f::UnitZ()));
|
||||
m.scale(inst->scaling_factor);
|
||||
::memcpy((void*)world_mat.data(), (const void*)m.data(), 16 * sizeof(float));
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(world_mat);
|
||||
|
||||
if (print_volume.contains(bb))
|
||||
inst->print_volume_state = ModelInstance::PVS_Inside;
|
||||
|
@ -1025,6 +962,16 @@ ModelMaterial* ModelVolume::assign_unique_material()
|
|||
return model->add_material(this->_material_id);
|
||||
}
|
||||
|
||||
void ModelVolume::calculate_convex_hull()
|
||||
{
|
||||
m_convex_hull = mesh.convex_hull_3d();
|
||||
}
|
||||
|
||||
const TriangleMesh& ModelVolume::get_convex_hull() const
|
||||
{
|
||||
return m_convex_hull;
|
||||
}
|
||||
|
||||
// Split this volume, append the result to the object owning this volume.
|
||||
// Return the number of volumes created from this one.
|
||||
// This is useful to assign different materials to different volumes of an object.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue