ENH: improve meshboolean gizmo user experience
jira: STUDIO-7401 1.support select meshboolean target from object list 2.other improvements Change-Id: I81cc914e412e622871930974ac65be9fd8bc36e1
This commit is contained in:
parent
16adcdd355
commit
f81a9d97c8
|
@ -38,6 +38,7 @@
|
||||||
#include <wx/renderer.h>
|
#include <wx/renderer.h>
|
||||||
#endif /* __WXMSW__ */
|
#endif /* __WXMSW__ */
|
||||||
#include "Gizmos/GLGizmoScale.hpp"
|
#include "Gizmos/GLGizmoScale.hpp"
|
||||||
|
#include "Gizmos/GLGizmoMeshBoolean.hpp"
|
||||||
|
|
||||||
namespace Slic3r
|
namespace Slic3r
|
||||||
{
|
{
|
||||||
|
@ -3391,8 +3392,17 @@ void ObjectList::part_selection_changed()
|
||||||
m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config;
|
m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config;
|
||||||
update_and_show_settings = true;
|
update_and_show_settings = true;
|
||||||
|
|
||||||
const ModelVolume *volume = (*m_objects)[obj_idx]->volumes[volume_id];
|
ModelVolume *volume = (*m_objects)[obj_idx]->volumes[volume_id];
|
||||||
enable_manipulation = !((*m_objects)[obj_idx]->is_cut() && (volume->is_cut_connector() || volume->is_model_part()));
|
enable_manipulation = !((*m_objects)[obj_idx]->is_cut() && (volume->is_cut_connector() || volume->is_model_part()));
|
||||||
|
|
||||||
|
GLGizmosManager& gizmos_mgr = wxGetApp().plater()->canvas3D()->get_gizmos_manager();
|
||||||
|
if (gizmos_mgr.get_current_type() == GLGizmosManager::EType::MeshBoolean) {
|
||||||
|
GLGizmoMeshBoolean* mesh_boolean = static_cast<GLGizmoMeshBoolean*>(gizmos_mgr.get_gizmo(GLGizmosManager::MeshBoolean));
|
||||||
|
if (mesh_boolean->get_selecting_state() == MeshBooleanSelectingState::SelectSource)
|
||||||
|
mesh_boolean->set_src_volume(volume);
|
||||||
|
else if (mesh_boolean->get_selecting_state() == MeshBooleanSelectingState::SelectTool)
|
||||||
|
mesh_boolean->set_tool_volume(volume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (type & itInstance) {
|
else if (type & itInstance) {
|
||||||
og_name = _L("Instance manipulation");
|
og_name = _L("Instance manipulation");
|
||||||
|
|
|
@ -26,6 +26,38 @@ GLGizmoMeshBoolean::~GLGizmoMeshBoolean()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoMeshBoolean::set_src_volume(ModelVolume* mv)
|
||||||
|
{
|
||||||
|
m_src.mv = mv;
|
||||||
|
m_src.trafo = mv->get_matrix();
|
||||||
|
m_src.volume_idx = -1;
|
||||||
|
const auto& volumes = mv->get_object()->volumes;
|
||||||
|
auto it = std::find(volumes.begin(), volumes.end(), mv);
|
||||||
|
assert(it != volumes.end());
|
||||||
|
if (it != volumes.end())
|
||||||
|
m_src.volume_idx = std::distance(volumes.begin(), it);
|
||||||
|
|
||||||
|
if (m_src.mv == m_tool.mv)
|
||||||
|
m_tool.reset();
|
||||||
|
|
||||||
|
m_selecting_state = MeshBooleanSelectingState::SelectTool;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoMeshBoolean::set_tool_volume(ModelVolume* mv)
|
||||||
|
{
|
||||||
|
if (mv == m_src.mv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_tool.mv = mv;
|
||||||
|
m_tool.trafo = mv->get_matrix();
|
||||||
|
m_tool.volume_idx = -1;
|
||||||
|
const auto& volumes = mv->get_object()->volumes;
|
||||||
|
auto it = std::find(volumes.begin(), volumes.end(), mv);
|
||||||
|
assert(it != volumes.end());
|
||||||
|
if (it != volumes.end())
|
||||||
|
m_tool.volume_idx = std::distance(volumes.begin(), it);
|
||||||
|
}
|
||||||
|
|
||||||
bool GLGizmoMeshBoolean::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down)
|
bool GLGizmoMeshBoolean::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down)
|
||||||
{
|
{
|
||||||
if (action == SLAGizmoEventType::LeftDown) {
|
if (action == SLAGizmoEventType::LeftDown) {
|
||||||
|
@ -69,16 +101,11 @@ bool GLGizmoMeshBoolean::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (get_selecting_state() == MeshBooleanSelectingState::SelectTool) {
|
if (get_selecting_state() == MeshBooleanSelectingState::SelectTool) {
|
||||||
m_tool.trafo = mo->volumes[closest_hit_mesh_id]->get_matrix();
|
|
||||||
m_tool.volume_idx = closest_hit_mesh_id;
|
|
||||||
set_tool_volume(mo->volumes[closest_hit_mesh_id]);
|
set_tool_volume(mo->volumes[closest_hit_mesh_id]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (get_selecting_state() == MeshBooleanSelectingState::SelectSource) {
|
if (get_selecting_state() == MeshBooleanSelectingState::SelectSource) {
|
||||||
m_src.trafo = mo->volumes[closest_hit_mesh_id]->get_matrix();
|
|
||||||
m_src.volume_idx = closest_hit_mesh_id;
|
|
||||||
set_src_volume(mo->volumes[closest_hit_mesh_id]);
|
set_src_volume(mo->volumes[closest_hit_mesh_id]);
|
||||||
m_selecting_state = MeshBooleanSelectingState::SelectTool;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,10 +121,11 @@ bool GLGizmoMeshBoolean::on_init()
|
||||||
std::string GLGizmoMeshBoolean::on_get_name() const
|
std::string GLGizmoMeshBoolean::on_get_name() const
|
||||||
{
|
{
|
||||||
if (!on_is_activable() && m_state == EState::Off) {
|
if (!on_is_activable() && m_state == EState::Off) {
|
||||||
|
if (m_parent.get_selection().get_volume_idxs().size() <= 1) {
|
||||||
|
return _u8L("Mesh Boolean") + ":\n" + _u8L("Please add at least one more object and select them together,\nthen right click to assembly these objects.");
|
||||||
|
}
|
||||||
if (!m_parent.get_selection().is_single_full_instance()) {
|
if (!m_parent.get_selection().is_single_full_instance()) {
|
||||||
return _u8L("Mesh Boolean") + ":\n" + _u8L("Please right click to assembly these objects.");
|
return _u8L("Mesh Boolean") + ":\n" + _u8L("Please right click to assembly these objects.");
|
||||||
} else if (m_parent.get_selection().get_volume_idxs().size() <= 1){
|
|
||||||
return _u8L("Mesh Boolean") + ":\n" + _u8L("Please add at least one more object and select them together,\nthen right click to assembly these objects.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _u8L("Mesh Boolean");
|
return _u8L("Mesh Boolean");
|
||||||
|
@ -105,7 +133,14 @@ std::string GLGizmoMeshBoolean::on_get_name() const
|
||||||
|
|
||||||
bool GLGizmoMeshBoolean::on_is_activable() const
|
bool GLGizmoMeshBoolean::on_is_activable() const
|
||||||
{
|
{
|
||||||
return m_parent.get_selection().is_single_full_instance() && m_parent.get_selection().get_volume_idxs().size() > 1;
|
auto& selection = m_parent.get_selection();
|
||||||
|
|
||||||
|
auto obj_idx = selection.get_object_idx();
|
||||||
|
int volumes_size = 0;
|
||||||
|
if (obj_idx != -1)
|
||||||
|
volumes_size = selection.get_volume_idxs_from_object(obj_idx).size();
|
||||||
|
|
||||||
|
return !selection.is_empty() && !selection.is_multiple_full_object() && volumes_size > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoMeshBoolean::on_render()
|
void GLGizmoMeshBoolean::on_render()
|
||||||
|
@ -128,8 +163,11 @@ void GLGizmoMeshBoolean::on_render()
|
||||||
const ModelObject* mo = m_c->selection_info()->model_object();
|
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||||
const ModelInstance* mi = mo->instances[m_parent.get_selection().get_instance_idx()];
|
const ModelInstance* mi = mo->instances[m_parent.get_selection().get_instance_idx()];
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
const Selection::IndicesList& idxs = selection.get_volume_idxs();
|
auto obj_idx = selection.get_object_idx();
|
||||||
for (unsigned int i : idxs) {
|
std::vector<unsigned int> volume_ids;
|
||||||
|
if (obj_idx != -1)
|
||||||
|
volume_ids = selection.get_volume_idxs_from_object(obj_idx);
|
||||||
|
for (unsigned int i : volume_ids) {
|
||||||
const GLVolume* volume = selection.get_volume(i);
|
const GLVolume* volume = selection.get_volume(i);
|
||||||
if(volume->volume_idx() == m_src.volume_idx) {
|
if(volume->volume_idx() == m_src.volume_idx) {
|
||||||
src_bb = volume->transformed_convex_hull_bounding_box();
|
src_bb = volume->transformed_convex_hull_bounding_box();
|
||||||
|
@ -287,6 +325,7 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l
|
||||||
if (ImGui::Button((into_u8(ImGui::TextSearchCloseIcon) + "##src").c_str(), {18, 18}))
|
if (ImGui::Button((into_u8(ImGui::TextSearchCloseIcon) + "##src").c_str(), {18, 18}))
|
||||||
{
|
{
|
||||||
m_src.reset();
|
m_src.reset();
|
||||||
|
m_selecting_state = MeshBooleanSelectingState::SelectSource;
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor(5);
|
ImGui::PopStyleColor(5);
|
||||||
}
|
}
|
||||||
|
@ -315,6 +354,7 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l
|
||||||
if (ImGui::Button((into_u8(ImGui::TextSearchCloseIcon) + "tool").c_str(), {18, 18}))
|
if (ImGui::Button((into_u8(ImGui::TextSearchCloseIcon) + "tool").c_str(), {18, 18}))
|
||||||
{
|
{
|
||||||
m_tool.reset();
|
m_tool.reset();
|
||||||
|
m_selecting_state = (m_src.mv == nullptr) ? MeshBooleanSelectingState::SelectSource : MeshBooleanSelectingState::SelectTool;
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor(5);
|
ImGui::PopStyleColor(5);
|
||||||
}
|
}
|
||||||
|
@ -337,6 +377,9 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l
|
||||||
else {
|
else {
|
||||||
m_warning_texts[index] = warning_text_common;
|
m_warning_texts[index] = warning_text_common;
|
||||||
}
|
}
|
||||||
|
m_selecting_state = MeshBooleanSelectingState::SelectSource;
|
||||||
|
m_src.reset();
|
||||||
|
m_tool.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_operation_mode == MeshBooleanOperation::Difference) {
|
else if (m_operation_mode == MeshBooleanOperation::Difference) {
|
||||||
|
@ -355,6 +398,9 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l
|
||||||
else {
|
else {
|
||||||
m_warning_texts[index] = warning_text_common;
|
m_warning_texts[index] = warning_text_common;
|
||||||
}
|
}
|
||||||
|
m_selecting_state = MeshBooleanSelectingState::SelectSource;
|
||||||
|
m_src.reset();
|
||||||
|
m_tool.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_operation_mode == MeshBooleanOperation::Intersection){
|
else if (m_operation_mode == MeshBooleanOperation::Intersection){
|
||||||
|
@ -373,8 +419,10 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l
|
||||||
else {
|
else {
|
||||||
m_warning_texts[index] = warning_text_intersection;
|
m_warning_texts[index] = warning_text_intersection;
|
||||||
}
|
}
|
||||||
|
m_selecting_state = MeshBooleanSelectingState::SelectSource;
|
||||||
|
m_src.reset();
|
||||||
|
m_tool.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (index >= 0 && index < m_warning_texts.size()) {
|
if (index >= 0 && index < m_warning_texts.size()) {
|
||||||
render_input_window_warning(m_warning_texts[index]);
|
render_input_window_warning(m_warning_texts[index]);
|
||||||
|
@ -426,20 +474,7 @@ void GLGizmoMeshBoolean::generate_new_volume(bool delete_input, const TriangleMe
|
||||||
|
|
||||||
// assign to new_volume from old_volume
|
// assign to new_volume from old_volume
|
||||||
ModelVolume* old_volume = m_src.mv;
|
ModelVolume* old_volume = m_src.mv;
|
||||||
std::string suffix;
|
new_volume->name = old_volume->name;
|
||||||
switch (m_operation_mode)
|
|
||||||
{
|
|
||||||
case MeshBooleanOperation::Union:
|
|
||||||
suffix = "union";
|
|
||||||
break;
|
|
||||||
case MeshBooleanOperation::Difference:
|
|
||||||
suffix = "difference";
|
|
||||||
break;
|
|
||||||
case MeshBooleanOperation::Intersection:
|
|
||||||
suffix = "intersection";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
new_volume->name = old_volume->name + " - " + suffix;
|
|
||||||
new_volume->set_new_unique_id();
|
new_volume->set_new_unique_id();
|
||||||
new_volume->config.apply(old_volume->config);
|
new_volume->config.apply(old_volume->config);
|
||||||
new_volume->set_type(old_volume->type());
|
new_volume->set_type(old_volume->type());
|
||||||
|
|
|
@ -42,18 +42,10 @@ public:
|
||||||
~GLGizmoMeshBoolean();
|
~GLGizmoMeshBoolean();
|
||||||
|
|
||||||
void set_enable(bool enable) { m_enable = enable; }
|
void set_enable(bool enable) { m_enable = enable; }
|
||||||
bool get_enable() { return m_enable; }
|
bool get_enable() const { return m_enable; }
|
||||||
MeshBooleanSelectingState get_selecting_state() { return m_selecting_state; }
|
MeshBooleanSelectingState get_selecting_state() const { return m_selecting_state; }
|
||||||
void set_src_volume(ModelVolume* mv) {
|
void set_src_volume(ModelVolume* mv);
|
||||||
m_src.mv = mv;
|
void set_tool_volume(ModelVolume* mv);
|
||||||
if (m_src.mv == m_tool.mv)
|
|
||||||
m_tool.reset();
|
|
||||||
}
|
|
||||||
void set_tool_volume(ModelVolume* mv) {
|
|
||||||
m_tool.mv = mv;
|
|
||||||
if (m_tool.mv == m_src.mv)
|
|
||||||
m_src.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
|
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue