SLA gizmo keeps track of current status of the points, enables the user to erase all points
This commit is contained in:
parent
a76bd40c62
commit
4eb4e40746
@ -592,6 +592,7 @@ ModelObject& ModelObject::assign_copy(const ModelObject &rhs)
|
|||||||
this->input_file = rhs.input_file;
|
this->input_file = rhs.input_file;
|
||||||
this->config = rhs.config;
|
this->config = rhs.config;
|
||||||
this->sla_support_points = rhs.sla_support_points;
|
this->sla_support_points = rhs.sla_support_points;
|
||||||
|
this->sla_points_status = rhs.sla_points_status;
|
||||||
this->layer_height_ranges = rhs.layer_height_ranges;
|
this->layer_height_ranges = rhs.layer_height_ranges;
|
||||||
this->layer_height_profile = rhs.layer_height_profile;
|
this->layer_height_profile = rhs.layer_height_profile;
|
||||||
this->origin_translation = rhs.origin_translation;
|
this->origin_translation = rhs.origin_translation;
|
||||||
@ -625,6 +626,7 @@ ModelObject& ModelObject::assign_copy(ModelObject &&rhs)
|
|||||||
this->input_file = std::move(rhs.input_file);
|
this->input_file = std::move(rhs.input_file);
|
||||||
this->config = std::move(rhs.config);
|
this->config = std::move(rhs.config);
|
||||||
this->sla_support_points = std::move(rhs.sla_support_points);
|
this->sla_support_points = std::move(rhs.sla_support_points);
|
||||||
|
this->sla_points_status = std::move(rhs.sla_points_status);
|
||||||
this->layer_height_ranges = std::move(rhs.layer_height_ranges);
|
this->layer_height_ranges = std::move(rhs.layer_height_ranges);
|
||||||
this->layer_height_profile = std::move(rhs.layer_height_profile);
|
this->layer_height_profile = std::move(rhs.layer_height_profile);
|
||||||
this->origin_translation = std::move(rhs.origin_translation);
|
this->origin_translation = std::move(rhs.origin_translation);
|
||||||
@ -1130,6 +1132,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b
|
|||||||
if (keep_upper) {
|
if (keep_upper) {
|
||||||
upper->set_model(nullptr);
|
upper->set_model(nullptr);
|
||||||
upper->sla_support_points.clear();
|
upper->sla_support_points.clear();
|
||||||
|
upper->sla_points_status = sla::PointsStatus::None;
|
||||||
upper->clear_volumes();
|
upper->clear_volumes();
|
||||||
upper->input_file = "";
|
upper->input_file = "";
|
||||||
}
|
}
|
||||||
@ -1137,6 +1140,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b
|
|||||||
if (keep_lower) {
|
if (keep_lower) {
|
||||||
lower->set_model(nullptr);
|
lower->set_model(nullptr);
|
||||||
lower->sla_support_points.clear();
|
lower->sla_support_points.clear();
|
||||||
|
lower->sla_points_status = sla::PointsStatus::None;
|
||||||
lower->clear_volumes();
|
lower->clear_volumes();
|
||||||
lower->input_file = "";
|
lower->input_file = "";
|
||||||
}
|
}
|
||||||
|
@ -180,6 +180,9 @@ public:
|
|||||||
// saved in mesh coordinates to allow using them for several instances.
|
// saved in mesh coordinates to allow using them for several instances.
|
||||||
// The format is (x, y, z, point_size, supports_island)
|
// The format is (x, y, z, point_size, supports_island)
|
||||||
std::vector<sla::SupportPoint> sla_support_points;
|
std::vector<sla::SupportPoint> sla_support_points;
|
||||||
|
// To keep track of where the points came from (used for synchronization between
|
||||||
|
// the SLA gizmo and the backend).
|
||||||
|
sla::PointsStatus sla_points_status = sla::PointsStatus::None;
|
||||||
|
|
||||||
/* This vector accumulates the total translation applied to the object by the
|
/* This vector accumulates the total translation applied to the object by the
|
||||||
center_around_origin() method. Callers might want to apply the same translation
|
center_around_origin() method. Callers might want to apply the same translation
|
||||||
|
@ -15,6 +15,14 @@ class TriangleMesh;
|
|||||||
|
|
||||||
namespace sla {
|
namespace sla {
|
||||||
|
|
||||||
|
// An enum to keep track of where the current points on the ModelObject came from.
|
||||||
|
enum class PointsStatus {
|
||||||
|
None, // No points were generated so far.
|
||||||
|
Generating, // The autogeneration algorithm triggered, but not yet finished.
|
||||||
|
AutoGenerated, // Points were autogenerated (i.e. copied from the backend).
|
||||||
|
UserModified // User has done some edits.
|
||||||
|
};
|
||||||
|
|
||||||
struct SupportPoint {
|
struct SupportPoint {
|
||||||
Vec3f pos;
|
Vec3f pos;
|
||||||
float head_front_radius;
|
float head_front_radius;
|
||||||
|
@ -342,6 +342,17 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf
|
|||||||
if (it_print_object_status != print_object_status.end())
|
if (it_print_object_status != print_object_status.end())
|
||||||
update_apply_status(it_print_object_status->print_object->invalidate_step(slaposSupportPoints));
|
update_apply_status(it_print_object_status->print_object->invalidate_step(slaposSupportPoints));
|
||||||
}
|
}
|
||||||
|
if (model_object.sla_points_status != model_object_new.sla_points_status) {
|
||||||
|
// Change of this status should invalidate support points. The points themselves are not enough, there are none
|
||||||
|
// in case that nothing was generated OR that points were autogenerated already and not copied to the front-end.
|
||||||
|
// These cases can only be differentiated by checking the status change. However, changing from 'Generating' should NOT
|
||||||
|
// invalidate - that would keep stopping the background processing without a reason.
|
||||||
|
if (model_object.sla_points_status != sla::PointsStatus::Generating)
|
||||||
|
if (it_print_object_status != print_object_status.end())
|
||||||
|
update_apply_status(it_print_object_status->print_object->invalidate_step(slaposSupportPoints));
|
||||||
|
model_object.sla_points_status = model_object_new.sla_points_status;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy the ModelObject name, input_file and instances. The instances will compared against PrintObject instances in the next step.
|
// Copy the ModelObject name, input_file and instances. The instances will compared against PrintObject instances in the next step.
|
||||||
model_object.name = model_object_new.name;
|
model_object.name = model_object_new.name;
|
||||||
model_object.input_file = model_object_new.input_file;
|
model_object.input_file = model_object_new.input_file;
|
||||||
@ -630,10 +641,11 @@ void SLAPrint::process()
|
|||||||
BOOST_LOG_TRIVIAL(debug) << "Support point count "
|
BOOST_LOG_TRIVIAL(debug) << "Support point count "
|
||||||
<< mo.sla_support_points.size();
|
<< mo.sla_support_points.size();
|
||||||
|
|
||||||
// If there are no points on the front-end, we will do the
|
// Unless the user modified the points or we already did the calculation, we will do
|
||||||
// autoplacement. Otherwise we will just blindly copy the frontend data
|
// the autoplacement. Otherwise we will just blindly copy the frontend data
|
||||||
// into the backend cache.
|
// into the backend cache.
|
||||||
if(mo.sla_support_points.empty()) {
|
if (mo.sla_points_status != sla::PointsStatus::UserModified) {
|
||||||
|
|
||||||
// calculate heights of slices (slices are calculated already)
|
// calculate heights of slices (slices are calculated already)
|
||||||
double lh = po.m_config.layer_height.getFloat();
|
double lh = po.m_config.layer_height.getFloat();
|
||||||
|
|
||||||
@ -645,7 +657,9 @@ void SLAPrint::process()
|
|||||||
this->throw_if_canceled();
|
this->throw_if_canceled();
|
||||||
SLAAutoSupports::Config config;
|
SLAAutoSupports::Config config;
|
||||||
const SLAPrintObjectConfig& cfg = po.config();
|
const SLAPrintObjectConfig& cfg = po.config();
|
||||||
config.density_relative = float(cfg.support_points_density_relative / 100.f); // the config value is in percents
|
|
||||||
|
// the density config value is in percents:
|
||||||
|
config.density_relative = float(cfg.support_points_density_relative / 100.f);
|
||||||
config.minimal_distance = float(cfg.support_points_minimal_distance);
|
config.minimal_distance = float(cfg.support_points_minimal_distance);
|
||||||
|
|
||||||
// Construction of this object does the calculation.
|
// Construction of this object does the calculation.
|
||||||
@ -669,7 +683,7 @@ void SLAPrint::process()
|
|||||||
report_status(*this, -1, L("Generating support points"), SlicingStatus::RELOAD_SLA_SUPPORT_POINTS);
|
report_status(*this, -1, L("Generating support points"), SlicingStatus::RELOAD_SLA_SUPPORT_POINTS);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// There are some points on the front-end, no calculation will be done.
|
// There are either some points on the front-end, or the user removed them on purpose. No calculation will be done.
|
||||||
po.m_supportdata->support_points = po.transformed_support_points();
|
po.m_supportdata->support_points = po.transformed_support_points();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1789,12 +1789,12 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const G
|
|||||||
if (is_mesh_update_necessary())
|
if (is_mesh_update_necessary())
|
||||||
update_mesh();
|
update_mesh();
|
||||||
|
|
||||||
// If there are no points, let's ask the backend if it calculated some.
|
|
||||||
if (m_editing_mode_cache.empty())
|
|
||||||
get_data_from_backend();
|
|
||||||
|
|
||||||
if (m_model_object != m_old_model_object)
|
if (m_model_object != m_old_model_object)
|
||||||
m_editing_mode = false;
|
m_editing_mode = false;
|
||||||
|
|
||||||
|
if (m_editing_mode_cache.empty() && m_model_object->sla_points_status != sla::PointsStatus::UserModified)
|
||||||
|
get_data_from_backend();
|
||||||
|
|
||||||
if (m_state == On) {
|
if (m_state == On) {
|
||||||
m_parent.toggle_model_objects_visibility(false);
|
m_parent.toggle_model_objects_visibility(false);
|
||||||
m_parent.toggle_model_objects_visibility(true, m_model_object, m_active_instance);
|
m_parent.toggle_model_objects_visibility(true, m_model_object, m_active_instance);
|
||||||
@ -2296,8 +2296,7 @@ RENDER_AGAIN:
|
|||||||
|
|
||||||
m_imgui->text(" "); // vertical gap
|
m_imgui->text(" "); // vertical gap
|
||||||
|
|
||||||
bool apply_changes = m_imgui->button(_(L("Apply changes")));
|
if (m_imgui->button(_(L("Apply changes")))) {
|
||||||
if (apply_changes) {
|
|
||||||
editing_mode_apply_changes();
|
editing_mode_apply_changes();
|
||||||
force_refresh = true;
|
force_refresh = true;
|
||||||
}
|
}
|
||||||
@ -2308,24 +2307,28 @@ RENDER_AGAIN:
|
|||||||
force_refresh = true;
|
force_refresh = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else { // not in editing mode:
|
||||||
/* ImGui::PushItemWidth(50.0f);
|
/*ImGui::PushItemWidth(100.0f);
|
||||||
m_imgui->text(_(L("Minimal points distance: ")));
|
m_imgui->text(_(L("Minimal points distance: ")));
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
bool value_changed = ImGui::InputDouble("mm", &m_minimal_point_distance, 0.0f, 0.0f, "%.2f");
|
bool value_changed = ImGui::SliderFloat("", &m_minimal_point_distance, 0.f, 20.f, "%.f mm");
|
||||||
m_imgui->text(_(L("Support points density: ")));
|
m_imgui->text(_(L("Support points density: ")));
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
value_changed |= ImGui::InputDouble("%", &m_density, 0.0f, 0.0f, "%.f");*/
|
value_changed |= ImGui::SliderFloat(" ", &m_density, 0.f, 200.f, "%.f %%");*/
|
||||||
|
|
||||||
bool generate = m_imgui->button(_(L("Auto-generate points [A]")));
|
bool generate = m_imgui->button(_(L("Auto-generate points [A]")));
|
||||||
|
|
||||||
if (generate)
|
if (generate)
|
||||||
auto_generate();
|
auto_generate();
|
||||||
|
|
||||||
m_imgui->text("");
|
|
||||||
m_imgui->text("");
|
m_imgui->text("");
|
||||||
if (m_imgui->button(_(L("Manual editing [M]"))))
|
if (m_imgui->button(_(L("Manual editing [M]"))))
|
||||||
switch_to_editing_mode();
|
switch_to_editing_mode();
|
||||||
|
|
||||||
|
m_imgui->text(m_model_object->sla_points_status == sla::PointsStatus::None ? "No points (will be autogenerated)" :
|
||||||
|
(m_model_object->sla_points_status == sla::PointsStatus::AutoGenerated ? "Autogenerated points (no modifications)" :
|
||||||
|
(m_model_object->sla_points_status == sla::PointsStatus::UserModified ? "User-modified points" :
|
||||||
|
(m_model_object->sla_points_status == sla::PointsStatus::Generating ? "Generation in progress..." : "UNKNOWN STATUS"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_imgui->end();
|
m_imgui->end();
|
||||||
@ -2448,16 +2451,18 @@ void GLGizmoSlaSupports::editing_mode_apply_changes()
|
|||||||
// If there are no changes, don't touch the front-end. The data in the cache could have been
|
// If there are no changes, don't touch the front-end. The data in the cache could have been
|
||||||
// taken from the backend and copying them to ModelObject would needlessly invalidate them.
|
// taken from the backend and copying them to ModelObject would needlessly invalidate them.
|
||||||
if (m_unsaved_changes) {
|
if (m_unsaved_changes) {
|
||||||
|
m_model_object->sla_points_status = sla::PointsStatus::UserModified;
|
||||||
m_model_object->sla_support_points.clear();
|
m_model_object->sla_support_points.clear();
|
||||||
for (const std::pair<sla::SupportPoint, bool>& point_and_selection : m_editing_mode_cache)
|
for (const std::pair<sla::SupportPoint, bool>& point_and_selection : m_editing_mode_cache)
|
||||||
m_model_object->sla_support_points.push_back(point_and_selection.first);
|
m_model_object->sla_support_points.push_back(point_and_selection.first);
|
||||||
|
|
||||||
|
// Recalculate support structures once the editing mode is left.
|
||||||
|
// m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||||
|
// m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||||
|
wxGetApp().plater()->reslice_SLA_supports(*m_model_object);
|
||||||
}
|
}
|
||||||
m_editing_mode = false;
|
m_editing_mode = false;
|
||||||
m_unsaved_changes = false;
|
m_unsaved_changes = false;
|
||||||
|
|
||||||
// Recalculate support structures once the editing mode is left.
|
|
||||||
// m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
|
||||||
wxGetApp().plater()->reslice_SLA_supports(*m_model_object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2476,10 +2481,15 @@ void GLGizmoSlaSupports::get_data_from_backend()
|
|||||||
{
|
{
|
||||||
for (const SLAPrintObject* po : m_parent.sla_print()->objects()) {
|
for (const SLAPrintObject* po : m_parent.sla_print()->objects()) {
|
||||||
if (po->model_object()->id() == m_model_object->id() && po->is_step_done(slaposSupportPoints)) {
|
if (po->model_object()->id() == m_model_object->id() && po->is_step_done(slaposSupportPoints)) {
|
||||||
|
m_editing_mode_cache.clear();
|
||||||
const std::vector<sla::SupportPoint>& points = po->get_support_points();
|
const std::vector<sla::SupportPoint>& points = po->get_support_points();
|
||||||
auto mat = po->trafo().inverse().cast<float>();
|
auto mat = po->trafo().inverse().cast<float>();
|
||||||
for (unsigned int i=0; i<points.size();++i)
|
for (unsigned int i=0; i<points.size();++i)
|
||||||
m_editing_mode_cache.emplace_back(sla::SupportPoint(mat * points[i].pos, points[i].head_front_radius, points[i].is_new_island), false);
|
m_editing_mode_cache.emplace_back(sla::SupportPoint(mat * points[i].pos, points[i].head_front_radius, points[i].is_new_island), false);
|
||||||
|
|
||||||
|
if (m_model_object->sla_points_status != sla::PointsStatus::UserModified)
|
||||||
|
m_model_object->sla_points_status = sla::PointsStatus::AutoGenerated;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2497,8 +2507,9 @@ void GLGizmoSlaSupports::auto_generate()
|
|||||||
"Are you sure you want to do it?\n"
|
"Are you sure you want to do it?\n"
|
||||||
)), _(L("Warning")), wxICON_WARNING | wxYES | wxNO);
|
)), _(L("Warning")), wxICON_WARNING | wxYES | wxNO);
|
||||||
|
|
||||||
if (m_model_object->sla_support_points.empty() || dlg.ShowModal() == wxID_YES) {
|
if (m_model_object->sla_points_status != sla::PointsStatus::UserModified || dlg.ShowModal() == wxID_YES) {
|
||||||
m_model_object->sla_support_points.clear();
|
m_model_object->sla_support_points.clear();
|
||||||
|
m_model_object->sla_points_status = sla::PointsStatus::Generating;
|
||||||
m_editing_mode_cache.clear();
|
m_editing_mode_cache.clear();
|
||||||
wxGetApp().plater()->reslice_SLA_supports(*m_model_object);
|
wxGetApp().plater()->reslice_SLA_supports(*m_model_object);
|
||||||
}
|
}
|
||||||
|
@ -489,19 +489,19 @@ private:
|
|||||||
#endif // not ENABLE_IMGUI
|
#endif // not ENABLE_IMGUI
|
||||||
|
|
||||||
bool m_lock_unique_islands = false;
|
bool m_lock_unique_islands = false;
|
||||||
bool m_editing_mode = false;
|
bool m_editing_mode = false; // Is editing mode active?
|
||||||
bool m_old_editing_state = false;
|
bool m_old_editing_state = false; // To keep track of whether the user toggled between the modes (needed for imgui refreshes).
|
||||||
float m_new_point_head_diameter = 0.4f;
|
float m_new_point_head_diameter = 0.4f; // Size of a new point.
|
||||||
double m_minimal_point_distance = 20.;
|
float m_minimal_point_distance = 20.f;
|
||||||
double m_density = 100.;
|
float m_density = 100.f;
|
||||||
std::vector<std::pair<sla::SupportPoint, bool>> m_editing_mode_cache; // a support point and whether it is currently selected
|
std::vector<std::pair<sla::SupportPoint, bool>> m_editing_mode_cache; // a support point and whether it is currently selected
|
||||||
|
|
||||||
bool m_selection_rectangle_active = false;
|
bool m_selection_rectangle_active = false;
|
||||||
Vec2d m_selection_rectangle_start_corner;
|
Vec2d m_selection_rectangle_start_corner;
|
||||||
Vec2d m_selection_rectangle_end_corner;
|
Vec2d m_selection_rectangle_end_corner;
|
||||||
bool m_ignore_up_event = false;
|
bool m_ignore_up_event = false;
|
||||||
bool m_combo_box_open = false;
|
bool m_combo_box_open = false; // To ensure proper rendering of the imgui combobox.
|
||||||
bool m_unsaved_changes = false;
|
bool m_unsaved_changes = false; // Are there unsaved changes in manual mode?
|
||||||
bool m_selection_empty = true;
|
bool m_selection_empty = true;
|
||||||
EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state)
|
EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state)
|
||||||
int m_canvas_width;
|
int m_canvas_width;
|
||||||
|
Loading…
Reference in New Issue
Block a user