mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 06:45:56 +08:00
Small refactoring of Cursors in TriangleSelector.
This commit is contained in:
parent
d23e114aed
commit
f253822707
@ -247,21 +247,15 @@ void TriangleSelector::select_patch(int facet_start, std::unique_ptr<Cursor> &&c
|
||||
// have to pass it around.
|
||||
m_cursor = std::move(cursor);
|
||||
|
||||
// In case user changed cursor size since last time, update triangle edge limit.
|
||||
// It is necessary to compare the internal radius in m_cursor! radius is in
|
||||
// world coords and does not change after scaling.
|
||||
if (m_old_cursor_radius_sqr != m_cursor->radius_sqr) {
|
||||
set_edge_limit(std::sqrt(m_cursor->radius_sqr) / 5.f);
|
||||
m_old_cursor_radius_sqr = m_cursor->radius_sqr;
|
||||
}
|
||||
// In case user changed cursor parameters size since last time, update triangle edge limit.
|
||||
set_edge_limit(m_cursor->get_edge_limit());
|
||||
|
||||
const float highlight_angle_limit = cos(Geometry::deg2rad(highlight_by_angle_deg));
|
||||
Vec3f vec_down = (trafo_no_translate.inverse() * -Vec3d::UnitZ()).normalized().cast<float>();
|
||||
|
||||
// Now start with the facet the pointer points to and check all adjacent facets.
|
||||
std::vector<int> facets_to_check;
|
||||
std::vector<int> facets_to_check = m_cursor->get_facets_to_select(facet_start, m_vertices, m_triangles, m_orig_size_vertices, m_orig_size_indices);
|
||||
facets_to_check.reserve(16);
|
||||
facets_to_check.emplace_back(facet_start);
|
||||
// Keep track of facets of the original mesh we already processed.
|
||||
std::vector<bool> visited(m_orig_size_indices, false);
|
||||
// Breadth-first search around the hit point. facets_to_check may grow significantly large.
|
||||
@ -293,13 +287,13 @@ bool TriangleSelector::is_facet_clipped(int facet_idx, const ClippingPlane &clp)
|
||||
}
|
||||
|
||||
void TriangleSelector::seed_fill_select_triangles(const Vec3f &hit, int facet_start, const Transform3d& trafo_no_translate,
|
||||
const ClippingPlane &clp, float seed_fill_angle, float highlight_by_angle_deg,
|
||||
bool force_reselection)
|
||||
const ClippingPlane &clp, float seed_fill_angle,
|
||||
float highlight_by_angle_deg, ForceReselection force_reselection)
|
||||
{
|
||||
assert(facet_start < m_orig_size_indices);
|
||||
|
||||
// Recompute seed fill only if the cursor is pointing on facet unselected by seed fill or a clipping plane is active.
|
||||
if (int start_facet_idx = select_unsplit_triangle(hit, facet_start); start_facet_idx >= 0 && m_triangles[start_facet_idx].is_selected_by_seed_fill() && !force_reselection && !clp.is_active())
|
||||
if (int start_facet_idx = select_unsplit_triangle(hit, facet_start); start_facet_idx >= 0 && m_triangles[start_facet_idx].is_selected_by_seed_fill() && force_reselection == ForceReselection::NO && !clp.is_active())
|
||||
return;
|
||||
|
||||
this->seed_fill_unselect_all_triangles();
|
||||
@ -451,19 +445,20 @@ void TriangleSelector::append_touching_edges(int itriangle, int vertexi, int ver
|
||||
process_subtriangle(touching.second, Partition::Second);
|
||||
}
|
||||
|
||||
void TriangleSelector::bucket_fill_select_triangles(const Vec3f& hit, int facet_start, const ClippingPlane &clp, bool propagate, bool force_reselection)
|
||||
{
|
||||
void TriangleSelector::bucket_fill_select_triangles(const Vec3f &hit, int facet_start, const ClippingPlane &clp,
|
||||
BucketFillPropagate propagate,
|
||||
ForceReselection force_reselection) {
|
||||
int start_facet_idx = select_unsplit_triangle(hit, facet_start);
|
||||
assert(start_facet_idx != -1);
|
||||
// Recompute bucket fill only if the cursor is pointing on facet unselected by bucket fill or a clipping plane is active.
|
||||
if (start_facet_idx == -1 || (m_triangles[start_facet_idx].is_selected_by_seed_fill() && !force_reselection && !clp.is_active()))
|
||||
if (start_facet_idx == -1 || (m_triangles[start_facet_idx].is_selected_by_seed_fill() && force_reselection == ForceReselection::NO && !clp.is_active()))
|
||||
return;
|
||||
|
||||
assert(!m_triangles[start_facet_idx].is_split());
|
||||
TriangleStateType start_facet_state = m_triangles[start_facet_idx].get_state();
|
||||
this->seed_fill_unselect_all_triangles();
|
||||
|
||||
if (!propagate) {
|
||||
if (propagate == BucketFillPropagate::NO) {
|
||||
m_triangles[start_facet_idx].select_by_seed_fill();
|
||||
return;
|
||||
}
|
||||
@ -878,7 +873,7 @@ bool TriangleSelector::select_triangle_recursive(int facet_idx, const Vec3i &nei
|
||||
|
||||
if (num_of_inside_vertices == 0
|
||||
&& ! m_cursor->is_pointer_in_triangle(*tr, m_vertices)
|
||||
&& ! m_cursor->is_edge_inside_cursor(*tr, m_vertices))
|
||||
&& ! m_cursor->is_any_edge_inside_cursor(*tr, m_vertices))
|
||||
return false;
|
||||
|
||||
if (num_of_inside_vertices == 3) {
|
||||
@ -949,8 +944,8 @@ void TriangleSelector::split_triangle(int facet_idx, const Vec3i &neighbors)
|
||||
|
||||
// In case the object is non-uniformly scaled, transform the
|
||||
// points to world coords.
|
||||
if (! m_cursor->uniform_scaling) {
|
||||
for (size_t i=0; i<pts.size(); ++i) {
|
||||
if (!m_cursor->uniform_scaling) {
|
||||
for (size_t i = 0; i < pts.size(); ++i) {
|
||||
pts_transformed[i] = m_cursor->trafo * (*pts[i]);
|
||||
pts[i] = &pts_transformed[i];
|
||||
}
|
||||
@ -1011,16 +1006,21 @@ int TriangleSelector::Cursor::vertices_inside(const Triangle &tr, const std::vec
|
||||
return inside;
|
||||
}
|
||||
|
||||
// Is any edge inside Sphere cursor?
|
||||
bool TriangleSelector::Sphere::is_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const
|
||||
{
|
||||
inline std::array<Vec3f, 3> TriangleSelector::Cursor::transform_triangle(const Triangle &tr, const std::vector<Vertex> &vertices) const {
|
||||
std::array<Vec3f, 3> pts;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
pts[i] = vertices[tr.verts_idxs[i]].v;
|
||||
if (!this->uniform_scaling)
|
||||
pts[i] = this->trafo * pts[i];
|
||||
}
|
||||
|
||||
return pts;
|
||||
}
|
||||
|
||||
// Is any edge inside Sphere cursor?
|
||||
bool TriangleSelector::Sphere::is_any_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const
|
||||
{
|
||||
const std::array<Vec3f, 3> pts = this->transform_triangle(tr, vertices);
|
||||
for (int side = 0; side < 3; ++side) {
|
||||
const Vec3f &edge_a = pts[side];
|
||||
const Vec3f &edge_b = pts[side < 2 ? side + 1 : 0];
|
||||
@ -1031,16 +1031,10 @@ bool TriangleSelector::Sphere::is_edge_inside_cursor(const Triangle &tr, const s
|
||||
}
|
||||
|
||||
// Is edge inside cursor?
|
||||
bool TriangleSelector::Circle::is_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const
|
||||
bool TriangleSelector::Circle::is_any_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const
|
||||
{
|
||||
std::array<Vec3f, 3> pts;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
pts[i] = vertices[tr.verts_idxs[i]].v;
|
||||
if (!this->uniform_scaling)
|
||||
pts[i] = this->trafo * pts[i];
|
||||
}
|
||||
|
||||
const Vec3f &p = this->center;
|
||||
const std::array<Vec3f, 3> pts = this->transform_triangle(tr, vertices);
|
||||
const Vec3f &p = this->center;
|
||||
for (int side = 0; side < 3; ++side) {
|
||||
const Vec3f &a = pts[side];
|
||||
const Vec3f &b = pts[side < 2 ? side + 1 : 0];
|
||||
@ -1216,7 +1210,7 @@ void TriangleSelector::reset()
|
||||
|
||||
void TriangleSelector::set_edge_limit(float edge_limit)
|
||||
{
|
||||
m_edge_limit_sqr = std::pow(edge_limit, 2.f);
|
||||
m_edge_limit_sqr = Slic3r::sqr(edge_limit);
|
||||
}
|
||||
|
||||
int TriangleSelector::push_triangle(int a, int b, int c, int source_triangle, const TriangleStateType state) {
|
||||
@ -1890,6 +1884,8 @@ TriangleSelector::Cursor::Cursor(const Vec3f &source_, float radius_world, const
|
||||
radius_sqr = Slic3r::sqr(radius_world);
|
||||
trafo_normal = trafo.linear().inverse().transpose();
|
||||
}
|
||||
|
||||
m_edge_limit = std::sqrt(radius_sqr) / 5.f;
|
||||
}
|
||||
|
||||
TriangleSelector::SinglePointCursor::SinglePointCursor(const Vec3f& center_, const Vec3f& source_, float radius_world, const Transform3d& trafo_, const ClippingPlane &clipping_plane_)
|
||||
@ -2048,15 +2044,9 @@ bool line_plane_intersection(const Vec3f &line_a, const Vec3f &line_b, const Vec
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TriangleSelector::Capsule3D::is_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const
|
||||
bool TriangleSelector::Capsule3D::is_any_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const
|
||||
{
|
||||
std::array<Vec3f, 3> pts;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
pts[i] = vertices[tr.verts_idxs[i]].v;
|
||||
if (!this->uniform_scaling)
|
||||
pts[i] = this->trafo * pts[i];
|
||||
}
|
||||
|
||||
const std::array<Vec3f, 3> pts = this->transform_triangle(tr, vertices);
|
||||
for (int side = 0; side < 3; ++side) {
|
||||
const Vec3f &edge_a = pts[side];
|
||||
const Vec3f &edge_b = pts[side < 2 ? side + 1 : 0];
|
||||
@ -2068,15 +2058,8 @@ bool TriangleSelector::Capsule3D::is_edge_inside_cursor(const Triangle &tr, cons
|
||||
}
|
||||
|
||||
// Is edge inside cursor?
|
||||
bool TriangleSelector::Capsule2D::is_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const
|
||||
bool TriangleSelector::Capsule2D::is_any_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const
|
||||
{
|
||||
std::array<Vec3f, 3> pts;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
pts[i] = vertices[tr.verts_idxs[i]].v;
|
||||
if (!this->uniform_scaling)
|
||||
pts[i] = this->trafo * pts[i];
|
||||
}
|
||||
|
||||
const Vec3f centers_diff = this->second_center - this->first_center;
|
||||
// Vector in the direction of line |AD| of the rectangle that intersects the circle with the center in first_center.
|
||||
const Vec3f rectangle_da_dir = centers_diff.cross(this->dir);
|
||||
@ -2095,6 +2078,7 @@ bool TriangleSelector::Capsule2D::is_edge_inside_cursor(const Triangle &tr, cons
|
||||
return false;
|
||||
};
|
||||
|
||||
const std::array<Vec3f, 3> pts = this->transform_triangle(tr, vertices);
|
||||
for (int side = 0; side < 3; ++side) {
|
||||
const Vec3f &edge_a = pts[side];
|
||||
const Vec3f &edge_b = pts[side < 2 ? side + 1 : 0];
|
||||
|
@ -67,12 +67,22 @@ protected:
|
||||
struct Vertex;
|
||||
|
||||
public:
|
||||
enum CursorType {
|
||||
enum class CursorType {
|
||||
CIRCLE,
|
||||
SPHERE,
|
||||
POINTER
|
||||
};
|
||||
|
||||
enum class ForceReselection {
|
||||
NO,
|
||||
YES
|
||||
};
|
||||
|
||||
enum class BucketFillPropagate {
|
||||
NO,
|
||||
YES
|
||||
};
|
||||
|
||||
struct ClippingPlane
|
||||
{
|
||||
Vec3f normal;
|
||||
@ -91,14 +101,21 @@ public:
|
||||
Cursor() = delete;
|
||||
virtual ~Cursor() = default;
|
||||
|
||||
float get_edge_limit() { return m_edge_limit; };
|
||||
|
||||
bool is_pointer_in_triangle(const Triangle &tr, const std::vector<Vertex> &vertices) const;
|
||||
std::array<Vec3f, 3> transform_triangle(const Triangle &tr, const std::vector<Vertex> &vertices) const;
|
||||
|
||||
virtual bool is_mesh_point_inside(const Vec3f &point) const = 0;
|
||||
virtual bool is_pointer_in_triangle(const Vec3f &p1, const Vec3f &p2, const Vec3f &p3) const = 0;
|
||||
virtual int vertices_inside(const Triangle &tr, const std::vector<Vertex> &vertices) const;
|
||||
virtual bool is_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const = 0;
|
||||
virtual bool is_any_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const = 0;
|
||||
virtual bool is_facet_visible(int facet_idx, const std::vector<Vec3f> &face_normals) const = 0;
|
||||
|
||||
virtual std::vector<int> get_facets_to_select(int facet_idx, const std::vector<Vertex> &vertices, const std::vector<Triangle> &triangles, int orig_size_vertices, int orig_size_indices) const {
|
||||
return { facet_idx };
|
||||
};
|
||||
|
||||
static bool is_facet_visible(const Cursor &cursor, int facet_idx, const std::vector<Vec3f> &face_normals);
|
||||
|
||||
protected:
|
||||
@ -115,6 +132,8 @@ public:
|
||||
|
||||
ClippingPlane clipping_plane; // Clipping plane to limit painting to not clipped facets only
|
||||
|
||||
float m_edge_limit;
|
||||
|
||||
friend TriangleSelector;
|
||||
};
|
||||
|
||||
@ -174,7 +193,7 @@ public:
|
||||
~Sphere() override = default;
|
||||
|
||||
bool is_mesh_point_inside(const Vec3f &point) const override;
|
||||
bool is_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const override;
|
||||
bool is_any_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const override;
|
||||
bool is_facet_visible(int facet_idx, const std::vector<Vec3f> &face_normals) const override { return true; }
|
||||
};
|
||||
|
||||
@ -187,9 +206,8 @@ public:
|
||||
~Circle() override = default;
|
||||
|
||||
bool is_mesh_point_inside(const Vec3f &point) const override;
|
||||
bool is_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const override;
|
||||
bool is_facet_visible(int facet_idx, const std::vector<Vec3f> &face_normals) const override
|
||||
{
|
||||
bool is_any_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const override;
|
||||
bool is_facet_visible(int facet_idx, const std::vector<Vec3f> &face_normals) const override {
|
||||
return TriangleSelector::Cursor::is_facet_visible(*this, facet_idx, face_normals);
|
||||
}
|
||||
};
|
||||
@ -204,7 +222,7 @@ public:
|
||||
~Capsule3D() override = default;
|
||||
|
||||
bool is_mesh_point_inside(const Vec3f &point) const override;
|
||||
bool is_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const override;
|
||||
bool is_any_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const override;
|
||||
bool is_facet_visible(int facet_idx, const std::vector<Vec3f> &face_normals) const override { return true; }
|
||||
};
|
||||
|
||||
@ -218,9 +236,8 @@ public:
|
||||
~Capsule2D() override = default;
|
||||
|
||||
bool is_mesh_point_inside(const Vec3f &point) const override;
|
||||
bool is_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const override;
|
||||
bool is_facet_visible(int facet_idx, const std::vector<Vec3f> &face_normals) const override
|
||||
{
|
||||
bool is_any_edge_inside_cursor(const Triangle &tr, const std::vector<Vertex> &vertices) const override;
|
||||
bool is_facet_visible(int facet_idx, const std::vector<Vec3f> &face_normals) const override {
|
||||
return TriangleSelector::Cursor::is_facet_visible(*this, facet_idx, face_normals);
|
||||
}
|
||||
};
|
||||
@ -298,19 +315,19 @@ public:
|
||||
bool triangle_splitting, // If triangles will be split base on the cursor or not
|
||||
float highlight_by_angle_deg = 0.f); // The maximal angle of overhang. If it is set to a non-zero value, it is possible to paint only the triangles of overhang defined by this angle in degrees.
|
||||
|
||||
void seed_fill_select_triangles(const Vec3f &hit, // point where to start
|
||||
int facet_start, // facet of the original mesh (unsplit) that the hit point belongs to
|
||||
const Transform3d &trafo_no_translate, // matrix to get from mesh to world without translation
|
||||
const ClippingPlane &clp, // Clipping plane to limit painting to not clipped facets only
|
||||
float seed_fill_angle, // the maximal angle between two facets to be painted by the same color
|
||||
float highlight_by_angle_deg = 0.f, // The maximal angle of overhang. If it is set to a non-zero value, it is possible to paint only the triangles of overhang defined by this angle in degrees.
|
||||
bool force_reselection = false); // force reselection of the triangle mesh even in cases that mouse is pointing on the selected triangle
|
||||
void seed_fill_select_triangles(const Vec3f &hit, // point where to start
|
||||
int facet_start, // facet of the original mesh (unsplit) that the hit point belongs to
|
||||
const Transform3d &trafo_no_translate, // matrix to get from mesh to world without translation
|
||||
const ClippingPlane &clp, // Clipping plane to limit painting to not clipped facets only
|
||||
float seed_fill_angle, // the maximal angle between two facets to be painted by the same color
|
||||
float highlight_by_angle_deg = 0.f, // The maximal angle of overhang. If it is set to a non-zero value, it is possible to paint only the triangles of overhang defined by this angle in degrees.
|
||||
ForceReselection force_reselection = ForceReselection::NO); // force reselection of the triangle mesh even in cases that mouse is pointing on the selected triangle
|
||||
|
||||
void bucket_fill_select_triangles(const Vec3f &hit, // point where to start
|
||||
int facet_start, // facet of the original mesh (unsplit) that the hit point belongs to
|
||||
const ClippingPlane &clp, // Clipping plane to limit painting to not clipped facets only
|
||||
bool propagate, // if bucket fill is propagated to neighbor faces or if it fills the only facet of the modified mesh that the hit point belongs to.
|
||||
bool force_reselection = false); // force reselection of the triangle mesh even in cases that mouse is pointing on the selected triangle
|
||||
void bucket_fill_select_triangles(const Vec3f &hit, // point where to start
|
||||
int facet_start, // facet of the original mesh (unsplit) that the hit point belongs to
|
||||
const ClippingPlane &clp, // Clipping plane to limit painting to not clipped facets only
|
||||
BucketFillPropagate propagate, // if bucket fill is propagated to neighbor faces or if it fills the only facet of the modified mesh that the hit point belongs to.
|
||||
ForceReselection force_reselection = ForceReselection::NO); // force reselection of the triangle mesh even in cases that mouse is pointing on the selected triangle
|
||||
|
||||
bool has_facets(TriangleStateType state) const;
|
||||
static bool has_facets(const TriangleSplittingData &data, TriangleStateType test_state);
|
||||
@ -450,8 +467,6 @@ protected:
|
||||
int m_orig_size_indices = 0;
|
||||
|
||||
std::unique_ptr<Cursor> m_cursor;
|
||||
// Zero indicates an uninitialized state.
|
||||
float m_old_cursor_radius_sqr = 0;
|
||||
|
||||
// Private functions:
|
||||
private:
|
||||
|
@ -139,9 +139,9 @@ void GLGizmoPainterBase::render_cursor()
|
||||
return;
|
||||
|
||||
if (m_tool_type == ToolType::BRUSH) {
|
||||
if (m_cursor_type == TriangleSelector::SPHERE)
|
||||
if (m_cursor_type == TriangleSelector::CursorType::SPHERE)
|
||||
render_cursor_sphere(trafo_matrices[m_rr.mesh_id]);
|
||||
else if (m_cursor_type == TriangleSelector::CIRCLE)
|
||||
else if (m_cursor_type == TriangleSelector::CursorType::CIRCLE)
|
||||
render_cursor_circle();
|
||||
}
|
||||
}
|
||||
@ -480,7 +480,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
||||
const Transform3d trafo_matrix_not_translate = mi->get_transformation().get_matrix_no_offset() * mo->volumes[m_rr.mesh_id]->get_matrix_no_offset();
|
||||
const Transform3d trafo_matrix = mi->get_transformation().get_matrix() * mo->volumes[m_rr.mesh_id]->get_matrix();
|
||||
m_triangle_selectors[m_rr.mesh_id]->seed_fill_select_triangles(m_rr.hit, int(m_rr.facet), trafo_matrix_not_translate, this->get_clipping_plane_in_volume_coordinates(trafo_matrix), m_smart_fill_angle,
|
||||
m_paint_on_overhangs_only ? m_highlight_by_angle_threshold_deg : 0.f, true);
|
||||
m_paint_on_overhangs_only ? m_highlight_by_angle_threshold_deg : 0.f, TriangleSelector::ForceReselection::YES);
|
||||
m_triangle_selectors[m_rr.mesh_id]->request_update_render_data();
|
||||
m_seed_fill_last_mesh_id = m_rr.mesh_id;
|
||||
}
|
||||
@ -561,13 +561,14 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
||||
const Vec3f mesh_hit = projected_mouse_position.mesh_hit;
|
||||
const int facet_idx = int(projected_mouse_position.facet_idx);
|
||||
m_triangle_selectors[mesh_idx]->seed_fill_apply_on_triangles(new_state);
|
||||
if (m_tool_type == ToolType::SMART_FILL)
|
||||
if (m_tool_type == ToolType::SMART_FILL) {
|
||||
m_triangle_selectors[mesh_idx]->seed_fill_select_triangles(mesh_hit, facet_idx, trafo_matrix_not_translate, clp, m_smart_fill_angle,
|
||||
m_paint_on_overhangs_only ? m_highlight_by_angle_threshold_deg : 0.f, true);
|
||||
else if (m_tool_type == ToolType::BRUSH && m_cursor_type == TriangleSelector::CursorType::POINTER)
|
||||
m_triangle_selectors[mesh_idx]->bucket_fill_select_triangles(mesh_hit, facet_idx, clp, false, true);
|
||||
else if (m_tool_type == ToolType::BUCKET_FILL)
|
||||
m_triangle_selectors[mesh_idx]->bucket_fill_select_triangles(mesh_hit, facet_idx, clp, true, true);
|
||||
(m_paint_on_overhangs_only ? m_highlight_by_angle_threshold_deg : 0.f), TriangleSelector::ForceReselection::YES);
|
||||
} else if (m_tool_type == ToolType::BRUSH && m_cursor_type == TriangleSelector::CursorType::POINTER) {
|
||||
m_triangle_selectors[mesh_idx]->bucket_fill_select_triangles(mesh_hit, facet_idx, clp, TriangleSelector::BucketFillPropagate::NO, TriangleSelector::ForceReselection::YES);
|
||||
} else if (m_tool_type == ToolType::BUCKET_FILL) {
|
||||
m_triangle_selectors[mesh_idx]->bucket_fill_select_triangles(mesh_hit, facet_idx, clp, TriangleSelector::BucketFillPropagate::YES, TriangleSelector::ForceReselection::YES);
|
||||
}
|
||||
|
||||
m_seed_fill_last_mesh_id = -1;
|
||||
}
|
||||
@ -649,9 +650,9 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
||||
m_triangle_selectors[m_rr.mesh_id]->seed_fill_select_triangles(m_rr.hit, int(m_rr.facet), trafo_matrix_not_translate, clp, m_smart_fill_angle,
|
||||
m_paint_on_overhangs_only ? m_highlight_by_angle_threshold_deg : 0.f);
|
||||
else if (m_tool_type == ToolType::BRUSH && m_cursor_type == TriangleSelector::CursorType::POINTER)
|
||||
m_triangle_selectors[m_rr.mesh_id]->bucket_fill_select_triangles(m_rr.hit, int(m_rr.facet), clp, false);
|
||||
m_triangle_selectors[m_rr.mesh_id]->bucket_fill_select_triangles(m_rr.hit, int(m_rr.facet), clp, TriangleSelector::BucketFillPropagate::NO);
|
||||
else if (m_tool_type == ToolType::BUCKET_FILL)
|
||||
m_triangle_selectors[m_rr.mesh_id]->bucket_fill_select_triangles(m_rr.hit, int(m_rr.facet), clp, true);
|
||||
m_triangle_selectors[m_rr.mesh_id]->bucket_fill_select_triangles(m_rr.hit, int(m_rr.facet), clp, TriangleSelector::BucketFillPropagate::YES);
|
||||
m_triangle_selectors[m_rr.mesh_id]->request_update_render_data();
|
||||
m_seed_fill_last_mesh_id = m_rr.mesh_id;
|
||||
return true;
|
||||
|
@ -132,7 +132,7 @@ protected:
|
||||
// For each model-part volume, store status and division of the triangles.
|
||||
std::vector<std::unique_ptr<TriangleSelectorGUI>> m_triangle_selectors;
|
||||
|
||||
TriangleSelector::CursorType m_cursor_type = TriangleSelector::SPHERE;
|
||||
TriangleSelector::CursorType m_cursor_type = TriangleSelector::CursorType::SPHERE;
|
||||
|
||||
enum class ToolType {
|
||||
BRUSH,
|
||||
|
Loading…
x
Reference in New Issue
Block a user