Hollowing config values contain min/max values, these are respected when setting through the gizmo
Rendering and hole transformation fixes (still WIP, though)
This commit is contained in:
parent
7ac0e0a8c9
commit
d0d73e6109
4 changed files with 128 additions and 93 deletions
|
@ -2887,8 +2887,9 @@ void PrintConfigDef::init_sla_params()
|
||||||
def->tooltip = L("Minimum wall thickness of a hollowed model.");
|
def->tooltip = L("Minimum wall thickness of a hollowed model.");
|
||||||
def->sidetext = L("mm");
|
def->sidetext = L("mm");
|
||||||
def->min = 1;
|
def->min = 1;
|
||||||
|
def->max = 10;
|
||||||
def->mode = comSimple;
|
def->mode = comSimple;
|
||||||
def->set_default_value(new ConfigOptionFloat(4));
|
def->set_default_value(new ConfigOptionFloat(3.));
|
||||||
|
|
||||||
def = this->add("hollowing_quality", coFloat);
|
def = this->add("hollowing_quality", coFloat);
|
||||||
def->label = L("Hollowing accuracy");
|
def->label = L("Hollowing accuracy");
|
||||||
|
@ -2904,6 +2905,7 @@ void PrintConfigDef::init_sla_params()
|
||||||
def->category = L("Hollowing");
|
def->category = L("Hollowing");
|
||||||
def->tooltip = L("");
|
def->tooltip = L("");
|
||||||
def->min = 0;
|
def->min = 0;
|
||||||
|
def->max = 10;
|
||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
def->set_default_value(new ConfigOptionFloat(2.0));
|
def->set_default_value(new ConfigOptionFloat(2.0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -443,7 +443,13 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
|
||||||
std::pair<Vec3f, Vec3f> pos_and_normal;
|
std::pair<Vec3f, Vec3f> pos_and_normal;
|
||||||
if (unproject_on_mesh(mouse_position, pos_and_normal)) { // we got an intersection
|
if (unproject_on_mesh(mouse_position, pos_and_normal)) { // we got an intersection
|
||||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Add drainage hole")));
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Add drainage hole")));
|
||||||
m_c->m_model_object->sla_drain_holes.emplace_back(pos_and_normal.first + HoleStickOutLength * pos_and_normal.second,
|
|
||||||
|
Vec3d scaling = m_c->m_model_object->instances[m_c->m_active_instance]->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));
|
||||||
|
|
||||||
|
m_c->m_model_object->sla_drain_holes.emplace_back(pos_and_normal.first + HoleStickOutLength * pos_and_normal.second/* normal_transformed.normalized()*/,
|
||||||
-pos_and_normal.second, m_new_hole_radius, m_new_hole_height+HoleStickOutLength);
|
-pos_and_normal.second, m_new_hole_radius, m_new_hole_height+HoleStickOutLength);
|
||||||
m_selected.push_back(false);
|
m_selected.push_back(false);
|
||||||
assert(m_selected.size() == m_c->m_model_object->sla_drain_holes.size());
|
assert(m_selected.size() == m_c->m_model_object->sla_drain_holes.size());
|
||||||
|
@ -580,10 +586,10 @@ std::pair<const TriangleMesh *, sla::HollowingConfig> GLGizmoHollow::get_hollowi
|
||||||
{
|
{
|
||||||
// FIXME this function is probably obsolete, caller could
|
// FIXME this function is probably obsolete, caller could
|
||||||
// get the data from model config himself
|
// get the data from model config himself
|
||||||
std::vector<const ConfigOption*> opts = get_config_options({"hollowing_min_thickness", "hollowing_quality", "hollowing_closing_distance"});
|
auto opts = get_config_options({"hollowing_min_thickness", "hollowing_quality", "hollowing_closing_distance"});
|
||||||
double offset = static_cast<const ConfigOptionFloat*>(opts[0])->value;
|
double offset = static_cast<const ConfigOptionFloat*>(opts[0].first)->value;
|
||||||
double quality = static_cast<const ConfigOptionFloat*>(opts[1])->value;
|
double quality = static_cast<const ConfigOptionFloat*>(opts[1].first)->value;
|
||||||
double closing_d = static_cast<const ConfigOptionFloat*>(opts[2])->value;
|
double closing_d = static_cast<const ConfigOptionFloat*>(opts[2].first)->value;
|
||||||
return std::make_pair(m_c->m_mesh, sla::HollowingConfig{offset, quality, closing_d});
|
return std::make_pair(m_c->m_mesh, sla::HollowingConfig{offset, quality, closing_d});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,16 +617,19 @@ void GLGizmoHollow::update_hollowed_mesh(std::unique_ptr<TriangleMesh> &&mesh)
|
||||||
if (! m_c->m_model_object->sla_drain_holes.empty()) {
|
if (! m_c->m_model_object->sla_drain_holes.empty()) {
|
||||||
TriangleMesh holes_mesh;
|
TriangleMesh holes_mesh;
|
||||||
for (const sla::DrainHole& hole : m_c->m_model_object->sla_drain_holes) {
|
for (const sla::DrainHole& hole : m_c->m_model_object->sla_drain_holes) {
|
||||||
TriangleMesh hole_mesh = make_cylinder(hole.radius, hole.height, 2*M_PI/8);
|
TriangleMesh hole_mesh = make_cylinder(hole.radius, hole.height, 2*M_PI/32);
|
||||||
|
|
||||||
|
Vec3d scaling = m_c->m_model_object->instances[m_c->m_active_instance]->get_scaling_factor();
|
||||||
|
Vec3d normal_transformed = Vec3d(hole.normal(0)/scaling(0), hole.normal(1)/scaling(1), hole.normal(2)/scaling(2));
|
||||||
|
normal_transformed.normalize();
|
||||||
|
|
||||||
// Rotate the cylinder appropriately
|
// Rotate the cylinder appropriately
|
||||||
Eigen::Quaternionf q;
|
Eigen::Quaterniond q;
|
||||||
Transform3f m = Transform3f::Identity();
|
Transform3d m = Transform3d::Identity();
|
||||||
m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(Vec3f::UnitZ(), hole.normal).toRotationMatrix();
|
m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(Vec3d::UnitZ(), normal_transformed).toRotationMatrix();
|
||||||
hole_mesh.transform(m.cast<double>());
|
hole_mesh.transform(m);
|
||||||
|
|
||||||
// If the instance is scaled, undo the scaling of the hole
|
// If the instance is scaled, undo the scaling of the hole
|
||||||
Vec3d scaling = m_c->m_model_object->instances[m_c->m_active_instance]->get_scaling_factor();
|
|
||||||
hole_mesh.scale(Vec3d(1/scaling(0), 1/scaling(1), 1/scaling(2)));
|
hole_mesh.scale(Vec3d(1/scaling(0), 1/scaling(1), 1/scaling(2)));
|
||||||
|
|
||||||
// Translate the hole into position and merge with the others
|
// Translate the hole into position and merge with the others
|
||||||
|
@ -647,9 +656,9 @@ void GLGizmoHollow::update_hollowed_mesh(std::unique_ptr<TriangleMesh> &&mesh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const ConfigOption*> GLGizmoHollow::get_config_options(const std::vector<std::string>& keys) const
|
std::vector<std::pair<const ConfigOption*, const ConfigOptionDef*>> GLGizmoHollow::get_config_options(const std::vector<std::string>& keys) const
|
||||||
{
|
{
|
||||||
std::vector<const ConfigOption*> out;
|
std::vector<std::pair<const ConfigOption*, const ConfigOptionDef*>> out;
|
||||||
|
|
||||||
if (!m_c->m_model_object)
|
if (!m_c->m_model_object)
|
||||||
return out;
|
return out;
|
||||||
|
@ -660,14 +669,14 @@ std::vector<const ConfigOption*> GLGizmoHollow::get_config_options(const std::ve
|
||||||
|
|
||||||
for (const std::string& key : keys) {
|
for (const std::string& key : keys) {
|
||||||
if (object_cfg.has(key))
|
if (object_cfg.has(key))
|
||||||
out.push_back(object_cfg.option(key));
|
out.emplace_back(object_cfg.option(key), &object_cfg.def()->options.at(key)); // at() needed for const map
|
||||||
else
|
else
|
||||||
if (print_cfg.has(key))
|
if (print_cfg.has(key))
|
||||||
out.push_back(print_cfg.option(key));
|
out.emplace_back(print_cfg.option(key), &print_cfg.def()->options.at(key));
|
||||||
else { // we must get it from defaults
|
else { // we must get it from defaults
|
||||||
if (default_cfg == nullptr)
|
if (default_cfg == nullptr)
|
||||||
default_cfg.reset(DynamicPrintConfig::new_from_defaults_keys(keys));
|
default_cfg.reset(DynamicPrintConfig::new_from_defaults_keys(keys));
|
||||||
out.push_back(default_cfg->option(key));
|
out.emplace_back(default_cfg->option(key), &default_cfg->def()->options.at(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,8 +723,8 @@ RENDER_AGAIN:
|
||||||
window_width = std::max(std::max(window_width, /*buttons_width_approx*/0.f), 0.f);
|
window_width = std::max(std::max(window_width, /*buttons_width_approx*/0.f), 0.f);
|
||||||
|
|
||||||
{
|
{
|
||||||
std::vector<const ConfigOption*> opts = get_config_options({"hollowing_enable"});
|
auto opts = get_config_options({"hollowing_enable"});
|
||||||
m_enable_hollowing = static_cast<const ConfigOptionBool*>(opts[0])->value;
|
m_enable_hollowing = static_cast<const ConfigOptionBool*>(opts[0].first)->value;
|
||||||
if (m_imgui->checkbox(m_desc["enable"], m_enable_hollowing)) {
|
if (m_imgui->checkbox(m_desc["enable"], m_enable_hollowing)) {
|
||||||
m_c->m_model_object->config.opt<ConfigOptionBool>("hollowing_enable", true)->value = m_enable_hollowing;
|
m_c->m_model_object->config.opt<ConfigOptionBool>("hollowing_enable", true)->value = m_enable_hollowing;
|
||||||
wxGetApp().obj_list()->update_and_show_object_settings_item();
|
wxGetApp().obj_list()->update_and_show_object_settings_item();
|
||||||
|
@ -727,29 +736,57 @@ RENDER_AGAIN:
|
||||||
if (m_imgui->button(m_desc["preview"]))
|
if (m_imgui->button(m_desc["preview"]))
|
||||||
hollow_mesh();
|
hollow_mesh();
|
||||||
|
|
||||||
std::vector<const ConfigOption*> opts = get_config_options({"hollowing_min_thickness", "hollowing_quality", "hollowing_closing_distance"});
|
std::vector<std::string> opts_keys = {"hollowing_min_thickness", "hollowing_quality", "hollowing_closing_distance"};
|
||||||
float offset = static_cast<const ConfigOptionFloat*>(opts[0])->value;
|
auto opts = get_config_options(opts_keys);
|
||||||
float quality = static_cast<const ConfigOptionFloat*>(opts[1])->value;
|
auto* offset_cfg = static_cast<const ConfigOptionFloat*>(opts[0].first);
|
||||||
float closing_d = static_cast<const ConfigOptionFloat*>(opts[2])->value;
|
float offset = offset_cfg->value;
|
||||||
|
double offset_min = opts[0].second->min;
|
||||||
|
double offset_max = opts[0].second->max;
|
||||||
|
|
||||||
|
auto* quality_cfg = static_cast<const ConfigOptionFloat*>(opts[1].first);
|
||||||
|
float quality = quality_cfg->value;
|
||||||
|
double quality_min = opts[1].second->min;
|
||||||
|
double quality_max = opts[1].second->max;
|
||||||
|
|
||||||
|
auto* closing_d_cfg = static_cast<const ConfigOptionFloat*>(opts[2].first);
|
||||||
|
float closing_d = closing_d_cfg->value;
|
||||||
|
double closing_d_min = opts[2].second->min;
|
||||||
|
double closing_d_max = opts[2].second->max;
|
||||||
|
|
||||||
|
|
||||||
m_imgui->text(m_desc.at("offset"));
|
m_imgui->text(m_desc.at("offset"));
|
||||||
ImGui::SameLine(settings_sliders_left);
|
ImGui::SameLine(settings_sliders_left);
|
||||||
ImGui::PushItemWidth(window_width - settings_sliders_left);
|
ImGui::PushItemWidth(window_width - settings_sliders_left);
|
||||||
ImGui::SliderFloat(" ", &offset, 0.f, 5.f, "%.1f");
|
ImGui::SliderFloat(" ", &offset, offset_min, offset_max, "%.1f");
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::TextUnformatted(_(opts[0].second->tooltip).ToUTF8());
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
bool slider_clicked = ImGui::IsItemClicked(); // someone clicked the slider
|
bool slider_clicked = ImGui::IsItemClicked(); // someone clicked the slider
|
||||||
bool slider_edited = ImGui::IsItemEdited(); // someone is dragging the slider
|
bool slider_edited = ImGui::IsItemEdited(); // someone is dragging the slider
|
||||||
bool slider_released = ImGui::IsItemDeactivatedAfterEdit(); // someone has just released the slider
|
bool slider_released = ImGui::IsItemDeactivatedAfterEdit(); // someone has just released the slider
|
||||||
|
|
||||||
m_imgui->text(m_desc.at("quality"));
|
m_imgui->text(m_desc.at("quality"));
|
||||||
ImGui::SameLine(settings_sliders_left);
|
ImGui::SameLine(settings_sliders_left);
|
||||||
ImGui::SliderFloat(" ", &quality, 0.f, 1.f, "%.1f");
|
ImGui::SliderFloat(" ", &quality, quality_min, quality_max, "%.1f");
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::TextUnformatted(_(opts[1].second->tooltip).ToUTF8());
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
slider_clicked |= ImGui::IsItemClicked();
|
slider_clicked |= ImGui::IsItemClicked();
|
||||||
slider_edited |= ImGui::IsItemEdited();
|
slider_edited |= ImGui::IsItemEdited();
|
||||||
slider_released |= ImGui::IsItemDeactivatedAfterEdit();
|
slider_released |= ImGui::IsItemDeactivatedAfterEdit();
|
||||||
|
|
||||||
m_imgui->text(m_desc.at("closing_distance"));
|
m_imgui->text(m_desc.at("closing_distance"));
|
||||||
ImGui::SameLine(settings_sliders_left);
|
ImGui::SameLine(settings_sliders_left);
|
||||||
ImGui::SliderFloat(" ", &closing_d, 0.f, 10.f, "%.1f");
|
ImGui::SliderFloat(" ", &closing_d, closing_d_min, closing_d_max, "%.1f");
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::TextUnformatted(_(opts[2].second->tooltip).ToUTF8());
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
slider_clicked |= ImGui::IsItemClicked();
|
slider_clicked |= ImGui::IsItemClicked();
|
||||||
slider_edited |= ImGui::IsItemEdited();
|
slider_edited |= ImGui::IsItemEdited();
|
||||||
slider_released |= ImGui::IsItemDeactivatedAfterEdit();
|
slider_released |= ImGui::IsItemDeactivatedAfterEdit();
|
||||||
|
@ -955,8 +992,8 @@ void GLGizmoHollow::on_set_state()
|
||||||
m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance);
|
m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance);
|
||||||
|
|
||||||
// Set default head diameter from config.
|
// Set default head diameter from config.
|
||||||
const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
|
//const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
|
||||||
m_new_hole_radius = static_cast<const ConfigOptionFloat*>(cfg.option("support_head_front_diameter"))->value;
|
//m_new_hole_radius = static_cast<const ConfigOptionFloat*>(cfg.option("support_head_front_diameter"))->value;
|
||||||
}
|
}
|
||||||
if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
|
if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
|
||||||
//Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned off")));
|
//Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned off")));
|
||||||
|
|
|
@ -21,10 +21,6 @@ enum class SLAGizmoEventType : unsigned char;
|
||||||
class GLGizmoHollow : public GLGizmoBase
|
class GLGizmoHollow : public GLGizmoBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
//ModelObject* m_model_object = nullptr;
|
|
||||||
//ObjectID m_model_object_id = 0;
|
|
||||||
//int m_active_instance = -1;
|
|
||||||
//float m_active_instance_bb_radius; // to cache the bb
|
|
||||||
mutable double m_z_shift = 0.;
|
mutable double m_z_shift = 0.;
|
||||||
bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
|
bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
|
||||||
|
|
||||||
|
@ -32,13 +28,6 @@ private:
|
||||||
|
|
||||||
GLUquadricObj* m_quadric;
|
GLUquadricObj* m_quadric;
|
||||||
|
|
||||||
//std::unique_ptr<MeshRaycaster> m_mesh_raycaster;
|
|
||||||
//std::unique_ptr<TriangleMesh> m_cavity_mesh;
|
|
||||||
//std::unique_ptr<GLVolume> m_volume_with_cavity;
|
|
||||||
//const TriangleMesh* m_mesh;
|
|
||||||
//mutable int m_old_timestamp = -1;
|
|
||||||
//mutable int m_print_object_idx = -1;
|
|
||||||
//mutable int m_print_objects_count = -1;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id, CommonGizmosData* cd);
|
GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id, CommonGizmosData* cd);
|
||||||
|
@ -69,7 +58,7 @@ private:
|
||||||
bool unsaved_changes() const;
|
bool unsaved_changes() const;
|
||||||
|
|
||||||
bool m_show_supports = true;
|
bool m_show_supports = true;
|
||||||
float m_new_hole_radius; // Size of a new hole.
|
float m_new_hole_radius = 4.f; // Size of a new hole.
|
||||||
float m_new_hole_height = 5.f;
|
float m_new_hole_height = 5.f;
|
||||||
mutable std::vector<bool> m_selected; // which holes are currently selected
|
mutable std::vector<bool> m_selected; // which holes are currently selected
|
||||||
|
|
||||||
|
@ -77,7 +66,7 @@ private:
|
||||||
|
|
||||||
// Stashes to keep data for undo redo. Is taken after the editing
|
// Stashes to keep data for undo redo. Is taken after the editing
|
||||||
// is done, the data are updated continuously.
|
// is done, the data are updated continuously.
|
||||||
float m_offset_stash = 2.0f;
|
float m_offset_stash = 3.0f;
|
||||||
float m_quality_stash = 0.5f;
|
float m_quality_stash = 0.5f;
|
||||||
float m_closing_d_stash = 2.f;
|
float m_closing_d_stash = 2.f;
|
||||||
Vec3f m_hole_before_drag = Vec3f::Zero();
|
Vec3f m_hole_before_drag = Vec3f::Zero();
|
||||||
|
@ -100,10 +89,7 @@ private:
|
||||||
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)
|
||||||
|
|
||||||
//mutable std::unique_ptr<MeshClipper> m_object_clipper;
|
std::vector<std::pair<const ConfigOption*, const ConfigOptionDef*>> get_config_options(const std::vector<std::string>& keys) const;
|
||||||
//mutable std::unique_ptr<MeshClipper> m_supports_clipper;
|
|
||||||
|
|
||||||
std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const;
|
|
||||||
bool is_mesh_point_clipped(const Vec3d& point) const;
|
bool is_mesh_point_clipped(const Vec3d& point) const;
|
||||||
|
|
||||||
// Methods that do the model_object and editing cache synchronization,
|
// Methods that do the model_object and editing cache synchronization,
|
||||||
|
|
|
@ -68,19 +68,31 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_c->m_model_object != model_object || m_c->m_model_object_id != model_object->id()) {
|
bool something_changed = false;
|
||||||
|
|
||||||
|
if (m_c->m_model_object != model_object
|
||||||
|
|| m_c->m_model_object_id != model_object->id()
|
||||||
|
|| m_c->m_active_instance != selection.get_instance_idx()) {
|
||||||
m_c->m_model_object = model_object;
|
m_c->m_model_object = model_object;
|
||||||
m_c->m_print_object_idx = -1;
|
m_c->m_print_object_idx = -1;
|
||||||
|
m_c->m_active_instance = selection.get_instance_idx();
|
||||||
|
something_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_c->m_active_instance = selection.get_instance_idx();
|
|
||||||
|
|
||||||
if (model_object && selection.is_from_single_instance())
|
if (model_object && selection.is_from_single_instance())
|
||||||
{
|
{
|
||||||
// Cache the bb - it's needed for dealing with the clipping plane quite often
|
// Cache the bb - it's needed for dealing with the clipping plane quite often
|
||||||
// It could be done inside update_mesh but one has to account for scaling of the instance.
|
// It could be done inside update_mesh but one has to account for scaling of the instance.
|
||||||
//FIXME calling ModelObject::instance_bounding_box() is expensive!
|
if (something_changed) {
|
||||||
m_c->m_active_instance_bb_radius = m_c->m_model_object->instance_bounding_box(m_c->m_active_instance).radius();
|
m_c->m_active_instance_bb_radius = m_c->m_model_object->instance_bounding_box(m_c->m_active_instance).radius();
|
||||||
|
if (m_state == On) {
|
||||||
|
m_parent.toggle_model_objects_visibility(false);
|
||||||
|
m_parent.toggle_model_objects_visibility(! m_c->m_cavity_mesh, m_c->m_model_object, m_c->m_active_instance);
|
||||||
|
m_parent.toggle_sla_auxiliaries_visibility(bool(m_c->m_cavity_mesh), m_c->m_model_object, m_c->m_active_instance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_parent.toggle_model_objects_visibility(true, nullptr, -1);
|
||||||
|
}
|
||||||
|
|
||||||
if (is_mesh_update_necessary()) {
|
if (is_mesh_update_necessary()) {
|
||||||
update_mesh();
|
update_mesh();
|
||||||
|
@ -90,14 +102,6 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S
|
||||||
// If we triggered autogeneration before, check backend and fetch results if they are there
|
// If we triggered autogeneration before, check backend and fetch results if they are there
|
||||||
if (m_c->m_model_object->sla_points_status == sla::PointsStatus::Generating)
|
if (m_c->m_model_object->sla_points_status == sla::PointsStatus::Generating)
|
||||||
get_data_from_backend();
|
get_data_from_backend();
|
||||||
|
|
||||||
if (m_state == On) {
|
|
||||||
m_parent.toggle_model_objects_visibility(false);
|
|
||||||
m_parent.toggle_model_objects_visibility(! m_c->m_cavity_mesh, m_c->m_model_object, m_c->m_active_instance);
|
|
||||||
m_parent.toggle_sla_auxiliaries_visibility(bool(m_c->m_cavity_mesh), m_c->m_model_object, m_c->m_active_instance);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_parent.toggle_model_objects_visibility(true, nullptr, -1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,41 +354,42 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now render the drain holes:
|
// Now render the drain holes:
|
||||||
// render_color[0] = 0.7f;
|
if (! m_c->m_cavity_mesh) {
|
||||||
// render_color[1] = 0.7f;
|
render_color[0] = 0.7f;
|
||||||
// render_color[2] = 0.7f;
|
render_color[1] = 0.7f;
|
||||||
// render_color[3] = 0.7f;
|
render_color[2] = 0.7f;
|
||||||
// glsafe(::glColor4fv(render_color));
|
render_color[3] = 0.7f;
|
||||||
// for (const sla::DrainHole& drain_hole : m_c->m_model_object->sla_drain_holes) {
|
glsafe(::glColor4fv(render_color));
|
||||||
// // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
|
for (const sla::DrainHole& drain_hole : m_c->m_model_object->sla_drain_holes) {
|
||||||
// glsafe(::glPushMatrix());
|
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
|
||||||
// glsafe(::glTranslatef(drain_hole.pos(0), drain_hole.pos(1), drain_hole.pos(2)));
|
glsafe(::glPushMatrix());
|
||||||
// glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data()));
|
glsafe(::glTranslatef(drain_hole.pos(0), drain_hole.pos(1), drain_hole.pos(2)));
|
||||||
|
glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data()));
|
||||||
|
|
||||||
// if (vol->is_left_handed())
|
if (vol->is_left_handed())
|
||||||
// glFrontFace(GL_CW);
|
glFrontFace(GL_CW);
|
||||||
|
|
||||||
// // Matrices set, we can render the point mark now.
|
// Matrices set, we can render the point mark now.
|
||||||
|
|
||||||
// Eigen::Quaterniond q;
|
Eigen::Quaterniond q;
|
||||||
// q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * (-drain_hole.normal).cast<double>());
|
q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * (-drain_hole.normal).cast<double>());
|
||||||
// Eigen::AngleAxisd aa(q);
|
Eigen::AngleAxisd aa(q);
|
||||||
// glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2)));
|
glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2)));
|
||||||
// glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
// glsafe(::glTranslated(0., 0., -drain_hole.height));
|
glsafe(::glTranslated(0., 0., -drain_hole.height));
|
||||||
// ::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height, 24, 1);
|
::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height, 24, 1);
|
||||||
// glsafe(::glTranslated(0., 0., drain_hole.height));
|
glsafe(::glTranslated(0., 0., drain_hole.height));
|
||||||
// ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1);
|
::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1);
|
||||||
// glsafe(::glTranslated(0., 0., -drain_hole.height));
|
glsafe(::glTranslated(0., 0., -drain_hole.height));
|
||||||
// glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f));
|
glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f));
|
||||||
// ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1);
|
::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1);
|
||||||
// glsafe(::glPopMatrix());
|
glsafe(::glPopMatrix());
|
||||||
|
|
||||||
// if (vol->is_left_handed())
|
if (vol->is_left_handed())
|
||||||
// glFrontFace(GL_CCW);
|
glFrontFace(GL_CCW);
|
||||||
// glsafe(::glPopMatrix());
|
glsafe(::glPopMatrix());
|
||||||
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
if (!picking)
|
if (!picking)
|
||||||
glsafe(::glDisable(GL_LIGHTING));
|
glsafe(::glDisable(GL_LIGHTING));
|
||||||
|
@ -454,10 +459,15 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec
|
||||||
if (m_c->m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_clipping_plane.get())) {
|
if (m_c->m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_clipping_plane.get())) {
|
||||||
// Check whether the hit is in a hole
|
// Check whether the hit is in a hole
|
||||||
bool in_hole = false;
|
bool in_hole = false;
|
||||||
for (const sla::DrainHole& hole : m_c->m_model_object->sla_drain_holes) {
|
// In case the hollowed and drilled mesh is available, we can allow
|
||||||
if (hole.is_inside(hit)) {
|
// placing points in holes, because they should never end up
|
||||||
in_hole = true;
|
// on surface that's been drilled away.
|
||||||
break;
|
if (! m_c->m_cavity_mesh) {
|
||||||
|
for (const sla::DrainHole& hole : m_c->m_model_object->sla_drain_holes) {
|
||||||
|
if (hole.is_inside(hit)) {
|
||||||
|
in_hole = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! in_hole) {
|
if (! in_hole) {
|
||||||
|
|
Loading…
Reference in a new issue