mirror of
https://git.mirrors.martin98.com/https://github.com/bambulab/BambuStudio.git
synced 2025-08-05 18:10:39 +08:00
NEW:split measure function to measure and assembly function
Jira: none Change-Id: Id88ed94251ee51b64e7a1574862b269a2ff6358b
This commit is contained in:
parent
0f0748a2ed
commit
0db285a2f7
7
resources/images/toolbar_assembly.svg
Normal file
7
resources/images/toolbar_assembly.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="7.80615" y="25.5195" width="29" height="9.19336" stroke="#00AE42"/>
|
||||
<rect x="19.1368" y="5.45404" width="15" height="6.00417" transform="rotate(25.5934 19.1368 5.45404)" stroke="#262E30"/>
|
||||
<rect x="14.8062" y="18.5156" width="15" height="6.00417" stroke="#00AE42" stroke-dasharray="1 1"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.4877 17.5905C13.5899 17.4883 13.5432 17.3137 13.4035 17.2762L4.93754 15.0078C4.79787 14.9704 4.67006 15.0982 4.70749 15.2378L6.97593 23.7038C7.01336 23.8435 7.18794 23.8902 7.29019 23.788L13.4877 17.5905ZM7.54629 22.2037L11.9034 17.8466L5.95148 16.2518L7.54629 22.2037Z" fill="#262E30"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.22678 16.0611C9.70526 15.1933 10.3436 14.4213 11.1102 13.787C11.8768 13.1526 12.7546 12.6699 13.6966 12.3623C13.7768 12.3361 13.8575 12.3112 13.9386 12.2875C13.9519 12.2837 13.9648 12.2792 13.9775 12.2743C14.1795 12.1952 14.3022 11.9815 14.252 11.767C14.1986 11.539 13.9701 11.3964 13.745 11.4608C13.7304 11.4649 13.7158 11.4692 13.7013 11.4734C13.609 11.5003 13.5172 11.5287 13.426 11.5586C12.3857 11.8993 11.4164 12.4329 10.5696 13.1336C9.72279 13.8344 9.01727 14.6868 8.4879 15.6449C8.44147 15.7289 8.3964 15.8138 8.35271 15.8994C8.34582 15.9129 8.33897 15.9264 8.33215 15.94C8.22679 16.1491 8.3241 16.4002 8.53808 16.4953C8.73944 16.5848 8.97228 16.5042 9.08775 16.3206C9.09499 16.3091 9.10177 16.2972 9.10806 16.2848C9.14646 16.2096 9.18604 16.135 9.22678 16.0611Z" fill="#262E30"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
7
resources/images/toolbar_assembly_dark.svg
Normal file
7
resources/images/toolbar_assembly_dark.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="7.80615" y="25.5195" width="29" height="9.19336" stroke="#262E30"/>
|
||||
<rect x="19.1368" y="5.45404" width="15" height="6.00417" transform="rotate(25.5934 19.1368 5.45404)" stroke="#262E30"/>
|
||||
<rect x="14.8062" y="18.5156" width="15" height="6.00417" stroke="#262E30" stroke-dasharray="1 1"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.4877 17.5905C13.5899 17.4883 13.5432 17.3137 13.4035 17.2762L4.93754 15.0078C4.79787 14.9704 4.67006 15.0982 4.70749 15.2378L6.97593 23.7038C7.01336 23.8435 7.18794 23.8902 7.29019 23.788L13.4877 17.5905ZM7.54629 22.2037L11.9034 17.8466L5.95148 16.2518L7.54629 22.2037Z" fill="#262E30"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.22678 16.0611C9.70526 15.1933 10.3436 14.4213 11.1102 13.787C11.8768 13.1526 12.7546 12.6699 13.6966 12.3623C13.7768 12.3361 13.8575 12.3112 13.9386 12.2875C13.9519 12.2837 13.9648 12.2792 13.9775 12.2743C14.1795 12.1952 14.3022 11.9815 14.252 11.767C14.1986 11.539 13.9701 11.3964 13.745 11.4608C13.7304 11.4649 13.7158 11.4692 13.7013 11.4734C13.609 11.5003 13.5172 11.5287 13.426 11.5586C12.3857 11.8993 11.4164 12.4329 10.5696 13.1336C9.72279 13.8344 9.01727 14.6868 8.4879 15.6449C8.44147 15.7289 8.3964 15.8138 8.35271 15.8994C8.34582 15.9129 8.33897 15.9264 8.33215 15.94C8.22679 16.1491 8.3241 16.4002 8.53808 16.4953C8.73944 16.5848 8.97228 16.5042 9.08775 16.3206C9.09499 16.3091 9.10177 16.2972 9.10806 16.2848C9.14646 16.2096 9.18604 16.135 9.22678 16.0611Z" fill="#262E30"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -139,6 +139,8 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/Gizmos/GLGizmoFaceDetector.hpp
|
||||
GUI/Gizmos/GLGizmoMeasure.cpp
|
||||
GUI/Gizmos/GLGizmoMeasure.hpp
|
||||
GUI/Gizmos/GLGizmoAssembly.cpp
|
||||
GUI/Gizmos/GLGizmoAssembly.hpp
|
||||
GUI/Gizmos/GLGizmoSeam.cpp
|
||||
GUI/Gizmos/GLGizmoSeam.hpp
|
||||
GUI/Gizmos/GLGizmoText.cpp
|
||||
|
@ -1400,5 +1400,82 @@ GLModel::Geometry smooth_torus(unsigned int primary_resolution, unsigned int sec
|
||||
return data;
|
||||
}
|
||||
|
||||
std::shared_ptr<GLModel> init_plane_data(const indexed_triangle_set &its, const std::vector<int> &triangle_indices)
|
||||
{
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = {GUI::GLModel::PrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3};
|
||||
init_data.reserve_indices(3 * triangle_indices.size());
|
||||
init_data.reserve_vertices(3 * triangle_indices.size());
|
||||
unsigned int i = 0;
|
||||
for (int idx : triangle_indices) {
|
||||
const Vec3f &v0 = its.vertices[its.indices[idx][0]];
|
||||
const Vec3f &v1 = its.vertices[its.indices[idx][1]];
|
||||
const Vec3f &v2 = its.vertices[its.indices[idx][2]];
|
||||
|
||||
const Vec3f n = (v1 - v0).cross(v2 - v0).normalized();
|
||||
init_data.add_vertex(v0, n);
|
||||
init_data.add_vertex(v1, n);
|
||||
init_data.add_vertex(v2, n);
|
||||
init_data.add_triangle(i, i + 1, i + 2);
|
||||
i += 3;
|
||||
}
|
||||
std::shared_ptr<GLModel> gl_data = std::make_shared<GLModel>();
|
||||
gl_data->init_from(std::move(init_data), true);
|
||||
return gl_data;
|
||||
}
|
||||
|
||||
std::shared_ptr<GLModel> init_torus_data(unsigned int primary_resolution,
|
||||
unsigned int secondary_resolution,
|
||||
const Vec3f & center,
|
||||
float radius,
|
||||
float thickness,
|
||||
const Vec3f & model_axis,
|
||||
const Transform3f &world_trafo)
|
||||
{
|
||||
const unsigned int torus_sector_count = std::max<unsigned int>(4, primary_resolution);
|
||||
const unsigned int section_sector_count = std::max<unsigned int>(4, secondary_resolution);
|
||||
const float torus_sector_step = 2.0f * float(M_PI) / float(torus_sector_count);
|
||||
const float section_sector_step = 2.0f * float(M_PI) / float(section_sector_count);
|
||||
|
||||
GLModel::Geometry data;
|
||||
data.format = {GLModel::PrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3};
|
||||
data.reserve_vertices(torus_sector_count * section_sector_count);
|
||||
data.reserve_indices(torus_sector_count * section_sector_count * 2 * 3);
|
||||
|
||||
// vertices
|
||||
const Transform3f local_to_world_matrix = world_trafo * Geometry::translation_transform(center.cast<double>()).cast<float>() *
|
||||
Eigen::Quaternion<float>::FromTwoVectors(Vec3f::UnitZ(), model_axis);
|
||||
for (unsigned int i = 0; i < torus_sector_count; ++i) {
|
||||
const float section_angle = torus_sector_step * i;
|
||||
const Vec3f radius_dir(std::cos(section_angle), std::sin(section_angle), 0.0f);
|
||||
const Vec3f local_section_center = radius * radius_dir;
|
||||
const Vec3f world_section_center = local_to_world_matrix * local_section_center;
|
||||
const Vec3f local_section_normal = local_section_center.normalized().cross(Vec3f::UnitZ()).normalized();
|
||||
const Vec3f world_section_normal = (Vec3f) (local_to_world_matrix.matrix().block(0, 0, 3, 3) * local_section_normal).normalized();
|
||||
const Vec3f base_v = thickness * radius_dir;
|
||||
for (unsigned int j = 0; j < section_sector_count; ++j) {
|
||||
const Vec3f v = Eigen::AngleAxisf(section_sector_step * j, world_section_normal) * base_v;
|
||||
data.add_vertex(world_section_center + v, (Vec3f) v.normalized());
|
||||
}
|
||||
}
|
||||
|
||||
// triangles
|
||||
for (unsigned int i = 0; i < torus_sector_count; ++i) {
|
||||
const unsigned int ii = i * section_sector_count;
|
||||
const unsigned int ii_next = ((i + 1) % torus_sector_count) * section_sector_count;
|
||||
for (unsigned int j = 0; j < section_sector_count; ++j) {
|
||||
const unsigned int j_next = (j + 1) % section_sector_count;
|
||||
const unsigned int i0 = ii + j;
|
||||
const unsigned int i1 = ii_next + j;
|
||||
const unsigned int i2 = ii_next + j_next;
|
||||
const unsigned int i3 = ii + j_next;
|
||||
data.add_triangle(i0, i1, i2);
|
||||
data.add_triangle(i0, i2, i3);
|
||||
}
|
||||
}
|
||||
std::shared_ptr<GLModel> gl_data = std::make_shared<GLModel>();
|
||||
gl_data->init_from(std::move(data), true);
|
||||
return gl_data;
|
||||
}
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
@ -225,6 +225,14 @@ namespace GUI {
|
||||
// the origin of the torus is in its center
|
||||
GLModel::Geometry smooth_torus(unsigned int primary_resolution, unsigned int secondary_resolution, float radius, float thickness);
|
||||
|
||||
std::shared_ptr<GLModel> init_plane_data(const indexed_triangle_set &its, const std::vector<int> &triangle_indices);
|
||||
std::shared_ptr<GLModel> init_torus_data(unsigned int primary_resolution,
|
||||
unsigned int secondary_resolution,
|
||||
const Vec3f & center,
|
||||
float radius,
|
||||
float thickness,
|
||||
const Vec3f & model_axis,
|
||||
const Transform3f &world_trafo);
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
|
@ -2325,35 +2325,6 @@ bool GLGizmoAdvancedCut::render_connect_type_radio_button(CutConnectorType type)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GLGizmoAdvancedCut::render_combo(const std::string &label, const std::vector<std::string> &lines, size_t &selection_idx, float label_width, float item_width)
|
||||
{
|
||||
ImGui::AlignTextToFramePadding();
|
||||
m_imgui->text(label);
|
||||
ImGui::SameLine(label_width);
|
||||
ImGui::PushItemWidth(item_width);
|
||||
|
||||
size_t selection_out = selection_idx;
|
||||
|
||||
const char *selected_str = (selection_idx >= 0 && selection_idx < int(lines.size())) ? lines[selection_idx].c_str() : "";
|
||||
if (ImGui::BBLBeginCombo(("##" + label).c_str(), selected_str, 0)) {
|
||||
for (size_t line_idx = 0; line_idx < lines.size(); ++line_idx) {
|
||||
ImGui::PushID(int(line_idx));
|
||||
if (ImGui::Selectable("", line_idx == selection_idx)) selection_out = line_idx;
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", lines[line_idx].c_str());
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
bool is_changed = selection_idx != selection_out;
|
||||
selection_idx = selection_out;
|
||||
|
||||
return is_changed;
|
||||
}
|
||||
|
||||
bool GLGizmoAdvancedCut::render_slider_double_input(const std::string &label, float &value_in, float &tolerance_in)
|
||||
{
|
||||
// -------- [ ] -------- [ ]
|
||||
|
@ -333,7 +333,6 @@ private:
|
||||
bool render_reset_button(const std::string &label_id, const std::string &tooltip) const;
|
||||
bool render_connect_type_radio_button(CutConnectorType type);
|
||||
|
||||
bool render_combo(const std::string &label, const std::vector<std::string> &lines, size_t &selection_idx, float label_width, float item_width);
|
||||
bool render_slider_double_input(const std::string &label, float &value_in, float &tolerance_in);
|
||||
bool render_slider_double_input_by_format(const std::string &label, float &value_in, float value_min, float value_max, DoubleShowType show_type = DoubleShowType::Normal);
|
||||
bool cut_line_processing() const;
|
||||
|
163
src/slic3r/GUI/Gizmos/GLGizmoAssembly.cpp
Normal file
163
src/slic3r/GUI/Gizmos/GLGizmoAssembly.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
#include "GLGizmoAssembly.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp"
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/MeasureUtils.hpp"
|
||||
|
||||
#include <imgui/imgui_internal.h>
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <future>
|
||||
#include <wx/clipbrd.h>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
GLGizmoAssembly::GLGizmoAssembly(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) :
|
||||
GLGizmoMeasure(parent, icon_filename, sprite_id)
|
||||
{
|
||||
m_measure_mode = EMeasureMode::ONLY_ASSEMBLY;
|
||||
}
|
||||
|
||||
std::string GLGizmoAssembly::on_get_name() const
|
||||
{
|
||||
if (!on_is_activable() && m_state == EState::Off) {
|
||||
if (wxGetApp().plater()->canvas3D()->get_canvas_type() == GLCanvas3D::ECanvasType::CanvasAssembleView) {
|
||||
return _u8L("Assembly") + ":\n" + _u8L("Please confirm explosion ratio = 1 and select at least two volumes.");
|
||||
}
|
||||
else {
|
||||
return _u8L("Assembly") + ":\n" + _u8L("Please select at least two volumes.");
|
||||
}
|
||||
} else {
|
||||
return _u8L("Assembly");
|
||||
}
|
||||
}
|
||||
|
||||
bool GLGizmoAssembly::on_is_activable() const
|
||||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const int selection_volumes_count = 2;
|
||||
if (wxGetApp().plater()->canvas3D()->get_canvas_type() == GLCanvas3D::ECanvasType::CanvasAssembleView) {
|
||||
if (abs(m_parent.get_explosion_ratio() - 1.0f) < 1e-2 && selection.volumes_count() >= selection_volumes_count) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return selection.volumes_count() >= selection_volumes_count;
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoAssembly::on_render_input_window(float x, float y, float bottom_limit)
|
||||
{
|
||||
static std::optional<Measure::SurfaceFeature> last_feature;
|
||||
static EMode last_mode = EMode::FeatureSelection;
|
||||
static SelectedFeatures last_selected_features;
|
||||
|
||||
static float last_y = 0.0f;
|
||||
static float last_h = 0.0f;
|
||||
|
||||
if (m_editing_distance)
|
||||
return;
|
||||
unsigned int current_active_id = ImGui::GetActiveID();
|
||||
// adjust window position to avoid overlap the view toolbar
|
||||
const float win_h = ImGui::GetWindowHeight();
|
||||
y = std::min(y, bottom_limit - win_h);
|
||||
GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f);
|
||||
if (last_h != win_h || last_y != y) {
|
||||
// ask canvas for another frame to render the window in the correct position
|
||||
m_imgui->set_requires_extra_frame();
|
||||
if (last_h != win_h)
|
||||
last_h = win_h;
|
||||
if (last_y != y)
|
||||
last_y = y;
|
||||
}
|
||||
// Orca
|
||||
ImGuiWrapper::push_toolbar_style(m_parent.get_scale());
|
||||
GizmoImguiBegin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
|
||||
init_render_input_window();
|
||||
|
||||
float moving_size = m_imgui->calc_text_size(_L("(Moving)")).x;
|
||||
float combox_content_size = (m_imgui->calc_text_size(_L("Point and point")).x +ImGui::GetStyle().FramePadding.x * 2.0f);
|
||||
float caption_size = moving_size + 2 * m_space_size;
|
||||
if (render_assembly_mode_combo(caption_size + 0.5 * m_space_size, 1.8 * combox_content_size)) {
|
||||
;
|
||||
}
|
||||
show_selection_ui();
|
||||
|
||||
ImGui::Separator();
|
||||
show_distance_xyz_ui();
|
||||
show_face_face_assembly();
|
||||
render_input_window_warning(m_same_model_object);
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f));
|
||||
float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y;
|
||||
float caption_max = 0.f;
|
||||
float total_text_max = 0.f;
|
||||
for (const auto &t : std::array<std::string, 3>{"point_selection", "reset", "unselect"}) {
|
||||
caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc[t + "_caption"]).x);
|
||||
total_text_max = std::max(total_text_max, m_imgui->calc_text_size(m_desc[t]).x);
|
||||
}
|
||||
show_tooltip_information(caption_max, x, get_cur_y);
|
||||
|
||||
float f_scale =m_parent.get_gizmos_manager().get_layout_scale();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale));
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
if (last_feature != m_curr_feature || last_mode != m_mode || last_selected_features != m_selected_features) {
|
||||
// the dialog may have changed its size, ask for an extra frame to render it properly
|
||||
last_feature = m_curr_feature;
|
||||
last_mode = m_mode;
|
||||
last_selected_features = m_selected_features;
|
||||
m_imgui->set_requires_extra_frame();
|
||||
}
|
||||
m_last_active_item_imgui = current_active_id;
|
||||
GizmoImguiEnd();
|
||||
// Orca
|
||||
ImGuiWrapper::pop_toolbar_style();
|
||||
}
|
||||
|
||||
void GLGizmoAssembly::render_input_window_warning(bool same_model_object)
|
||||
{
|
||||
if (wxGetApp().plater()->canvas3D()->get_canvas_type() == GLCanvas3D::ECanvasType::CanvasView3D) {
|
||||
if (m_hit_different_volumes.size() == 2) {
|
||||
if (same_model_object == false) {
|
||||
m_imgui->text(_L("Warning") + ": " + _L("Due to ensuer_on_bed, assembly between \ndifferent objects may not be correct in 3D view.\n It is recommended to assemble them together."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GLGizmoAssembly::render_assembly_mode_combo(double label_width, float item_width)
|
||||
{
|
||||
ImGui::AlignTextToFramePadding();
|
||||
size_t selection_idx = int(m_assembly_mode);
|
||||
std::vector<std::string> modes = {_u8L("Face and face"), _u8L("Point and point")};
|
||||
bool is_changed = false;
|
||||
|
||||
ImGuiWrapper::push_combo_style(m_parent.get_scale());
|
||||
if (render_combo(_u8L("Mode"), modes, selection_idx, label_width, item_width)) {
|
||||
is_changed = true;
|
||||
switch_to_mode((AssemblyMode) selection_idx);
|
||||
}
|
||||
ImGuiWrapper::pop_combo_style();
|
||||
return is_changed;
|
||||
}
|
||||
|
||||
void GLGizmoAssembly::switch_to_mode(AssemblyMode new_mode)
|
||||
{
|
||||
m_assembly_mode = new_mode;
|
||||
reset_all_feature();
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
43
src/slic3r/GUI/Gizmos/GLGizmoAssembly.hpp
Normal file
43
src/slic3r/GUI/Gizmos/GLGizmoAssembly.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef slic3r_GLGizmoAssembly_hpp_
|
||||
#define slic3r_GLGizmoAssembly_hpp_
|
||||
|
||||
#include "GLGizmoMeasure.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
namespace GUI {
|
||||
class GLGizmoAssembly : public GLGizmoMeasure
|
||||
{
|
||||
|
||||
public:
|
||||
GLGizmoAssembly(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
/// <summary>
|
||||
/// Apply rotation on select plane
|
||||
/// </summary>
|
||||
/// <param name="mouse_event">Keep information about mouse click</param>
|
||||
/// <returns>Return True when use the information otherwise False.</returns>
|
||||
//bool on_mouse(const wxMouseEvent &mouse_event) override;
|
||||
//void data_changed(bool is_serializing) override;
|
||||
//bool gizmo_event(SLAGizmoEventType action, const Vec2d &mouse_position, bool shift_down, bool alt_down, bool control_down) override;
|
||||
|
||||
bool wants_enter_leave_snapshots() const override { return true; }
|
||||
std::string get_gizmo_entering_text() const override { return _u8L("Entering Assembly gizmo"); }
|
||||
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Assembly gizmo"); }
|
||||
protected:
|
||||
//bool on_init() override;
|
||||
std::string on_get_name() const override;
|
||||
bool on_is_activable() const override;
|
||||
//void on_render() override;
|
||||
//void on_set_state() override;
|
||||
virtual void on_render_input_window(float x, float y, float bottom_limit) override;
|
||||
|
||||
void render_input_window_warning(bool same_model_object) override;
|
||||
bool render_assembly_mode_combo(double label_width, float item_width);
|
||||
|
||||
void switch_to_mode(AssemblyMode new_mode);
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // slic3r_GLGizmoAssembly_hpp_
|
@ -190,6 +190,35 @@ bool GLGizmoBase::render_slider_double_input_by_format(
|
||||
return !is_approx(old_val, value_in);
|
||||
}
|
||||
|
||||
bool GLGizmoBase::render_combo(const std::string &label, const std::vector<std::string> &lines, size_t &selection_idx, float label_width, float item_width)
|
||||
{
|
||||
ImGui::AlignTextToFramePadding();
|
||||
m_imgui->text(label);
|
||||
ImGui::SameLine(label_width);
|
||||
ImGui::PushItemWidth(item_width);
|
||||
|
||||
size_t selection_out = selection_idx;
|
||||
|
||||
const char *selected_str = (selection_idx >= 0 && selection_idx < int(lines.size())) ? lines[selection_idx].c_str() : "";
|
||||
if (ImGui::BBLBeginCombo(("##" + label).c_str(), selected_str, 0)) {
|
||||
for (size_t line_idx = 0; line_idx < lines.size(); ++line_idx) {
|
||||
ImGui::PushID(int(line_idx));
|
||||
if (ImGui::Selectable("", line_idx == selection_idx)) selection_out = line_idx;
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", lines[line_idx].c_str());
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
bool is_changed = selection_idx != selection_out;
|
||||
selection_idx = selection_out;
|
||||
|
||||
return is_changed;
|
||||
}
|
||||
|
||||
GLGizmoBase::GLGizmoBase(GLCanvas3D &parent, const std::string &icon_filename, unsigned int sprite_id)
|
||||
: m_parent(parent)
|
||||
, m_group_id(-1)
|
||||
|
@ -170,6 +170,8 @@ protected:
|
||||
float value_max,
|
||||
int keep_digit ,
|
||||
DoubleShowType show_type = DoubleShowType::Normal);
|
||||
bool render_combo(const std::string &label, const std::vector<std::string> &lines,
|
||||
size_t &selection_idx, float label_width, float item_width);
|
||||
|
||||
public:
|
||||
GLGizmoBase(GLCanvas3D& parent,
|
||||
|
@ -20,45 +20,21 @@
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
static const Slic3r::ColorRGBA SELECTED_1ST_COLOR = { 0.25f, 0.75f, 0.75f, 1.0f };
|
||||
static const Slic3r::ColorRGBA SELECTED_2ND_COLOR = { 0.75f, 0.25f, 0.75f, 1.0f };
|
||||
static const Slic3r::ColorRGBA NEUTRAL_COLOR = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
static const Slic3r::ColorRGBA HOVER_COLOR = {0.0f, 1.0f, 0.0f, 1.0f};//Green
|
||||
|
||||
static const int POINT_ID = 100;
|
||||
static const int EDGE_ID = 200;
|
||||
static const int CIRCLE_ID = 300;
|
||||
static const int PLANE_ID = 400;
|
||||
static const int SEL_SPHERE_1_ID = 501;
|
||||
static const int SEL_SPHERE_2_ID = 502;
|
||||
|
||||
static const float TRIANGLE_BASE = 10.0f;
|
||||
static const float TRIANGLE_HEIGHT = TRIANGLE_BASE * 1.618033f;
|
||||
|
||||
static const std::string CTRL_STR =
|
||||
#ifdef __APPLE__
|
||||
"⌘"
|
||||
#else
|
||||
"Ctrl"
|
||||
#endif //__APPLE__
|
||||
;
|
||||
|
||||
static std::string format_double(double value)
|
||||
std::string GLGizmoMeasure::format_double(double value)
|
||||
{
|
||||
char buf[1024];
|
||||
sprintf(buf, "%.3f", value);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
static std::string format_vec3(const Vec3d& v)
|
||||
std::string GLGizmoMeasure::format_vec3(const Vec3d &v)
|
||||
{
|
||||
char buf[1024];
|
||||
sprintf(buf, "X: %.3f, Y: %.3f, Z: %.3f", v.x(), v.y(), v.z());
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
static std::string surface_feature_type_as_string(Measure::SurfaceFeatureType type)
|
||||
std::string GLGizmoMeasure::surface_feature_type_as_string(Measure::SurfaceFeatureType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@ -71,7 +47,7 @@ static std::string surface_feature_type_as_string(Measure::SurfaceFeatureType ty
|
||||
}
|
||||
}
|
||||
|
||||
static std::string point_on_feature_type_as_string(Measure::SurfaceFeatureType type, int hover_id)
|
||||
std::string GLGizmoMeasure::point_on_feature_type_as_string(Measure::SurfaceFeatureType type, int hover_id)
|
||||
{
|
||||
std::string ret;
|
||||
switch (type) {
|
||||
@ -84,7 +60,7 @@ static std::string point_on_feature_type_as_string(Measure::SurfaceFeatureType t
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::string center_on_feature_type_as_string(Measure::SurfaceFeatureType type)
|
||||
std::string GLGizmoMeasure::center_on_feature_type_as_string(Measure::SurfaceFeatureType type)
|
||||
{
|
||||
std::string ret;
|
||||
switch (type) {
|
||||
@ -95,92 +71,13 @@ static std::string center_on_feature_type_as_string(Measure::SurfaceFeatureType
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::shared_ptr<GLModel> init_plane_data(const indexed_triangle_set &its, const std::vector<int> &triangle_indices)
|
||||
{
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = {GUI::GLModel::PrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3};
|
||||
init_data.reserve_indices(3 * triangle_indices.size());
|
||||
init_data.reserve_vertices(3 * triangle_indices.size());
|
||||
unsigned int i = 0;
|
||||
for (int idx : triangle_indices) {
|
||||
const Vec3f &v0 = its.vertices[its.indices[idx][0]];
|
||||
const Vec3f &v1 = its.vertices[its.indices[idx][1]];
|
||||
const Vec3f &v2 = its.vertices[its.indices[idx][2]];
|
||||
|
||||
const Vec3f n = (v1 - v0).cross(v2 - v0).normalized();
|
||||
init_data.add_vertex(v0, n);
|
||||
init_data.add_vertex(v1, n);
|
||||
init_data.add_vertex(v2, n);
|
||||
init_data.add_triangle(i, i + 1, i + 2);
|
||||
i += 3;
|
||||
}
|
||||
std::shared_ptr<GLModel> gl_data = std::make_shared<GLModel>();
|
||||
gl_data->init_from(std::move(init_data),true);
|
||||
return gl_data;
|
||||
}
|
||||
|
||||
|
||||
static std::shared_ptr<GLModel> init_torus_data(unsigned int primary_resolution,
|
||||
unsigned int secondary_resolution,
|
||||
const Vec3f & center,
|
||||
float radius,
|
||||
float thickness,
|
||||
const Vec3f& model_axis,
|
||||
const Transform3f& world_trafo)
|
||||
{
|
||||
const unsigned int torus_sector_count = std::max<unsigned int>(4, primary_resolution);
|
||||
const unsigned int section_sector_count = std::max<unsigned int>(4, secondary_resolution);
|
||||
const float torus_sector_step = 2.0f * float(M_PI) / float(torus_sector_count);
|
||||
const float section_sector_step = 2.0f * float(M_PI) / float(section_sector_count);
|
||||
|
||||
GLModel::Geometry data;
|
||||
data.format = {GLModel::PrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3};
|
||||
data.reserve_vertices(torus_sector_count * section_sector_count);
|
||||
data.reserve_indices(torus_sector_count * section_sector_count * 2 * 3);
|
||||
|
||||
// vertices
|
||||
const Transform3f local_to_world_matrix = world_trafo * Geometry::translation_transform(center.cast<double>()).cast<float>() *
|
||||
Eigen::Quaternion<float>::FromTwoVectors(Vec3f::UnitZ(), model_axis);
|
||||
for (unsigned int i = 0; i < torus_sector_count; ++i) {
|
||||
const float section_angle = torus_sector_step * i;
|
||||
const Vec3f radius_dir(std::cos(section_angle), std::sin(section_angle), 0.0f);
|
||||
const Vec3f local_section_center = radius * radius_dir;
|
||||
const Vec3f world_section_center = local_to_world_matrix * local_section_center;
|
||||
const Vec3f local_section_normal = local_section_center.normalized().cross(Vec3f::UnitZ()).normalized();
|
||||
const Vec3f world_section_normal = (Vec3f) (local_to_world_matrix.matrix().block(0, 0, 3, 3) * local_section_normal).normalized();
|
||||
const Vec3f base_v = thickness * radius_dir;
|
||||
for (unsigned int j = 0; j < section_sector_count; ++j) {
|
||||
const Vec3f v = Eigen::AngleAxisf(section_sector_step * j, world_section_normal) * base_v;
|
||||
data.add_vertex(world_section_center + v, (Vec3f) v.normalized());
|
||||
}
|
||||
}
|
||||
|
||||
// triangles
|
||||
for (unsigned int i = 0; i < torus_sector_count; ++i) {
|
||||
const unsigned int ii = i * section_sector_count;
|
||||
const unsigned int ii_next = ((i + 1) % torus_sector_count) * section_sector_count;
|
||||
for (unsigned int j = 0; j < section_sector_count; ++j) {
|
||||
const unsigned int j_next = (j + 1) % section_sector_count;
|
||||
const unsigned int i0 = ii + j;
|
||||
const unsigned int i1 = ii_next + j;
|
||||
const unsigned int i2 = ii_next + j_next;
|
||||
const unsigned int i3 = ii + j_next;
|
||||
data.add_triangle(i0, i1, i2);
|
||||
data.add_triangle(i0, i2, i3);
|
||||
}
|
||||
}
|
||||
std::shared_ptr<GLModel> gl_data = std::make_shared<GLModel>();
|
||||
gl_data->init_from(std::move(data), true);
|
||||
return gl_data;
|
||||
}
|
||||
|
||||
static bool is_feature_with_center(const Measure::SurfaceFeature& feature)
|
||||
bool GLGizmoMeasure::is_feature_with_center(const Measure::SurfaceFeature &feature)
|
||||
{
|
||||
const Measure::SurfaceFeatureType type = feature.get_type();
|
||||
return (type == Measure::SurfaceFeatureType::Circle || (type == Measure::SurfaceFeatureType::Edge && feature.get_extra_point().has_value()));
|
||||
}
|
||||
|
||||
static Vec3d get_feature_offset(const Measure::SurfaceFeature& feature)
|
||||
Vec3d GLGizmoMeasure::get_feature_offset(const Measure::SurfaceFeature &feature)
|
||||
{
|
||||
Vec3d ret;
|
||||
switch (feature.get_type())
|
||||
@ -208,79 +105,74 @@ static Vec3d get_feature_offset(const Measure::SurfaceFeature& feature)
|
||||
return ret;
|
||||
}
|
||||
|
||||
class TransformHelper
|
||||
Vec3d TransformHelper::model_to_world(const Vec3d &model, const Transform3d &world_matrix) {
|
||||
return world_matrix * model;
|
||||
}
|
||||
|
||||
Vec4d TransformHelper::world_to_clip(const Vec3d &world, const Matrix4d &projection_view_matrix)
|
||||
{
|
||||
struct Cache
|
||||
{
|
||||
std::array<int, 4> viewport;
|
||||
Matrix4d ndc_to_ss_matrix;
|
||||
Transform3d ndc_to_ss_matrix_inverse;
|
||||
};
|
||||
return projection_view_matrix * Vec4d(world.x(), world.y(), world.z(), 1.0);
|
||||
}
|
||||
|
||||
static Cache s_cache;
|
||||
Vec3d TransformHelper::clip_to_ndc(const Vec4d &clip) {
|
||||
return Vec3d(clip.x(), clip.y(), clip.z()) / clip.w();
|
||||
}
|
||||
|
||||
public:
|
||||
static Vec3d model_to_world(const Vec3d& model, const Transform3d& world_matrix) {
|
||||
return world_matrix * model;
|
||||
}
|
||||
|
||||
static Vec4d world_to_clip(const Vec3d& world, const Matrix4d& projection_view_matrix) {
|
||||
return projection_view_matrix * Vec4d(world.x(), world.y(), world.z(), 1.0);
|
||||
}
|
||||
|
||||
static Vec3d clip_to_ndc(const Vec4d& clip) {
|
||||
return Vec3d(clip.x(), clip.y(), clip.z()) / clip.w();
|
||||
}
|
||||
|
||||
static Vec2d ndc_to_ss(const Vec3d& ndc, const std::array<int, 4>& viewport) {
|
||||
const double half_w = 0.5 * double(viewport[2]);
|
||||
const double half_h = 0.5 * double(viewport[3]);
|
||||
return { half_w * ndc.x() + double(viewport[0]) + half_w, half_h * ndc.y() + double(viewport[1]) + half_h };
|
||||
};
|
||||
|
||||
static Vec4d model_to_clip(const Vec3d& model, const Transform3d& world_matrix, const Matrix4d& projection_view_matrix) {
|
||||
return world_to_clip(model_to_world(model, world_matrix), projection_view_matrix);
|
||||
}
|
||||
|
||||
static Vec3d model_to_ndc(const Vec3d& model, const Transform3d& world_matrix, const Matrix4d& projection_view_matrix) {
|
||||
return clip_to_ndc(world_to_clip(model_to_world(model, world_matrix), projection_view_matrix));
|
||||
}
|
||||
|
||||
static Vec2d model_to_ss(const Vec3d& model, const Transform3d& world_matrix, const Matrix4d& projection_view_matrix, const std::array<int, 4>& viewport) {
|
||||
return ndc_to_ss(clip_to_ndc(world_to_clip(model_to_world(model, world_matrix), projection_view_matrix)), viewport);
|
||||
}
|
||||
|
||||
static Vec2d world_to_ss(const Vec3d& world, const Matrix4d& projection_view_matrix, const std::array<int, 4>& viewport) {
|
||||
return ndc_to_ss(clip_to_ndc(world_to_clip(world, projection_view_matrix)), viewport);
|
||||
}
|
||||
|
||||
static const Matrix4d& ndc_to_ss_matrix(const std::array<int, 4>& viewport) {
|
||||
update(viewport);
|
||||
return s_cache.ndc_to_ss_matrix;
|
||||
}
|
||||
|
||||
static const Transform3d ndc_to_ss_matrix_inverse(const std::array<int, 4>& viewport) {
|
||||
update(viewport);
|
||||
return s_cache.ndc_to_ss_matrix_inverse;
|
||||
}
|
||||
|
||||
private:
|
||||
static void update(const std::array<int, 4>& viewport) {
|
||||
if (s_cache.viewport == viewport)
|
||||
return;
|
||||
|
||||
const double half_w = 0.5 * double(viewport[2]);
|
||||
const double half_h = 0.5 * double(viewport[3]);
|
||||
s_cache.ndc_to_ss_matrix << half_w, 0.0, 0.0, double(viewport[0]) + half_w,
|
||||
0.0, half_h, 0.0, double(viewport[1]) + half_h,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0;
|
||||
|
||||
s_cache.ndc_to_ss_matrix_inverse = s_cache.ndc_to_ss_matrix.inverse();
|
||||
s_cache.viewport = viewport;
|
||||
}
|
||||
Vec2d TransformHelper::ndc_to_ss(const Vec3d &ndc, const std::array<int, 4> &viewport)
|
||||
{
|
||||
const double half_w = 0.5 * double(viewport[2]);
|
||||
const double half_h = 0.5 * double(viewport[3]);
|
||||
return { half_w * ndc.x() + double(viewport[0]) + half_w, half_h * ndc.y() + double(viewport[1]) + half_h };
|
||||
};
|
||||
|
||||
Vec4d TransformHelper::model_to_clip(const Vec3d &model, const Transform3d &world_matrix, const Matrix4d &projection_view_matrix)
|
||||
{
|
||||
return world_to_clip(model_to_world(model, world_matrix), projection_view_matrix);
|
||||
}
|
||||
|
||||
Vec3d TransformHelper::model_to_ndc(const Vec3d &model, const Transform3d &world_matrix, const Matrix4d &projection_view_matrix)
|
||||
{
|
||||
return clip_to_ndc(world_to_clip(model_to_world(model, world_matrix), projection_view_matrix));
|
||||
}
|
||||
|
||||
Vec2d TransformHelper::model_to_ss(const Vec3d &model, const Transform3d &world_matrix, const Matrix4d &projection_view_matrix, const std::array<int, 4> &viewport)
|
||||
{
|
||||
return ndc_to_ss(clip_to_ndc(world_to_clip(model_to_world(model, world_matrix), projection_view_matrix)), viewport);
|
||||
}
|
||||
|
||||
Vec2d TransformHelper::world_to_ss(const Vec3d &world, const Matrix4d &projection_view_matrix, const std::array<int, 4> &viewport)
|
||||
{
|
||||
return ndc_to_ss(clip_to_ndc(world_to_clip(world, projection_view_matrix)), viewport);
|
||||
}
|
||||
|
||||
const Matrix4d &TransformHelper::ndc_to_ss_matrix(const std::array<int, 4> &viewport)
|
||||
{
|
||||
update(viewport);
|
||||
return s_cache.ndc_to_ss_matrix;
|
||||
}
|
||||
|
||||
const Transform3d TransformHelper::ndc_to_ss_matrix_inverse(const std::array<int, 4> &viewport)
|
||||
{
|
||||
update(viewport);
|
||||
return s_cache.ndc_to_ss_matrix_inverse;
|
||||
}
|
||||
|
||||
void TransformHelper::update(const std::array<int, 4> &viewport)
|
||||
{
|
||||
if (s_cache.viewport == viewport)
|
||||
return;
|
||||
|
||||
const double half_w = 0.5 * double(viewport[2]);
|
||||
const double half_h = 0.5 * double(viewport[3]);
|
||||
s_cache.ndc_to_ss_matrix << half_w, 0.0, 0.0, double(viewport[0]) + half_w,
|
||||
0.0, half_h, 0.0, double(viewport[1]) + half_h,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0;
|
||||
|
||||
s_cache.ndc_to_ss_matrix_inverse = s_cache.ndc_to_ss_matrix.inverse();
|
||||
s_cache.viewport = viewport;
|
||||
}
|
||||
|
||||
TransformHelper::Cache TransformHelper::s_cache = { { 0, 0, 0, 0 }, Matrix4d::Identity(), Transform3d::Identity() };
|
||||
|
||||
GLGizmoMeasure::GLGizmoMeasure(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
||||
@ -374,6 +266,11 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event)
|
||||
if (m_selected_features.first.feature.has_value()) {
|
||||
reset_feature2_render();
|
||||
const SelectedFeatures::Item item = detect_current_item();
|
||||
if (!is_pick_meet_assembly_mode(item)) { // assembly deal
|
||||
m_selected_wrong_feature_waring_tip = true;
|
||||
return true;
|
||||
}
|
||||
m_selected_wrong_feature_waring_tip = false;
|
||||
if (m_selected_features.first != item) {
|
||||
bool processed = false;
|
||||
if (item.is_center) {
|
||||
@ -437,6 +334,11 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event)
|
||||
// 1st feature selection
|
||||
reset_feature1_render();
|
||||
const SelectedFeatures::Item item = detect_current_item();
|
||||
if (!is_pick_meet_assembly_mode(item)) {//assembly deal
|
||||
m_selected_wrong_feature_waring_tip = true;
|
||||
return true;
|
||||
}
|
||||
m_selected_wrong_feature_waring_tip = false;
|
||||
m_selected_features.first = item;
|
||||
if (requires_sphere_raycaster_for_picking(item)) {
|
||||
auto pick = std::make_shared<PickRaycaster>(m_sphere->mesh, SEL_SPHERE_1_ID);
|
||||
@ -479,7 +381,7 @@ bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event)
|
||||
|
||||
return false;
|
||||
}
|
||||
void func() {}
|
||||
|
||||
|
||||
void GLGizmoMeasure::data_changed(bool is_serializing)
|
||||
{
|
||||
@ -1723,7 +1625,8 @@ void GLGizmoMeasure::render_dimensioning()
|
||||
const Measure::DistAndPoints& dap = m_measurement_result.distance_infinite.has_value()
|
||||
? *m_measurement_result.distance_infinite
|
||||
: *m_measurement_result.distance_strict;
|
||||
if (m_selected_features.second.feature.has_value()) {
|
||||
if (m_selected_features.second.feature.has_value() &&
|
||||
!(m_measure_mode == EMeasureMode::ONLY_ASSEMBLY && m_assembly_mode == AssemblyMode::FACE_FACE)) {
|
||||
auto x_to = dap.from;
|
||||
x_to[0] = dap.to[0];
|
||||
point_point(dap.from, x_to, x_to[0] - dap.from[0], ColorRGBA::RED().get_data(), false, false);
|
||||
@ -1849,90 +1752,74 @@ void GLGizmoMeasure::on_render_for_picking()
|
||||
|
||||
}
|
||||
|
||||
void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit)
|
||||
void GLGizmoMeasure::show_selection_ui()
|
||||
{
|
||||
static std::optional<Measure::SurfaceFeature> last_feature;
|
||||
static EMode last_mode = EMode::FeatureSelection;
|
||||
static SelectedFeatures last_selected_features;
|
||||
|
||||
static float last_y = 0.0f;
|
||||
static float last_h = 0.0f;
|
||||
|
||||
if (m_editing_distance)
|
||||
return;
|
||||
unsigned int current_active_id = ImGui::GetActiveID();
|
||||
// adjust window position to avoid overlap the view toolbar
|
||||
const float win_h = ImGui::GetWindowHeight();
|
||||
y = std::min(y, bottom_limit - win_h);
|
||||
GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f);
|
||||
if (last_h != win_h || last_y != y) {
|
||||
// ask canvas for another frame to render the window in the correct position
|
||||
m_imgui->set_requires_extra_frame();
|
||||
if (last_h != win_h)
|
||||
last_h = win_h;
|
||||
if (last_y != y)
|
||||
last_y = y;
|
||||
}
|
||||
|
||||
// Orca
|
||||
ImGuiWrapper::push_toolbar_style(m_parent.get_scale());
|
||||
|
||||
GizmoImguiBegin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
|
||||
|
||||
float caption_max = 0.f;
|
||||
float total_text_max = 0.f;
|
||||
for (const auto &t : std::array<std::string, 3>{ "point_selection", "reset", "unselect"}) {
|
||||
caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc[t + "_caption"]).x);
|
||||
total_text_max = std::max(total_text_max, m_imgui->calc_text_size(m_desc[t]).x);
|
||||
}
|
||||
|
||||
const bool use_inches = wxGetApp().app_config->get("use_inches") == "1";
|
||||
const std::string units = use_inches ? " " + _u8L("in") : " " + _u8L("mm");
|
||||
const float space_size = ImGui::CalcTextSize(" ").x * 2;
|
||||
float input_size_max = ImGui::CalcTextSize("-100.00").x * 1.2;
|
||||
auto space_size = m_space_size;
|
||||
// Show selection
|
||||
{
|
||||
auto format_item_text = [this, use_inches, &units](const SelectedFeatures::Item& item) {
|
||||
if (!item.feature.has_value())
|
||||
return _u8L("None");
|
||||
auto format_item_text = [this](const SelectedFeatures::Item &item) {
|
||||
if (!item.feature.has_value()) return _u8L("None");
|
||||
|
||||
std::string text = (item.source == item.feature) ? surface_feature_type_as_string(item.feature->get_type()) :
|
||||
item.is_center ? center_on_feature_type_as_string(item.source->get_type()) : point_on_feature_type_as_string(item.source->get_type(), m_hover_id);
|
||||
item.is_center ? center_on_feature_type_as_string(item.source->get_type()) :
|
||||
point_on_feature_type_as_string(item.source->get_type(), m_hover_id);
|
||||
if (item.feature.has_value() && item.feature->get_type() == Measure::SurfaceFeatureType::Circle) {
|
||||
auto [center, radius, normal] = item.feature->get_circle();
|
||||
const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true);
|
||||
radius = (on_circle - center).norm();
|
||||
if (use_inches)
|
||||
const Vec3d on_circle = center + radius * Measure::get_orthogonal(normal, true);
|
||||
radius = (on_circle - center).norm();
|
||||
if (m_use_inches)
|
||||
radius = GizmoObjectManipulation::mm_to_in * radius;
|
||||
text += " (" + _u8L("Diameter") + ": " + format_double(2.0 * radius) + units + ")";
|
||||
}
|
||||
else if (item.feature.has_value() && item.feature->get_type() == Measure::SurfaceFeatureType::Edge) {
|
||||
text += " (" + _u8L("Diameter") + ": " + format_double(2.0 * radius) + m_units + ")";
|
||||
} else if (item.feature.has_value() && item.feature->get_type() == Measure::SurfaceFeatureType::Edge) {
|
||||
auto [start, end] = item.feature->get_edge();
|
||||
double length = (end - start).norm();
|
||||
if (use_inches)
|
||||
double length = (end - start).norm();
|
||||
if (m_use_inches)
|
||||
length = GizmoObjectManipulation::mm_to_in * length;
|
||||
text += " (" + _u8L("Length") + ": " + format_double(length) + units + ")";
|
||||
text += " (" + _u8L("Length") + ": " + format_double(length) + m_units + ")";
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
const float selection_cap_length = ImGui::CalcTextSize((_u8L("Selection") + " 1").c_str()).x * 1.2;
|
||||
auto feature_first_text= format_item_text(m_selected_features.first);
|
||||
float selection_cap_length;
|
||||
if (m_measure_mode == EMeasureMode::ONLY_ASSEMBLY) {
|
||||
if (m_assembly_mode == AssemblyMode::FACE_FACE) {
|
||||
selection_cap_length = ImGui::CalcTextSize((_u8L("Selection") + " 1" + _u8L(" (Moving)")).c_str()).x * 1.2;
|
||||
} else if (m_assembly_mode == AssemblyMode::POINT_POINT) {
|
||||
selection_cap_length = ImGui::CalcTextSize((_u8L("Selection") + " 1" + _u8L(" (Moving)")).c_str()).x * 1.2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
selection_cap_length = ImGui::CalcTextSize((_u8L("Selection") + " 1").c_str()).x * 1.2;
|
||||
}
|
||||
auto feature_first_text = format_item_text(m_selected_features.first);
|
||||
const float feature_first_text_length = ImGui::CalcTextSize((_u8L(feature_first_text)).c_str()).x;
|
||||
ImGui::AlignTextToFramePadding();
|
||||
if (m_measure_mode == EMeasureMode::ONLY_ASSEMBLY) {
|
||||
if (m_assembly_mode == AssemblyMode::FACE_FACE) {
|
||||
m_imgui->text(_u8L("Select 2 faces on objects and \n make the object assemble together.")); // tip
|
||||
} else if (m_assembly_mode == AssemblyMode::POINT_POINT) {
|
||||
m_imgui->text(_u8L("Select 2 points or circles on objects and \n specify distance between them.")); // tip
|
||||
}
|
||||
}
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::to_ImVec4(SELECTED_1ST_COLOR));
|
||||
|
||||
m_imgui->text(_u8L("Selection") + " 1");
|
||||
if (m_measure_mode == EMeasureMode::ONLY_ASSEMBLY) {
|
||||
if (m_assembly_mode == AssemblyMode::FACE_FACE) {
|
||||
m_imgui->text(_u8L("Face") + " 1" + _u8L(" (Fixed)"));
|
||||
} else if (m_assembly_mode == AssemblyMode::POINT_POINT) {
|
||||
m_imgui->text(_u8L("Point") + " 1" + _u8L(" (Fixed)"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_imgui->text(_u8L("Selection") + " 1");
|
||||
}
|
||||
ImGui::SameLine(selection_cap_length + space_size);
|
||||
ImGui::PushItemWidth(feature_first_text_length);
|
||||
m_imgui->text(feature_first_text);
|
||||
if (m_selected_features.first.feature.has_value()) {
|
||||
ImGui::SameLine(selection_cap_length + feature_first_text_length + space_size * 2);
|
||||
ImGui::PushItemWidth(space_size * 2);
|
||||
ImGui::PushID("Reset1");//for image_button
|
||||
if (m_imgui->image_button(m_is_dark_mode ? ImGui::RevertBtn : ImGui::RevertBtn, _L("Reset"))) {
|
||||
reset_feature1();
|
||||
}
|
||||
ImGui::PushID("Reset1"); // for image_button
|
||||
if (m_imgui->image_button(m_is_dark_mode ? ImGui::RevertBtn : ImGui::RevertBtn, _L("Reset"))) { reset_feature1(); }
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
@ -1941,7 +1828,15 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit
|
||||
const float feature_second_text_length = ImGui::CalcTextSize((_u8L(feature_second_text)).c_str()).x;
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::to_ImVec4(SELECTED_2ND_COLOR));
|
||||
m_imgui->text(_u8L("Selection") + " 2");
|
||||
if (m_measure_mode == EMeasureMode::ONLY_ASSEMBLY) {
|
||||
if (m_assembly_mode == AssemblyMode::FACE_FACE) {
|
||||
m_imgui->text(_u8L("Face") + " 2"+ _u8L(" (Moving)"));
|
||||
} else if (m_assembly_mode == AssemblyMode::POINT_POINT) {
|
||||
m_imgui->text(_u8L("Point") + " 2"+ _u8L(" (Moving)"));
|
||||
}
|
||||
} else {
|
||||
m_imgui->text(_u8L("Selection") + " 2");
|
||||
}
|
||||
ImGui::SameLine(selection_cap_length + space_size);
|
||||
ImGui::PushItemWidth(feature_second_text_length);
|
||||
m_imgui->text(feature_second_text);
|
||||
@ -1950,26 +1845,39 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit
|
||||
ImGui::SameLine(selection_cap_length + feature_second_text_length + space_size * 2);
|
||||
ImGui::PushItemWidth(space_size * 2);
|
||||
ImGui::PushID("Reset2");
|
||||
if (m_imgui->image_button(m_is_dark_mode ? ImGui::RevertBtn : ImGui::RevertBtn, _L("Reset"))) {
|
||||
reset_feature2();
|
||||
}
|
||||
if (m_imgui->image_button(m_is_dark_mode ? ImGui::RevertBtn : ImGui::RevertBtn, _L("Reset"))) { reset_feature2(); }
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
m_imgui->disabled_begin(!m_selected_features.first.feature.has_value());
|
||||
if (m_imgui->button(_L("Restart selection"))) {
|
||||
reset_all_feature();
|
||||
m_imgui->set_requires_extra_frame();
|
||||
}
|
||||
if (m_imgui->button(_L("Restart selection"))) {
|
||||
reset_all_feature();
|
||||
m_imgui->set_requires_extra_frame();
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
|
||||
if (m_show_reset_first_tip) {
|
||||
m_imgui->text(_L("Feature 1 has been reset, \nfeature 2 has been feature 1"));
|
||||
}
|
||||
if (m_selected_wrong_feature_waring_tip) {
|
||||
if (m_measure_mode == EMeasureMode::ONLY_ASSEMBLY) {
|
||||
if (m_assembly_mode == AssemblyMode::FACE_FACE) {
|
||||
m_imgui->text(_L("Warning:please select Plane's feature."));
|
||||
} else if (m_assembly_mode == AssemblyMode::POINT_POINT) {
|
||||
m_imgui->text(_L("Warning:please select Point's or Circle's feature."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto add_measure_row_to_table = [this](const std::string& col_1, const ImVec4& col_1_color, const std::string& col_2, const ImVec4& col_2_color) {
|
||||
void GLGizmoMeasure::show_distance_xyz_ui()
|
||||
{
|
||||
if (m_measure_mode == EMeasureMode::ONLY_MEASURE) {
|
||||
m_imgui->text(_u8L("Measure"));
|
||||
}
|
||||
auto add_measure_row_to_table = [this](const std::string &col_1, const ImVec4 &col_1_color, const std::string &col_2, const ImVec4 &col_2_color) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
m_imgui->text_colored(col_1_color, col_1);
|
||||
@ -1982,16 +1890,18 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit
|
||||
wxTheClipboard->Close();
|
||||
}
|
||||
};
|
||||
bool same_model_object = is_two_volume_in_same_model_object();
|
||||
auto add_edit_distance_xyz_box = [this, &input_size_max, &same_model_object, ¤t_active_id](Vec3d &distance) {
|
||||
auto add_edit_distance_xyz_box = [this](Vec3d &distance) {
|
||||
m_imgui->disabled_begin(m_hit_different_volumes.size() == 1);
|
||||
{
|
||||
if (m_measure_mode == EMeasureMode::ONLY_MEASURE) {
|
||||
m_can_set_xyz_distance = false;
|
||||
}
|
||||
m_imgui->disabled_begin(!m_can_set_xyz_distance);
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
m_imgui->text_colored(ImGuiWrapper::COL_RED, "X:");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::PushItemWidth(input_size_max);
|
||||
ImGui::PushItemWidth(m_input_size_max);
|
||||
ImGui::BBLInputDouble("##measure_distance_x", &m_buffered_distance[0], 0.0f, 0.0f, "%.2f");
|
||||
|
||||
ImGui::TableNextRow();
|
||||
@ -2001,7 +1911,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit
|
||||
ImGui::BBLInputDouble("##measure_distance_y", &m_buffered_distance[1], 0.0f, 0.0f, "%.2f");
|
||||
m_imgui->disabled_end();
|
||||
|
||||
m_imgui->disabled_begin(!(same_model_object && m_can_set_xyz_distance));
|
||||
m_imgui->disabled_begin(!(m_same_model_object && m_can_set_xyz_distance));
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
m_imgui->text_colored(ImGuiWrapper::COL_BLUE, "Z:");
|
||||
@ -2010,66 +1920,62 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit
|
||||
m_imgui->disabled_end();
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
if (m_last_active_item_imgui != current_active_id && m_hit_different_volumes.size() == 2) {
|
||||
if (m_last_active_item_imgui != m_current_active_imgui_id && m_hit_different_volumes.size() == 2) {
|
||||
Vec3d displacement = Vec3d::Zero();
|
||||
if (std::abs(m_buffered_distance[0] - distance[0]) > EPSILON) {
|
||||
displacement[0] = m_buffered_distance[0] - distance[0];
|
||||
distance[0] = m_buffered_distance[0];
|
||||
distance[0] = m_buffered_distance[0];
|
||||
} else if (std::abs(m_buffered_distance[1] - distance[1]) > EPSILON) {
|
||||
displacement[1] = m_buffered_distance[1] - distance[1];
|
||||
distance[1] = m_buffered_distance[1];
|
||||
distance[1] = m_buffered_distance[1];
|
||||
} else if (std::abs(m_buffered_distance[2] - distance[2]) > EPSILON) {
|
||||
displacement[2] = m_buffered_distance[2] - distance[2];
|
||||
distance[2] = m_buffered_distance[2];
|
||||
}
|
||||
if (displacement.norm() > 0.0f) {
|
||||
set_distance(same_model_object, displacement);
|
||||
}
|
||||
if (displacement.norm() > 0.0f) { set_distance(m_same_model_object, displacement); }
|
||||
}
|
||||
};
|
||||
ImGui::Separator();
|
||||
m_imgui->text(_u8L("Measure"));
|
||||
|
||||
const unsigned int max_measure_row_count = 2;
|
||||
unsigned int measure_row_count = 0;
|
||||
unsigned int measure_row_count = 0;
|
||||
if (ImGui::BeginTable("Measure", 4)) {
|
||||
if (m_selected_features.second.feature.has_value()) {
|
||||
const Measure::MeasurementResult& measure = m_measurement_result;
|
||||
if (measure.angle.has_value()) {
|
||||
const Measure::MeasurementResult &measure = m_measurement_result;
|
||||
if (measure.angle.has_value() && m_measure_mode == EMeasureMode::ONLY_MEASURE)
|
||||
{
|
||||
ImGui::PushID("ClipboardAngle");
|
||||
add_measure_row_to_table(_u8L("Angle"), ImGuiWrapper::COL_BAMBU, format_double(Geometry::rad2deg(measure.angle->angle)) + "°",
|
||||
ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
++measure_row_count;
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
const bool show_strict = measure.distance_strict.has_value() &&
|
||||
(!measure.distance_infinite.has_value() || std::abs(measure.distance_strict->dist - measure.distance_infinite->dist) > EPSILON);
|
||||
(!measure.distance_infinite.has_value() || std::abs(measure.distance_strict->dist - measure.distance_infinite->dist) > EPSILON);
|
||||
|
||||
if (measure.distance_infinite.has_value()) {
|
||||
if (measure.distance_infinite.has_value() && m_measure_mode == EMeasureMode::ONLY_MEASURE) {
|
||||
double distance = measure.distance_infinite->dist;
|
||||
if (use_inches)
|
||||
distance = GizmoObjectManipulation::mm_to_in * distance;
|
||||
if (m_use_inches) distance = GizmoObjectManipulation::mm_to_in * distance;
|
||||
ImGui::PushID("ClipboardDistanceInfinite");
|
||||
add_measure_row_to_table(show_strict ? _u8L("Perpendicular distance") : _u8L("Distance"), ImGuiWrapper::COL_BAMBU, format_double(distance) + units,
|
||||
ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
add_measure_row_to_table(show_strict ? _u8L("Perpendicular distance") : _u8L("Distance"), ImGuiWrapper::COL_BAMBU, format_double(distance) + m_units,
|
||||
ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
++measure_row_count;
|
||||
ImGui::PopID();
|
||||
}
|
||||
if (show_strict) {
|
||||
if (show_strict &&
|
||||
(m_measure_mode == EMeasureMode::ONLY_MEASURE ||
|
||||
(m_measure_mode == EMeasureMode::ONLY_ASSEMBLY && m_assembly_mode == AssemblyMode::POINT_POINT)))
|
||||
{
|
||||
double distance = measure.distance_strict->dist;
|
||||
if (use_inches)
|
||||
if (m_use_inches)
|
||||
distance = GizmoObjectManipulation::mm_to_in * distance;
|
||||
ImGui::PushID("ClipboardDistanceStrict");
|
||||
add_measure_row_to_table(_u8L("Direct distance"), ImGuiWrapper::COL_BAMBU, format_double(distance) + units,
|
||||
ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
add_measure_row_to_table(_u8L("Direct distance"), ImGuiWrapper::COL_BAMBU, format_double(distance) + m_units, ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
++measure_row_count;
|
||||
ImGui::PopID();
|
||||
}
|
||||
if (measure.distance_xyz.has_value()) {
|
||||
if (measure.distance_xyz.has_value() && m_measure_mode == EMeasureMode::ONLY_MEASURE) {
|
||||
Vec3d distance = *measure.distance_xyz;
|
||||
if (use_inches)
|
||||
distance = GizmoObjectManipulation::mm_to_in * distance;
|
||||
if (m_use_inches) distance = GizmoObjectManipulation::mm_to_in * distance;
|
||||
if (measure.distance_xyz->norm() > EPSILON) {
|
||||
ImGui::PushID("ClipboardDistanceXYZ");
|
||||
add_measure_row_to_table(_u8L("Distance XYZ"), ImGuiWrapper::COL_BAMBU, format_vec3(distance), ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
@ -2078,8 +1984,10 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit
|
||||
}
|
||||
}
|
||||
|
||||
if (m_distance.norm() >0.01) {
|
||||
add_edit_distance_xyz_box(m_distance);
|
||||
if (m_distance.norm() > 0.01) {
|
||||
if (!(m_measure_mode == EMeasureMode::ONLY_ASSEMBLY && m_assembly_mode == AssemblyMode::FACE_FACE)) {
|
||||
add_edit_distance_xyz_box(m_distance);
|
||||
}
|
||||
}
|
||||
}
|
||||
// add dummy rows to keep dialog size fixed
|
||||
@ -2087,97 +1995,149 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit
|
||||
add_strings_row_to_table(*m_imgui, " ", ImGuiWrapper::COL_BAMBU, " ", ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
}*/
|
||||
ImGui::EndTable();
|
||||
if (m_hit_different_volumes.size() == 2 && m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Plane &&
|
||||
m_selected_features.second.feature->get_type() == Measure::SurfaceFeatureType::Plane) {
|
||||
ImGui::Separator();
|
||||
auto &action = m_assembly_action;
|
||||
auto set_to_parallel_size = m_imgui->calc_button_size(_L("Parallel")).x;
|
||||
auto set_to_center_coincidence_size = m_imgui->calc_button_size(_L("Center coincidence")).x;
|
||||
auto feature_text_size = m_imgui->calc_button_size(_L("Featue 1")).x + m_imgui->calc_button_size(":").x;
|
||||
auto set_to_reverse_rotation_size = m_imgui->calc_button_size(_L("Reverse rotation")).x;
|
||||
auto rotate_around_center_size = m_imgui->calc_button_size(_L("Rotate around center:")).x;
|
||||
auto parallel_distance_size = m_imgui->calc_button_size(_L("Parallel_distance:")).x;
|
||||
//set_feature_1
|
||||
if (action.can_set_feature_1_reverse_rotation) {
|
||||
m_imgui->text(_L("Featue 1") + ":");
|
||||
{
|
||||
ImGui::SameLine(feature_text_size + space_size);
|
||||
ImGui::PushItemWidth(set_to_reverse_rotation_size);
|
||||
if (m_imgui->button(_L("Reverse rotation"))) {
|
||||
set_to_reverse_rotation(same_model_object, 0);
|
||||
}
|
||||
//ImGui::SameLine(set_to_reverse1_rotation_size + 2 * space_size);
|
||||
}
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_imgui->text(_L("Featue 2") + ":");
|
||||
ImGui::SameLine(feature_text_size + space_size);
|
||||
m_imgui->disabled_begin(!action.can_set_feature_2_reverse_rotation);
|
||||
{
|
||||
ImGui::PushItemWidth(set_to_reverse_rotation_size);
|
||||
ImGui::PushID("Featue2");
|
||||
if (m_imgui->button(_L("Reverse rotation"))) {
|
||||
set_to_reverse_rotation(same_model_object, 1);
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
void GLGizmoMeasure::show_point_point_assembly()
|
||||
{
|
||||
}
|
||||
|
||||
m_imgui->disabled_begin(!action.can_set_to_parallel);
|
||||
{
|
||||
if (m_imgui->button(_L("Parallel"))) {
|
||||
set_to_parallel(same_model_object);
|
||||
}
|
||||
ImGui::SameLine(set_to_parallel_size + space_size *2);
|
||||
void GLGizmoMeasure::show_face_face_assembly()
|
||||
{
|
||||
if (m_measure_mode == EMeasureMode::ONLY_ASSEMBLY && m_hit_different_volumes.size() == 2 &&
|
||||
m_selected_features.first.feature->get_type() == Measure::SurfaceFeatureType::Plane &&
|
||||
m_selected_features.second.feature->get_type() == Measure::SurfaceFeatureType::Plane) {
|
||||
auto &action = m_assembly_action;
|
||||
auto set_to_parallel_size = m_imgui->calc_button_size(_L("Parallel")).x;
|
||||
auto set_to_center_coincidence_size = m_imgui->calc_button_size(_L("Center coincidence")).x;
|
||||
auto feature_text_size = m_imgui->calc_button_size(_L("Featue 1")).x + m_imgui->calc_button_size(":").x;
|
||||
auto set_to_reverse_rotation_size = m_imgui->calc_button_size(_L("Reverse rotation")).x;
|
||||
auto rotate_around_center_size = m_imgui->calc_button_size(_L("Rotate around center:")).x;
|
||||
auto parallel_distance_size = m_imgui->calc_button_size(_L("Parallel_distance:")).x;
|
||||
// set_feature_1//keep code
|
||||
//if (action.can_set_feature_1_reverse_rotation) {
|
||||
// m_imgui->text(_L("Featue 1") + ":");
|
||||
// {
|
||||
// ImGui::SameLine(feature_text_size + m_space_size);
|
||||
// ImGui::PushItemWidth(set_to_reverse_rotation_size);
|
||||
// if (m_imgui->button(_L("Reverse rotation"))) {
|
||||
// set_to_reverse_rotation(m_same_model_object, 0);
|
||||
// }
|
||||
// // ImGui::SameLine(set_to_reverse1_rotation_size + 2 * space_size);
|
||||
// }
|
||||
// ImGui::Separator();
|
||||
//}
|
||||
//m_imgui->text(_L("Featue 2") + ":");
|
||||
m_imgui->disabled_begin(!(action.can_set_to_center_coincidence));
|
||||
{
|
||||
ImGui::PushItemWidth(set_to_center_coincidence_size);
|
||||
if (m_imgui->button(_L("Center coincidence"))) {
|
||||
set_to_center_coincidence(m_same_model_object);
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
ImGui::SameLine(set_to_center_coincidence_size + m_space_size * 2);
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
|
||||
m_imgui->disabled_begin(!(action.can_set_to_center_coincidence));
|
||||
{
|
||||
ImGui::PushItemWidth(set_to_center_coincidence_size);
|
||||
if (m_imgui->button(_L("Center coincidence"))) {
|
||||
set_to_center_coincidence(same_model_object);
|
||||
}
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
|
||||
if (action.has_parallel_distance) {
|
||||
m_imgui->text(_u8L("Parallel_distance:"));
|
||||
ImGui::SameLine(parallel_distance_size + space_size);
|
||||
ImGui::PushItemWidth(input_size_max);
|
||||
ImGui::BBLInputDouble("##parallel_distance_z", &m_buffered_parallel_distance, 0.0f, 0.0f, "%.2f");
|
||||
if (m_last_active_item_imgui != current_active_id && std::abs(m_buffered_parallel_distance - action.parallel_distance) > EPSILON) {
|
||||
set_parallel_distance(same_model_object, m_buffered_parallel_distance);
|
||||
}
|
||||
}
|
||||
if (action.can_around_center_of_faces) {
|
||||
m_imgui->text(_u8L("Rotate around center:"));
|
||||
ImGui::SameLine(rotate_around_center_size + space_size);
|
||||
ImGui::PushItemWidth(input_size_max);
|
||||
ImGui::BBLInputDouble("##rotate_around_center", &m_buffered_around_center, 0.0f, 0.0f, "%.2f");
|
||||
if (m_last_active_item_imgui != current_active_id && std::abs(m_buffered_around_center) > EPSILON) {
|
||||
set_to_around_center_of_faces(same_model_object, m_buffered_around_center);
|
||||
m_buffered_around_center = 0;
|
||||
}
|
||||
ImGui::SameLine(rotate_around_center_size + space_size + input_size_max+ space_size / 2.0f);
|
||||
m_imgui->text(_L("°"));
|
||||
m_imgui->disabled_begin(!action.can_set_to_parallel);
|
||||
{
|
||||
if (m_imgui->button(_L("Parallel"))) {
|
||||
set_to_parallel(m_same_model_object);
|
||||
}
|
||||
}
|
||||
}
|
||||
render_input_window_warning(same_model_object);
|
||||
m_imgui->disabled_end();
|
||||
|
||||
if (m_imgui->bbl_checkbox(_L("Flip by Face 2"), m_flip_volume_2)) {
|
||||
set_to_reverse_rotation(m_same_model_object, 1);
|
||||
}
|
||||
/*ImGui::SameLine(feature_text_size + m_space_size);
|
||||
m_imgui->disabled_begin(!action.can_set_feature_2_reverse_rotation);
|
||||
{
|
||||
ImGui::PushItemWidth(set_to_reverse_rotation_size);
|
||||
ImGui::PushID("Featue2");
|
||||
if (m_imgui->button(_L("Reverse rotation"))) {
|
||||
set_to_reverse_rotation(m_same_model_object, 1);
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
m_imgui->disabled_end();*/
|
||||
|
||||
if (action.has_parallel_distance) {
|
||||
m_imgui->text(_u8L("Parallel_distance:"));
|
||||
ImGui::SameLine(parallel_distance_size + m_space_size);
|
||||
ImGui::PushItemWidth(m_input_size_max);
|
||||
ImGui::BBLInputDouble("##parallel_distance_z", &m_buffered_parallel_distance, 0.0f, 0.0f, "%.2f");
|
||||
if (m_last_active_item_imgui != m_current_active_imgui_id && std::abs(m_buffered_parallel_distance - action.parallel_distance) > EPSILON) {
|
||||
set_parallel_distance(m_same_model_object, m_buffered_parallel_distance);
|
||||
}
|
||||
}
|
||||
if (action.can_around_center_of_faces) {
|
||||
m_imgui->text(_u8L("Rotate around center:"));
|
||||
ImGui::SameLine(rotate_around_center_size + m_space_size);
|
||||
ImGui::PushItemWidth(m_input_size_max);
|
||||
ImGui::BBLInputDouble("##rotate_around_center", &m_buffered_around_center, 0.0f, 0.0f, "%.2f");
|
||||
if (m_last_active_item_imgui != m_current_active_imgui_id && std::abs(m_buffered_around_center) > EPSILON) {
|
||||
set_to_around_center_of_faces(m_same_model_object, m_buffered_around_center);
|
||||
m_buffered_around_center = 0;
|
||||
}
|
||||
ImGui::SameLine(rotate_around_center_size + m_space_size + m_input_size_max + m_space_size / 2.0f);
|
||||
m_imgui->text(_L("°"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoMeasure::init_render_input_window()
|
||||
{
|
||||
m_use_inches = wxGetApp().app_config->get("use_inches") == "1";
|
||||
m_units = m_use_inches ? " " + _u8L("in") : " " + _u8L("mm");
|
||||
m_space_size = ImGui::CalcTextSize(" ").x * 2;
|
||||
m_input_size_max = ImGui::CalcTextSize("-100.00").x * 1.2;
|
||||
m_same_model_object = is_two_volume_in_same_model_object();
|
||||
}
|
||||
|
||||
void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit)
|
||||
{
|
||||
static std::optional<Measure::SurfaceFeature> last_feature;
|
||||
static EMode last_mode = EMode::FeatureSelection;
|
||||
static SelectedFeatures last_selected_features;
|
||||
|
||||
static float last_y = 0.0f;
|
||||
static float last_h = 0.0f;
|
||||
|
||||
if (m_editing_distance)
|
||||
return;
|
||||
m_current_active_imgui_id = ImGui::GetActiveID();
|
||||
// adjust window position to avoid overlap the view toolbar
|
||||
const float win_h = ImGui::GetWindowHeight();
|
||||
y = std::min(y, bottom_limit - win_h);
|
||||
GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f);
|
||||
if (last_h != win_h || last_y != y) {
|
||||
// ask canvas for another frame to render the window in the correct position
|
||||
m_imgui->set_requires_extra_frame();
|
||||
if (last_h != win_h)
|
||||
last_h = win_h;
|
||||
if (last_y != y)
|
||||
last_y = y;
|
||||
}
|
||||
ImGuiWrapper::push_toolbar_style(m_parent.get_scale());
|
||||
GizmoImguiBegin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
|
||||
|
||||
init_render_input_window();
|
||||
show_selection_ui();
|
||||
|
||||
ImGui::Separator();
|
||||
show_distance_xyz_ui();
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f));
|
||||
float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y;
|
||||
float caption_max = 0.f;
|
||||
float total_text_max = 0.f;
|
||||
for (const auto &t : std::array<std::string, 3>{"point_selection", "reset", "unselect"}) {
|
||||
caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc[t + "_caption"]).x);
|
||||
total_text_max = std::max(total_text_max, m_imgui->calc_text_size(m_desc[t]).x);
|
||||
}
|
||||
show_tooltip_information(caption_max, x, get_cur_y);
|
||||
|
||||
float f_scale =m_parent.get_gizmos_manager().get_layout_scale();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale));
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
ImGui::PopStyleVar(1);
|
||||
if (last_feature != m_curr_feature || last_mode != m_mode || last_selected_features != m_selected_features) {
|
||||
// the dialog may have changed its size, ask for an extra frame to render it properly
|
||||
last_feature = m_curr_feature;
|
||||
@ -2185,22 +2145,14 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit
|
||||
last_selected_features = m_selected_features;
|
||||
m_imgui->set_requires_extra_frame();
|
||||
}
|
||||
m_last_active_item_imgui = current_active_id;
|
||||
m_last_active_item_imgui = m_current_active_imgui_id;
|
||||
GizmoImguiEnd();
|
||||
|
||||
// Orca
|
||||
ImGuiWrapper::pop_toolbar_style();
|
||||
}
|
||||
|
||||
void GLGizmoMeasure::render_input_window_warning(bool same_model_object)
|
||||
{
|
||||
if (wxGetApp().plater()->canvas3D()->get_canvas_type() == GLCanvas3D::ECanvasType::CanvasView3D) {
|
||||
if (m_hit_different_volumes.size() == 2) {
|
||||
if (same_model_object == false) {
|
||||
m_imgui->text(_L("Warning") + ": " + _L("Due to ensuer_on_bed, assembly between \ndifferent objects may not be correct in 3D view.\n It is recommended to assemble them together."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoMeasure::remove_selected_sphere_raycaster(int id)
|
||||
@ -2355,6 +2307,7 @@ void GLGizmoMeasure::reset_feature2_render()
|
||||
|
||||
void GLGizmoMeasure::reset_feature1()
|
||||
{
|
||||
m_selected_wrong_feature_waring_tip = false;
|
||||
reset_feature1_render();
|
||||
if (m_selected_features.second.feature.has_value()) {
|
||||
if (m_hit_different_volumes.size() == 2) {
|
||||
@ -2395,6 +2348,7 @@ void GLGizmoMeasure::reset_feature2()
|
||||
remove_selected_sphere_raycaster(SEL_SPHERE_2_ID);
|
||||
m_selected_features.second.reset();
|
||||
m_show_reset_first_tip = false;
|
||||
m_selected_wrong_feature_waring_tip = false;
|
||||
reset_gripper_pick(GripperType::PLANE_2);
|
||||
reset_gripper_pick(GripperType::CIRCLE_2);
|
||||
reset_gripper_pick(GripperType::SPHERE_2);
|
||||
@ -2677,5 +2631,22 @@ void GLGizmoMeasure::set_parallel_distance(bool same_model_object, float dist)
|
||||
}
|
||||
}
|
||||
|
||||
bool GLGizmoMeasure::is_pick_meet_assembly_mode(const SelectedFeatures::Item &item) {
|
||||
if (m_measure_mode == EMeasureMode::ONLY_ASSEMBLY) {
|
||||
if (m_assembly_mode == AssemblyMode::FACE_FACE && item.feature->get_type() == Measure::SurfaceFeatureType::Plane) {
|
||||
return true;
|
||||
}
|
||||
if (m_assembly_mode == AssemblyMode::POINT_POINT &&
|
||||
(item.feature->get_type() == Measure::SurfaceFeatureType::Point||
|
||||
item.feature->get_type() == Measure::SurfaceFeatureType::Circle)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
@ -15,9 +15,66 @@ namespace Measure { class Measuring; }
|
||||
namespace GUI {
|
||||
|
||||
enum class SLAGizmoEventType : unsigned char;
|
||||
enum class EMeasureMode : unsigned char {
|
||||
ONLY_MEASURE,
|
||||
ONLY_ASSEMBLY
|
||||
};
|
||||
enum class AssemblyMode : unsigned char {
|
||||
FACE_FACE,
|
||||
POINT_POINT,
|
||||
};
|
||||
static const Slic3r::ColorRGBA SELECTED_1ST_COLOR = {0.25f, 0.75f, 0.75f, 1.0f};
|
||||
static const Slic3r::ColorRGBA SELECTED_2ND_COLOR = {0.75f, 0.25f, 0.75f, 1.0f};
|
||||
static const Slic3r::ColorRGBA NEUTRAL_COLOR = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
static const Slic3r::ColorRGBA HOVER_COLOR = {0.0f, 1.0f, 0.0f, 1.0f}; // Green
|
||||
|
||||
static const int POINT_ID = 100;
|
||||
static const int EDGE_ID = 200;
|
||||
static const int CIRCLE_ID = 300;
|
||||
static const int PLANE_ID = 400;
|
||||
static const int SEL_SPHERE_1_ID = 501;
|
||||
static const int SEL_SPHERE_2_ID = 502;
|
||||
|
||||
static const float TRIANGLE_BASE = 10.0f;
|
||||
static const float TRIANGLE_HEIGHT = TRIANGLE_BASE * 1.618033f;
|
||||
|
||||
static const std::string CTRL_STR =
|
||||
#ifdef __APPLE__
|
||||
"⌘"
|
||||
#else
|
||||
"Ctrl"
|
||||
#endif //__APPLE__
|
||||
;
|
||||
|
||||
class TransformHelper
|
||||
{
|
||||
struct Cache
|
||||
{
|
||||
std::array<int, 4> viewport;
|
||||
Matrix4d ndc_to_ss_matrix;
|
||||
Transform3d ndc_to_ss_matrix_inverse;
|
||||
};
|
||||
static Cache s_cache;
|
||||
|
||||
public:
|
||||
static Vec3d model_to_world(const Vec3d &model, const Transform3d &world_matrix);
|
||||
static Vec4d world_to_clip(const Vec3d &world, const Matrix4d &projection_view_matrix);
|
||||
static Vec3d clip_to_ndc(const Vec4d &clip);
|
||||
static Vec2d ndc_to_ss(const Vec3d &ndc, const std::array<int, 4> &viewport);
|
||||
static Vec4d model_to_clip(const Vec3d &model, const Transform3d &world_matrix, const Matrix4d &projection_view_matrix);
|
||||
static Vec3d model_to_ndc(const Vec3d &model, const Transform3d &world_matrix, const Matrix4d &projection_view_matrix);
|
||||
static Vec2d model_to_ss(const Vec3d &model, const Transform3d &world_matrix, const Matrix4d &projection_view_matrix, const std::array<int, 4> &viewport);
|
||||
static Vec2d world_to_ss(const Vec3d &world, const Matrix4d &projection_view_matrix, const std::array<int, 4> &viewport);
|
||||
static const Matrix4d & ndc_to_ss_matrix(const std::array<int, 4> &viewport);
|
||||
static const Transform3d ndc_to_ss_matrix_inverse(const std::array<int, 4> &viewport);
|
||||
|
||||
private:
|
||||
static void update(const std::array<int, 4> &viewport);
|
||||
};
|
||||
|
||||
class GLGizmoMeasure : public GLGizmoBase
|
||||
{
|
||||
protected:
|
||||
enum class EMode : unsigned char
|
||||
{
|
||||
FeatureSelection,
|
||||
@ -116,8 +173,6 @@ class GLGizmoMeasure : public GLGizmoBase
|
||||
GLModel arc;
|
||||
};
|
||||
Dimensioning m_dimensioning;
|
||||
bool m_show_reset_first_tip{false};
|
||||
|
||||
|
||||
std::map<GLVolume*, std::shared_ptr<PickRaycaster>> m_mesh_raycaster_map;
|
||||
std::vector<GLVolume*> m_hit_different_volumes;
|
||||
@ -172,7 +227,7 @@ public:
|
||||
|
||||
void data_changed(bool is_serializing) override;
|
||||
|
||||
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
|
||||
virtual bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
|
||||
|
||||
bool wants_enter_leave_snapshots() const override { return true; }
|
||||
std::string get_gizmo_entering_text() const override { return _u8L("Entering Measure gizmo"); }
|
||||
@ -187,9 +242,14 @@ protected:
|
||||
void on_set_state() override;
|
||||
|
||||
virtual void on_render_for_picking() override;
|
||||
void show_selection_ui();
|
||||
void show_distance_xyz_ui();
|
||||
void show_point_point_assembly();
|
||||
void show_face_face_assembly();
|
||||
void init_render_input_window();
|
||||
virtual void on_render_input_window(float x, float y, float bottom_limit) override;
|
||||
|
||||
void render_input_window_warning(bool same_model_object);
|
||||
virtual void render_input_window_warning(bool same_model_object);
|
||||
void remove_selected_sphere_raycaster(int id);
|
||||
void update_measurement_result();
|
||||
|
||||
@ -199,6 +259,14 @@ protected:
|
||||
void register_single_mesh_pick();
|
||||
void update_single_mesh_pick(GLVolume* v);
|
||||
|
||||
std::string format_double(double value);
|
||||
std::string format_vec3(const Vec3d &v);
|
||||
std::string surface_feature_type_as_string(Measure::SurfaceFeatureType type);
|
||||
std::string point_on_feature_type_as_string(Measure::SurfaceFeatureType type, int hover_id);
|
||||
std::string center_on_feature_type_as_string(Measure::SurfaceFeatureType type);
|
||||
bool is_feature_with_center(const Measure::SurfaceFeature &feature);
|
||||
Vec3d get_feature_offset(const Measure::SurfaceFeature &feature);
|
||||
|
||||
void reset_all_feature();
|
||||
void reset_feature1_render();
|
||||
void reset_feature2_render();
|
||||
@ -214,10 +282,23 @@ protected:
|
||||
void set_to_around_center_of_faces(bool same_model_object,float rotate_degree);
|
||||
void set_to_center_coincidence(bool same_model_object);
|
||||
void set_parallel_distance(bool same_model_object,float dist);
|
||||
private:
|
||||
|
||||
bool is_pick_meet_assembly_mode(const SelectedFeatures::Item& item);
|
||||
protected:
|
||||
// This map holds all translated description texts, so they can be easily referenced during layout calculations
|
||||
// etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect.
|
||||
std::map<std::string, wxString> m_desc;
|
||||
bool m_show_reset_first_tip{false};
|
||||
bool m_selected_wrong_feature_waring_tip{false};
|
||||
EMeasureMode m_measure_mode{EMeasureMode::ONLY_MEASURE};
|
||||
AssemblyMode m_assembly_mode{AssemblyMode::FACE_FACE};
|
||||
bool m_flip_volume_2{false};
|
||||
float m_space_size;
|
||||
float m_input_size_max;
|
||||
bool m_use_inches;
|
||||
std::string m_units;
|
||||
mutable bool m_same_model_object;
|
||||
mutable unsigned int m_current_active_imgui_id;
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoSimplify.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoText.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoMeshBoolean.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoMeasure.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoAssembly.hpp"
|
||||
|
||||
#include "libslic3r/format.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
@ -62,6 +62,7 @@ std::vector<size_t> GLGizmosManager::get_selectable_idxs() const
|
||||
if (m_gizmos[i]->get_sprite_id() == (unsigned int) Move ||
|
||||
m_gizmos[i]->get_sprite_id() == (unsigned int) Rotate ||
|
||||
m_gizmos[i]->get_sprite_id() == (unsigned int) Measure ||
|
||||
m_gizmos[i]->get_sprite_id() == (unsigned int) Assembly ||
|
||||
m_gizmos[i]->get_sprite_id() == (unsigned int) MmuSegmentation)
|
||||
out.push_back(i);
|
||||
}
|
||||
@ -182,6 +183,9 @@ void GLGizmosManager::switch_gizmos_icon_filename()
|
||||
case (EType::Measure):
|
||||
gizmo->set_icon_filename(m_is_dark ? "toolbar_measure_dark.svg" : "toolbar_measure.svg");
|
||||
break;
|
||||
case (EType::Assembly):
|
||||
gizmo->set_icon_filename(m_is_dark ? "toolbar_assembly_dark.svg" : "toolbar_assembly.svg");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
@ -219,6 +223,7 @@ bool GLGizmosManager::init()
|
||||
m_gizmos.emplace_back(new GLGizmoText(m_parent, m_is_dark ? "toolbar_text_dark.svg" : "toolbar_text.svg", EType::Text));
|
||||
m_gizmos.emplace_back(new GLGizmoMmuSegmentation(m_parent, m_is_dark ? "mmu_segmentation_dark.svg" : "mmu_segmentation.svg", EType::MmuSegmentation));
|
||||
m_gizmos.emplace_back(new GLGizmoMeasure(m_parent, m_is_dark ? "toolbar_measure_dark.svg" : "toolbar_measure.svg", EType::Measure));
|
||||
m_gizmos.emplace_back(new GLGizmoAssembly(m_parent, m_is_dark ? "toolbar_assembly_dark.svg" : "toolbar_assembly.svg", EType::Assembly));
|
||||
m_gizmos.emplace_back(new GLGizmoSimplify(m_parent, "reduce_triangles.svg", EType::Simplify));
|
||||
//m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", sprite_id++));
|
||||
//m_gizmos.emplace_back(new GLGizmoFaceDetector(m_parent, "face recognition.svg", sprite_id++));
|
||||
@ -385,7 +390,7 @@ bool GLGizmosManager::check_gizmos_closed_except(EType type) const
|
||||
|
||||
void GLGizmosManager::set_hover_id(int id)
|
||||
{
|
||||
if (m_current == EType::Measure) { return; }
|
||||
if (m_current == EType::Measure || m_current == EType::Assembly) { return; }
|
||||
if (!m_enabled || m_current == Undefined)
|
||||
return;
|
||||
|
||||
@ -663,7 +668,8 @@ bool GLGizmosManager::is_gizmo_click_empty_not_exit()
|
||||
get_current_type() == GLGizmosManager::EType::Seam ||
|
||||
get_current_type() == GLGizmosManager::EType::FdmSupports ||
|
||||
get_current_type() == GLGizmosManager::EType::MmuSegmentation ||
|
||||
get_current_type() == GLGizmosManager::EType::Measure) {
|
||||
get_current_type() == GLGizmosManager::EType::Measure ||
|
||||
get_current_type() == GLGizmosManager::EType::Assembly) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -730,6 +736,8 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p
|
||||
return dynamic_cast<GLGizmoText*>(m_gizmos[Text].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||
else if (m_current == Measure)
|
||||
return dynamic_cast<GLGizmoMeasure *>(m_gizmos[Measure].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||
else if (m_current == Assembly)
|
||||
return dynamic_cast<GLGizmoAssembly *>(m_gizmos[Assembly].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||
else if (m_current == Cut)
|
||||
return dynamic_cast<GLGizmoAdvancedCut *>(m_gizmos[Cut].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||
else if (m_current == MeshBoolean)
|
||||
@ -1020,7 +1028,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
||||
// the gizmo got the event and took some action, there is no need to do anything more
|
||||
processed = true;
|
||||
else if (!selection.is_empty() && grabber_contains_mouse()) {
|
||||
if (m_current != Measure) {
|
||||
if (!(m_current == Measure || m_current == Assembly)) {
|
||||
update_data();
|
||||
selection.start_dragging();
|
||||
start_dragging();
|
||||
@ -1168,7 +1176,7 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt)
|
||||
case WXK_ESCAPE:
|
||||
{
|
||||
if (m_current != Undefined) {
|
||||
if (m_current == Measure && gizmo_event(SLAGizmoEventType::Escape)) {
|
||||
if ((m_current == Measure || m_current == Assembly) && gizmo_event(SLAGizmoEventType::Escape)) {
|
||||
// do nothing
|
||||
} else if ((m_current != SlaSupports) || !gizmo_event(SLAGizmoEventType::DiscardChanges))
|
||||
reset_all_states();
|
||||
@ -1206,7 +1214,7 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt)
|
||||
|
||||
//case WXK_BACK:
|
||||
case WXK_DELETE: {
|
||||
if ((m_current == Cut || m_current == Measure) && gizmo_event(SLAGizmoEventType::Delete))
|
||||
if ((m_current == Cut || m_current == Measure || m_current == Assembly) && gizmo_event(SLAGizmoEventType::Delete))
|
||||
processed = true;
|
||||
break;
|
||||
}
|
||||
@ -1313,7 +1321,7 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
if (m_current == Measure) {
|
||||
if (m_current == Measure || m_current == Assembly) {
|
||||
if (keyCode == WXK_CONTROL)
|
||||
gizmo_event(SLAGizmoEventType::CtrlUp, Vec2d::Zero(), evt.ShiftDown(), evt.AltDown(), evt.CmdDown());
|
||||
else if (keyCode == WXK_SHIFT)
|
||||
@ -1400,7 +1408,7 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
|
||||
// force extra frame to automatically update window size
|
||||
wxGetApp().imgui()->set_requires_extra_frame();
|
||||
}
|
||||
} else if (m_current == Measure) {
|
||||
} else if (m_current == Measure || m_current == Assembly) {
|
||||
if (keyCode == WXK_CONTROL)
|
||||
gizmo_event(SLAGizmoEventType::CtrlDown, Vec2d::Zero(), evt.ShiftDown(), evt.AltDown(), evt.CmdDown());
|
||||
else if (keyCode == WXK_SHIFT)
|
||||
|
@ -79,6 +79,7 @@ public:
|
||||
Text,
|
||||
MmuSegmentation,
|
||||
Measure,
|
||||
Assembly,
|
||||
Simplify,
|
||||
SlaSupports,
|
||||
// BBS
|
||||
|
@ -263,9 +263,6 @@ ObjColorPanel::ObjColorPanel(wxWindow * parent,
|
||||
specify_cluster_sizer->Add(specify_color_cluster_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
|
||||
m_color_cluster_num_by_user_ebox = new wxTextCtrl(m_page_simple, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(25), -1), wxTE_PROCESS_ENTER);
|
||||
if (m_color_num_recommend == 1) {
|
||||
m_color_cluster_num_by_user_ebox->Enable(false);
|
||||
}
|
||||
m_color_cluster_num_by_user_ebox->SetValue(std::to_string(m_color_cluster_num_by_algo).c_str());
|
||||
{//event
|
||||
auto on_apply_color_cluster_text_modify = [this](wxEvent &e) {
|
||||
@ -674,7 +671,7 @@ void ObjColorPanel::draw_table()
|
||||
m_gridsizer->Add(row_panel, 0, wxALIGN_LEFT | wxALL, FromDIP(HEADER_BORDER));
|
||||
}
|
||||
m_scrolledWindow->SetSizer(m_gridsizer);
|
||||
int totalHeight = row_height *(row+1);
|
||||
int totalHeight = row_height *(row+1) * 2;
|
||||
m_scrolledWindow->SetVirtualSize(MIN_OBJCOLOR_DIALOG_WIDTH, totalHeight);
|
||||
auto look = FIX_SCROLL_HEIGTH;
|
||||
if (totalHeight > FIX_SCROLL_HEIGTH) {
|
||||
@ -736,7 +733,7 @@ void ObjColorPanel::deal_add_btn()
|
||||
int new_index = m_colours.size() + 1;
|
||||
for (size_t i = 0; i < new_color_size; i++) {
|
||||
if (m_colours.size() + new_icons.size() >= g_max_color) {
|
||||
m_warning_text->SetLabelText(_L("Waring:The count of newly added and current extruders exceeds 16."));
|
||||
m_warning_text->SetLabelText(_L("Waring:The count of newly added and \n current extruders exceeds 16."));
|
||||
break;
|
||||
}
|
||||
wxColour cur_color = convert_to_wxColour(m_cluster_colors_from_algo[i]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user