From 3b1c51b64d4cff556ea0940cd3dc968b46bccce7 Mon Sep 17 00:00:00 2001 From: "zhou.xu" Date: Mon, 13 Jan 2025 10:50:46 +0800 Subject: [PATCH] FIX:try mcut for NotBoundAVolume error jira: none Change-Id: I46be009d413beede839afee4fcf7fa54a0202d45 --- src/slic3r/GUI/Gizmos/GLGizmoMeshBoolean.cpp | 11 ++++++---- src/slic3r/GUI/Plater.cpp | 21 +++++++++++--------- src/slic3r/GUI/Plater.hpp | 6 ++++-- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeshBoolean.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeshBoolean.cpp index 9226c834f..fa480546f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeshBoolean.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeshBoolean.cpp @@ -72,7 +72,7 @@ bool GLGizmoMeshBoolean::gizmo_event(SLAGizmoEventType action, const Vec2d& mous std::vector trafo_matrices; for (const ModelVolume* mv : mo->volumes) { //if (mv->is_model_part()) { - trafo_matrices.emplace_back(mi->get_transformation().get_matrix() * mv->get_matrix()); + trafo_matrices.emplace_back(mi->get_transformation().get_matrix() * mv->get_matrix()); //} } @@ -368,7 +368,8 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l if (m_operation_mode == MeshBooleanOperation::Union) { if (operate_button(_L("Union") + "##btn", enable_button)) { - m_warning_texts[index] = check_boolean_possible({ m_src.mv, m_tool.mv }); + csg::BooleanFailReason fail_reason; + m_warning_texts[index] = check_boolean_possible({m_src.mv, m_tool.mv}, fail_reason); if(m_warning_texts[index] == "") { TriangleMesh temp_src_mesh = m_src.mv->mesh(); temp_src_mesh.transform(m_src.trafo); @@ -392,7 +393,8 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l else if (m_operation_mode == MeshBooleanOperation::Difference) { m_imgui->bbl_checkbox(_L("Delete input"), m_diff_delete_input); if (operate_button(_L("Difference") + "##btn", enable_button)) { - m_warning_texts[index] = check_boolean_possible({ m_src.mv, m_tool.mv }); + csg::BooleanFailReason fail_reason; + m_warning_texts[index] = check_boolean_possible({m_src.mv, m_tool.mv}, fail_reason); if (m_warning_texts[index] == "") { TriangleMesh temp_src_mesh = m_src.mv->mesh(); temp_src_mesh.transform(m_src.trafo); @@ -416,7 +418,8 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l else if (m_operation_mode == MeshBooleanOperation::Intersection){ m_imgui->bbl_checkbox(_L("Delete input"), m_inter_delete_input); if (operate_button(_L("Intersection") + "##btn", enable_button)) { - m_warning_texts[index] = check_boolean_possible({ m_src.mv, m_tool.mv }); + csg::BooleanFailReason fail_reason; + m_warning_texts[index] = check_boolean_possible({m_src.mv, m_tool.mv}, fail_reason); if (m_warning_texts[index] == "") { TriangleMesh temp_src_mesh = m_src.mv->mesh(); temp_src_mesh.transform(m_src.trafo); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d606e4983..c986eef17 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -13046,7 +13046,8 @@ bool check_printer_initialized(MachineObject *obj) } // OK if fail_msg is empty -std::string check_boolean_possible(const std::vector& volumes) { +std::string check_boolean_possible(const std::vector &volumes, csg::BooleanFailReason& fail_reason) +{ std::string fail_msg; std::vector csgmesh; csgmesh.reserve(2 * volumes.size()); @@ -13056,6 +13057,7 @@ std::string check_boolean_possible(const std::vector& volume if (auto fail_reason_name = csg::check_csgmesh_booleans(Range{ std::begin(csgmesh), std::end(csgmesh) }); std::get<0>(fail_reason_name) != csg::BooleanFailReason::OK) { fail_msg = _u8L("Unable to perform boolean operation on model meshes. " "You may fix the meshes and try again."); + fail_reason = std::get<0>(fail_reason_name); std::string name = std::get<1>(fail_reason_name); std::map fail_reasons = { {csg::BooleanFailReason::OK, "OK"}, @@ -13077,14 +13079,16 @@ TriangleMesh Plater::combine_mesh_fff(const ModelObject& mo, int instance_id, st csgmesh.reserve(2 * mo.volumes.size()); bool has_splitable_volume = csg::model_to_csgmesh(mo.const_volumes(), Transform3d::Identity(), std::back_inserter(csgmesh), csg::mpartsPositive | csg::mpartsNegative); - - std::string fail_msg = check_boolean_possible(mo.const_volumes()); - if (fail_msg.empty()) { + csg::BooleanFailReason fail_reason; + std::string fail_msg = check_boolean_possible(mo.const_volumes(), fail_reason); + if (fail_msg.empty() || fail_reason == csg::BooleanFailReason::NotBoundAVolume) { try { - MeshBoolean::mcut::McutMeshPtr meshPtr = csg::perform_csgmesh_booleans_mcut(Range{ std::begin(csgmesh), std::end(csgmesh) }); - mesh = MeshBoolean::mcut::mcut_to_triangle_mesh(*meshPtr); - } - catch (...) {} + MeshBoolean::mcut::McutMeshPtr meshPtr = csg::perform_csgmesh_booleans_mcut(Range{std::begin(csgmesh), std::end(csgmesh)}); + mesh = MeshBoolean::mcut::mcut_to_triangle_mesh(*meshPtr); + if (mesh.its.indices.size() > 0) { + fail_msg = ""; + } + } catch (...) {} #if 0 // if mcut fails, try again with CGAL if (mesh.empty()) { @@ -13096,7 +13100,6 @@ TriangleMesh Plater::combine_mesh_fff(const ModelObject& mo, int instance_id, st } #endif } - if (mesh.empty()) { if (notify_func) notify_func(fail_msg); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 3b043161f..c3265c0c1 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -52,7 +52,9 @@ class SlicingStatusEvent; enum SLAPrintObjectStep : unsigned int; enum class ConversionType : int; class Ams; - +namespace csg { +enum class BooleanFailReason; +} using ModelInstancePtrs = std::vector; @@ -828,7 +830,7 @@ private: }; std::vector get_min_flush_volumes(const DynamicPrintConfig &full_config, size_t nozzle_id); -std::string check_boolean_possible(const std::vector& volumes); +std::string check_boolean_possible(const std::vector &volumes, csg::BooleanFailReason& fail_reason); Preset *get_printer_preset(MachineObject *obj); wxArrayString get_all_camera_view_type();