FIX:cancle does_bound_a_volume check and try boolean with warning
jira: STUDIO-10754 Change-Id: I0aadd9fe63b0dfeed13b03b62753405040e12e11
This commit is contained in:
parent
ce74f77310
commit
04bed7f239
|
@ -254,7 +254,7 @@ void perform_csgmesh_booleans_mcut(MeshBoolean::mcut::McutMeshPtr& mcutm,
|
|||
}
|
||||
|
||||
mcutm = std::move(opstack.top().mcutptr);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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!";
|
||||
|
|
|
@ -760,47 +760,50 @@ 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)
|
||||
{
|
||||
TriangleMesh tri_src = mcut_to_triangle_mesh(srcMesh);
|
||||
std::vector<indexed_triangle_set> src_parts = its_split(tri_src.its);
|
||||
try {
|
||||
TriangleMesh tri_src = mcut_to_triangle_mesh(srcMesh);
|
||||
std::vector<indexed_triangle_set> src_parts = its_split(tri_src.its);
|
||||
|
||||
TriangleMesh tri_cut = mcut_to_triangle_mesh(cutMesh);
|
||||
std::vector<indexed_triangle_set> cut_parts = its_split(tri_cut.its);
|
||||
TriangleMesh tri_cut = mcut_to_triangle_mesh(cutMesh);
|
||||
std::vector<indexed_triangle_set> cut_parts = its_split(tri_cut.its);
|
||||
|
||||
if (src_parts.empty() && boolean_opts == "UNION") {
|
||||
srcMesh = cutMesh;
|
||||
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,
|
||||
// and do booleans seperately, then merge all the results.
|
||||
indexed_triangle_set all_its;
|
||||
if (boolean_opts == "UNION" || boolean_opts == "A_NOT_B") {
|
||||
for (size_t i = 0; i < src_parts.size(); i++) {
|
||||
auto src_part = triangle_mesh_to_mcut(src_parts[i]);
|
||||
for (size_t j = 0; j < cut_parts.size(); j++) {
|
||||
auto cut_part = triangle_mesh_to_mcut(cut_parts[j]);
|
||||
do_boolean_single(*src_part, *cut_part, boolean_opts);
|
||||
}
|
||||
TriangleMesh tri_part = mcut_to_triangle_mesh(*src_part);
|
||||
its_merge(all_its, tri_part.its);
|
||||
if (src_parts.empty() && boolean_opts == "UNION") {
|
||||
srcMesh = cutMesh;
|
||||
return;
|
||||
}
|
||||
}
|
||||
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++) {
|
||||
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,
|
||||
// and do booleans seperately, then merge all the results.
|
||||
indexed_triangle_set all_its;
|
||||
if (boolean_opts == "UNION" || boolean_opts == "A_NOT_B") {
|
||||
for (size_t i = 0; i < src_parts.size(); i++) {
|
||||
auto src_part = triangle_mesh_to_mcut(src_parts[i]);
|
||||
auto cut_part = triangle_mesh_to_mcut(cut_parts[j]);
|
||||
bool success = do_boolean_single(*src_part, *cut_part, boolean_opts);
|
||||
if (success) {
|
||||
TriangleMesh tri_part = mcut_to_triangle_mesh(*src_part);
|
||||
its_merge(all_its, tri_part.its);
|
||||
for (size_t j = 0; j < cut_parts.size(); j++) {
|
||||
auto cut_part = triangle_mesh_to_mcut(cut_parts[j]);
|
||||
do_boolean_single(*src_part, *cut_part, boolean_opts);
|
||||
}
|
||||
TriangleMesh tri_part = mcut_to_triangle_mesh(*src_part);
|
||||
its_merge(all_its, tri_part.its);
|
||||
}
|
||||
} 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]);
|
||||
auto cut_part = triangle_mesh_to_mcut(cut_parts[j]);
|
||||
bool success = do_boolean_single(*src_part, *cut_part, boolean_opts);
|
||||
if (success) {
|
||||
TriangleMesh tri_part = mcut_to_triangle_mesh(*src_part);
|
||||
its_merge(all_its, tri_part.its);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
srcMesh = *triangle_mesh_to_mcut(all_its);
|
||||
} catch (const std::exception &e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "check error:" << e.what();
|
||||
}
|
||||
srcMesh = *triangle_mesh_to_mcut(all_its);
|
||||
}
|
||||
|
||||
void make_boolean(const TriangleMesh &src_mesh, const TriangleMesh &cut_mesh, std::vector<TriangleMesh> &dst_mesh, const std::string &boolean_opts)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue