diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index aa85b5952c..01b4c5f6ff 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1369,7 +1369,26 @@ void ModelVolume::apply_tolerance() set_offset(get_offset() + rot_norm * z_offset); } -void ModelObject::process_connector_cut(ModelVolume* volume, ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, +static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelVolume* src_volume, const Transform3d& cut_matrix, const std::string& suffix = {}, ModelVolumeType type = ModelVolumeType::MODEL_PART) +{ + if (mesh.empty()) + return; + + mesh.transform(cut_matrix); + ModelVolume* vol = object->add_volume(mesh); + vol->set_type(type); + + vol->name = src_volume->name + suffix; + // Don't copy the config's ID. + vol->config.assign_config(src_volume->config); + assert(vol->config.id().valid()); + assert(vol->config.id() != src_volume->config.id()); + vol->set_material(src_volume->material_id(), *src_volume->material()); + vol->cut_info = src_volume->cut_info; +} + +void ModelObject::process_connector_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix, + ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, std::vector& dowels, Vec3d& local_dowels_displace) { assert(volume->cut_info.is_connector); @@ -1379,39 +1398,53 @@ void ModelObject::process_connector_cut(ModelVolume* volume, ModelObjectCutAttri // ! Don't apply instance transformation for the conntectors. // This transformation is already there - if (attributes.has(ModelObjectCutAttribute::KeepUpper)) { - ModelVolume* vol = upper->add_volume(*volume); - vol->set_transformation(volume_matrix); - vol->apply_tolerance(); - } - if (attributes.has(ModelObjectCutAttribute::KeepLower)) { - ModelVolume* vol = lower->add_volume(*volume); - vol->set_transformation(volume_matrix); - - if (volume->cut_info.connector_type == CutConnectorType::Dowel) + if (volume->cut_info.connector_type != CutConnectorType::Dowel) { + if (attributes.has(ModelObjectCutAttribute::KeepUpper)) { + ModelVolume* vol = upper->add_volume(*volume); + vol->set_transformation(volume_matrix); vol->apply_tolerance(); - else + } + if (attributes.has(ModelObjectCutAttribute::KeepLower)) { + ModelVolume* vol = lower->add_volume(*volume); + vol->set_transformation(volume_matrix); // 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 (volume->cut_info.connector_type == CutConnectorType::Dowel && - attributes.has(ModelObjectCutAttribute::CreateDowels)) { - ModelObject* dowel{ nullptr }; - // Clone the object to duplicate instances, materials etc. - clone_for_cut(&dowel); + else { + if (attributes.has(ModelObjectCutAttribute::CreateDowels)) { + ModelObject* dowel{ nullptr }; + // Clone the object to duplicate instances, materials etc. + clone_for_cut(&dowel); - // add one more solid part same as connector if this connector is a dowel - ModelVolume* vol = dowel->add_volume(*volume); - vol->set_type(ModelVolumeType::MODEL_PART); + // add one more solid part same as connector if this connector is a dowel + ModelVolume* vol = dowel->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); + // 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)); + // 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)); - dowels.push_back(dowel); + dowels.push_back(dowel); + } + + // Cut the dowel + volume->apply_tolerance(); + + // Perform cut + TriangleMesh upper_mesh, lower_mesh; + process_volume_cut(volume, instance_matrix, cut_matrix, attributes, upper_mesh, lower_mesh); + + // add small Z offset to better preview + upper_mesh.translate((-0.05 * Vec3d::UnitZ()).cast()); + lower_mesh.translate((0.05 * Vec3d::UnitZ()).cast()); + + // Add cut parts to the related objects + add_cut_volume(upper_mesh, upper, volume, cut_matrix, "_A", volume->type()); + add_cut_volume(lower_mesh, lower, volume, cut_matrix, "_B", volume->type()); } } @@ -1433,25 +1466,8 @@ void ModelObject::process_modifier_cut(ModelVolume* volume, const Transform3d& i lower->add_volume(*volume); } -static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelVolume* src_volume, const Transform3d& cut_matrix, const std::string& suffix = {}) -{ - if (mesh.empty()) - return; - - mesh.transform(cut_matrix); - ModelVolume* vol = object->add_volume(mesh); - - vol->name = src_volume->name + suffix; - // Don't copy the config's ID. - vol->config.assign_config(src_volume->config); - assert(vol->config.id().valid()); - assert(vol->config.id() != src_volume->config.id()); - vol->set_material(src_volume->material_id(), *src_volume->material()); - vol->cut_info = src_volume->cut_info; -} - -void ModelObject::process_solid_part_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix, - ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, Vec3d& local_displace) +void ModelObject::process_volume_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix, + ModelObjectCutAttributes attributes, TriangleMesh& upper_mesh, TriangleMesh& lower_mesh) { const auto volume_matrix = volume->get_matrix(); @@ -1465,23 +1481,20 @@ void ModelObject::process_solid_part_cut(ModelVolume* volume, const Transform3d& TriangleMesh mesh(volume->mesh()); mesh.transform(invert_cut_matrix * instance_matrix * volume_matrix, true); - volume->reset_mesh(); - // Reset volume transformation except for offset - const Vec3d offset = volume->get_offset(); - volume->set_transformation(Geometry::Transformation()); - volume->set_offset(offset); + indexed_triangle_set upper_its, lower_its; + cut_mesh(mesh.its, 0.0f, &upper_its, &lower_its); + if (attributes.has(ModelObjectCutAttribute::KeepUpper)) + upper_mesh = TriangleMesh(upper_its); + if (attributes.has(ModelObjectCutAttribute::KeepLower)) + lower_mesh = TriangleMesh(lower_its); +} +void ModelObject::process_solid_part_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix, + ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, Vec3d& local_displace) +{ // Perform cut - TriangleMesh upper_mesh, lower_mesh; - { - indexed_triangle_set upper_its, lower_its; - cut_mesh(mesh.its, 0.0f, &upper_its, &lower_its); - if (attributes.has(ModelObjectCutAttribute::KeepUpper)) - upper_mesh = TriangleMesh(upper_its); - if (attributes.has(ModelObjectCutAttribute::KeepLower)) - lower_mesh = TriangleMesh(lower_its); - } + process_volume_cut(volume, instance_matrix, cut_matrix, attributes, upper_mesh, lower_mesh); // Add required cut parts to the objects @@ -1612,7 +1625,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Transform3d& cut_matrix, if (volume->cut_info.is_processed) process_modifier_cut(volume, instance_matrix, inverse_cut_matrix, attributes, upper, lower); else - process_connector_cut(volume, attributes, upper, lower, dowels, local_dowels_displace); + process_connector_cut(volume, instance_matrix, cut_matrix, attributes, upper, lower, dowels, local_dowels_displace); } else if (!volume->mesh().empty()) process_solid_part_cut(volume, instance_matrix, cut_matrix, attributes, upper, lower, local_displace); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 79d9ed3ca7..2e0ec3e16d 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -459,10 +459,13 @@ public: void synchronize_model_after_cut(); void apply_cut_attributes(ModelObjectCutAttributes attributes); void clone_for_cut(ModelObject **obj); - void process_connector_cut(ModelVolume* volume, ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, + void process_connector_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix, + ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, std::vector& dowels, Vec3d& local_dowels_displace); void process_modifier_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& inverse_cut_matrix, ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower); + void process_volume_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix, + ModelObjectCutAttributes attributes, TriangleMesh& upper_mesh, TriangleMesh& lower_mesh); void process_solid_part_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix, ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, Vec3d& local_displace); ModelObjectPtrs cut(size_t instance, const Transform3d&cut_matrix, ModelObjectCutAttributes attributes); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 4613cf7839..dc33b56fbf 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -1004,8 +1004,10 @@ void GLGizmoCut3D::update_raycasters_for_picking_transform() Vec3d pos = connector.pos + instance_offset; if (connector.attribs.type == CutConnectorType::Dowel && connector.attribs.style == CutConnectorStyle::Prism) { - pos -= height * m_clp_normal; - height *= 2; + if (is_looking_forward()) + pos -= static_cast(height - 0.05f) * m_clp_normal; + else + pos += 0.05 * m_clp_normal; } pos[Z] += sla_shift; @@ -2089,11 +2091,19 @@ void GLGizmoCut3D::render_connectors() const Camera& camera = wxGetApp().plater()->get_camera(); if (connector.attribs.type == CutConnectorType::Dowel && connector.attribs.style == CutConnectorStyle::Prism) { - if (is_looking_forward()) - pos -= height * m_clp_normal; - else - pos += height * m_clp_normal; - height *= 2; + if (m_connectors_editing) { + if (is_looking_forward()) + pos -= static_cast(height-0.05f) * m_clp_normal; + else + pos += 0.05 * m_clp_normal; + } + else { + if (is_looking_forward()) + pos -= static_cast(height) * m_clp_normal; + else + pos += static_cast(height) * m_clp_normal; + height *= 2; + } } else if (!is_looking_forward()) pos += 0.05 * m_clp_normal;