Changed internal coordinates of drain holes

Drain holes reference position was saved slightly above the mesh to avoid problem when the hole is placed on flat or nearly flat surface
The depth of the hole was internally bigger than what the user has set to compensato for it
However, this leads to problem with scaling and makes reprojection of the holes on the mesh complicated

This commit changes the reference point to the point on the mesh and the extra elevation is handled when rendering and drilling the hole.
The change is reflected in 3MF drain holes versioning so that old 3MFs are loaded correctly.
Reprojection on the mesh after reload from disk/fix through netfabb has been enabled.
This commit is contained in:
Lukas Matena 2020-08-19 15:24:55 +02:00
parent ba03429679
commit a95509ce36
8 changed files with 43 additions and 33 deletions

View File

@ -1103,7 +1103,7 @@ namespace Slic3r {
sla::DrainHoles sla_drain_holes;
if (version == 1) {
if (version == 1 || version == 2) {
for (unsigned int i=0; i<object_data_points.size(); i+=8)
sla_drain_holes.emplace_back(Vec3f{float(std::atof(object_data_points[i+0].c_str())),
float(std::atof(object_data_points[i+1].c_str())),
@ -1115,6 +1115,16 @@ namespace Slic3r {
float(std::atof(object_data_points[i+7].c_str())));
}
if (version == 1) {
// In this version the holes were saved elevated above the mesh and deeper (bad idea indeed).
// Place the hole to the mesh and make it shallower to compensate.
// The offset was 1 mm above the mesh.
for (sla::DrainHole& hole : sla_drain_holes) {
hole.pos += hole.normal.normalized();
hole.height -= 1.f;
}
}
if (!sla_drain_holes.empty())
m_sla_drain_holes.insert(IdToSlaDrainHolesMap::value_type(object_id, sla_drain_holes));
}

View File

@ -20,8 +20,15 @@ namespace Slic3r {
support_points_format_version = 1
};
/* The same for holes.
* version 0: undefined
* version 1: holes saved a bit above the mesh and deeper
* version 2: holes are saved on the mesh exactly
*/
enum {
drain_holes_format_version = 1
drain_holes_format_version = 2
};
class Model;
@ -35,6 +42,6 @@ namespace Slic3r {
// The model could be modified during the export process if meshes are not repaired or have no shared vertices
extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data = nullptr);
}; // namespace Slic3r
} // namespace Slic3r
#endif /* slic3r_Format_3mf_hpp_ */

View File

@ -58,6 +58,8 @@ struct DrainHole
using DrainHoles = std::vector<DrainHole>;
constexpr float HoleStickOutLength = 1.f;
std::unique_ptr<TriangleMesh> generate_interior(const TriangleMesh &mesh,
const HollowingConfig & = {},
const JobController &ctl = {});

View File

@ -28,15 +28,9 @@ void reproject_support_points(const IndexedMesh &mesh, std::vector<PointType> &p
inline void reproject_points_and_holes(ModelObject *object)
{
bool has_sppoints = !object->sla_support_points.empty();
bool has_holes = !object->sla_drain_holes.empty();
// Disabling reprojection of holes as they have a significant offset away
// from the model body which tolerates minor geometrical changes.
//
// TODO: uncomment and ensure the right offset of the hole points if
// reprojection would still be necessary.
// bool has_holes = !object->sla_drain_holes.empty();
if (!object || (/*!has_holes &&*/ !has_sppoints)) return;
if (!object || (!has_holes && !has_sppoints)) return;
TriangleMesh rmsh = object->raw_mesh();
rmsh.require_shared_vertices();
@ -45,8 +39,8 @@ inline void reproject_points_and_holes(ModelObject *object)
if (has_sppoints)
reproject_support_points(emesh, object->sla_support_points);
// if (has_holes)
// reproject_support_points(emesh, object->sla_drain_holes);
if (has_holes)
reproject_support_points(emesh, object->sla_drain_holes);
}
}}

View File

@ -1181,6 +1181,12 @@ sla::DrainHoles SLAPrintObject::transformed_drainhole_points() const
hl.normal = Vec3f(hl.normal(0)/(sc(0)*sc(0)),
hl.normal(1)/(sc(1)*sc(1)),
hl.normal(2)/(sc(2)*sc(2)));
// Now shift the hole a bit above the object and make it deeper to
// compensate for it. This is to avoid problems when the hole is placed
// on (nearly) flat surface.
hl.pos -= hl.normal.normalized() * sla::HoleStickOutLength;
hl.height += sla::HoleStickOutLength;
}
return pts;

View File

@ -130,7 +130,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
const sla::DrainHole& drain_hole = drain_holes[i];
const bool& point_selected = m_selected[i];
if (is_mesh_point_clipped((drain_hole.pos+HoleStickOutLength*drain_hole.normal).cast<double>()))
if (is_mesh_point_clipped(drain_hole.pos.cast<double>()))
continue;
// First decide about the color of the point.
@ -174,10 +174,10 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2)));
glsafe(::glPushMatrix());
glsafe(::glTranslated(0., 0., -drain_hole.height));
::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height, 24, 1);
glsafe(::glTranslated(0., 0., drain_hole.height));
::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength, 24, 1);
glsafe(::glTranslated(0., 0., drain_hole.height + sla::HoleStickOutLength));
::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1);
glsafe(::glTranslated(0., 0., -drain_hole.height));
glsafe(::glTranslated(0., 0., -drain_hole.height - sla::HoleStickOutLength));
glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f));
::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1);
glsafe(::glPopMatrix());
@ -307,12 +307,7 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
if (unproject_on_mesh(mouse_position, pos_and_normal)) { // we got an intersection
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Add drainage hole")));
Vec3d scaling = mo->instances[active_inst]->get_scaling_factor();
Vec3f normal_transformed(pos_and_normal.second(0)/scaling(0),
pos_and_normal.second(1)/scaling(1),
pos_and_normal.second(2)/scaling(2));
mo->sla_drain_holes.emplace_back(pos_and_normal.first + HoleStickOutLength * pos_and_normal.second/* normal_transformed.normalized()*/,
mo->sla_drain_holes.emplace_back(pos_and_normal.first,
-pos_and_normal.second, m_new_hole_radius, m_new_hole_height);
m_selected.push_back(false);
assert(m_selected.size() == mo->sla_drain_holes.size());
@ -447,7 +442,7 @@ void GLGizmoHollow::on_update(const UpdateData& data)
std::pair<Vec3f, Vec3f> pos_and_normal;
if (! unproject_on_mesh(data.mouse_pos.cast<double>(), pos_and_normal))
return;
drain_holes[m_hover_id].pos = pos_and_normal.first + HoleStickOutLength * pos_and_normal.second;
drain_holes[m_hover_id].pos = pos_and_normal.first;
drain_holes[m_hover_id].normal = -pos_and_normal.second;
}
}
@ -661,9 +656,7 @@ RENDER_AGAIN:
m_imgui->text(m_desc["hole_depth"]);
ImGui::SameLine(diameter_slider_left);
m_new_hole_height -= HoleStickOutLength;
ImGui::SliderFloat(" ", &m_new_hole_height, 0.f, 10.f, "%.1f mm");
m_new_hole_height += HoleStickOutLength;
clicked |= ImGui::IsItemClicked();
edited |= ImGui::IsItemEdited();

View File

@ -222,7 +222,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
render_color[3] = 0.7f;
glsafe(::glColor4fv(render_color));
for (const sla::DrainHole& drain_hole : m_c->selection_info()->model_object()->sla_drain_holes) {
if (is_mesh_point_clipped((drain_hole.pos+HoleStickOutLength*drain_hole.normal).cast<double>()))
if (is_mesh_point_clipped(drain_hole.pos.cast<double>()))
continue;
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
@ -241,10 +241,10 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2)));
glsafe(::glPushMatrix());
glsafe(::glTranslated(0., 0., -drain_hole.height));
::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height, 24, 1);
glsafe(::glTranslated(0., 0., drain_hole.height));
::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength, 24, 1);
glsafe(::glTranslated(0., 0., drain_hole.height + sla::HoleStickOutLength));
::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1);
glsafe(::glTranslated(0., 0., -drain_hole.height));
glsafe(::glTranslated(0., 0., -drain_hole.height - sla::HoleStickOutLength));
glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f));
::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1);
glsafe(::glPopMatrix());

View File

@ -15,8 +15,6 @@ namespace GUI {
class GLCanvas3D;
static constexpr float HoleStickOutLength = 1.f;
enum class SLAGizmoEventType : unsigned char {
LeftDown = 1,
LeftUp,