mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 21:02:02 +08:00
WIP: Cut with Rivets
* Code refactoring: get_connector_mesh() and apply_cut_connectors() moved from ModelObject to CutGizmo. * Allow to change values of space and bulges for snaps
This commit is contained in:
parent
2e6d1ff08f
commit
7cd99d98f5
@ -1280,66 +1280,6 @@ bool ModelObject::has_connectors() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
indexed_triangle_set ModelObject::get_connector_mesh(CutConnectorAttributes connector_attributes)
|
|
||||||
{
|
|
||||||
indexed_triangle_set connector_mesh;
|
|
||||||
|
|
||||||
int sectorCount {1};
|
|
||||||
switch (CutConnectorShape(connector_attributes.shape)) {
|
|
||||||
case CutConnectorShape::Triangle:
|
|
||||||
sectorCount = 3;
|
|
||||||
break;
|
|
||||||
case CutConnectorShape::Square:
|
|
||||||
sectorCount = 4;
|
|
||||||
break;
|
|
||||||
case CutConnectorShape::Circle:
|
|
||||||
sectorCount = 360;
|
|
||||||
break;
|
|
||||||
case CutConnectorShape::Hexagon:
|
|
||||||
sectorCount = 6;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connector_attributes.type == CutConnectorType::Rivet)
|
|
||||||
connector_mesh = its_make_rivet(1.0, 1.0);
|
|
||||||
else if (connector_attributes.style == CutConnectorStyle::Prism)
|
|
||||||
connector_mesh = its_make_cylinder(1.0, 1.0, (2 * PI / sectorCount));
|
|
||||||
else if (connector_attributes.type == CutConnectorType::Plug)
|
|
||||||
connector_mesh = its_make_frustum(1.0, 1.0, (2 * PI / sectorCount));
|
|
||||||
else
|
|
||||||
connector_mesh = its_make_frustum_dowel(1.0, 1.0, sectorCount);
|
|
||||||
|
|
||||||
return connector_mesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelObject::apply_cut_connectors(const std::string& new_name)
|
|
||||||
{
|
|
||||||
if (cut_connectors.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
using namespace Geometry;
|
|
||||||
|
|
||||||
size_t connector_id = cut_id.connectors_cnt();
|
|
||||||
for (const CutConnector& connector : cut_connectors) {
|
|
||||||
TriangleMesh mesh = TriangleMesh(get_connector_mesh(connector.attribs));
|
|
||||||
// Mesh will be centered when loading.
|
|
||||||
ModelVolume* new_volume = add_volume(std::move(mesh), ModelVolumeType::NEGATIVE_VOLUME);
|
|
||||||
|
|
||||||
// Transform the new modifier to be aligned inside the instance
|
|
||||||
new_volume->set_transformation(translation_transform(connector.pos) * connector.rotation_m *
|
|
||||||
scale_transform(Vec3f(connector.radius, connector.radius, connector.height).cast<double>()));
|
|
||||||
|
|
||||||
new_volume->cut_info = { connector.attribs.type, connector.radius_tolerance, connector.height_tolerance };
|
|
||||||
new_volume->name = new_name + "-" + std::to_string(++connector_id);
|
|
||||||
}
|
|
||||||
cut_id.increase_connectors_cnt(cut_connectors.size());
|
|
||||||
|
|
||||||
// delete all connectors
|
|
||||||
cut_connectors.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelObject::invalidate_cut()
|
void ModelObject::invalidate_cut()
|
||||||
{
|
{
|
||||||
this->cut_id.invalidate();
|
this->cut_id.invalidate();
|
||||||
|
@ -463,8 +463,6 @@ public:
|
|||||||
size_t materials_count() const;
|
size_t materials_count() const;
|
||||||
size_t facets_count() const;
|
size_t facets_count() const;
|
||||||
size_t parts_count() const;
|
size_t parts_count() const;
|
||||||
static indexed_triangle_set get_connector_mesh(CutConnectorAttributes connector_attributes);
|
|
||||||
void apply_cut_connectors(const std::string& name);
|
|
||||||
// invalidate cut state for this object and its connectors/volumes
|
// invalidate cut state for this object and its connectors/volumes
|
||||||
void invalidate_cut();
|
void invalidate_cut();
|
||||||
// delete volumes which are marked as connector for this object
|
// delete volumes which are marked as connector for this object
|
||||||
|
@ -1262,7 +1262,7 @@ indexed_triangle_set its_make_frustum_dowel(double radius, double h, int sectorC
|
|||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
indexed_triangle_set its_make_rivet(double r, double h, float space_proportion)
|
indexed_triangle_set its_make_snap(double r, double h, float space_proportion, float bulge_proportion)
|
||||||
{
|
{
|
||||||
const float radius = (float)r;
|
const float radius = (float)r;
|
||||||
const float height = (float)h;
|
const float height = (float)h;
|
||||||
@ -1272,7 +1272,7 @@ indexed_triangle_set its_make_rivet(double r, double h, float space_proportion)
|
|||||||
const float space_len = space_proportion * radius;
|
const float space_len = space_proportion * radius;
|
||||||
|
|
||||||
const float b_len = radius;
|
const float b_len = radius;
|
||||||
const float m_len = (1 + 0.5f*space_proportion) * radius;
|
const float m_len = (1 + bulge_proportion) * radius;
|
||||||
const float t_len = 0.5f * radius;
|
const float t_len = 0.5f * radius;
|
||||||
|
|
||||||
const float b_height = 0.f;
|
const float b_height = 0.f;
|
||||||
@ -1351,7 +1351,7 @@ indexed_triangle_set its_make_rivet(double r, double h, float space_proportion)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add d side vertices and facets
|
// add d side vertices and facets
|
||||||
while (b_angle_start < b_angle_stop) {
|
while (!is_approx(b_angle_start, b_angle_stop)) {
|
||||||
b_angle_start += b_angle_step;
|
b_angle_start += b_angle_step;
|
||||||
t_angle_start += t_angle_step;
|
t_angle_start += t_angle_step;
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ indexed_triangle_set its_make_frustum(double r, double h, double fa=(2*PI/360
|
|||||||
indexed_triangle_set its_make_frustum_dowel(double r, double h, int sectorCount);
|
indexed_triangle_set its_make_frustum_dowel(double r, double h, int sectorCount);
|
||||||
indexed_triangle_set its_make_pyramid(float base, float height);
|
indexed_triangle_set its_make_pyramid(float base, float height);
|
||||||
indexed_triangle_set its_make_sphere(double radius, double fa);
|
indexed_triangle_set its_make_sphere(double radius, double fa);
|
||||||
indexed_triangle_set its_make_rivet(double r, double h, float space_proportion = 0.25f);
|
indexed_triangle_set its_make_snap(double r, double h, float space_proportion = 0.25f, float bulge_proportion = 0.125f);
|
||||||
|
|
||||||
indexed_triangle_set its_convex_hull(const std::vector<Vec3f> &pts);
|
indexed_triangle_set its_convex_hull(const std::vector<Vec3f> &pts);
|
||||||
inline indexed_triangle_set its_convex_hull(const indexed_triangle_set &its) { return its_convex_hull(its.vertices); }
|
inline indexed_triangle_set its_convex_hull(const indexed_triangle_set &its) { return its_convex_hull(its.vertices); }
|
||||||
|
@ -230,7 +230,7 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename,
|
|||||||
{"Size" , _u8L("Size")},
|
{"Size" , _u8L("Size")},
|
||||||
};
|
};
|
||||||
|
|
||||||
update_connector_shape();
|
// update_connector_shape();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GLGizmoCut3D::get_tooltip() const
|
std::string GLGizmoCut3D::get_tooltip() const
|
||||||
@ -498,8 +498,8 @@ bool GLGizmoCut3D::render_combo(const std::string& label, const std::vector<std:
|
|||||||
ImGui::AlignTextToFramePadding();
|
ImGui::AlignTextToFramePadding();
|
||||||
const bool is_changed = m_imgui->combo(label, lines, selection_idx, 0, m_label_width, m_control_width);
|
const bool is_changed = m_imgui->combo(label, lines, selection_idx, 0, m_label_width, m_control_width);
|
||||||
|
|
||||||
if (is_changed)
|
//if (is_changed)
|
||||||
update_connector_shape();
|
// update_connector_shape();
|
||||||
|
|
||||||
return is_changed;
|
return is_changed;
|
||||||
}
|
}
|
||||||
@ -524,7 +524,7 @@ bool GLGizmoCut3D::render_double_input(const std::string& label, double& value_i
|
|||||||
return !is_approx(old_val, value);
|
return !is_approx(old_val, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoCut3D::render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in, float max_val/* = -0.1f*/, float max_tolerance/* = -0.1f*/)
|
bool GLGizmoCut3D::render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in, float min_val/* = -0.1f*/, float max_tolerance/* = -0.1f*/)
|
||||||
{
|
{
|
||||||
constexpr float UndefMinVal = -0.1f;
|
constexpr float UndefMinVal = -0.1f;
|
||||||
const float f_mm_to_in = static_cast<float>(ObjectManipulation::mm_to_in);
|
const float f_mm_to_in = static_cast<float>(ObjectManipulation::mm_to_in);
|
||||||
@ -548,7 +548,7 @@ bool GLGizmoCut3D::render_slider_double_input(const std::string& label, float& v
|
|||||||
|
|
||||||
const BoundingBoxf3 bbox = m_bounding_box;
|
const BoundingBoxf3 bbox = m_bounding_box;
|
||||||
const float mean_size = float((bbox.size().x() + bbox.size().y() + bbox.size().z()) / 9.0) * (m_imperial_units ? f_mm_to_in : 1.f);
|
const float mean_size = float((bbox.size().x() + bbox.size().y() + bbox.size().z()) / 9.0) * (m_imperial_units ? f_mm_to_in : 1.f);
|
||||||
const float max_v = max_val > 0.f ? /*std::min(max_val, mean_size)*/max_val : mean_size;
|
const float min_v = min_val > 0.f ? /*std::min(max_val, mean_size)*/min_val : 1.f;
|
||||||
|
|
||||||
ImGuiWrapper::text(label);
|
ImGuiWrapper::text(label);
|
||||||
|
|
||||||
@ -556,7 +556,7 @@ bool GLGizmoCut3D::render_slider_double_input(const std::string& label, float& v
|
|||||||
ImGui::PushItemWidth(m_control_width * 0.7f);
|
ImGui::PushItemWidth(m_control_width * 0.7f);
|
||||||
|
|
||||||
// const bool is_value_changed = render_slider("##" + label, value_in, 1.f, mean_size, _L("Value"));
|
// const bool is_value_changed = render_slider("##" + label, value_in, 1.f, mean_size, _L("Value"));
|
||||||
const bool is_value_changed = render_slider("##" + label, value_in, 1.f, max_v, _L("Value"));
|
const bool is_value_changed = render_slider("##" + label, value_in, min_v, mean_size, _L("Value"));
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::PushItemWidth(m_control_width * 0.45f);
|
ImGui::PushItemWidth(m_control_width * 0.45f);
|
||||||
@ -599,7 +599,7 @@ bool GLGizmoCut3D::render_connect_type_radio_button(CutConnectorType type)
|
|||||||
ImGui::PushItemWidth(m_control_width);
|
ImGui::PushItemWidth(m_control_width);
|
||||||
if (ImGui::RadioButton(m_connector_types[size_t(type)].c_str(), m_connector_type == type)) {
|
if (ImGui::RadioButton(m_connector_types[size_t(type)].c_str(), m_connector_type == type)) {
|
||||||
m_connector_type = type;
|
m_connector_type = type;
|
||||||
update_connector_shape();
|
// update_connector_shape();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -2013,7 +2013,8 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors)
|
|||||||
apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.shape = CutConnectorShape(m_connector_shape_id); });
|
apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.shape = CutConnectorShape(m_connector_shape_id); });
|
||||||
m_imgui->disabled_end();
|
m_imgui->disabled_end();
|
||||||
|
|
||||||
if (render_slider_double_input(m_labels_map["Depth"], m_connector_depth_ratio, m_connector_depth_ratio_tolerance))
|
const float depth_min_value = m_connector_type == CutConnectorType::Rivet ? m_connector_size : -0.1f;
|
||||||
|
if (render_slider_double_input(m_labels_map["Depth"], m_connector_depth_ratio, m_connector_depth_ratio_tolerance, depth_min_value))
|
||||||
apply_selected_connectors([this, &connectors](size_t idx) {
|
apply_selected_connectors([this, &connectors](size_t idx) {
|
||||||
if (m_connector_depth_ratio > 0)
|
if (m_connector_depth_ratio > 0)
|
||||||
connectors[idx].height = m_connector_depth_ratio;
|
connectors[idx].height = m_connector_depth_ratio;
|
||||||
@ -2029,6 +2030,45 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors)
|
|||||||
connectors[idx].radius_tolerance = 0.5f * m_connector_size_tolerance;
|
connectors[idx].radius_tolerance = 0.5f * m_connector_size_tolerance;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (m_connector_type == CutConnectorType::Rivet) {
|
||||||
|
|
||||||
|
const std::string format = "%.0f %%";
|
||||||
|
|
||||||
|
bool is_changed = false;
|
||||||
|
{
|
||||||
|
const std::string label = _u8L("Bulge");
|
||||||
|
ImGuiWrapper::text(label);
|
||||||
|
|
||||||
|
ImGui::SameLine(m_label_width);
|
||||||
|
ImGui::PushItemWidth(m_control_width * 0.7f);
|
||||||
|
|
||||||
|
float val = m_snap_bulge_proportion *100.f;
|
||||||
|
if (m_imgui->slider_float(("##snap_" + label).c_str(), &val, 5.f, 100.f * m_snap_space_proportion, format.c_str(), 1.f, true, _u8L("Bulge proportion related to radius"))) {
|
||||||
|
m_snap_bulge_proportion = val * 0.01f;
|
||||||
|
is_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string label = _u8L("Space");
|
||||||
|
ImGuiWrapper::text(label);
|
||||||
|
|
||||||
|
ImGui::SameLine(m_label_width);
|
||||||
|
ImGui::PushItemWidth(m_control_width * 0.7f);
|
||||||
|
|
||||||
|
float val = m_snap_space_proportion *100.f;
|
||||||
|
if (m_imgui->slider_float(("##snap_" + label).c_str(), &val, 10.f, 50.f, format.c_str(), 1.f, true, _u8L("Space proportion related to radius"))) {
|
||||||
|
m_snap_space_proportion = val * 0.01f;
|
||||||
|
is_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_changed) {
|
||||||
|
update_connector_shape();
|
||||||
|
update_raycasters_for_picking();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (m_imgui->button(_L("Confirm connectors"))) {
|
if (m_imgui->button(_L("Confirm connectors"))) {
|
||||||
@ -2224,7 +2264,7 @@ void GLGizmoCut3D::render_groove_input(const std::string& label, float& in_val,
|
|||||||
reset_cut_by_contours();
|
reset_cut_by_contours();
|
||||||
// Plater::TakeSnapshot snapshot(wxGetApp().plater(), format_wxstr("%1%: %2%", _L("Groove change"), label), UndoRedo::SnapshotType::GizmoAction);
|
// Plater::TakeSnapshot snapshot(wxGetApp().plater(), format_wxstr("%1%: %2%", _L("Groove change"), label), UndoRedo::SnapshotType::GizmoAction);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors)
|
void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors)
|
||||||
{
|
{
|
||||||
@ -2758,7 +2798,7 @@ void GLGizmoCut3D::apply_connectors_in_model(ModelObject* mo, int &dowels_count)
|
|||||||
connector.pos += m_cut_normal * 0.5 * double(connector.height);
|
connector.pos += m_cut_normal * 0.5 * double(connector.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mo->apply_cut_connectors(_u8L("Connector"));
|
apply_cut_connectors(mo, _u8L("Connector"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3252,7 +3292,7 @@ void GLGizmoCut3D::init_connector_shapes()
|
|||||||
if (type == CutConnectorType::Rivet && shape != CutConnectorShape::Circle)
|
if (type == CutConnectorType::Rivet && shape != CutConnectorShape::Circle)
|
||||||
continue;
|
continue;
|
||||||
const CutConnectorAttributes attribs = { type, style, shape };
|
const CutConnectorAttributes attribs = { type, style, shape };
|
||||||
indexed_triangle_set its = ModelObject::get_connector_mesh(attribs);
|
indexed_triangle_set its = get_connector_mesh(attribs);
|
||||||
m_shapes[attribs].model.init_from(its);
|
m_shapes[attribs].model.init_from(its);
|
||||||
m_shapes[attribs].mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
|
m_shapes[attribs].mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
|
||||||
}
|
}
|
||||||
@ -3263,9 +3303,18 @@ void GLGizmoCut3D::update_connector_shape()
|
|||||||
{
|
{
|
||||||
CutConnectorAttributes attribs = { m_connector_type, CutConnectorStyle(m_connector_style), CutConnectorShape(m_connector_shape_id) };
|
CutConnectorAttributes attribs = { m_connector_type, CutConnectorStyle(m_connector_style), CutConnectorShape(m_connector_shape_id) };
|
||||||
|
|
||||||
const indexed_triangle_set its = ModelObject::get_connector_mesh(attribs);
|
if (m_connector_type == CutConnectorType::Rivet) {
|
||||||
m_connector_mesh.clear();
|
indexed_triangle_set its = get_connector_mesh(attribs);
|
||||||
m_connector_mesh = TriangleMesh(its);
|
m_shapes[attribs].reset();
|
||||||
|
m_shapes[attribs].model.init_from(its);
|
||||||
|
m_shapes[attribs].mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
|
||||||
|
|
||||||
|
//const indexed_triangle_set its = get_connector_mesh(attribs);
|
||||||
|
//m_connector_mesh.clear();
|
||||||
|
//m_connector_mesh = TriangleMesh(its);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoCut3D::cut_line_processing() const
|
bool GLGizmoCut3D::cut_line_processing() const
|
||||||
@ -3522,5 +3571,69 @@ void GLGizmoCut3D::data_changed(bool is_serializing)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
indexed_triangle_set GLGizmoCut3D::get_connector_mesh(CutConnectorAttributes connector_attributes)
|
||||||
|
{
|
||||||
|
indexed_triangle_set connector_mesh;
|
||||||
|
|
||||||
|
int sectorCount{ 1 };
|
||||||
|
switch (CutConnectorShape(connector_attributes.shape)) {
|
||||||
|
case CutConnectorShape::Triangle:
|
||||||
|
sectorCount = 3;
|
||||||
|
break;
|
||||||
|
case CutConnectorShape::Square:
|
||||||
|
sectorCount = 4;
|
||||||
|
break;
|
||||||
|
case CutConnectorShape::Circle:
|
||||||
|
sectorCount = 360;
|
||||||
|
break;
|
||||||
|
case CutConnectorShape::Hexagon:
|
||||||
|
sectorCount = 6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connector_attributes.type == CutConnectorType::Rivet)
|
||||||
|
connector_mesh = its_make_snap(1.0, 1.0, m_snap_space_proportion, m_snap_bulge_proportion);
|
||||||
|
else if (connector_attributes.style == CutConnectorStyle::Prism)
|
||||||
|
connector_mesh = its_make_cylinder(1.0, 1.0, (2 * PI / sectorCount));
|
||||||
|
else if (connector_attributes.type == CutConnectorType::Plug)
|
||||||
|
connector_mesh = its_make_frustum(1.0, 1.0, (2 * PI / sectorCount));
|
||||||
|
else
|
||||||
|
connector_mesh = its_make_frustum_dowel(1.0, 1.0, sectorCount);
|
||||||
|
|
||||||
|
return connector_mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoCut3D::apply_cut_connectors(ModelObject* mo, const std::string& connector_name)
|
||||||
|
{
|
||||||
|
if (mo->cut_connectors.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
using namespace Geometry;
|
||||||
|
|
||||||
|
size_t connector_id = mo->cut_id.connectors_cnt();
|
||||||
|
for (const CutConnector& connector : mo->cut_connectors) {
|
||||||
|
TriangleMesh mesh = TriangleMesh(get_connector_mesh(connector.attribs));
|
||||||
|
// Mesh will be centered when loading.
|
||||||
|
ModelVolume* new_volume = mo->add_volume(std::move(mesh), ModelVolumeType::NEGATIVE_VOLUME);
|
||||||
|
|
||||||
|
// Transform the new modifier to be aligned inside the instance
|
||||||
|
new_volume->set_transformation(translation_transform(connector.pos) * connector.rotation_m *
|
||||||
|
scale_transform(Vec3f(connector.radius, connector.radius, connector.height).cast<double>()));
|
||||||
|
|
||||||
|
new_volume->cut_info = { connector.attribs.type, connector.radius_tolerance, connector.height_tolerance };
|
||||||
|
new_volume->name = connector_name + "-" + std::to_string(++connector_id);
|
||||||
|
}
|
||||||
|
mo->cut_id.increase_connectors_cnt(mo->cut_connectors.size());
|
||||||
|
|
||||||
|
// delete all connectors
|
||||||
|
mo->cut_connectors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -127,6 +127,10 @@ class GLGizmoCut3D : public GLGizmoBase
|
|||||||
float m_groove_width_tolerance{ 0.1f };
|
float m_groove_width_tolerance{ 0.1f };
|
||||||
bool m_optimaze_groove_rendering{ true };
|
bool m_optimaze_groove_rendering{ true };
|
||||||
|
|
||||||
|
// Input params for cut with snaps
|
||||||
|
float m_snap_bulge_proportion{ 0.15f };
|
||||||
|
float m_snap_space_proportion{ 0.3f };
|
||||||
|
|
||||||
bool m_hide_cut_plane{ false };
|
bool m_hide_cut_plane{ false };
|
||||||
bool m_connectors_editing{ false };
|
bool m_connectors_editing{ false };
|
||||||
bool m_cut_plane_as_circle{ false };
|
bool m_cut_plane_as_circle{ false };
|
||||||
@ -323,7 +327,7 @@ private:
|
|||||||
bool render_cut_mode_combo();
|
bool render_cut_mode_combo();
|
||||||
bool render_combo(const std::string&label, const std::vector<std::string>&lines, int&selection_idx);
|
bool render_combo(const std::string&label, const std::vector<std::string>&lines, int&selection_idx);
|
||||||
bool render_double_input(const std::string& label, double& value_in);
|
bool render_double_input(const std::string& label, double& value_in);
|
||||||
bool render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in, float max_val = -0.1f, float max_tolerance = -0.1f);
|
bool render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in, float min_val = -0.1f, float max_tolerance = -0.1f);
|
||||||
void render_move_center_input(int axis);
|
void render_move_center_input(int axis);
|
||||||
void render_connect_mode_radio_button(CutConnectorMode mode);
|
void render_connect_mode_radio_button(CutConnectorMode mode);
|
||||||
bool render_reset_button(const std::string& label_id, const std::string& tooltip) const;
|
bool render_reset_button(const std::string& label_id, const std::string& tooltip) const;
|
||||||
@ -364,6 +368,9 @@ private:
|
|||||||
void check_and_update_connectors_state();
|
void check_and_update_connectors_state();
|
||||||
|
|
||||||
void toggle_model_objects_visibility();
|
void toggle_model_objects_visibility();
|
||||||
|
|
||||||
|
indexed_triangle_set get_connector_mesh(CutConnectorAttributes connector_attributes);
|
||||||
|
void apply_cut_connectors(ModelObject* mo, const std::string& connector_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
|
Loading…
x
Reference in New Issue
Block a user