ENH:Improve the performance of the cutting tool and avoid cutting unless necessary.

jira: STUDIO-11452
code is form PrusaSlicer,thanks for PrusaSlicer and enricoturri1966
commit 224ee922c52334f944b709d600b8cd7f134d2a6d
Author: enricoturri1966 <enricoturri@seznam.cz>
Date:   Thu Feb 9 15:03:39 2023 +0100

    'gouraud' shader modified to allow to draw an object with two different colors in Cut Gizmo

Change-Id: I4ebeb48faa045b93226b24c3704d4edd4bf6f882
This commit is contained in:
zhou.xu 2025-04-18 18:13:40 +08:00 committed by lane.wei
parent e5c9c0fa65
commit 6063b11e9c
16 changed files with 230 additions and 103 deletions

View File

@ -30,6 +30,10 @@ struct SlopeDetection
}; };
uniform vec4 uniform_color; uniform vec4 uniform_color;
uniform bool use_color_clip_plane;
uniform vec4 uniform_color_clip_plane_1;
uniform vec4 uniform_color_clip_plane_2;
uniform vec4 color_clip_plane;
uniform SlopeDetection slope; uniform SlopeDetection slope;
//BBS: add outline_color //BBS: add outline_color
@ -60,6 +64,13 @@ void main()
vec3 color = uniform_color.rgb; vec3 color = uniform_color.rgb;
float alpha = uniform_color.a; float alpha = uniform_color.a;
if (use_color_clip_plane){
float color_clip_plane_dot = dot(world_pos, color_clip_plane);
vec4 full_color = (color_clip_plane_dot < EPSILON) ? uniform_color_clip_plane_1 : uniform_color_clip_plane_2;
color = full_color.rgb;
alpha = full_color.a;
}
if (slope.actived) { if (slope.actived) {
if(world_pos.z<0.1&&world_pos.z>-0.1) if(world_pos.z<0.1&&world_pos.z>-0.1)
{ {

View File

@ -30,6 +30,10 @@ struct SlopeDetection
}; };
uniform vec4 uniform_color; uniform vec4 uniform_color;
uniform bool use_color_clip_plane;
uniform vec4 uniform_color_clip_plane_1;
uniform vec4 uniform_color_clip_plane_2;
uniform vec4 color_clip_plane;
uniform SlopeDetection slope; uniform SlopeDetection slope;
//BBS: add outline_color //BBS: add outline_color
@ -62,6 +66,13 @@ void main()
vec3 color = uniform_color.rgb; vec3 color = uniform_color.rgb;
float alpha = uniform_color.a; float alpha = uniform_color.a;
if (use_color_clip_plane){
float color_clip_plane_dot = dot(world_pos, color_clip_plane);
vec4 full_color = (color_clip_plane_dot < EPSILON) ? uniform_color_clip_plane_1 : uniform_color_clip_plane_2;
color = full_color.rgb;
alpha = full_color.a;
}
if (slope.actived) { if (slope.actived) {
if(world_pos.z<0.1&&world_pos.z>-0.1) if(world_pos.z<0.1&&world_pos.z>-0.1)
{ {

View File

@ -15,12 +15,19 @@ namespace Slic3r {
// The stored pointer is not checked for being null when dereferenced. // The stored pointer is not checked for being null when dereferenced.
// //
// This is a movable only object due to the fact that it can possibly hold // This is a movable only object due to the fact that it can possibly hold
// a unique_ptr which a non-copy. // a unique_ptr which can only be moved.
template<class T> //
class AnyPtr { // Drawbacks:
enum { RawPtr, UPtr, ShPtr, WkPtr }; // No custom deleters are supported when storing a unique_ptr, but overloading
// std::default_delete for a particular type could be a workaround
//
// raw array types are problematic, since std::default_delete also does not
// support them well.
template<class T> class AnyPtr
{
enum { RawPtr, UPtr, ShPtr };
boost::variant<T*, std::unique_ptr<T>, std::shared_ptr<T>, std::weak_ptr<T>> ptr; boost::variant<T *, std::unique_ptr<T>, std::shared_ptr<T>> ptr;
template<class Self> static T *get_ptr(Self &&s) template<class Self> static T *get_ptr(Self &&s)
{ {
@ -28,101 +35,108 @@ class AnyPtr {
case RawPtr: return boost::get<T *>(s.ptr); case RawPtr: return boost::get<T *>(s.ptr);
case UPtr: return boost::get<std::unique_ptr<T>>(s.ptr).get(); case UPtr: return boost::get<std::unique_ptr<T>>(s.ptr).get();
case ShPtr: return boost::get<std::shared_ptr<T>>(s.ptr).get(); case ShPtr: return boost::get<std::shared_ptr<T>>(s.ptr).get();
case WkPtr: {
auto shptr = boost::get<std::weak_ptr<T>>(s.ptr).lock();
return shptr.get();
}
} }
return nullptr; return nullptr;
} }
public: template<class TT> friend class AnyPtr;
template<class TT = T, class = std::enable_if_t<std::is_convertible_v<TT, T>>>
AnyPtr(TT *p = nullptr) : ptr{p}
{}
template<class TT, class = std::enable_if_t<std::is_convertible_v<TT, T>>>
AnyPtr(std::unique_ptr<TT> p) : ptr{std::unique_ptr<T>(std::move(p))}
{}
template<class TT, class = std::enable_if_t<std::is_convertible_v<TT, T>>>
AnyPtr(std::shared_ptr<TT> p) : ptr{std::shared_ptr<T>(std::move(p))}
{}
template<class TT, class = std::enable_if_t<std::is_convertible_v<TT, T>>>
AnyPtr(std::weak_ptr<TT> p) : ptr{std::weak_ptr<T>(std::move(p))}
{}
~AnyPtr() = default; template<class TT> using SimilarPtrOnly = std::enable_if_t<std::is_convertible_v<TT *, T *>>;
public:
AnyPtr() noexcept = default;
AnyPtr(T *p) noexcept : ptr{p} {}
AnyPtr(std::nullptr_t) noexcept {};
template<class TT, class = SimilarPtrOnly<TT>> AnyPtr(TT *p) noexcept : ptr{p} {}
template<class TT = T, class = SimilarPtrOnly<TT>> AnyPtr(std::unique_ptr<TT> p) noexcept : ptr{std::unique_ptr<T>(std::move(p))} {}
template<class TT = T, class = SimilarPtrOnly<TT>> AnyPtr(std::shared_ptr<TT> p) noexcept : ptr{std::shared_ptr<T>(std::move(p))} {}
AnyPtr(AnyPtr &&other) noexcept : ptr{std::move(other.ptr)} {} AnyPtr(AnyPtr &&other) noexcept : ptr{std::move(other.ptr)} {}
template<class TT, class = SimilarPtrOnly<TT>> AnyPtr(AnyPtr<TT> &&other) noexcept { this->operator=(std::move(other)); }
AnyPtr(const AnyPtr &other) = delete; AnyPtr(const AnyPtr &other) = delete;
AnyPtr &operator=(AnyPtr &&other) noexcept { ptr = std::move(other.ptr); return *this; } AnyPtr &operator=(AnyPtr &&other) noexcept
{
ptr = std::move(other.ptr);
return *this;
}
AnyPtr &operator=(const AnyPtr &other) = delete; AnyPtr &operator=(const AnyPtr &other) = delete;
template<class TT, class = std::enable_if_t<std::is_convertible_v<TT, T>>> template<class TT, class = SimilarPtrOnly<TT>> AnyPtr &operator=(AnyPtr<TT> &&other) noexcept
AnyPtr &operator=(TT *p) { ptr = p; return *this; } {
switch (other.ptr.which()) {
case RawPtr: *this = boost::get<TT *>(other.ptr); break;
case UPtr: *this = std::move(boost::get<std::unique_ptr<TT>>(other.ptr)); break;
case ShPtr: *this = std::move(boost::get<std::shared_ptr<TT>>(other.ptr)); break;
}
template<class TT, class = std::enable_if_t<std::is_convertible_v<TT, T>>> return *this;
AnyPtr &operator=(std::unique_ptr<TT> p) { ptr = std::move(p); return *this; } }
template<class TT, class = std::enable_if_t<std::is_convertible_v<TT, T>>> template<class TT, class = SimilarPtrOnly<TT>> AnyPtr &operator=(TT *p) noexcept
AnyPtr &operator=(std::shared_ptr<TT> p) { ptr = p; return *this; } {
ptr = static_cast<T *>(p);
return *this;
}
template<class TT, class = std::enable_if_t<std::is_convertible_v<TT, T>>> template<class TT, class = SimilarPtrOnly<TT>> AnyPtr &operator=(std::unique_ptr<TT> p) noexcept
AnyPtr &operator=(std::weak_ptr<TT> p) { ptr = std::move(p); return *this; } {
ptr = std::unique_ptr<T>(std::move(p));
return *this;
}
const T &operator*() const { return *get_ptr(*this); } template<class TT, class = SimilarPtrOnly<TT>> AnyPtr &operator=(std::shared_ptr<TT> p) noexcept
T &operator*() { return *get_ptr(*this); } {
ptr = std::shared_ptr<T>(std::move(p));
return *this;
}
T *operator->() { return get_ptr(*this); } const T &operator*() const noexcept { return *get_ptr(*this); }
const T *operator->() const { return get_ptr(*this); } T & operator*() noexcept { return *get_ptr(*this); }
T *get() { return get_ptr(*this); } T * operator->() noexcept { return get_ptr(*this); }
const T *get() const { return get_ptr(*this); } const T *operator->() const noexcept { return get_ptr(*this); }
operator bool() const T * get() noexcept { return get_ptr(*this); }
const T *get() const noexcept { return get_ptr(*this); }
operator bool() const noexcept
{ {
switch (ptr.which()) { switch (ptr.which()) {
case RawPtr: return bool(boost::get<T *>(ptr)); case RawPtr: return bool(boost::get<T *>(ptr));
case UPtr: return bool(boost::get<std::unique_ptr<T>>(ptr)); case UPtr: return bool(boost::get<std::unique_ptr<T>>(ptr));
case ShPtr: return bool(boost::get<std::shared_ptr<T>>(ptr)); case ShPtr: return bool(boost::get<std::shared_ptr<T>>(ptr));
case WkPtr: {
auto shptr = boost::get<std::weak_ptr<T>>(ptr).lock();
return bool(shptr);
}
} }
return false; return false;
} }
// If the stored pointer is a shared or weak pointer, returns a reference // If the stored pointer is a shared pointer, returns a reference
// counted copy. Empty shared pointer is returned otherwise. // counted copy. Empty shared pointer is returned otherwise.
std::shared_ptr<T> get_shared_cpy() const std::shared_ptr<T> get_shared_cpy() const noexcept
{ {
std::shared_ptr<T> ret; std::shared_ptr<T> ret;
switch (ptr.which()) { if (ptr.which() == ShPtr) ret = boost::get<std::shared_ptr<T>>(ptr);
case ShPtr: ret = boost::get<std::shared_ptr<T>>(ptr); break;
case WkPtr: ret = boost::get<std::weak_ptr<T>>(ptr).lock(); break;
default:
;
}
return ret; return ret;
} }
// If the underlying pointer is unique, convert to shared pointer // If the underlying pointer is unique, convert to shared pointer
void convert_unique_to_shared() void convert_unique_to_shared() noexcept
{ {
if (ptr.which() == UPtr) if (ptr.which() == UPtr) ptr = std::shared_ptr<T>{std::move(boost::get<std::unique_ptr<T>>(ptr))};
ptr = std::shared_ptr<T>{std::move(boost::get<std::unique_ptr<T>>(ptr))};
} }
// Returns true if the data is owned by this AnyPtr instance // Returns true if the data is owned by this AnyPtr instance
bool is_owned() const noexcept bool is_owned() const noexcept { return ptr.which() == UPtr || ptr.which() == ShPtr; }
{
return ptr.which() == UPtr || ptr.which() == ShPtr;
}
}; };
} // namespace Slic3r } // namespace Slic3r

View File

@ -1684,8 +1684,12 @@ void GLVolumeCollection::render(GUI::ERenderPipelineStage render_pip
if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) { if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) {
shader->set_uniform("is_text_shape", volume.first->is_text_shape); shader->set_uniform("is_text_shape", volume.first->is_text_shape);
shader->set_uniform("uniform_color", volume.first->render_color); shader->set_uniform("uniform_color", volume.first->render_color);
shader->set_uniform("z_range", m_z_range, 2); shader->set_uniform("z_range", m_z_range);
shader->set_uniform("clipping_plane", m_clipping_plane, 4); shader->set_uniform("clipping_plane", m_clipping_plane);
shader->set_uniform("use_color_clip_plane", m_use_color_clip_plane);
shader->set_uniform("color_clip_plane", m_color_clip_plane);
shader->set_uniform("uniform_color_clip_plane_1", m_color_clip_plane_colors[0]);
shader->set_uniform("uniform_color_clip_plane_2", m_color_clip_plane_colors[1]);
//BOOST_LOG_TRIVIAL(info) << boost::format("set uniform_color to {%1%, %2%, %3%, %4%}, with_outline=%5%, selected %6%") //BOOST_LOG_TRIVIAL(info) << boost::format("set uniform_color to {%1%, %2%, %3%, %4%}, with_outline=%5%, selected %6%")
// %volume.first->render_color[0]%volume.first->render_color[1]%volume.first->render_color[2]%volume.first->render_color[3] // %volume.first->render_color[0]%volume.first->render_color[1]%volume.first->render_color[2]%volume.first->render_color[3]
// %with_outline%volume.first->selected; // %with_outline%volume.first->selected;

View File

@ -669,10 +669,15 @@ private:
PrintVolume m_render_volume; PrintVolume m_render_volume;
// z range for clipping in shaders // z range for clipping in shaders
float m_z_range[2]; std::array<float, 2> m_z_range;
// plane coeffs for clipping in shaders // plane coeffs for clipping in shaders
float m_clipping_plane[4]; std::array<float, 4> m_clipping_plane;
// plane coeffs for render volumes with different colors in shaders
// used by cut gizmo
std::array<float, 4> m_color_clip_plane;
bool m_use_color_clip_plane{false};
std::array<ColorRGBA, 2> m_color_clip_plane_colors{ColorRGBA::RED(), ColorRGBA::BLUE()};
struct Slope struct Slope
{ {
@ -774,6 +779,17 @@ public:
m_clipping_plane[3] = coeffs[3]; m_clipping_plane[3] = coeffs[3];
} }
const std::array<float, 2> & get_z_range() const { return m_z_range; }
const std::array<float, 4> &get_clipping_plane() const { return m_clipping_plane; }
void set_use_color_clip_plane(bool use) { m_use_color_clip_plane = use; }
void set_color_clip_plane(const Vec3d &cp_normal, double offset)
{
for (int i = 0; i < 3; ++i) m_color_clip_plane[i] = -cp_normal[i];
m_color_clip_plane[3] = offset;
}
void set_color_clip_plane_colors(const std::array<ColorRGBA, 2> &colors) { m_color_clip_plane_colors = colors; }
bool is_slope_GlobalActive() const { return m_slope.isGlobalActive; } bool is_slope_GlobalActive() const { return m_slope.isGlobalActive; }
bool is_slope_active() const { return m_slope.active; } bool is_slope_active() const { return m_slope.active; }
void set_slope_active(bool active) { m_slope.active = active; } void set_slope_active(bool active) { m_slope.active = active; }

View File

@ -2246,6 +2246,9 @@ void GLCanvas3D::render(bool only_init)
if (!ogl_manager.are_framebuffers_supported()) { if (!ogl_manager.are_framebuffers_supported()) {
picking_effect = EPickingEffect::StencilOutline; // use stencil outline as framebuffer not supported yet. picking_effect = EPickingEffect::StencilOutline; // use stencil outline as framebuffer not supported yet.
} }
if (!m_gizmos.is_allow_show_volume_highlight_outline()) {
picking_effect = EPickingEffect::Disabled;
}
} }
const bool off_screen_rendering_enabled = ogl_manager.is_fxaa_enabled(); const bool off_screen_rendering_enabled = ogl_manager.is_fxaa_enabled();
@ -4720,7 +4723,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
} }
} }
else if (evt.Dragging() && evt.LeftIsDown() && m_mouse.drag.move_volume_idx != -1 && m_layers_editing.state == LayersEditing::Unknown) { else if (evt.Dragging() && evt.LeftIsDown() && m_mouse.drag.move_volume_idx != -1 && m_layers_editing.state == LayersEditing::Unknown) {
if (m_canvas_type != ECanvasType::CanvasAssembleView) { if (m_canvas_type != ECanvasType::CanvasAssembleView && m_gizmos.is_allow_drag_volume()) {
if (!m_mouse.drag.move_requires_threshold) { if (!m_mouse.drag.move_requires_threshold) {
m_mouse.dragging = true; m_mouse.dragging = true;
Vec3d cur_pos = m_mouse.drag.start_position_3D; Vec3d cur_pos = m_mouse.drag.start_position_3D;

View File

@ -856,6 +856,9 @@ public:
bool get_use_clipping_planes() const { return m_use_clipping_planes; } bool get_use_clipping_planes() const { return m_use_clipping_planes; }
const std::array<ClippingPlane, 2> &get_clipping_planes() const { return m_clipping_planes; }; const std::array<ClippingPlane, 2> &get_clipping_planes() const { return m_clipping_planes; };
void set_use_color_clip_plane(bool use) { m_volumes.set_use_color_clip_plane(use); }
void set_color_clip_plane(const Vec3d &cp_normal, double offset) { m_volumes.set_color_clip_plane(cp_normal, offset); }
void set_color_clip_plane_colors(const std::array<ColorRGBA, 2> &colors) { m_volumes.set_color_clip_plane_colors(colors); }
void set_color_by(const std::string& value); void set_color_by(const std::string& value);

View File

@ -383,6 +383,16 @@ bool GLShaderProgram::set_uniform(const char* name, const ColorRGB& value) const
return false; return false;
} }
bool GLShaderProgram::set_uniform(const char *name, const ColorRGBA &value) const
{
int id = get_uniform_location(name);
if (id >= 0) {
glsafe(::glUniform4fv(id, 1, static_cast<const GLfloat *>(value.data())));
return true;
}
return false;
}
int GLShaderProgram::get_attrib_location(const char* name) const int GLShaderProgram::get_attrib_location(const char* name) const
{ {
assert(m_id > 0); assert(m_id > 0);

View File

@ -9,7 +9,7 @@
namespace Slic3r { namespace Slic3r {
class ColorRGB; class ColorRGB;
class ColorRGBA;
class GLShaderProgram class GLShaderProgram
{ {
friend class GLShadersManager; friend class GLShadersManager;
@ -63,7 +63,7 @@ public:
bool set_uniform(const char* name, const Vec3f& value) const; bool set_uniform(const char* name, const Vec3f& value) const;
bool set_uniform(const char* name, const Vec3d& value) const; bool set_uniform(const char* name, const Vec3d& value) const;
bool set_uniform(const char* name, const ColorRGB& value) const; bool set_uniform(const char* name, const ColorRGB& value) const;
bool set_uniform(const char *name, const ColorRGBA& value) const;
// returns -1 if not found // returns -1 if not found
int get_attrib_location(const char* name) const; int get_attrib_location(const char* name) const;
// returns -1 if not found // returns -1 if not found

View File

@ -171,10 +171,11 @@ bool GLGizmoAdvancedCut::gizmo_event(SLAGizmoEventType action, const Vec2d &mous
else if (action == SLAGizmoEventType::RightDown) { else if (action == SLAGizmoEventType::RightDown) {
if (!m_connectors_editing && m_cut_mode == CutMode::cutPlanar) { //&& control_down if (!m_connectors_editing && m_cut_mode == CutMode::cutPlanar) { //&& control_down
// Check the internal part raycasters. // Check the internal part raycasters.
if (m_part_selection && m_part_selection->valid()) { if (m_part_selection && !m_part_selection->valid())
process_contours();
m_part_selection->toggle_selection(mouse_position); m_part_selection->toggle_selection(mouse_position);
check_and_update_connectors_state(); // after a contour is deactivated, its connectors are inside the object check_and_update_connectors_state(); // after a contour is deactivated, its connectors are inside the object
}
return true; return true;
} }
if (m_hover_id < c_connectors_group_id) if (m_hover_id < c_connectors_group_id)
@ -489,6 +490,14 @@ std::string GLGizmoAdvancedCut::on_get_name() const
} }
} }
void GLGizmoAdvancedCut::apply_color_clip_plane_colors()
{
if (CutMode(m_cut_mode) == CutMode::cutTongueAndGroove)
m_parent.set_color_clip_plane_colors({CUT_PLANE_DEF_COLOR, CUT_PLANE_DEF_COLOR});
else
m_parent.set_color_clip_plane_colors({UPPER_PART_COLOR, LOWER_PART_COLOR});
}
void GLGizmoAdvancedCut::on_load(cereal::BinaryInputArchive &ar) void GLGizmoAdvancedCut::on_load(cereal::BinaryInputArchive &ar)
{ {
size_t mode; size_t mode;
@ -544,7 +553,6 @@ void GLGizmoAdvancedCut::data_changed(bool is_serializing)
update_bb(); update_bb();
if (auto oc = m_c->object_clipper()) { if (auto oc = m_c->object_clipper()) {
oc->set_behaviour(m_connectors_editing, m_connectors_editing, double(m_contour_width)); oc->set_behaviour(m_connectors_editing, m_connectors_editing, double(m_contour_width));
reset_cut_by_contours();
} }
} }
} }
@ -555,6 +563,7 @@ void GLGizmoAdvancedCut::on_set_state()
// Reset m_cut_z on gizmo activation // Reset m_cut_z on gizmo activation
if (get_state() == On) { if (get_state() == On) {
m_parent.set_use_color_clip_plane(true);
const Selection &selection = m_parent.get_selection(); const Selection &selection = m_parent.get_selection();
if (selection.is_empty()) {//check selection again if (selection.is_empty()) {//check selection again
close(); close();
@ -582,6 +591,7 @@ void GLGizmoAdvancedCut::on_set_state()
oc->release(); oc->release();
} }
m_selected.clear(); m_selected.clear();
m_parent.set_use_color_clip_plane(false);
m_c->selection_info()->set_use_shift(false); m_c->selection_info()->set_use_shift(false);
// Make sure that the part selection data are released when the gizmo is closed. // Make sure that the part selection data are released when the gizmo is closed.
@ -625,7 +635,6 @@ CommonGizmosDataID GLGizmoAdvancedCut::on_get_requirements() const
{ {
return CommonGizmosDataID(int(CommonGizmosDataID::SelectionInfo) return CommonGizmosDataID(int(CommonGizmosDataID::SelectionInfo)
| int(CommonGizmosDataID::InstancesHider) | int(CommonGizmosDataID::InstancesHider)
| int(CommonGizmosDataID::Raycaster)
| int(CommonGizmosDataID::ObjectClipper)); | int(CommonGizmosDataID::ObjectClipper));
} }
@ -771,7 +780,9 @@ void GLGizmoAdvancedCut::on_render()
if (m_part_selection) { if (m_part_selection) {
if (!m_connectors_editing) { if (!m_connectors_editing) {
if (m_is_dragging == false) { m_part_selection->part_render(nullptr,nullptr); } if (m_is_dragging == false) {
m_part_selection->part_render(nullptr,nullptr);
}
} else { } else {
m_part_selection->part_render(&m_plane_center, &m_plane_normal); m_part_selection->part_render(&m_plane_center, &m_plane_normal);
} }
@ -790,8 +801,8 @@ void GLGizmoAdvancedCut::on_render_for_picking()
const Camera& camera = wxGetApp().plater()->get_picking_camera(); const Camera& camera = wxGetApp().plater()->get_picking_camera();
const auto& view_matrix = camera.get_view_matrix(); const auto& view_matrix = camera.get_view_matrix();
const auto& projection_matrix = camera.get_projection_matrix(); const auto& projection_matrix = camera.get_projection_matrix();
if (!m_connectors_editing) {
glsafe(::glDisable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_DEPTH_TEST));
if (!m_connectors_editing) {
std::array<float, 4> color; std::array<float, 4> color;
// pick plane // pick plane
{ {
@ -824,7 +835,6 @@ void GLGizmoAdvancedCut::on_render_for_picking()
} }
} else { } else {
glsafe(::glEnable(GL_DEPTH_TEST));
auto inst_id = m_c->selection_info()->get_active_instance(); auto inst_id = m_c->selection_info()->get_active_instance();
if (inst_id < 0) return; if (inst_id < 0) return;
@ -1216,6 +1226,7 @@ void GLGizmoAdvancedCut::update_clipper()
double offset = normal.dot(m_plane_center); double offset = normal.dot(m_plane_center);
double dist = normal.dot(beg); double dist = normal.dot(beg);
m_parent.set_color_clip_plane(normal, offset);
if (!is_looking_forward()) { if (!is_looking_forward()) {
// recalculate normal and offset for clipping plane, if camera is looking downward to cut plane // recalculate normal and offset for clipping plane, if camera is looking downward to cut plane
normal = m_rotate_matrix * (-1. * Vec3d::UnitZ()); normal = m_rotate_matrix * (-1. * Vec3d::UnitZ());
@ -1793,6 +1804,7 @@ void GLGizmoAdvancedCut::switch_to_mode(CutMode new_mode) {
if (m_cut_mode == CutMode::cutTongueAndGroove) { if (m_cut_mode == CutMode::cutTongueAndGroove) {
m_cut_to_parts = false;//into Groove function,cancel m_cut_to_parts m_cut_to_parts = false;//into Groove function,cancel m_cut_to_parts
} }
apply_color_clip_plane_colors();
if (auto oc = m_c->object_clipper()) { if (auto oc = m_c->object_clipper()) {
m_contour_width = m_cut_mode == CutMode::cutTongueAndGroove ? 0.f : 0.4f; m_contour_width = m_cut_mode == CutMode::cutTongueAndGroove ? 0.f : 0.4f;
oc->set_behaviour(m_connectors_editing, m_connectors_editing, double(m_contour_width)); // for debug oc->set_behaviour(m_connectors_editing, m_connectors_editing, double(m_contour_width)); // for debug
@ -1857,6 +1869,13 @@ bool GLGizmoAdvancedCut::has_valid_groove() const
return false; return false;
const Transform3d cp_matrix = Geometry::translation_transform(m_plane_center) * m_rotate_matrix; const Transform3d cp_matrix = Geometry::translation_transform(m_plane_center) * m_rotate_matrix;
if (!m_c->raycaster()) {
if (!m_c->selection_info()) {
m_c->update(get_requirements());
}
wxBusyCursor wait;
m_c->raycaster_ptr()->update();
}
for (size_t id = 0; id < m_groove_vertices.size(); id += 2) { for (size_t id = 0; id < m_groove_vertices.size(); id += 2) {
const Vec3d beg = cp_matrix * m_groove_vertices[id]; const Vec3d beg = cp_matrix * m_groove_vertices[id];
@ -1895,7 +1914,7 @@ void GLGizmoAdvancedCut::reset_cut_by_contours()
return; return;
process_contours(); process_contours();
} else { } else {
process_contours(); toggle_model_objects_visibility();
} }
} }
@ -2001,7 +2020,7 @@ void GLGizmoAdvancedCut::update_bb()
else else
set_center_pos(m_bb_center); set_center_pos(m_bb_center);
reset_cut_by_contours(); reset_cut_by_contours();
apply_color_clip_plane_colors();
m_contour_width = m_cut_mode == CutMode::cutTongueAndGroove ? 0.f : 0.4f; m_contour_width = m_cut_mode == CutMode::cutTongueAndGroove ? 0.f : 0.4f;
m_radius = box.radius(); m_radius = box.radius();

View File

@ -235,6 +235,7 @@ protected:
virtual void data_changed(bool is_serializing) override; virtual void data_changed(bool is_serializing) override;
virtual std::string on_get_name() const; virtual std::string on_get_name() const;
virtual std::string on_get_name_str() override { return "Cut"; } virtual std::string on_get_name_str() override { return "Cut"; }
void apply_color_clip_plane_colors();
virtual void on_set_state(); virtual void on_set_state();
void close(); void close();
virtual bool on_is_activable() const; virtual bool on_is_activable() const;

View File

@ -176,7 +176,7 @@ void InstancesHider::on_update()
for (const TriangleMesh* mesh : meshes) { for (const TriangleMesh* mesh : meshes) {
m_clippers.emplace_back(new MeshClipper); m_clippers.emplace_back(new MeshClipper);
m_clippers.back()->set_plane(ClippingPlane(-Vec3d::UnitZ(), z_min)); m_clippers.back()->set_plane(ClippingPlane(-Vec3d::UnitZ(), z_min));
m_clippers.back()->set_mesh(*mesh); m_clippers.back()->set_mesh(mesh->its);
} }
m_old_meshes = meshes; m_old_meshes = meshes;
} }
@ -374,29 +374,24 @@ void ObjectClipper::on_update()
// which mesh should be cut? // which mesh should be cut?
std::vector<const TriangleMesh *> meshes; std::vector<const TriangleMesh *> meshes;
std::vector<Geometry::Transformation> trafos; std::vector<Geometry::Transformation> trafos;
bool force_clipper_regeneration = false;
std::unique_ptr<MeshClipper> mc;
Geometry::Transformation mc_tr; Geometry::Transformation mc_tr;
if (!mc && meshes.empty()) { if (meshes.empty()) {
for (const ModelVolume *mv : mo->volumes) { for (const ModelVolume *mv : mo->volumes) {
meshes.emplace_back(&mv->mesh()); meshes.emplace_back(&mv->mesh());
trafos.emplace_back(mv->get_transformation()); trafos.emplace_back(mv->get_transformation());
} }
} }
if (mc || force_clipper_regeneration || meshes != m_old_meshes) { if (meshes != m_old_meshes) {
m_clippers.clear(); m_clippers.clear();
for (size_t i = 0; i < meshes.size(); ++i) { for (size_t i = 0; i < meshes.size(); ++i) {
m_clippers.emplace_back(new MeshClipper, trafos[i]); m_clippers.emplace_back(new MeshClipper, trafos[i]);
auto tri_mesh = new TriangleMesh(meshes[i]->its); m_clippers.back().first->set_mesh(meshes[i]->its);
m_clippers.back().first->set_mesh(*tri_mesh);
} }
m_old_meshes = std::move(meshes); m_old_meshes = std::move(meshes);
if (mc) { m_clippers.emplace_back(std::move(mc), mc_tr); }
m_active_inst_bb_radius = mo->instance_bounding_box(get_pool()->selection_info()->get_active_instance()).radius(); m_active_inst_bb_radius = mo->instance_bounding_box(get_pool()->selection_info()->get_active_instance()).radius();
} }
} }
@ -581,7 +576,7 @@ void SupportsClipper::on_update()
// The timestamp has changed. // The timestamp has changed.
m_clipper.reset(new MeshClipper); m_clipper.reset(new MeshClipper);
// The mesh should already have the shared vertices calculated. // The mesh should already have the shared vertices calculated.
m_clipper->set_mesh(print_object->support_mesh()); m_clipper->set_mesh(print_object->support_mesh().its);
m_old_timestamp = timestamp; m_old_timestamp = timestamp;
} }
} }
@ -737,7 +732,7 @@ void ModelObjectsClipper::on_update()
m_clippers.clear(); m_clippers.clear();
for (const TriangleMesh* mesh : meshes) { for (const TriangleMesh* mesh : meshes) {
m_clippers.emplace_back(new MeshClipper); m_clippers.emplace_back(new MeshClipper);
m_clippers.back()->set_mesh(*mesh); m_clippers.back()->set_mesh(mesh->its);
} }
m_old_meshes = meshes; m_old_meshes = meshes;

View File

@ -463,7 +463,7 @@ void GLGizmosManager::update_data()
{ {
if (!m_enabled) if (!m_enabled)
return; return;
wxBusyCursor wait;
const Selection& selection = m_parent.get_selection(); const Selection& selection = m_parent.get_selection();
if (m_common_gizmos_data) { if (m_common_gizmos_data) {
m_common_gizmos_data->update(get_current() m_common_gizmos_data->update(get_current()
@ -737,6 +737,27 @@ bool GLGizmosManager::is_allow_select_all() {
return false; return false;
} }
bool GLGizmosManager::is_allow_show_volume_highlight_outline() const
{
if (m_current == EType::Cut) {
return false;
}
return true;
}
bool GLGizmosManager::is_allow_drag_volume() const
{
if (m_current == EType::Cut) { return false; }
return true;
}
bool GLGizmosManager::is_allow_mouse_drag_selected() const
{
if (m_current == Measure || m_current == Assembly)
return false;
return true;
}
ClippingPlane GLGizmosManager::get_clipping_plane() const ClippingPlane GLGizmosManager::get_clipping_plane() const
{ {
if (! m_common_gizmos_data if (! m_common_gizmos_data
@ -1043,7 +1064,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
// the gizmo got the event and took some action, there is no need to do anything more // the gizmo got the event and took some action, there is no need to do anything more
processed = true; processed = true;
else if (!selection.is_empty() && grabber_contains_mouse()) { else if (!selection.is_empty() && grabber_contains_mouse()) {
if (!(m_current == Measure || m_current == Assembly)) { if (is_allow_mouse_drag_selected ()) {
selection.start_dragging(); selection.start_dragging();
start_dragging(); start_dragging();

View File

@ -293,6 +293,9 @@ public:
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false, bool alt_down = false, bool control_down = false); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false, bool alt_down = false, bool control_down = false);
bool is_paint_gizmo(); bool is_paint_gizmo();
bool is_allow_select_all(); bool is_allow_select_all();
bool is_allow_show_volume_highlight_outline() const;
bool is_allow_drag_volume() const;
bool is_allow_mouse_drag_selected() const;
ClippingPlane get_clipping_plane() const; ClippingPlane get_clipping_plane() const;
ClippingPlane get_assemble_view_clipping_plane() const; ClippingPlane get_assemble_view_clipping_plane() const;
bool wants_reslice_supports_on_undo() const; bool wants_reslice_supports_on_undo() const;

View File

@ -46,23 +46,37 @@ void MeshClipper::set_limiting_plane(const ClippingPlane& plane)
} }
} }
void MeshClipper::set_mesh(const TriangleMesh& mesh) void MeshClipper::set_mesh(const indexed_triangle_set &mesh)
{ {
if (m_mesh != &mesh) { if (m_mesh.get() != &mesh) {
m_mesh = &mesh; m_mesh = &mesh;
reset(); m_result.reset();
} }
} }
void MeshClipper::set_negative_mesh(const TriangleMesh& mesh) void MeshClipper::set_mesh(AnyPtr<const indexed_triangle_set> &&ptr)
{ {
if (m_negative_mesh != &mesh) { if (m_mesh.get() != ptr.get()) {
m_negative_mesh = &mesh; m_mesh = std::move(ptr);
reset(); m_result.reset();
} }
} }
void MeshClipper::set_negative_mesh(const indexed_triangle_set &mesh)
{
if (m_negative_mesh.get() != &mesh) {
m_negative_mesh = &mesh;
m_result.reset();
}
}
void MeshClipper::set_negative_mesh(AnyPtr<const indexed_triangle_set> &&ptr)
{
if (m_negative_mesh.get() != ptr.get()) {
m_negative_mesh = std::move(ptr);
m_result.reset();
}
}
void MeshClipper::set_transformation(const Geometry::Transformation& trafo) void MeshClipper::set_transformation(const Geometry::Transformation& trafo)
{ {
@ -208,10 +222,10 @@ void MeshClipper::recalculate_triangles()
// if (m_csgmesh.empty()) { // if (m_csgmesh.empty()) {
if (m_mesh) { if (m_mesh) {
expolys = union_ex(slice_mesh(m_mesh->its, height_mesh, slicing_params)); expolys = union_ex(slice_mesh(*m_mesh, height_mesh, slicing_params));
} }
if (m_negative_mesh && !m_negative_mesh->empty()) { if (m_negative_mesh && !m_negative_mesh->empty()) {
const ExPolygons neg_expolys = union_ex(slice_mesh(m_negative_mesh->its, height_mesh, slicing_params)); const ExPolygons neg_expolys = union_ex(slice_mesh(*m_negative_mesh, height_mesh, slicing_params));
expolys = diff_ex(expolys, neg_expolys); expolys = diff_ex(expolys, neg_expolys);
} }

View File

@ -6,7 +6,7 @@
#include "libslic3r/Geometry.hpp" #include "libslic3r/Geometry.hpp"
#include "libslic3r/SLA/IndexedMesh.hpp" #include "libslic3r/SLA/IndexedMesh.hpp"
#include "admesh/stl.h" #include "admesh/stl.h"
#include "libslic3r/AnyPtr.hpp"
#include "slic3r/GUI/GLModel.hpp" #include "slic3r/GUI/GLModel.hpp"
#include <cfloat> #include <cfloat>
@ -93,9 +93,11 @@ public:
// Which mesh to cut. MeshClipper remembers const * to it, caller // Which mesh to cut. MeshClipper remembers const * to it, caller
// must make sure that it stays valid. // must make sure that it stays valid.
void set_mesh(const TriangleMesh& mesh); void set_mesh(const indexed_triangle_set &mesh);
void set_mesh(AnyPtr<const indexed_triangle_set> &&ptr);
void set_negative_mesh(const TriangleMesh &mesh); void set_negative_mesh(const indexed_triangle_set &mesh);
void set_negative_mesh(AnyPtr<const indexed_triangle_set> &&ptr);
// Inform the MeshClipper about the transformation that transforms the mesh // Inform the MeshClipper about the transformation that transforms the mesh
// into world coordinates. // into world coordinates.
@ -115,8 +117,8 @@ private:
void recalculate_triangles(); void recalculate_triangles();
void reset(); void reset();
Geometry::Transformation m_trafo; Geometry::Transformation m_trafo;
const TriangleMesh * m_mesh = nullptr; AnyPtr<const indexed_triangle_set> m_mesh;
const TriangleMesh * m_negative_mesh = nullptr; AnyPtr<const indexed_triangle_set> m_negative_mesh;
ClippingPlane m_plane; ClippingPlane m_plane;
ClippingPlane m_limiting_plane = ClippingPlane::ClipsNothing(); ClippingPlane m_limiting_plane = ClippingPlane::ClipsNothing();