mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-06-14 07:52:56 +00:00
BBS Port: Mesh Subdivision (#12150)
Ported from BBS You can now right-click a part and choose Subdivide Part to apply Loop subdivision with multiple iterations. This is useful for models with low original mesh resolution. > [!NOTE] > 1. Only meshes without non-manifold edges are supported. > 2. Color attributes will be lost after subdivision. We recommend subdividing first, then painting and applying colors. Not perfect and it can break some features but a nice to have and we can improve it. https://github.com/user-attachments/assets/33f10e49-f6dc-44d3-8c21-9e12e1fe23dc Best case scenario a sphere: Each picture is a Mesh subdivision step over the other <img width="541" height="495" alt="260202_164257_orca-slicer" src="https://github.com/user-attachments/assets/e62b3f4d-ee6b-4451-95a4-40a154d3a405" /> <img width="541" height="495" alt="260202_164302_%pn" src="https://github.com/user-attachments/assets/f7399457-be8d-45e7-b93f-f42064dadd64" /> <img width="541" height="495" alt="260202_164306_%pn" src="https://github.com/user-attachments/assets/55370035-219f-4b7f-94f4-9b31733820d6" /> <img width="541" height="495" alt="260202_164310_%pn" src="https://github.com/user-attachments/assets/3be8c904-cc6f-4efe-b4f8-f390b50d310c" />
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
#endif /* __WXMSW__ */
|
||||
#include "Gizmos/GLGizmoScale.hpp"
|
||||
|
||||
#include "libslic3r/TriangleMeshDeal.hpp"
|
||||
namespace Slic3r
|
||||
{
|
||||
namespace GUI
|
||||
@@ -5931,6 +5932,92 @@ void ObjectList::simplify()
|
||||
gizmos_mgr.open_gizmo(GLGizmosManager::EType::Simplify);
|
||||
}
|
||||
|
||||
void GUI::ObjectList::smooth_mesh()
|
||||
{
|
||||
wxBusyCursor cursor;
|
||||
auto plater = wxGetApp().plater();
|
||||
if (!plater) { return; }
|
||||
plater->take_snapshot("smooth_mesh");
|
||||
std::vector<int> obj_idxs, vol_idxs;
|
||||
get_selection_indexes(obj_idxs, vol_idxs);
|
||||
auto object_idx = obj_idxs.front();
|
||||
ModelObject *obj{nullptr};
|
||||
auto show_warning_dlg = [this](int cur_face_count,std::string name,bool is_part) {
|
||||
int limit_face_count = 1000000;
|
||||
if (cur_face_count > limit_face_count) {
|
||||
auto name_str = wxString::FromUTF8(name);
|
||||
auto content = wxString::Format(_L("\"%s\" will exceed 1 million faces after this subdivision, which may increase slicing time. Do you want to continue?"), name_str);
|
||||
WarningDialog dlg(static_cast<wxWindow *>(wxGetApp().mainframe), (is_part ? _L("Part") : _L("Object")) + " " + content, _L("BambuStudio warning"), wxYES_NO);
|
||||
if (dlg.ShowModal() == wxID_NO) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
auto show_smooth_mesh_error_dlg = [this](std::string name) {
|
||||
auto name_str = wxString::FromUTF8(name);
|
||||
auto content = wxString::Format(_L("\"%s\" part's mesh contains errors. Please repair it first."), name_str);
|
||||
WarningDialog dlg(static_cast<wxWindow *>(wxGetApp().mainframe), content, _L("BambuStudio warning"), wxOK);
|
||||
dlg.ShowModal();
|
||||
};
|
||||
bool has_show_smooth_mesh_error_dlg = false;
|
||||
if (vol_idxs.empty()) {
|
||||
obj = object(object_idx);
|
||||
auto future_face_count = static_cast<int>(obj->facets_count()) * 4;
|
||||
if (show_warning_dlg(future_face_count, obj->name,false)) {
|
||||
return;
|
||||
}
|
||||
for (auto mv : obj->volumes) {
|
||||
bool ok;
|
||||
auto result_mesh = TriangleMeshDeal::smooth_triangle_mesh(mv->mesh(), ok);
|
||||
if (ok) {
|
||||
mv->set_mesh(result_mesh);
|
||||
mv->reset_extra_facets(); // reset paint color
|
||||
mv->calculate_convex_hull();
|
||||
mv->invalidate_convex_hull_2d();
|
||||
mv->set_new_unique_id();
|
||||
} else {
|
||||
if (!has_show_smooth_mesh_error_dlg) {
|
||||
show_smooth_mesh_error_dlg(mv->name);
|
||||
has_show_smooth_mesh_error_dlg = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
obj->invalidate_bounding_box();
|
||||
obj->ensure_on_bed();
|
||||
plater->changed_mesh(object_idx);
|
||||
} else {
|
||||
obj = object(obj_idxs.front());
|
||||
for (int vol_idx : vol_idxs) {
|
||||
auto mv = obj->volumes[vol_idx];
|
||||
auto future_face_count = static_cast<int>(mv->mesh().facets_count()) * 4;
|
||||
if (show_warning_dlg(future_face_count, mv->name,true)) {
|
||||
return;
|
||||
}
|
||||
bool ok;
|
||||
auto result_mesh = TriangleMeshDeal::smooth_triangle_mesh(mv->mesh(),ok);
|
||||
if (ok) {
|
||||
mv->set_mesh(result_mesh);
|
||||
mv->reset_extra_facets(); // reset paint color
|
||||
mv->calculate_convex_hull();
|
||||
mv->invalidate_convex_hull_2d();
|
||||
mv->set_new_unique_id();
|
||||
} else {
|
||||
if (!has_show_smooth_mesh_error_dlg) {
|
||||
show_smooth_mesh_error_dlg(mv->name);
|
||||
has_show_smooth_mesh_error_dlg = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj) {
|
||||
obj->invalidate_bounding_box();
|
||||
obj->ensure_on_bed();
|
||||
plater->changed_mesh(object_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectList::update_item_error_icon(const int obj_idx, const int vol_idx) const
|
||||
{
|
||||
auto obj = object(obj_idx);
|
||||
|
||||
Reference in New Issue
Block a user