Hollowing gizmo: Invalidate drilled mesh in case a hole is manipulated

This way the holes cannot be placed on its own walls
Downside is that AABB trees have to be recalculated
This commit is contained in:
Lukas Matena 2020-02-04 13:03:28 +01:00
parent 808cf2e38a
commit 0e3ebb3e07
4 changed files with 18 additions and 0 deletions

View File

@ -1241,6 +1241,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>);
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);

View File

@ -91,6 +91,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_SELECT_ALL, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>); // data: +1 => increase, -1 => decrease
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);

View File

@ -330,6 +330,7 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, V
{
if (! m_c->m_mesh_raycaster)
return false;
// if the gizmo doesn't have the V, F structures for igl, calculate them first:
// !!! is it really necessary?
//m_c->update_from_backend(m_parent, m_c->m_model_object);
@ -344,6 +345,18 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, V
Vec3f hit;
Vec3f normal;
if (m_c->m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_c->m_clipping_plane.get())) {
// User is about to manipulate a hole. If the gizmo currently shows drilled mesh,
// invalidate slaposDrillHoles so it returns to normal. To do this, hackishly
// add a hole, force SLAPrint::apply call that will invalidate the step because
// of it and then remove the hole again.
if (m_c->has_drilled_mesh()) {
m_c->m_model_object->sla_drain_holes.push_back(sla::DrainHole());
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE));
wxGetApp().CallAfter([this] { m_c->m_model_object->sla_drain_holes.pop_back();});
return false;
}
// Return both the point and the facet normal.
pos_and_normal = std::make_pair(hit, normal);
return true;
@ -513,6 +526,8 @@ void GLGizmoHollow::delete_selected_points()
}
}
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE));
select_point(NoPoints);
}

View File

@ -2062,6 +2062,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [this](Event<int> &evt)
{ if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); });
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); });
view3D_canvas->Bind(EVT_GLCANVAS_FORCE_UPDATE, [this](SimpleEvent&) { update(); });
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this);
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_ROTATED, &priv::on_wipetower_rotated, this);
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); });