Cut WIP: Suppress un-universal scaling for cut objects
Added editing of the tolerance
This commit is contained in:
parent
003acee218
commit
0fd29dfec7
@ -713,7 +713,7 @@ ModelVolume* ModelObject::add_volume(const ModelVolume &other, ModelVolumeType t
|
||||
ModelVolume* v = new ModelVolume(this, other);
|
||||
if (type != ModelVolumeType::INVALID && v->type() != type)
|
||||
v->set_type(type);
|
||||
v->source.is_connector = other.source.is_connector;
|
||||
v->cut_info = other.cut_info;
|
||||
this->volumes.push_back(v);
|
||||
// The volume should already be centered at this point of time when copying shared pointers of the triangle mesh and convex hull.
|
||||
// v->center_geometry_after_creation();
|
||||
@ -1380,10 +1380,9 @@ indexed_triangle_set ModelObject::get_connector_mesh(CutConnectorAttributes conn
|
||||
|
||||
void ModelObject::apply_cut_connectors(const std::string& name, CutConnectorAttributes connector_attributes)
|
||||
{
|
||||
// discard old connector markers vor volumes
|
||||
for (ModelVolume* volume : volumes) {
|
||||
volume->source.is_connector = false;
|
||||
}
|
||||
// discard old connector markers for volumes
|
||||
for (ModelVolume* volume : volumes)
|
||||
volume->cut_info.discard();
|
||||
|
||||
if (cut_connectors.empty())
|
||||
return;
|
||||
@ -1404,8 +1403,8 @@ void ModelObject::apply_cut_connectors(const std::string& name, CutConnectorAttr
|
||||
Vec3d::Ones()
|
||||
));
|
||||
|
||||
new_volume->cut_info = { true, connector.radius_tolerance, connector.height_tolerance };
|
||||
new_volume->name = name + "-" + std::to_string(++connector_id);
|
||||
new_volume->source.is_connector = true;
|
||||
}
|
||||
cut_id.increase_connectors_cnt(cut_connectors.size());
|
||||
|
||||
@ -1481,27 +1480,47 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Vec3d& cut_center, const
|
||||
dowels->input_file.clear();
|
||||
}
|
||||
|
||||
using namespace Geometry;
|
||||
|
||||
// Because transformations are going to be applied to meshes directly,
|
||||
// we reset transformation of all instances and volumes,
|
||||
// except for translation and Z-rotation on instances, which are preserved
|
||||
// in the transformation matrix and not applied to the mesh transform.
|
||||
|
||||
// const auto instance_matrix = instances[instance]->get_matrix(true);
|
||||
const auto instance_matrix = Geometry::assemble_transform(
|
||||
const auto instance_matrix = assemble_transform(
|
||||
Vec3d::Zero(), // don't apply offset
|
||||
instances[instance]->get_rotation().cwiseProduct(Vec3d(1.0, 1.0, 1.0)),
|
||||
instances[instance]->get_scaling_factor(),
|
||||
instances[instance]->get_mirror()
|
||||
);
|
||||
|
||||
const auto cut_matrix = Geometry::assemble_transform(-cut_center);
|
||||
|
||||
const auto invert_cut_matrix = Geometry::assemble_transform(cut_center, cut_rotation);
|
||||
const auto cut_matrix = rotation_transform(cut_rotation).inverse() * assemble_transform(-cut_center);
|
||||
const auto invert_cut_matrix = assemble_transform(cut_center, cut_rotation);
|
||||
|
||||
// Displacement (in instance coordinates) to be applied to place the upper parts
|
||||
Vec3d local_displace = Vec3d::Zero();
|
||||
Vec3d local_dowels_displace = Vec3d::Zero();
|
||||
|
||||
Vec3d rotate_z180 = deg2rad(180.0) * Vec3d::UnitX();
|
||||
|
||||
auto apply_tolerance = [](ModelVolume * vol)
|
||||
{
|
||||
Vec3d sf = vol->get_scaling_factor();
|
||||
/*
|
||||
// correct Z offset in respect to the new size
|
||||
Vec3d pos = vol->get_offset();
|
||||
pos[Z] += sf[Z] * 0.5 * vol->cut_info.height_tolerance;
|
||||
vol->set_offset(pos);
|
||||
*/
|
||||
// make a "hole" wider
|
||||
sf[X] *= (1 + vol->cut_info.radius_tolerance);
|
||||
sf[Y] *= (1 + vol->cut_info.radius_tolerance);
|
||||
// make a "hole" dipper
|
||||
sf[Z] *= (1 + vol->cut_info.height_tolerance);
|
||||
vol->set_scaling_factor(sf);
|
||||
};
|
||||
|
||||
for (ModelVolume* volume : volumes) {
|
||||
const auto volume_matrix = volume->get_matrix();
|
||||
|
||||
@ -1510,43 +1529,33 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Vec3d& cut_center, const
|
||||
volume->mmu_segmentation_facets.reset();
|
||||
|
||||
if (!volume->is_model_part()) {
|
||||
if (volume->source.is_connector) {
|
||||
if (volume->cut_info.is_connector) {
|
||||
// ! Don't apply instance transformation for the conntectors.
|
||||
// This transformation is already there
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper)) {
|
||||
|
||||
Transform3d m = attributes.has(ModelObjectCutAttribute::PlaceOnCutUpper) ?
|
||||
Geometry::rotation_transform(cut_rotation).inverse() * cut_matrix * instance_matrix * volume_matrix :
|
||||
instance_matrix * volume_matrix;
|
||||
volume->set_transformation(m);
|
||||
|
||||
ModelVolume* vol = upper->add_volume(*volume);
|
||||
// make a "hole" dipper
|
||||
vol->set_scaling_factor(Z, 1.1 * vol->get_scaling_factor(Z));
|
||||
vol->set_transformation(volume_matrix);
|
||||
apply_tolerance(vol);
|
||||
}
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower)) {
|
||||
|
||||
Transform3d m = attributes.has(ModelObjectCutAttribute::PlaceOnCutLower) ?
|
||||
Geometry::rotation_transform(Geometry::deg2rad(180.0) * Vec3d::UnitX()) * Geometry::rotation_transform(cut_rotation).inverse() * cut_matrix * instance_matrix * volume_matrix :
|
||||
instance_matrix * volume_matrix;
|
||||
volume->set_transformation(m);
|
||||
ModelVolume* vol = lower->add_volume(*volume);
|
||||
vol->set_transformation(volume_matrix);
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::CreateDowels))
|
||||
// make a "hole" dipper
|
||||
vol->set_scaling_factor(Z, 1.2 * vol->get_scaling_factor(Z));
|
||||
apply_tolerance(vol);
|
||||
else
|
||||
// for lower part change type of connector from NEGATIVE_VOLUME to MODEL_PART if this connector is a plug
|
||||
vol->set_type(ModelVolumeType::MODEL_PART);
|
||||
}
|
||||
if (attributes.has(ModelObjectCutAttribute::CreateDowels)) {
|
||||
// add one more solid part same as connector if this connector is a dowel
|
||||
// But discard rotation and Z-offset for this volume
|
||||
volume->set_rotation(Vec3d::Zero());
|
||||
Vec3d offset = volume->get_offset();
|
||||
offset[Z] = 0.0;
|
||||
volume->set_offset(offset);
|
||||
|
||||
ModelVolume* vol = dowels->add_volume(*volume);
|
||||
vol->set_type(ModelVolumeType::MODEL_PART);
|
||||
|
||||
// But discard rotation and Z-offset for this volume
|
||||
vol->set_rotation(Vec3d::Zero());
|
||||
vol->set_offset(Z, 0.0);
|
||||
|
||||
// Compute the displacement (in instance coordinates) to be applied to place the dowels
|
||||
local_dowels_displace = lower->full_raw_mesh_bounding_box().size().cwiseProduct(Vec3d(1.0, 1.0, 0.0));
|
||||
}
|
||||
@ -1556,19 +1565,18 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Vec3d& cut_center, const
|
||||
// to the modifier volume transformation to preserve their shape properly.
|
||||
volume->set_transformation(Geometry::Transformation(instance_matrix * volume_matrix));
|
||||
|
||||
// #ysFIXME - add logic for the negative volumes/connectors
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper))
|
||||
upper->add_volume(*volume);
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower))
|
||||
lower->add_volume(*volume);
|
||||
}
|
||||
}
|
||||
else if (!volume->mesh().empty()
|
||||
// && !volume->source.is_connector // we don't allow to cut a connectors
|
||||
) {
|
||||
else if (!volume->mesh().empty()) {
|
||||
// Transform the mesh by the combined transformation matrix.
|
||||
// Flip the triangles in case the composite transformation is left handed.
|
||||
TriangleMesh mesh(volume->mesh());
|
||||
mesh.transform(Geometry::rotation_transform(cut_rotation).inverse() * cut_matrix * instance_matrix * volume_matrix, true);
|
||||
mesh.transform(cut_matrix * instance_matrix* volume_matrix, true);
|
||||
|
||||
volume->reset_mesh();
|
||||
// Reset volume transformation except for offset
|
||||
@ -1588,7 +1596,6 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Vec3d& cut_center, const
|
||||
}
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper) && !upper_mesh.empty()) {
|
||||
if (!attributes.has(ModelObjectCutAttribute::PlaceOnCutUpper))
|
||||
upper_mesh.transform(invert_cut_matrix);
|
||||
|
||||
ModelVolume* vol = upper->add_volume(upper_mesh);
|
||||
@ -1600,9 +1607,6 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Vec3d& cut_center, const
|
||||
vol->set_material(volume->material_id(), *volume->material());
|
||||
}
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower) && !lower_mesh.empty()) {
|
||||
if (attributes.has(ModelObjectCutAttribute::PlaceOnCutLower))
|
||||
lower_mesh.transform(Geometry::assemble_transform(Vec3d::Zero(), Geometry::deg2rad(180.0)*Vec3d::UnitX()));
|
||||
else
|
||||
lower_mesh.transform(invert_cut_matrix);
|
||||
|
||||
ModelVolume* vol = lower->add_volume(lower_mesh);
|
||||
@ -1643,7 +1647,22 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Vec3d& cut_center, const
|
||||
|
||||
obj_instance->set_transformation(Geometry::Transformation());
|
||||
obj_instance->set_offset(offset + displace);
|
||||
obj_instance->set_rotation(Vec3d(attributes.has(ModelObjectCutAttribute::FlipUpper) ? Geometry::deg2rad(180.0) : 0.0, 0.0, i == instance ? 0.0 : rot_z));
|
||||
|
||||
Vec3d rotation = Vec3d::Zero();
|
||||
if (attributes.has(ModelObjectCutAttribute::PlaceOnCutUpper)) {
|
||||
Transform3d trafo = rotation_transform(cut_rotation).inverse();
|
||||
if (i != instance)
|
||||
trafo = rotation_transform(rot_z * Vec3d::UnitZ()) * trafo;
|
||||
rotation = Transformation(trafo).get_rotation();
|
||||
}
|
||||
else if (attributes.has(ModelObjectCutAttribute::FlipUpper)) {
|
||||
rotation = rotate_z180;
|
||||
if (i != instance)
|
||||
rotation[Z] = rot_z;
|
||||
}
|
||||
else if (i != instance)
|
||||
rotation[Z] = rot_z/* * Vec3d::UnitZ()*/;
|
||||
obj_instance->set_rotation(rotation);
|
||||
}
|
||||
|
||||
res.push_back(upper);
|
||||
@ -1666,7 +1685,22 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Vec3d& cut_center, const
|
||||
const double rot_z = obj_instance->get_rotation().z();
|
||||
obj_instance->set_transformation(Geometry::Transformation());
|
||||
obj_instance->set_offset(offset);
|
||||
obj_instance->set_rotation(Vec3d(attributes.has(ModelObjectCutAttribute::FlipLower) ? Geometry::deg2rad(180.0) : 0.0, 0.0, i == instance ? 0.0 : rot_z));
|
||||
|
||||
Vec3d rotation = Vec3d::Zero();
|
||||
if (attributes.has(ModelObjectCutAttribute::PlaceOnCutLower)) {
|
||||
Transform3d trafo = rotation_transform(rotate_z180) * rotation_transform(cut_rotation).inverse();
|
||||
if (i != instance)
|
||||
trafo = rotation_transform(rot_z * Vec3d::UnitZ()) * trafo;
|
||||
rotation = Transformation(trafo).get_rotation();
|
||||
}
|
||||
else if (attributes.has(ModelObjectCutAttribute::FlipLower)) {
|
||||
rotation = rotate_z180;
|
||||
if (i != instance)
|
||||
rotation[Z] = rot_z;
|
||||
}
|
||||
else if (i != instance)
|
||||
rotation[Z] = rot_z;
|
||||
obj_instance->set_rotation(rotation);
|
||||
}
|
||||
|
||||
res.push_back(lower);
|
||||
|
@ -225,18 +225,20 @@ struct CutConnector
|
||||
Vec3d rotation;
|
||||
float radius;
|
||||
float height;
|
||||
float radius_tolerance;// [0.f : 1.f]
|
||||
float height_tolerance;// [0.f : 1.f]
|
||||
bool failed = false;
|
||||
|
||||
CutConnector()
|
||||
: pos(Vec3d::Zero()), rotation(Vec3d::UnitZ()), radius(5.f), height(10.f)
|
||||
: pos(Vec3d::Zero()), rotation(Vec3d::UnitZ()), radius(5.f), height(10.f), radius_tolerance(0.f), height_tolerance(0.1f)
|
||||
{}
|
||||
|
||||
CutConnector(Vec3d p, Vec3d rot, float r, float h, bool fl = false)
|
||||
: pos(p), rotation(rot), radius(r), height(h), failed(fl)
|
||||
CutConnector(Vec3d p, Vec3d rot, float r, float h, float rt, float ht, bool fl = false)
|
||||
: pos(p), rotation(rot), radius(r), height(h), radius_tolerance(rt), height_tolerance(ht), failed(fl)
|
||||
{}
|
||||
|
||||
CutConnector(const CutConnector& rhs) :
|
||||
CutConnector(rhs.pos, rhs.rotation, rhs.radius, rhs.height, rhs.failed) {}
|
||||
CutConnector(rhs.pos, rhs.rotation, rhs.radius, rhs.height, rhs.radius_tolerance, rhs.height_tolerance, rhs.failed) {}
|
||||
|
||||
bool operator==(const CutConnector& sp) const;
|
||||
|
||||
@ -251,7 +253,7 @@ struct CutConnector
|
||||
*/
|
||||
template<class Archive> inline void serialize(Archive& ar)
|
||||
{
|
||||
ar(pos, rotation, radius, height, failed);
|
||||
ar(pos, rotation, radius, height, radius_tolerance, height_tolerance, failed);
|
||||
}
|
||||
|
||||
static constexpr size_t steps = 32;
|
||||
@ -696,16 +698,25 @@ public:
|
||||
bool is_converted_from_meters{ false };
|
||||
bool is_from_builtin_objects{ false };
|
||||
|
||||
bool is_connector{ false };
|
||||
|
||||
template<class Archive> void serialize(Archive& ar) {
|
||||
//FIXME Vojtech: Serialize / deserialize only if the Source is set.
|
||||
// likely testing input_file or object_idx would be sufficient.
|
||||
ar(input_file, object_idx, volume_idx, mesh_offset, transform, is_converted_from_inches, is_converted_from_meters, is_from_builtin_objects, is_connector);
|
||||
ar(input_file, object_idx, volume_idx, mesh_offset, transform, is_converted_from_inches, is_converted_from_meters, is_from_builtin_objects);
|
||||
}
|
||||
};
|
||||
Source source;
|
||||
|
||||
// struct used by cut command
|
||||
// It contains information about connetors
|
||||
struct CutInfo
|
||||
{
|
||||
bool is_connector {false};
|
||||
float radius_tolerance;// [0.f : 1.f]
|
||||
float height_tolerance;// [0.f : 1.f]
|
||||
|
||||
void discard() { is_connector = false; }
|
||||
} cut_info;
|
||||
|
||||
// The triangular model.
|
||||
const TriangleMesh& mesh() const { return *m_mesh.get(); }
|
||||
void set_mesh(const TriangleMesh &mesh) { m_mesh = std::make_shared<const TriangleMesh>(mesh); }
|
||||
|
@ -2499,6 +2499,7 @@ void ObjectList::part_selection_changed()
|
||||
|
||||
bool enable_manipulation {true};
|
||||
bool disable_ss_manipulation {false};
|
||||
bool disable_ununiform_scale {false};
|
||||
|
||||
const auto item = GetSelection();
|
||||
|
||||
@ -2543,6 +2544,7 @@ void ObjectList::part_selection_changed()
|
||||
disable_ss_manipulation = true;
|
||||
break;
|
||||
}
|
||||
disable_ununiform_scale = !cut_objects.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2649,8 +2651,11 @@ void ObjectList::part_selection_changed()
|
||||
|
||||
if (disable_ss_manipulation)
|
||||
wxGetApp().obj_manipul()->DisableScale();
|
||||
else
|
||||
else {
|
||||
wxGetApp().obj_manipul()->Enable(enable_manipulation);
|
||||
if (disable_ununiform_scale)
|
||||
wxGetApp().obj_manipul()->DisableUnuniformScale();
|
||||
}
|
||||
}
|
||||
|
||||
if (update_and_show_settings)
|
||||
|
@ -580,7 +580,11 @@ void ObjectManipulation::Enable(const bool enadle)
|
||||
{
|
||||
for (auto editor : m_editors)
|
||||
editor->Enable(enadle);
|
||||
for (wxWindow* win : std::initializer_list<wxWindow*>{ m_reset_scale_button, m_reset_rotation_button, m_drop_to_bed_button, m_check_inch, m_lock_bnt })
|
||||
for (wxWindow* win : std::initializer_list<wxWindow*>{ m_reset_scale_button, m_reset_rotation_button, m_drop_to_bed_button, m_check_inch, m_lock_bnt
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
,m_reset_skew_button
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
})
|
||||
win->Enable(enadle);
|
||||
}
|
||||
|
||||
@ -588,10 +592,19 @@ void ObjectManipulation::DisableScale()
|
||||
{
|
||||
for (auto editor : m_editors)
|
||||
editor->Enable(editor->has_opt_key("scale") || editor->has_opt_key("size") ? false : true);
|
||||
for (wxWindow* win : std::initializer_list<wxWindow*>{ m_reset_scale_button, m_lock_bnt })
|
||||
for (wxWindow* win : std::initializer_list<wxWindow*>{ m_reset_scale_button, m_lock_bnt
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
,m_reset_skew_button
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
})
|
||||
win->Enable(false);
|
||||
}
|
||||
|
||||
void ObjectManipulation::DisableUnuniformScale()
|
||||
{
|
||||
m_lock_bnt->disable();
|
||||
}
|
||||
|
||||
void ObjectManipulation::update_ui_from_settings()
|
||||
{
|
||||
if (m_imperial_units != (wxGetApp().app_config->get("use_inches") == "1")) {
|
||||
|
@ -201,6 +201,7 @@ public:
|
||||
void Enable(const bool enadle = true);
|
||||
void Disable() { Enable(false); }
|
||||
void DisableScale();
|
||||
void DisableUnuniformScale();
|
||||
void update_ui_from_settings();
|
||||
bool use_colors() { return m_use_colors; }
|
||||
|
||||
|
@ -430,12 +430,12 @@ bool GLGizmoCut3D::render_double_input(const std::string& label, double& value_i
|
||||
return old_val != value;
|
||||
}
|
||||
|
||||
bool GLGizmoCut3D::render_slicer_double_input(const std::string& label, double& value_in)
|
||||
bool GLGizmoCut3D::render_slider_double_input(const std::string& label, double& value_in, int& tolerance_in)
|
||||
{
|
||||
ImGui::AlignTextToFramePadding();
|
||||
m_imgui->text(label);
|
||||
ImGui::SameLine(m_label_width);
|
||||
ImGui::PushItemWidth(m_control_width);
|
||||
ImGui::PushItemWidth(m_control_width * 0.85f);
|
||||
|
||||
float value = (float)value_in;
|
||||
if (m_imperial_units)
|
||||
@ -443,15 +443,25 @@ bool GLGizmoCut3D::render_slicer_double_input(const std::string& label, double&
|
||||
float old_val = value;
|
||||
|
||||
const BoundingBoxf3 bbox = bounding_box();
|
||||
const float mean_size = float((bbox.size().x() + bbox.size().y() + bbox.size().z()) / 9.0);
|
||||
|
||||
m_imgui->slider_float(("##" + label).c_str(), &value, 1.0f, mean_size);
|
||||
|
||||
ImGui::SameLine();
|
||||
m_imgui->text(m_imperial_units ? _L("in") : _L("mm"));
|
||||
float mean_size = float((bbox.size().x() + bbox.size().y() + bbox.size().z()) / 9.0);
|
||||
float min_size = 1.f;
|
||||
if (m_imperial_units) {
|
||||
mean_size *= ObjectManipulation::mm_to_in;
|
||||
min_size *= ObjectManipulation::mm_to_in;
|
||||
}
|
||||
std::string format = m_imperial_units ? "%.4f " + _u8L("in") : "%.2f " + _u8L("mm");
|
||||
|
||||
m_imgui->slider_float(("##" + label).c_str(), &value, min_size, mean_size, format.c_str());
|
||||
value_in = (double)(value * (m_imperial_units ? ObjectManipulation::in_to_mm : 1.0));
|
||||
return old_val != value;
|
||||
|
||||
ImGui::SameLine(m_label_width + m_control_width + 3);
|
||||
ImGui::PushItemWidth(m_control_width * 0.3f);
|
||||
|
||||
float old_tolerance, tolerance = old_tolerance = (float)tolerance_in;
|
||||
m_imgui->slider_float(("##tolerance_" + label).c_str(), &tolerance, 1.f, 20.f, "%.f %%", 1.f, true, _L("Tolerance"));
|
||||
tolerance_in = (int)tolerance;
|
||||
|
||||
return old_val != value || old_tolerance != tolerance;
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::render_move_center_input(int axis)
|
||||
@ -1253,11 +1263,11 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit)
|
||||
if (m_imgui->button(" " + _L("Reset") + " ##connectors"))
|
||||
reset_connectors();
|
||||
m_imgui->disabled_end();
|
||||
|
||||
/*
|
||||
m_imgui->text(_L("Mode"));
|
||||
render_connect_mode_radio_button(CutConnectorMode::Auto);
|
||||
render_connect_mode_radio_button(CutConnectorMode::Manual);
|
||||
|
||||
*/
|
||||
m_imgui->text(_L("Type"));
|
||||
render_connect_type_radio_button(CutConnectorType::Plug);
|
||||
render_connect_type_radio_button(CutConnectorType::Dowel);
|
||||
@ -1267,12 +1277,16 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit)
|
||||
if (render_combo(_u8L("Shape"), m_connector_shapes, m_connector_shape_id))
|
||||
update_connector_shape();
|
||||
|
||||
if (render_slicer_double_input(_u8L("Depth ratio"), m_connector_depth_ratio))
|
||||
for (auto& connector : connectors)
|
||||
if (render_slider_double_input(_u8L("Depth ratio"), m_connector_depth_ratio, m_connector_depth_ratio_tolerance))
|
||||
for (auto& connector : connectors) {
|
||||
connector.height = float(m_connector_depth_ratio);
|
||||
if (render_slicer_double_input(_u8L("Size"), m_connector_size))
|
||||
for (auto& connector : connectors)
|
||||
connector.height_tolerance = 0.01f * m_connector_depth_ratio;
|
||||
}
|
||||
if (render_slider_double_input(_u8L("Size"), m_connector_size, m_connector_size_tolerance))
|
||||
for (auto& connector : connectors) {
|
||||
connector.radius = float(m_connector_size * 0.5);
|
||||
connector.radius_tolerance = 0.01f * m_connector_size_tolerance;
|
||||
}
|
||||
|
||||
m_imgui->disabled_end();
|
||||
|
||||
@ -1710,7 +1724,9 @@ bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_posi
|
||||
//std::cout << hit.x() << "\t" << hit.y() << "\t" << hit.z() << std::endl;
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Add connector"), UndoRedo::SnapshotType::GizmoAction);
|
||||
|
||||
connectors.emplace_back(hit, Geometry::Transformation(m_rotation_m).get_rotation(), float(m_connector_size * 0.5), float(m_connector_depth_ratio));
|
||||
connectors.emplace_back(hit, Geometry::Transformation(m_rotation_m).get_rotation(),
|
||||
float(m_connector_size * 0.5), float(m_connector_depth_ratio),
|
||||
float(0.01f * m_connector_size_tolerance), float(0.01f * m_connector_depth_ratio_tolerance));
|
||||
update_model_object();
|
||||
m_selected.push_back(false);
|
||||
assert(m_selected.size() == connectors.size());
|
||||
|
@ -81,6 +81,9 @@ class GLGizmoCut3D : public GLGizmoBase
|
||||
double m_connector_depth_ratio{ 3.0 };
|
||||
double m_connector_size{ 2.5 };
|
||||
|
||||
int m_connector_depth_ratio_tolerance{ 10 };
|
||||
int m_connector_size_tolerance{ 0 };
|
||||
|
||||
float m_label_width{ 150.0 };
|
||||
float m_control_width{ 200.0 };
|
||||
bool m_imperial_units{ false };
|
||||
@ -174,7 +177,7 @@ private:
|
||||
void set_center(const Vec3d& center);
|
||||
bool render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx);
|
||||
bool render_double_input(const std::string& label, double& value_in);
|
||||
bool render_slicer_double_input(const std::string& label, double& value_in);
|
||||
bool render_slider_double_input(const std::string& label, double& value_in, int& tolerance_in);
|
||||
void render_move_center_input(int axis);
|
||||
void render_connect_mode_radio_button(CutConnectorMode mode);
|
||||
bool render_revert_button(const std::string& label);
|
||||
|
Loading…
Reference in New Issue
Block a user