ENH:add brim ear invalid warning
1.fix dragging causes wrong orientation 2.clean up useless include jira:nojira Change-Id: Ia723da626ac5434a1675e4a1b781579057f1403a (cherry picked from commit 252ff6f0247546761ac9660e04ecf1bb2951d80e)
This commit is contained in:
parent
a4e636d1a9
commit
38c5c25cdd
|
@ -185,6 +185,15 @@ bool overlaps(const ExPolygons& expolys1, const ExPolygons& expolys2)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool overlaps(const ExPolygons& expolys, const ExPolygon& expoly)
|
||||
{
|
||||
for (const ExPolygon& el : expolys) {
|
||||
if (el.overlaps(expoly))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Point projection_onto(const ExPolygons& polygons, const Point& from)
|
||||
{
|
||||
Point projected_pt;
|
||||
|
|
|
@ -457,6 +457,7 @@ inline ExPolygons expolygons_simplify(const ExPolygons &expolys, double toleranc
|
|||
bool expolygons_match(const ExPolygon &l, const ExPolygon &r);
|
||||
|
||||
bool overlaps(const ExPolygons& expolys1, const ExPolygons& expolys2);
|
||||
bool overlaps(const ExPolygons& expolys, const ExPolygon& expoly);
|
||||
|
||||
Point projection_onto(const ExPolygons& expolys, const Point& pt);
|
||||
|
||||
|
|
|
@ -1,30 +1,19 @@
|
|||
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
|
||||
#include "GLGizmoBrimEars.hpp"
|
||||
#include <GL/glew.h>
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
#include "slic3r/GUI/Camera.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
|
||||
#include "slic3r/GUI/MainFrame.hpp"
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoSimplify.hpp"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/stattext.h>
|
||||
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/GUI_ObjectSettings.hpp"
|
||||
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/NotificationManager.hpp"
|
||||
#include "slic3r/GUI/MsgDialog.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/SLAPrint.hpp"
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
static const ColorRGBA DEF_COLOR = {0.7f, 0.7f, 0.7f, 1.f};
|
||||
static const ColorRGBA SELECTED_COLOR = {0.0f, 0.5f, 0.5f, 1.0f};
|
||||
static const ColorRGBA ERR_COLOR = {1.0f, 0.3f, 0.3f, 0.5f};
|
||||
static const ColorRGBA HOVER_COLOR = {0.7f, 0.7f, 0.7f, 0.5f};
|
||||
|
||||
static ModelVolume *get_model_volume(const Selection &selection, Model &model)
|
||||
{
|
||||
const Selection::IndicesList &idxs = selection.get_volume_idxs();
|
||||
|
@ -83,8 +72,7 @@ void GLGizmoBrimEars::on_render()
|
|||
const Selection &selection = m_parent.get_selection();
|
||||
|
||||
// If current m_c->m_model_object does not match selection, ask GLCanvas3D to turn us off
|
||||
if (m_state == On && (mo != selection.get_model()->objects[selection.get_object_idx()]
|
||||
|| m_c->selection_info()->get_active_instance() != selection.get_instance_idx())) {
|
||||
if (m_state == On && (mo != selection.get_model()->objects[selection.get_object_idx()] || m_c->selection_info()->get_active_instance() != selection.get_instance_idx())) {
|
||||
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_RESETGIZMOS));
|
||||
return;
|
||||
}
|
||||
|
@ -131,18 +119,19 @@ void GLGizmoBrimEars::render_points(const Selection &selection, bool picking) co
|
|||
glsafe(::glPushMatrix());
|
||||
glsafe(::glMultMatrixd(instance_matrix.data()));
|
||||
|
||||
std::array<float, 4> render_color;
|
||||
ColorRGBA render_color;
|
||||
for (size_t i = 0; i < cache_size; ++i) {
|
||||
const BrimPoint &brim_point = editing_cache[i].brim_point;
|
||||
const bool &point_selected = editing_cache[i].selected;
|
||||
const bool &hover = editing_cache[i].is_hover;
|
||||
const bool &error = editing_cache[i].is_error;
|
||||
// keep show brim ear
|
||||
// if (is_mesh_point_clipped(brim_point.pos.cast<double>()))
|
||||
// continue;
|
||||
|
||||
// First decide about the color of the point.
|
||||
if (hover) {
|
||||
render_color = {0.7f, 0.7f, 0.7f, 0.5f};
|
||||
render_color = HOVER_COLOR;
|
||||
} else {
|
||||
if (picking)
|
||||
render_color = picking_color_component(i);
|
||||
|
@ -151,14 +140,18 @@ void GLGizmoBrimEars::render_points(const Selection &selection, bool picking) co
|
|||
render_color = {0.f, 1.f, 1.f, 1.f};
|
||||
else { // neigher hover nor picking
|
||||
if (point_selected)
|
||||
render_color = {1.f, 0.3f, 0.3f, 1.f};
|
||||
else
|
||||
render_color = {0.7f, 0.7f, 0.7f, 1.f};
|
||||
render_color = SELECTED_COLOR;
|
||||
else {
|
||||
if (error)
|
||||
render_color = ERR_COLOR;
|
||||
else
|
||||
render_color = DEF_COLOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const_cast<GLModel *>(&m_cylinder)->set_color(-1, render_color);
|
||||
const_cast<GLModel *>(&m_cylinder)->set_color(render_color);
|
||||
if (shader && !picking) shader->set_uniform("emission_factor", 0.5f);
|
||||
|
||||
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
|
||||
|
@ -336,6 +329,7 @@ bool GLGizmoBrimEars::gizmo_event(SLAGizmoEventType action, const Vec2d &mouse_p
|
|||
add_point_to_cache(object_pos.cast<float>(), m_new_point_head_diameter / 2.f, false, (inverse_trsf * m_world_normal).cast<float>());
|
||||
m_parent.set_as_dirty();
|
||||
m_wait_for_up_event = true;
|
||||
find_single();
|
||||
} else
|
||||
return false;
|
||||
} else
|
||||
|
@ -411,6 +405,7 @@ bool GLGizmoBrimEars::gizmo_event(SLAGizmoEventType action, const Vec2d &mouse_p
|
|||
select_point(NoPoints);
|
||||
select_point(m_hover_id);
|
||||
delete_selected_points();
|
||||
find_single();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -460,10 +455,12 @@ void GLGizmoBrimEars::on_update(const UpdateData &data)
|
|||
{
|
||||
if (m_hover_id != -1) {
|
||||
std::pair<Vec3f, Vec3f> pos_and_normal;
|
||||
if (!unproject_on_mesh(data.mouse_pos.cast<double>(), pos_and_normal)) return;
|
||||
if (!unproject_on_mesh2(data.mouse_pos.cast<double>(), pos_and_normal)) return;
|
||||
m_editing_cache[m_hover_id].brim_point.pos[0] = pos_and_normal.first.x();
|
||||
m_editing_cache[m_hover_id].brim_point.pos[1] = pos_and_normal.first.y();
|
||||
m_editing_cache[m_hover_id].normal = pos_and_normal.second;
|
||||
//m_editing_cache[m_hover_id].normal = pos_and_normal.second;
|
||||
m_editing_cache[m_hover_id].normal = Vec3f(0, 0, 1);
|
||||
find_single();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -544,14 +541,19 @@ void GLGizmoBrimEars::on_render_input_window(float x, float y, float bottom_limi
|
|||
m_imgui->text(m_desc["head_diameter"]);
|
||||
ImGui::SameLine(caption_size);
|
||||
ImGui::PushItemWidth(slider_width);
|
||||
auto update_cache_radius = [this]() {
|
||||
for (auto &cache_entry : m_editing_cache)
|
||||
if (cache_entry.selected) {
|
||||
cache_entry.brim_point.head_front_radius = m_new_point_head_diameter / 2.f;
|
||||
find_single();
|
||||
}
|
||||
};
|
||||
m_imgui->bbl_slider_float_style("##head_diameter", &m_new_point_head_diameter, 5, 10, "%.1f", 1.0f, true);
|
||||
if (m_imgui->get_last_slider_status().clicked) {
|
||||
if (m_old_point_head_diameter == 0.f) m_old_point_head_diameter = initial_value;
|
||||
}
|
||||
if (m_imgui->get_last_slider_status().edited) {
|
||||
for (auto &cache_entry : m_editing_cache)
|
||||
if (cache_entry.selected) cache_entry.brim_point.head_front_radius = m_new_point_head_diameter / 2.f;
|
||||
}
|
||||
if (m_imgui->get_last_slider_status().edited)
|
||||
update_cache_radius();
|
||||
if (m_imgui->get_last_slider_status().deactivated_after_edit) {
|
||||
// momentarily restore the old value to take snapshot
|
||||
for (auto &cache_entry : m_editing_cache)
|
||||
|
@ -560,8 +562,7 @@ void GLGizmoBrimEars::on_render_input_window(float x, float y, float bottom_limi
|
|||
m_new_point_head_diameter = m_old_point_head_diameter;
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Change point head diameter");
|
||||
m_new_point_head_diameter = backup;
|
||||
for (auto &cache_entry : m_editing_cache)
|
||||
if (cache_entry.selected) cache_entry.brim_point.head_front_radius = m_new_point_head_diameter / 2.f;
|
||||
update_cache_radius();
|
||||
m_old_point_head_diameter = 0.f;
|
||||
}
|
||||
ImGui::SameLine(drag_left_width);
|
||||
|
@ -617,9 +618,13 @@ void GLGizmoBrimEars::on_render_input_window(float x, float y, float bottom_limi
|
|||
delete_selected_points();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(1);
|
||||
|
||||
if (!m_single_brim.empty()) {
|
||||
wxString out = _L("Warning") + ": " + std::to_string(m_single_brim.size()) + _L(" invalid brim ears");
|
||||
m_imgui->warning_text(out);
|
||||
}
|
||||
|
||||
GizmoImguiEnd();
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGuiWrapper::pop_toolbar_style();
|
||||
|
@ -841,6 +846,7 @@ void GLGizmoBrimEars::auto_generate()
|
|||
for (Point &p : inner_points) { add_point(p); }
|
||||
}
|
||||
}
|
||||
find_single();
|
||||
}
|
||||
|
||||
bool GLGizmoBrimEars::add_point_to_cache(Vec3f pos, float head_radius, bool selected, Vec3f normal)
|
||||
|
@ -884,7 +890,67 @@ void GLGizmoBrimEars::reset_all_pick() { std::map<GLVolume *, std::shared_ptr<Pi
|
|||
|
||||
float GLGizmoBrimEars::get_brim_default_radius() const
|
||||
{
|
||||
const DynamicPrintConfig& pring_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
const DynamicPrintConfig &pring_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
return pring_cfg.get_abs_value("initial_layer_line_width") * 16.0f;
|
||||
}
|
||||
|
||||
ExPolygon GLGizmoBrimEars::make_polygon(BrimPoint point, const Geometry::Transformation &trsf)
|
||||
{
|
||||
ExPolygon point_round;
|
||||
Transform3d model_trsf = trsf.get_matrix();
|
||||
Vec3f world_pos = point.transform(trsf.get_matrix());
|
||||
coord_t size_ear = scale_(point.head_front_radius);
|
||||
for (size_t i = 0; i < POLY_SIDE_COUNT; i++) {
|
||||
double angle = (2.0 * PI * i) / POLY_SIDE_COUNT;
|
||||
point_round.contour.points.emplace_back(size_ear * cos(angle), size_ear * sin(angle));
|
||||
}
|
||||
Vec3f pos = point.transform(model_trsf);
|
||||
int32_t pt_x = scale_(pos.x());
|
||||
int32_t pt_y = scale_(pos.y());
|
||||
point_round.translate(Point(pt_x, pt_y));
|
||||
return point_round;
|
||||
}
|
||||
|
||||
void GLGizmoBrimEars::find_single()
|
||||
{
|
||||
if (m_editing_cache.size() == 0) {
|
||||
m_single_brim.clear();
|
||||
return;
|
||||
}
|
||||
const Selection &selection = m_parent.get_selection();
|
||||
const GLVolume *volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
Geometry::Transformation trsf = volume->get_instance_transformation();
|
||||
ExPolygons model_pl = m_first_layer;
|
||||
|
||||
m_single_brim.clear();
|
||||
for (int i = 0; i < m_editing_cache.size(); i++)
|
||||
m_single_brim[i] = m_editing_cache[i];
|
||||
unsigned int index = 0;
|
||||
bool cyc = true;
|
||||
while (cyc) {
|
||||
index++;
|
||||
if (index > 99999999) break; // cycle protection
|
||||
if (m_single_brim.empty()) {
|
||||
break;
|
||||
}
|
||||
auto end = --m_single_brim.end();
|
||||
for (auto it = m_single_brim.begin(); it != m_single_brim.end(); ++it) {
|
||||
ExPolygon point_pl = make_polygon(it->second.brim_point, trsf);
|
||||
if (overlaps(model_pl, point_pl)) {
|
||||
model_pl.emplace_back(point_pl);
|
||||
model_pl = union_ex(model_pl);
|
||||
it = m_single_brim.erase(it);
|
||||
break;
|
||||
} else {
|
||||
if (it == end) cyc = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& it : m_editing_cache) {
|
||||
it.is_error = false;
|
||||
}
|
||||
for (auto &it : m_single_brim) {
|
||||
m_editing_cache[it.first].is_error = true;
|
||||
}
|
||||
}
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
|
@ -3,12 +3,8 @@
|
|||
|
||||
#include "GLGizmoBase.hpp"
|
||||
#include "slic3r/GUI/GLSelectionRectangle.hpp"
|
||||
|
||||
#include "libslic3r/BrimEarsPoint.hpp"
|
||||
#include "libslic3r/ObjectID.hpp"
|
||||
#include <wx/dialog.h>
|
||||
|
||||
#include <cereal/types/vector.hpp>
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
@ -31,10 +27,16 @@ private:
|
|||
class CacheEntry {
|
||||
public:
|
||||
CacheEntry() :
|
||||
brim_point(BrimPoint()), selected(false), normal(Vec3f(0, 0, 1)), is_hover(false) {}
|
||||
brim_point(BrimPoint()),
|
||||
selected(false),
|
||||
normal(Vec3f(0, 0, 1)),
|
||||
is_hover(false),
|
||||
is_error(false)
|
||||
{}
|
||||
|
||||
CacheEntry(const BrimPoint &point, bool sel = false, const Vec3f &norm = Vec3f(0, 0, 1), bool hover = false)
|
||||
:brim_point(point), selected(sel), normal(norm), is_hover(hover) {}
|
||||
CacheEntry(const BrimPoint &point, bool sel = false, const Vec3f &norm = Vec3f(0, 0, 1), bool hover = false, bool error = false)
|
||||
: brim_point(point), selected(sel), normal(norm), is_hover(hover), is_error(error)
|
||||
{}
|
||||
|
||||
bool operator==(const CacheEntry& rhs) const {
|
||||
return (brim_point == rhs.brim_point);
|
||||
|
@ -53,11 +55,13 @@ private:
|
|||
selected = false;
|
||||
normal.setZero();
|
||||
is_hover = false;
|
||||
is_error = false;
|
||||
}
|
||||
|
||||
BrimPoint brim_point;
|
||||
bool selected; // whether the point is selected
|
||||
bool is_hover; // show mouse hover cylinder
|
||||
bool is_error;
|
||||
Vec3f normal;
|
||||
|
||||
template<class Archive>
|
||||
|
@ -96,6 +100,7 @@ private:
|
|||
CacheEntry m_point_before_drag; // undo/redo - so we know what state was edited
|
||||
float m_old_point_head_diameter = 0.; // the same
|
||||
mutable std::vector<CacheEntry> m_editing_cache; // a support point and whether it is currently selectedchanges or undo/redo
|
||||
std::map<int, CacheEntry> m_single_brim;
|
||||
ObjectID m_old_mo_id;
|
||||
const Vec3d m_world_normal = {0, 0, 1};
|
||||
std::map<GLVolume*, std::shared_ptr<PickRaycaster>> m_mesh_raycaster_map;
|
||||
|
@ -156,6 +161,8 @@ protected:
|
|||
void reset_all_pick();
|
||||
bool add_point_to_cache(Vec3f pos, float head_radius, bool selected, Vec3f normal);
|
||||
float get_brim_default_radius() const;
|
||||
ExPolygon make_polygon(BrimPoint point, const Geometry::Transformation &trsf);
|
||||
void find_single();
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
|
Loading…
Reference in New Issue