Cut: ObjectClipper now allows to not render all the contours
This commit is contained in:
parent
b9bba5ff6b
commit
d0ee5e7ca3
@ -1467,6 +1467,19 @@ void GLGizmoCut3D::on_render()
|
||||
m_c->selection_info()->set_use_shift(true);
|
||||
}
|
||||
|
||||
|
||||
::glDisable(GL_DEPTH_TEST);
|
||||
std::vector<Vec3d> pts = m_c->object_clipper()->point_per_contour();
|
||||
if (! pts.empty()) {
|
||||
const Vec3d dir = (m_plane_center-pts.front()).dot(m_cut_normal) * m_cut_normal;
|
||||
for (const Vec3d& pt : pts)
|
||||
render_model(m_sphere.model, ColorRGBA::GREEN(), wxGetApp().plater()->get_camera().get_view_matrix() * translation_transform(pt+dir));
|
||||
}
|
||||
::glEnable(GL_DEPTH_TEST);
|
||||
|
||||
|
||||
|
||||
|
||||
update_clipper();
|
||||
|
||||
init_picking_models();
|
||||
@ -1733,7 +1746,7 @@ void GLGizmoCut3D::flip_cut_plane()
|
||||
}
|
||||
|
||||
|
||||
GLGizmoCut3D::PartSelection::PartSelection(const ModelObject* mo, const Transform3d& cut_matrix, int instance_idx_in, const Vec3d& center, const Vec3d& normal)
|
||||
GLGizmoCut3D::PartSelection::PartSelection(const ModelObject* mo, const Transform3d& cut_matrix, int instance_idx_in, const Vec3d& center, const Vec3d& normal, const CommonGizmosDataObjects::ObjectClipper& oc)
|
||||
{
|
||||
m_model = Model();
|
||||
m_model.add_object(*mo);
|
||||
@ -1773,6 +1786,15 @@ GLGizmoCut3D::PartSelection::PartSelection(const ModelObject* mo, const Transfor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now go through the contours and create a map from contours to parts.
|
||||
if (std::vector<Vec3d> pts = oc.point_per_contour();! pts.empty()) {
|
||||
const Vec3d dir = (center-pts.front()).dot(normal) * normal;
|
||||
for (Vec3d& pt : pts)
|
||||
pt = pt+dir;
|
||||
// pts are now in world coordinates.
|
||||
}
|
||||
|
||||
|
||||
m_valid = true;
|
||||
}
|
||||
@ -1798,7 +1820,7 @@ void GLGizmoCut3D::process_contours()
|
||||
const int instance_idx = selection.get_instance_idx();
|
||||
const int object_idx = selection.get_object_idx();
|
||||
|
||||
m_part_selection = PartSelection(model_objects[object_idx], get_cut_matrix(selection), instance_idx, m_plane_center, m_cut_normal);
|
||||
m_part_selection = PartSelection(model_objects[object_idx], get_cut_matrix(selection), instance_idx, m_plane_center, m_cut_normal, *m_c->object_clipper());
|
||||
m_parent.toggle_model_objects_visibility(false);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,8 @@ class Selection;
|
||||
|
||||
enum class SLAGizmoEventType : unsigned char;
|
||||
|
||||
namespace CommonGizmosDataObjects { class ObjectClipper; }
|
||||
|
||||
class GLGizmoCut3D : public GLGizmoBase
|
||||
{
|
||||
enum GrabberID {
|
||||
@ -140,7 +142,7 @@ class GLGizmoCut3D : public GLGizmoBase
|
||||
class PartSelection {
|
||||
public:
|
||||
PartSelection() = default;
|
||||
PartSelection(const ModelObject* mo, const Transform3d& cut_matrix, int instance_idx, const Vec3d& center, const Vec3d& normal);
|
||||
PartSelection(const ModelObject* mo, const Transform3d& cut_matrix, int instance_idx, const Vec3d& center, const Vec3d& normal, const CommonGizmosDataObjects::ObjectClipper& oc);
|
||||
|
||||
struct Part {
|
||||
GLModel glmodel;
|
||||
|
@ -370,21 +370,30 @@ void ObjectClipper::on_release()
|
||||
|
||||
}
|
||||
|
||||
void ObjectClipper::render_cut() const
|
||||
void ObjectClipper::render_cut(const std::vector<size_t>* ignore_idxs) const
|
||||
{
|
||||
if (m_clp_ratio == 0.)
|
||||
return;
|
||||
const SelectionInfo* sel_info = get_pool()->selection_info();
|
||||
const Geometry::Transformation inst_trafo = sel_info->model_object()->instances[sel_info->get_active_instance()]->get_transformation();
|
||||
|
||||
std::vector<size_t> ignore_idxs_local = ignore_idxs ? *ignore_idxs : std::vector<size_t>();
|
||||
|
||||
for (auto& clipper : m_clippers) {
|
||||
Geometry::Transformation trafo = inst_trafo * clipper.second;
|
||||
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift()));
|
||||
clipper.first->set_plane(*m_clp);
|
||||
clipper.first->set_transformation(trafo);
|
||||
clipper.first->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD));
|
||||
clipper.first->render_cut({ 1.0f, 0.37f, 0.0f, 1.0f });
|
||||
clipper.first->render_contour({ 1.f, 1.f, 1.f, 1.f });
|
||||
Geometry::Transformation trafo = inst_trafo * clipper.second;
|
||||
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift()));
|
||||
clipper.first->set_plane(*m_clp);
|
||||
clipper.first->set_transformation(trafo);
|
||||
clipper.first->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD));
|
||||
clipper.first->render_cut({ 1.0f, 0.37f, 0.0f, 1.0f }, &ignore_idxs_local);
|
||||
clipper.first->render_contour({ 1.f, 1.f, 1.f, 1.f }, &ignore_idxs_local);
|
||||
|
||||
// Now update the ignore idxs. Find the first element belonging to the next clipper,
|
||||
// and remove everything before it and decrement everything by current number of contours.
|
||||
const int num_of_contours = clipper.first->get_number_of_contours();
|
||||
ignore_idxs_local.erase(ignore_idxs_local.begin(), std::find_if(ignore_idxs_local.begin(), ignore_idxs_local.end(), [num_of_contours](size_t idx) { return idx >= num_of_contours; } ));
|
||||
for (size_t& idx : ignore_idxs_local)
|
||||
idx -= num_of_contours;
|
||||
}
|
||||
}
|
||||
|
||||
@ -415,6 +424,25 @@ bool ObjectClipper::has_valid_contour() const
|
||||
return m_clp_ratio != 0. && std::any_of(m_clippers.begin(), m_clippers.end(), [](const auto& cl) { return cl.first->has_valid_contour(); });
|
||||
}
|
||||
|
||||
std::vector<Vec3d> ObjectClipper::point_per_contour() const
|
||||
{
|
||||
std::vector<Vec3d> pts;
|
||||
|
||||
const SelectionInfo* sel_info = get_pool()->selection_info();
|
||||
const Geometry::Transformation inst_trafo = sel_info->model_object()->instances[sel_info->get_active_instance()]->get_transformation();
|
||||
|
||||
for (auto& clipper : m_clippers) {
|
||||
Geometry::Transformation trafo = inst_trafo * clipper.second;
|
||||
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift()));
|
||||
|
||||
// FIXME: do not assume just one clipper
|
||||
pts = clipper.first->point_per_contour();
|
||||
//for (Vec3d& v : pts)
|
||||
// v = trafo.get_matrix() * v;
|
||||
}
|
||||
return pts;
|
||||
}
|
||||
|
||||
|
||||
void ObjectClipper::set_position_by_ratio(double pos, bool keep_normal)
|
||||
{
|
||||
|
@ -242,12 +242,13 @@ public:
|
||||
void set_normal(const Vec3d& dir);
|
||||
double get_position() const { return m_clp_ratio; }
|
||||
const ClippingPlane* get_clipping_plane(bool ignore_hide_clipped = false) const;
|
||||
void render_cut() const;
|
||||
void render_cut(const std::vector<size_t>* ignore_idxs = nullptr) const;
|
||||
void set_position_by_ratio(double pos, bool keep_normal);
|
||||
void set_range_and_pos(const Vec3d& cpl_normal, double cpl_offset, double pos);
|
||||
void set_behavior(bool hide_clipped, bool fill_cut, double contour_width);
|
||||
|
||||
int get_number_of_contours() const;
|
||||
std::vector<Vec3d> point_per_contour() const;
|
||||
|
||||
int is_projection_inside_cut(const Vec3d& point_in) const;
|
||||
bool has_valid_contour() const;
|
||||
|
@ -94,7 +94,7 @@ void MeshClipper::set_transformation(const Geometry::Transformation& trafo)
|
||||
}
|
||||
}
|
||||
|
||||
void MeshClipper::render_cut(const ColorRGBA& color)
|
||||
void MeshClipper::render_cut(const ColorRGBA& color, const std::vector<size_t>* ignore_idxs)
|
||||
{
|
||||
if (! m_result)
|
||||
recalculate_triangles();
|
||||
@ -108,7 +108,10 @@ void MeshClipper::render_cut(const ColorRGBA& color)
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
for (CutIsland& isl : m_result->cut_islands) {
|
||||
for (size_t i=0; i<m_result->cut_islands.size(); ++i) {
|
||||
if (ignore_idxs && std::binary_search(ignore_idxs->begin(), ignore_idxs->end(), i))
|
||||
continue;
|
||||
CutIsland& isl = m_result->cut_islands[i];
|
||||
isl.model.set_color(isl.disabled ? ColorRGBA(0.5f, 0.5f, 0.5f, 1.f) : color);
|
||||
isl.model.render();
|
||||
}
|
||||
@ -120,7 +123,7 @@ void MeshClipper::render_cut(const ColorRGBA& color)
|
||||
}
|
||||
|
||||
|
||||
void MeshClipper::render_contour(const ColorRGBA& color)
|
||||
void MeshClipper::render_contour(const ColorRGBA& color, const std::vector<size_t>* ignore_idxs)
|
||||
{
|
||||
if (! m_result)
|
||||
recalculate_triangles();
|
||||
@ -135,7 +138,10 @@ void MeshClipper::render_contour(const ColorRGBA& color)
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
for (CutIsland& isl : m_result->cut_islands) {
|
||||
for (size_t i=0; i<m_result->cut_islands.size(); ++i) {
|
||||
if (ignore_idxs && std::binary_search(ignore_idxs->begin(), ignore_idxs->end(), i))
|
||||
continue;
|
||||
CutIsland& isl = m_result->cut_islands[i];
|
||||
isl.model_expanded.set_color(isl.disabled ? ColorRGBA(1.f, 0.f, 0.f, 1.f) : color);
|
||||
isl.model_expanded.render();
|
||||
}
|
||||
@ -166,6 +172,20 @@ bool MeshClipper::has_valid_contour() const
|
||||
return m_result && std::any_of(m_result->cut_islands.begin(), m_result->cut_islands.end(), [](const CutIsland& isl) { return !isl.expoly.empty(); });
|
||||
}
|
||||
|
||||
std::vector<Vec3d> MeshClipper::point_per_contour() const
|
||||
{
|
||||
std::vector<Vec3d> out;
|
||||
if (!m_result || m_result->cut_islands.empty())
|
||||
return out;
|
||||
|
||||
for (const CutIsland& isl : m_result->cut_islands) {
|
||||
// FIXME: There might be holes !
|
||||
Vec2d c = unscale(isl.expoly.contour.centroid());
|
||||
out.emplace_back(m_result->trafo * Vec3d(c.x(), c.y(), 0.));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
void MeshClipper::recalculate_triangles()
|
||||
{
|
||||
|
@ -115,13 +115,14 @@ public:
|
||||
|
||||
// Render the triangulated cut. Transformation matrices should
|
||||
// be set in world coords.
|
||||
void render_cut(const ColorRGBA& color);
|
||||
void render_contour(const ColorRGBA& color);
|
||||
void render_cut(const ColorRGBA& color, const std::vector<size_t>* ignore_idxs = nullptr);
|
||||
void render_contour(const ColorRGBA& color, const std::vector<size_t>* ignore_idxs = nullptr);
|
||||
|
||||
// Returns index of the contour which was clicked, -1 otherwise.
|
||||
int is_projection_inside_cut(const Vec3d& point) const;
|
||||
bool has_valid_contour() const;
|
||||
int get_number_of_contours() const { return m_result ? m_result->cut_islands.size() : 0; }
|
||||
std::vector<Vec3d> point_per_contour() const;
|
||||
|
||||
private:
|
||||
void recalculate_triangles();
|
||||
|
Loading…
Reference in New Issue
Block a user