FIX:cancle does_bound_a_volume check and try boolean with warning

jira: STUDIO-10754
Change-Id: I0aadd9fe63b0dfeed13b03b62753405040e12e11
This commit is contained in:
zhou.xu 2025-03-11 16:20:42 +08:00 committed by lane.wei
parent ce74f77310
commit 04bed7f239
4 changed files with 56 additions and 44 deletions

View File

@ -286,12 +286,12 @@ std::tuple<BooleanFailReason,std::string> check_csgmesh_booleans(const Range<It>
return;
}
if (!MeshBoolean::cgal::does_bound_a_volume(*m)) {
/*if (!MeshBoolean::cgal::does_bound_a_volume(*m)) {//has crash problem
BOOST_LOG_TRIVIAL(info) << "check_csgmesh_booleans fails! mesh "<<i<<"/"<<csgrange.size()<<" does_bound_a_volume is false, cannot do boolean!";
fail_reason= BooleanFailReason::NotBoundAVolume;
fail_part_name = csgpart.name;
return;
}
}*/
if (MeshBoolean::cgal::does_self_intersect(*m)) {
BOOST_LOG_TRIVIAL(info) << "check_csgmesh_booleans fails! mesh " << i << "/" << csgrange.size() << " does_self_intersect is true, cannot do boolean!";

View File

@ -760,6 +760,7 @@ bool do_boolean_single(McutMesh &srcMesh, const McutMesh &cutMesh, const std::st
void do_boolean(McutMesh& srcMesh, const McutMesh& cutMesh, const std::string& boolean_opts)
{
try {
TriangleMesh tri_src = mcut_to_triangle_mesh(srcMesh);
std::vector<indexed_triangle_set> src_parts = its_split(tri_src.its);
@ -770,7 +771,7 @@ void do_boolean(McutMesh& srcMesh, const McutMesh& cutMesh, const std::string& b
srcMesh = cutMesh;
return;
}
if(cut_parts.empty()) return;
if (cut_parts.empty()) return;
// when src mesh has multiple connected components, mcut refuses to work.
// But we can force it to work by spliting the src mesh into disconnected components,
@ -786,8 +787,7 @@ void do_boolean(McutMesh& srcMesh, const McutMesh& cutMesh, const std::string& b
TriangleMesh tri_part = mcut_to_triangle_mesh(*src_part);
its_merge(all_its, tri_part.its);
}
}
else if (boolean_opts == "INTERSECTION") {
} else if (boolean_opts == "INTERSECTION") {
for (size_t i = 0; i < src_parts.size(); i++) {
for (size_t j = 0; j < cut_parts.size(); j++) {
auto src_part = triangle_mesh_to_mcut(src_parts[i]);
@ -801,6 +801,9 @@ void do_boolean(McutMesh& srcMesh, const McutMesh& cutMesh, const std::string& b
}
}
srcMesh = *triangle_mesh_to_mcut(all_its);
} catch (const std::exception &e) {
BOOST_LOG_TRIVIAL(error) << "check error:" << e.what();
}
}
void make_boolean(const TriangleMesh &src_mesh, const TriangleMesh &cut_mesh, std::vector<TriangleMesh> &dst_mesh, const std::string &boolean_opts)

View File

@ -19,7 +19,7 @@ namespace Slic3r {
namespace GUI {
static const std::string warning_text_common = _u8L("Unable to perform boolean operation on selected parts");
static const std::string warning_text_intersection = _u8L("Performed boolean intersection fails \n because the selected parts have no intersection");
static const std::string warning_text_intersection = _u8L("Performed boolean intersection fails because the selected parts have no intersection");
GLGizmoMeshBoolean::GLGizmoMeshBoolean(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoBase(parent, icon_filename, sprite_id)
@ -361,6 +361,10 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l
m_selecting_state = (m_src.mv == nullptr) ? MeshBooleanSelectingState::SelectSource : MeshBooleanSelectingState::SelectTool;
}
ImGui::PopStyleColor(5);
m_full_width = ImGui::GetWindowWidth();
} else {
float space_size = m_imgui->get_style_scaling() * 8;
m_full_width = max_tab_length * 3 + space_size *3;
}
bool enable_button = m_src.mv && m_tool.mv;
@ -368,9 +372,10 @@ 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)) {
wxBusyCursor temp_cursor;
csg::BooleanFailReason fail_reason;
m_warning_texts[index] = check_boolean_possible({m_src.mv, m_tool.mv}, fail_reason);
if(m_warning_texts[index] == "") {
if (m_warning_texts[index] == "" || fail_reason == csg::BooleanFailReason::SelfIntersect) {
TriangleMesh temp_src_mesh = m_src.mv->mesh();
temp_src_mesh.transform(m_src.trafo);
TriangleMesh temp_tool_mesh = m_tool.mv->mesh();
@ -393,9 +398,10 @@ 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)) {
wxBusyCursor temp_cursor;
csg::BooleanFailReason fail_reason;
m_warning_texts[index] = check_boolean_possible({m_src.mv, m_tool.mv}, fail_reason);
if (m_warning_texts[index] == "") {
if (m_warning_texts[index] == "" || fail_reason == csg::BooleanFailReason::SelfIntersect) {
TriangleMesh temp_src_mesh = m_src.mv->mesh();
temp_src_mesh.transform(m_src.trafo);
TriangleMesh temp_tool_mesh = m_tool.mv->mesh();
@ -418,9 +424,10 @@ 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)) {
wxBusyCursor temp_cursor;
csg::BooleanFailReason fail_reason;
m_warning_texts[index] = check_boolean_possible({m_src.mv, m_tool.mv}, fail_reason);
if (m_warning_texts[index] == "") {
if (m_warning_texts[index] == "" || fail_reason == csg::BooleanFailReason::SelfIntersect) {
TriangleMesh temp_src_mesh = m_src.mv->mesh();
temp_src_mesh.transform(m_src.trafo);
TriangleMesh temp_tool_mesh = m_tool.mv->mesh();
@ -441,7 +448,7 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l
}
}
if (index >= 0 && index < m_warning_texts.size()) {
render_input_window_warning(m_warning_texts[index]);
render_input_window_warning(m_warning_texts[index], m_full_width);
}
float win_w = ImGui::GetWindowWidth();
@ -460,9 +467,10 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l
ImGuiWrapper::pop_toolbar_style();
}
void GLGizmoMeshBoolean::render_input_window_warning(const std::string &text) {
void GLGizmoMeshBoolean::render_input_window_warning(const std::string &text, int width)
{
if (text.size() > 0) {
m_imgui->warning_text(_L("Warning") + ": " + _L(text));
m_imgui->warning_text_wrapped(_L("Warning") + ": " + _L(text), width);
}
}

View File

@ -59,12 +59,13 @@ protected:
virtual void on_set_state() override;
virtual CommonGizmosDataID on_get_requirements() const override;
virtual void on_render_input_window(float x, float y, float bottom_limit);
virtual void render_input_window_warning(const std::string &text);
virtual void render_input_window_warning(const std::string &text,int width);
void on_load(cereal::BinaryInputArchive &ar) override;
void on_save(cereal::BinaryOutputArchive &ar) const override;
private:
bool m_enable{ false };
int m_full_width;
MeshBooleanOperation m_operation_mode;
MeshBooleanSelectingState m_selecting_state;
bool m_diff_delete_input = false;