Fixed volume transformations in SLA:
Volume transformations were ignored in SLA mode. This did not matter for plain STLs and PS own 3MF, because in those cases, the volume trafo was identity. Importing a 3rd party 3MF leads to issues with support/holes placement and generation. Fixes #6100 and #6744.
This commit is contained in:
parent
fec5d92bc8
commit
6b25a9c836
4 changed files with 68 additions and 31 deletions
|
@ -35,11 +35,24 @@ inline void reproject_points_and_holes(ModelObject *object)
|
||||||
TriangleMesh rmsh = object->raw_mesh();
|
TriangleMesh rmsh = object->raw_mesh();
|
||||||
IndexedMesh emesh{rmsh};
|
IndexedMesh emesh{rmsh};
|
||||||
|
|
||||||
if (has_sppoints)
|
const Transform3f& tr = object->volumes.front()->get_matrix().cast<float>();
|
||||||
reproject_support_points(emesh, object->sla_support_points);
|
|
||||||
|
|
||||||
if (has_holes)
|
if (has_sppoints) {
|
||||||
reproject_support_points(emesh, object->sla_drain_holes);
|
SupportPoints transformed_points = object->sla_support_points;
|
||||||
|
for (SupportPoint& pt : transformed_points)
|
||||||
|
pt.pos = tr * pt.pos;
|
||||||
|
reproject_support_points(emesh, transformed_points);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_holes) {
|
||||||
|
DrainHoles transformed_holes = object->sla_drain_holes;
|
||||||
|
for (DrainHole& hole : transformed_holes) {
|
||||||
|
// Hole normals are not transformed here, but the reprojection
|
||||||
|
// does not use them.
|
||||||
|
hole.pos = tr * hole.pos;
|
||||||
|
}
|
||||||
|
reproject_support_points(emesh, transformed_holes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1167,7 +1167,9 @@ sla::SupportPoints SLAPrintObject::transformed_support_points() const
|
||||||
{
|
{
|
||||||
assert(m_model_object != nullptr);
|
assert(m_model_object != nullptr);
|
||||||
auto spts = m_model_object->sla_support_points;
|
auto spts = m_model_object->sla_support_points;
|
||||||
auto tr = trafo().cast<float>();
|
|
||||||
|
auto tr = (trafo() * m_model_object->volumes.front()->get_transformation().get_matrix()).cast<float>();
|
||||||
|
|
||||||
for (sla::SupportPoint& suppt : spts) {
|
for (sla::SupportPoint& suppt : spts) {
|
||||||
suppt.pos = tr * suppt.pos;
|
suppt.pos = tr * suppt.pos;
|
||||||
}
|
}
|
||||||
|
@ -1179,8 +1181,8 @@ sla::DrainHoles SLAPrintObject::transformed_drainhole_points() const
|
||||||
{
|
{
|
||||||
assert(m_model_object != nullptr);
|
assert(m_model_object != nullptr);
|
||||||
auto pts = m_model_object->sla_drain_holes;
|
auto pts = m_model_object->sla_drain_holes;
|
||||||
auto tr = trafo().cast<float>();
|
Transform3f tr = (trafo() * m_model_object->volumes.front()->get_matrix()).cast<float>();
|
||||||
auto sc = m_model_object->instances.front()->get_scaling_factor().cast<float>();
|
Vec3f sc = Geometry::Transformation(tr.cast<double>()).get_scaling_factor().cast<float>();
|
||||||
for (sla::DrainHole &hl : pts) {
|
for (sla::DrainHole &hl : pts) {
|
||||||
hl.pos = tr * hl.pos;
|
hl.pos = tr * hl.pos;
|
||||||
hl.normal = tr * hl.normal - tr.translation();
|
hl.normal = tr * hl.normal - tr.translation();
|
||||||
|
|
|
@ -106,9 +106,13 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
|
||||||
shader->start_using();
|
shader->start_using();
|
||||||
ScopeGuard guard([shader]() { if (shader) shader->stop_using(); });
|
ScopeGuard guard([shader]() { if (shader) shader->stop_using(); });
|
||||||
|
|
||||||
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
|
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||||
const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
|
const ModelInstance* mi = mo->instances[m_c->selection_info()->get_active_instance()];
|
||||||
const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
|
const ModelVolume* mv = mo->volumes.front();
|
||||||
|
Geometry::Transformation transformation(mi->get_transformation() * mv->get_transformation());
|
||||||
|
|
||||||
|
const Transform3d& instance_scaling_matrix_inverse = transformation.get_matrix(true, true, false, true).inverse();
|
||||||
|
const Transform3d& instance_matrix = transformation.get_matrix();
|
||||||
|
|
||||||
glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
glsafe(::glTranslated(0.0, 0.0, m_c->selection_info()->get_sla_shift()));
|
glsafe(::glTranslated(0.0, 0.0, m_c->selection_info()->get_sla_shift()));
|
||||||
|
@ -117,6 +121,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
|
||||||
std::array<float, 4> render_color;
|
std::array<float, 4> render_color;
|
||||||
const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
|
const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
|
||||||
size_t cache_size = drain_holes.size();
|
size_t cache_size = drain_holes.size();
|
||||||
|
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||||
|
|
||||||
for (size_t i = 0; i < cache_size; ++i) {
|
for (size_t i = 0; i < cache_size; ++i) {
|
||||||
const sla::DrainHole& drain_hole = drain_holes[i];
|
const sla::DrainHole& drain_hole = drain_holes[i];
|
||||||
|
@ -184,13 +189,13 @@ bool GLGizmoHollow::is_mesh_point_clipped(const Vec3d& point) const
|
||||||
if (m_c->object_clipper()->get_position() == 0.)
|
if (m_c->object_clipper()->get_position() == 0.)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto sel_info = m_c->selection_info();
|
|
||||||
int active_inst = m_c->selection_info()->get_active_instance();
|
int active_inst = m_c->selection_info()->get_active_instance();
|
||||||
const ModelInstance* mi = sel_info->model_object()->instances[active_inst];
|
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||||
const Transform3d& trafo = mi->get_transformation().get_matrix();
|
const ModelInstance* mi = mo->instances[active_inst];
|
||||||
|
const Transform3d trafo = (mi->get_transformation() * mo->volumes.front()->get_transformation()).get_matrix();
|
||||||
|
|
||||||
Vec3d transformed_point = trafo * point;
|
Vec3d transformed_point = trafo * point;
|
||||||
transformed_point(2) += sel_info->get_sla_shift();
|
transformed_point(2) += m_c->selection_info()->get_sla_shift();
|
||||||
return m_c->object_clipper()->get_clipping_plane()->is_point_clipped(transformed_point);
|
return m_c->object_clipper()->get_clipping_plane()->is_point_clipped(transformed_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,9 +210,12 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, V
|
||||||
|
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||||
Geometry::Transformation trafo = volume->get_instance_transformation();
|
const ModelInstance* mi = mo->instances[selection.get_instance_idx()];
|
||||||
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
|
const ModelVolume* mv = mo->volumes.front();
|
||||||
|
|
||||||
|
Transform3d trafo = mi->get_transformation().get_matrix() * mv->get_matrix();
|
||||||
|
trafo.pretranslate(Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
|
||||||
|
|
||||||
double clp_dist = m_c->object_clipper()->get_position();
|
double clp_dist = m_c->object_clipper()->get_position();
|
||||||
const ClippingPlane* clp = m_c->object_clipper()->get_clipping_plane();
|
const ClippingPlane* clp = m_c->object_clipper()->get_clipping_plane();
|
||||||
|
@ -217,7 +225,7 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, V
|
||||||
Vec3f normal;
|
Vec3f normal;
|
||||||
if (m_c->raycaster()->raycaster()->unproject_on_mesh(
|
if (m_c->raycaster()->raycaster()->unproject_on_mesh(
|
||||||
mouse_pos,
|
mouse_pos,
|
||||||
trafo.get_matrix(),
|
trafo,
|
||||||
camera,
|
camera,
|
||||||
hit,
|
hit,
|
||||||
normal,
|
normal,
|
||||||
|
@ -307,8 +315,11 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
|
||||||
GLSelectionRectangle::EState rectangle_status = m_selection_rectangle.get_state();
|
GLSelectionRectangle::EState rectangle_status = m_selection_rectangle.get_state();
|
||||||
|
|
||||||
// First collect positions of all the points in world coordinates.
|
// First collect positions of all the points in world coordinates.
|
||||||
Geometry::Transformation trafo = mo->instances[active_inst]->get_transformation();
|
const ModelInstance* mi = mo->instances[active_inst];
|
||||||
|
const ModelVolume* mv = mo->volumes.front();
|
||||||
|
Geometry::Transformation trafo(mi->get_transformation() * mv->get_transformation());
|
||||||
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
|
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
|
||||||
|
|
||||||
std::vector<Vec3d> points;
|
std::vector<Vec3d> points;
|
||||||
for (unsigned int i=0; i<mo->sla_drain_holes.size(); ++i)
|
for (unsigned int i=0; i<mo->sla_drain_holes.size(); ++i)
|
||||||
points.push_back(trafo.get_matrix() * mo->sla_drain_holes[i].pos.cast<double>());
|
points.push_back(trafo.get_matrix() * mo->sla_drain_holes[i].pos.cast<double>());
|
||||||
|
|
|
@ -127,9 +127,13 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
});
|
});
|
||||||
|
|
||||||
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
|
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||||
const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
|
const ModelInstance* mi = mo->instances[m_c->selection_info()->get_active_instance()];
|
||||||
const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
|
const ModelVolume* mv = mo->volumes.front();
|
||||||
|
Geometry::Transformation transformation(mi->get_transformation() * mv->get_transformation());
|
||||||
|
|
||||||
|
const Transform3d& instance_scaling_matrix_inverse = transformation.get_matrix(true, true, false, true).inverse();
|
||||||
|
const Transform3d& instance_matrix = transformation.get_matrix();
|
||||||
float z_shift = m_c->selection_info()->get_sla_shift();
|
float z_shift = m_c->selection_info()->get_sla_shift();
|
||||||
|
|
||||||
glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
|
@ -137,6 +141,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
||||||
glsafe(::glMultMatrixd(instance_matrix.data()));
|
glsafe(::glMultMatrixd(instance_matrix.data()));
|
||||||
|
|
||||||
std::array<float, 4> render_color;
|
std::array<float, 4> render_color;
|
||||||
|
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||||
for (size_t i = 0; i < cache_size; ++i) {
|
for (size_t i = 0; i < cache_size; ++i) {
|
||||||
const sla::SupportPoint& support_point = m_editing_mode ? m_editing_cache[i].support_point : m_normal_cache[i];
|
const sla::SupportPoint& support_point = m_editing_mode ? m_editing_cache[i].support_point : m_normal_cache[i];
|
||||||
const bool& point_selected = m_editing_mode ? m_editing_cache[i].selected : false;
|
const bool& point_selected = m_editing_mode ? m_editing_cache[i].selected : false;
|
||||||
|
@ -265,13 +270,13 @@ bool GLGizmoSlaSupports::is_mesh_point_clipped(const Vec3d& point) const
|
||||||
if (m_c->object_clipper()->get_position() == 0.)
|
if (m_c->object_clipper()->get_position() == 0.)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto sel_info = m_c->selection_info();
|
|
||||||
int active_inst = m_c->selection_info()->get_active_instance();
|
int active_inst = m_c->selection_info()->get_active_instance();
|
||||||
const ModelInstance* mi = sel_info->model_object()->instances[active_inst];
|
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||||
const Transform3d& trafo = mi->get_transformation().get_matrix();
|
const ModelInstance* mi = mo->instances[active_inst];
|
||||||
|
const Transform3d trafo = (mi->get_transformation() * mo->volumes.front()->get_transformation()).get_matrix();
|
||||||
|
|
||||||
Vec3d transformed_point = trafo * point;
|
Vec3d transformed_point = trafo * point;
|
||||||
transformed_point(2) += sel_info->get_sla_shift();
|
transformed_point(2) += m_c->selection_info()->get_sla_shift();
|
||||||
return m_c->object_clipper()->get_clipping_plane()->is_point_clipped(transformed_point);
|
return m_c->object_clipper()->get_clipping_plane()->is_point_clipped(transformed_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,9 +291,12 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec
|
||||||
|
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||||
Geometry::Transformation trafo = volume->get_instance_transformation();
|
const ModelInstance* mi = mo->instances[selection.get_instance_idx()];
|
||||||
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
|
const ModelVolume* mv = mo->volumes.front();
|
||||||
|
|
||||||
|
Transform3d trafo = mi->get_transformation().get_matrix() * mv->get_matrix();
|
||||||
|
trafo.pretranslate(Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
|
||||||
|
|
||||||
double clp_dist = m_c->object_clipper()->get_position();
|
double clp_dist = m_c->object_clipper()->get_position();
|
||||||
const ClippingPlane* clp = m_c->object_clipper()->get_clipping_plane();
|
const ClippingPlane* clp = m_c->object_clipper()->get_clipping_plane();
|
||||||
|
@ -298,7 +306,7 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec
|
||||||
Vec3f normal;
|
Vec3f normal;
|
||||||
if (m_c->raycaster()->raycaster()->unproject_on_mesh(
|
if (m_c->raycaster()->raycaster()->unproject_on_mesh(
|
||||||
mouse_pos,
|
mouse_pos,
|
||||||
trafo.get_matrix(),
|
trafo,
|
||||||
camera,
|
camera,
|
||||||
hit,
|
hit,
|
||||||
normal,
|
normal,
|
||||||
|
@ -388,8 +396,11 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
||||||
GLSelectionRectangle::EState rectangle_status = m_selection_rectangle.get_state();
|
GLSelectionRectangle::EState rectangle_status = m_selection_rectangle.get_state();
|
||||||
|
|
||||||
// First collect positions of all the points in world coordinates.
|
// First collect positions of all the points in world coordinates.
|
||||||
Geometry::Transformation trafo = mo->instances[active_inst]->get_transformation();
|
const ModelInstance* mi = mo->instances[active_inst];
|
||||||
|
const ModelVolume* mv = mo->volumes.front();
|
||||||
|
Geometry::Transformation trafo(mi->get_transformation() * mv->get_transformation());
|
||||||
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
|
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_c->selection_info()->get_sla_shift()));
|
||||||
|
|
||||||
std::vector<Vec3d> points;
|
std::vector<Vec3d> points;
|
||||||
for (unsigned int i=0; i<m_editing_cache.size(); ++i)
|
for (unsigned int i=0; i<m_editing_cache.size(); ++i)
|
||||||
points.push_back(trafo.get_matrix() * m_editing_cache[i].support_point.pos.cast<double>());
|
points.push_back(trafo.get_matrix() * m_editing_cache[i].support_point.pos.cast<double>());
|
||||||
|
|
Loading…
Add table
Reference in a new issue