diff --git a/resources/icons/colorchange_add_off.png b/resources/icons/colorchange_add_off.png deleted file mode 100644 index 6ddeccbe0..000000000 Binary files a/resources/icons/colorchange_add_off.png and /dev/null differ diff --git a/resources/icons/colorchange_add_on.png b/resources/icons/colorchange_add_on.png deleted file mode 100644 index cc800b81e..000000000 Binary files a/resources/icons/colorchange_add_on.png and /dev/null differ diff --git a/resources/icons/colorchange_delete_off.png b/resources/icons/colorchange_delete_off.png deleted file mode 100644 index c16655271..000000000 Binary files a/resources/icons/colorchange_delete_off.png and /dev/null differ diff --git a/resources/icons/colorchange_delete_on.png b/resources/icons/colorchange_delete_on.png deleted file mode 100644 index 8f27ce9fe..000000000 Binary files a/resources/icons/colorchange_delete_on.png and /dev/null differ diff --git a/resources/icons/down_half_circle.png b/resources/icons/down_half_circle.png deleted file mode 100644 index f86a2932c..000000000 Binary files a/resources/icons/down_half_circle.png and /dev/null differ diff --git a/resources/icons/left_half_circle.png b/resources/icons/left_half_circle.png deleted file mode 100644 index 3bdc4c3ee..000000000 Binary files a/resources/icons/left_half_circle.png and /dev/null differ diff --git a/resources/icons/mirroring_transparent.png b/resources/icons/mirroring_transparent.png deleted file mode 100644 index 841010fcc..000000000 Binary files a/resources/icons/mirroring_transparent.png and /dev/null differ diff --git a/resources/icons/mirroring_transparent.svg b/resources/icons/mirroring_transparent.svg new file mode 100644 index 000000000..c0e831cc3 --- /dev/null +++ b/resources/icons/mirroring_transparent.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/resources/icons/mode_advanced_.png b/resources/icons/mode_advanced_.png deleted file mode 100644 index d98d8f709..000000000 Binary files a/resources/icons/mode_advanced_.png and /dev/null differ diff --git a/resources/icons/mode_advanced_sq.png b/resources/icons/mode_advanced_sq.png deleted file mode 100644 index 6df2a52fe..000000000 Binary files a/resources/icons/mode_advanced_sq.png and /dev/null differ diff --git a/resources/icons/mode_expert_.png b/resources/icons/mode_expert_.png deleted file mode 100644 index 4d78bcccf..000000000 Binary files a/resources/icons/mode_expert_.png and /dev/null differ diff --git a/resources/icons/mode_expert_sq.png b/resources/icons/mode_expert_sq.png deleted file mode 100644 index 742ffc088..000000000 Binary files a/resources/icons/mode_expert_sq.png and /dev/null differ diff --git a/resources/icons/mode_simple_.png b/resources/icons/mode_simple_.png deleted file mode 100644 index aac2b61b0..000000000 Binary files a/resources/icons/mode_simple_.png and /dev/null differ diff --git a/resources/icons/mode_simple_sq.png b/resources/icons/mode_simple_sq.png deleted file mode 100644 index cb8ab7bd4..000000000 Binary files a/resources/icons/mode_simple_sq.png and /dev/null differ diff --git a/resources/icons/one_layer_lock_off.png b/resources/icons/one_layer_lock_off.png deleted file mode 100644 index f6e61d058..000000000 Binary files a/resources/icons/one_layer_lock_off.png and /dev/null differ diff --git a/resources/icons/one_layer_lock_on.png b/resources/icons/one_layer_lock_on.png deleted file mode 100644 index 011099972..000000000 Binary files a/resources/icons/one_layer_lock_on.png and /dev/null differ diff --git a/resources/icons/one_layer_unlock_off.png b/resources/icons/one_layer_unlock_off.png deleted file mode 100644 index 46fabfb05..000000000 Binary files a/resources/icons/one_layer_unlock_off.png and /dev/null differ diff --git a/resources/icons/one_layer_unlock_on.png b/resources/icons/one_layer_unlock_on.png deleted file mode 100644 index 265b92610..000000000 Binary files a/resources/icons/one_layer_unlock_on.png and /dev/null differ diff --git a/resources/icons/pause_add.png b/resources/icons/pause_add.png deleted file mode 100644 index afe881de8..000000000 Binary files a/resources/icons/pause_add.png and /dev/null differ diff --git a/resources/icons/right_half_circle.png b/resources/icons/right_half_circle.png deleted file mode 100644 index ecc8980b3..000000000 Binary files a/resources/icons/right_half_circle.png and /dev/null differ diff --git a/resources/icons/row.png b/resources/icons/row.png deleted file mode 100644 index 18a6034fd..000000000 Binary files a/resources/icons/row.png and /dev/null differ diff --git a/resources/icons/shape_ungroup.png b/resources/icons/shape_ungroup.png deleted file mode 100644 index 97aaceb23..000000000 Binary files a/resources/icons/shape_ungroup.png and /dev/null differ diff --git a/resources/icons/table.png b/resources/icons/table.png deleted file mode 100644 index 3bc0bd32f..000000000 Binary files a/resources/icons/table.png and /dev/null differ diff --git a/resources/icons/up_half_circle.png b/resources/icons/up_half_circle.png deleted file mode 100644 index aac6e32c3..000000000 Binary files a/resources/icons/up_half_circle.png and /dev/null differ diff --git a/resources/icons/variable_layer_height_reset.png b/resources/icons/variable_layer_height_reset.png deleted file mode 100644 index 6e051fe95..000000000 Binary files a/resources/icons/variable_layer_height_reset.png and /dev/null differ diff --git a/resources/icons/variable_layer_height_tooltip.png b/resources/icons/variable_layer_height_tooltip.png deleted file mode 100644 index 182005292..000000000 Binary files a/resources/icons/variable_layer_height_tooltip.png and /dev/null differ diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index b681cbdf4..1ade36e36 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -513,6 +513,22 @@ void Model::convert_from_meters(bool only_small_volumes) } } +static constexpr const double zero_volume = 0.0000000001; + +int Model::removed_objects_with_zero_volume() +{ + if (objects.size() == 0) + return 0; + + int removed = 0; + for (int i = int(objects.size()) - 1; i >= 0; i--) + if (objects[i]->get_object_stl_stats().volume < zero_volume) { + delete_object(size_t(i)); + removed++; + } + return removed; +} + void Model::adjust_min_z() { if (objects.empty()) @@ -1629,10 +1645,10 @@ TriangleMeshStats ModelObject::get_object_stl_stats() const return full_stats; } -int ModelObject::get_mesh_errors_count(const int vol_idx /*= -1*/) const +int ModelObject::get_repaired_errors_count(const int vol_idx /*= -1*/) const { if (vol_idx >= 0) - return this->volumes[vol_idx]->get_mesh_errors_count(); + return this->volumes[vol_idx]->get_repaired_errors_count(); const RepairedMeshErrors& stats = get_object_stl_stats().repaired_errors; @@ -1704,7 +1720,7 @@ void ModelVolume::calculate_convex_hull() assert(m_convex_hull.get()); } -int ModelVolume::get_mesh_errors_count() const +int ModelVolume::get_repaired_errors_count() const { const RepairedMeshErrors &stats = this->mesh().stats().repaired_errors; diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index ea1d0ed17..11cbdc0cf 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -377,7 +377,7 @@ public: // Get full stl statistics for all object's meshes TriangleMeshStats get_object_stl_stats() const; // Get count of errors in the mesh( or all object's meshes, if volume index isn't defined) - int get_mesh_errors_count(const int vol_idx = -1) const; + int get_repaired_errors_count(const int vol_idx = -1) const; private: friend class Model; @@ -682,7 +682,7 @@ public: const TriangleMesh& get_convex_hull() const; std::shared_ptr get_convex_hull_shared_ptr() const { return m_convex_hull; } // Get count of errors in the mesh - int get_mesh_errors_count() const; + int get_repaired_errors_count() const; // Helpers for loading / storing into AMF / 3MF files. static ModelVolumeType type_from_string(const std::string &s); @@ -1124,6 +1124,7 @@ public: void convert_from_imperial_units(bool only_small_volumes); bool looks_like_saved_in_meters() const; void convert_from_meters(bool only_small_volumes); + int removed_objects_with_zero_volume(); // Ensures that the min z of the model is not negative void adjust_min_z(); diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index e98dcf554..bb3c9fc5c 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -68,8 +68,7 @@ TriangleMesh::TriangleMesh(const indexed_triangle_set &its) : its(its) TriangleMesh::TriangleMesh(indexed_triangle_set &&its, const RepairedMeshErrors& errors/* = RepairedMeshErrors()*/) : its(std::move(its)) { - if (errors.repaired()) - m_stats.repaired_errors = errors; + m_stats.repaired_errors = errors; fill_initial_stats(this->its, m_stats); } diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index b223b4346..5223631c0 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -33,14 +33,12 @@ struct RepairedMeshErrors { void clear() { *this = RepairedMeshErrors(); } - RepairedMeshErrors merge(const RepairedMeshErrors& rhs) const { - RepairedMeshErrors out; - out.edges_fixed = this->edges_fixed + rhs.edges_fixed; - out.degenerate_facets = this->degenerate_facets + rhs.degenerate_facets; - out.facets_removed = this->facets_removed + rhs.facets_removed; - out.facets_reversed = this->facets_reversed + rhs.facets_reversed; - out.backwards_edges = this->backwards_edges + rhs.backwards_edges; - return out; + void merge(const RepairedMeshErrors& rhs) { + this->edges_fixed += rhs.edges_fixed; + this->degenerate_facets += rhs.degenerate_facets; + this->facets_removed += rhs.facets_removed; + this->facets_reversed += rhs.facets_reversed; + this->backwards_edges += rhs.backwards_edges; } bool repaired() const { return degenerate_facets > 0 || edges_fixed > 0 || facets_removed > 0 || facets_reversed > 0 || backwards_edges > 0; } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 6c416c475..d2a6b6e9a 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -375,9 +375,9 @@ void ObjectList::get_selection_indexes(std::vector& obj_idxs, std::vector= 0 ? (*m_objects)[obj_idx]->get_mesh_errors_count(vol_idx) : 0; + return obj_idx >= 0 ? (*m_objects)[obj_idx]->get_repaired_errors_count(vol_idx) : 0; } static std::string get_warning_icon_name(const TriangleMeshStats& stats) @@ -385,8 +385,11 @@ static std::string get_warning_icon_name(const TriangleMeshStats& stats) return stats.manifold() ? (stats.repaired() ? "exclamation_manifold" : "") : "exclamation"; } -std::pair ObjectList::get_mesh_errors(const int obj_idx, const int vol_idx /*= -1*/, wxString* sidebar_info /*= nullptr*/) const +MeshErrorsInfo ObjectList::get_mesh_errors_info(const int obj_idx, const int vol_idx /*= -1*/, wxString* sidebar_info /*= nullptr*/) const { + if (obj_idx < 0) + return { {}, {} }; // hide tooltip + const TriangleMeshStats& stats = vol_idx == -1 ? (*m_objects)[obj_idx]->get_object_stl_stats() : (*m_objects)[obj_idx]->volumes[vol_idx]->mesh().stats(); @@ -401,7 +404,7 @@ std::pair ObjectList::get_mesh_errors(const int obj_idx, // Create tooltip string, if there are errors if (stats.repaired()) { - const int errors = get_mesh_errors_count(obj_idx, vol_idx); + const int errors = get_repaired_errors_count(obj_idx, vol_idx); auto_repaired_info = format_wxstr(_L_PLURAL("Auto-repaired %1$d error", "Auto-repaired %1$d errors", errors), errors); tooltip += auto_repaired_info +":\n"; @@ -434,15 +437,24 @@ std::pair ObjectList::get_mesh_errors(const int obj_idx, return { tooltip, get_warning_icon_name(stats) }; } -std::pair ObjectList::get_mesh_errors(wxString* sidebar_info /*= nullptr*/) +MeshErrorsInfo ObjectList::get_mesh_errors_info(wxString* sidebar_info /*= nullptr*/) { - if (!GetSelection()) + wxDataViewItem item = GetSelection(); + if (!item) return { "", "" }; int obj_idx, vol_idx; get_selected_item_indexes(obj_idx, vol_idx); - return get_mesh_errors(obj_idx, vol_idx, sidebar_info); + if (obj_idx < 0) { // child of ObjectItem is selected + if (sidebar_info) + obj_idx = m_objects_model->GetObjectIdByItem(item); + else + return { "", "" }; + } + assert(obj_idx >= 0); + + return get_mesh_errors_info(obj_idx, vol_idx, sidebar_info); } void ObjectList::set_tooltip_for_item(const wxPoint& pt) @@ -478,9 +490,12 @@ void ObjectList::set_tooltip_for_item(const wxPoint& pt) #endif //__WXMSW__ else if (col->GetTitle() == _("Name") && (pt.x >= 2 * wxGetApp().em_unit() && pt.x <= 4 * wxGetApp().em_unit())) { - int obj_idx, vol_idx; - get_selected_item_indexes(obj_idx, vol_idx, item); - tooltip = get_mesh_errors(obj_idx, vol_idx).first; + if (const ItemType type = m_objects_model->GetItemType(item); + type & (itObject | itVolume)) { + int obj_idx = m_objects_model->GetObjectIdByItem(item); + int vol_idx = type & itVolume ? m_objects_model->GetVolumeIdByItem(item) : -1; + tooltip = get_mesh_errors_info(obj_idx, vol_idx).tooltip; + } } GetMainWindow()->SetToolTip(tooltip); @@ -1797,10 +1812,8 @@ void ObjectList::del_subobject_item(wxDataViewItem& item) // If last volume item with warning was deleted, unmark object item if (type & itVolume) { - if (auto obj = object(obj_idx); obj->get_mesh_errors_count() == 0) - m_objects_model->DeleteWarningIcon(parent); - else - m_objects_model->AddWarningIcon(parent, get_warning_icon_name(obj->mesh().stats())); + const std::string& icon_name = get_warning_icon_name(object(obj_idx)->get_object_stl_stats()); + m_objects_model->UpdateWarningIcon(parent, icon_name); } m_objects_model->Delete(item); @@ -2509,7 +2522,7 @@ void ObjectList::part_selection_changed() if (item) { // wxGetApp().obj_manipul()->get_og()->set_value("object_name", m_objects_model->GetName(item)); wxGetApp().obj_manipul()->update_item_name(m_objects_model->GetName(item)); - wxGetApp().obj_manipul()->update_warning_icon_state(get_mesh_errors(obj_idx, volume_id)); + wxGetApp().obj_manipul()->update_warning_icon_state(get_mesh_errors_info(obj_idx, volume_id)); } } @@ -2769,10 +2782,7 @@ void ObjectList::delete_from_model_and_list(const std::vector& it m_objects_model->SetExtruder(extruder, parent); } // If last volume item with warning was deleted, unmark object item - if (obj->get_mesh_errors_count() == 0) - m_objects_model->DeleteWarningIcon(parent); - else - m_objects_model->AddWarningIcon(parent, get_warning_icon_name(obj->mesh().stats())); + m_objects_model->UpdateWarningIcon(parent, get_warning_icon_name(obj->get_object_stl_stats())); } wxGetApp().plater()->canvas3D()->ensure_on_bed(item->obj_idx, printer_technology() != ptSLA); } @@ -4055,7 +4065,7 @@ void ObjectList::fix_through_netfabb() if (vol_idxs.empty()) { #if !FIX_THROUGH_NETFABB_ALWAYS for (int i = int(obj_idxs.size())-1; i >= 0; --i) - if (object(obj_idxs[i])->get_mesh_errors_count() == 0) + if (object(obj_idxs[i])->get_repaired_errors_count() == 0) obj_idxs.erase(obj_idxs.begin()+i); #endif // FIX_THROUGH_NETFABB_ALWAYS for (int obj_idx : obj_idxs) @@ -4065,7 +4075,7 @@ void ObjectList::fix_through_netfabb() ModelObject* obj = object(obj_idxs.front()); #if !FIX_THROUGH_NETFABB_ALWAYS for (int i = int(vol_idxs.size()) - 1; i >= 0; --i) - if (obj->get_mesh_errors_count(vol_idxs[i]) == 0) + if (obj->get_repaired_errors_count(vol_idxs[i]) == 0) vol_idxs.erase(vol_idxs.begin() + i); #endif // FIX_THROUGH_NETFABB_ALWAYS for (int vol_idx : vol_idxs) @@ -4121,7 +4131,7 @@ void ObjectList::fix_through_netfabb() int vol_idx{ -1 }; for (int obj_idx : obj_idxs) { #if !FIX_THROUGH_NETFABB_ALWAYS - if (object(obj_idx)->get_mesh_errors_count(vol_idx) == 0) + if (object(obj_idx)->get_repaired_errors_count(vol_idx) == 0) continue; #endif // FIX_THROUGH_NETFABB_ALWAYS if (!fix_and_update_progress(obj_idx, vol_idx, model_idx, progress_dlg, succes_models, failed_models)) @@ -4178,24 +4188,18 @@ void ObjectList::simplify() void ObjectList::update_item_error_icon(const int obj_idx, const int vol_idx) const { - const wxDataViewItem item = vol_idx <0 ? m_objects_model->GetItemById(obj_idx) : - m_objects_model->GetItemByVolumeId(obj_idx, vol_idx); - if (!item) + auto obj = object(obj_idx); + if (wxDataViewItem obj_item = m_objects_model->GetItemById(obj_idx)) { + const std::string& icon_name = get_warning_icon_name(obj->get_object_stl_stats()); + m_objects_model->UpdateWarningIcon(obj_item, icon_name); + } + + if (vol_idx < 0) return; - if (get_mesh_errors_count(obj_idx, vol_idx) == 0) - { - // if whole object has no errors more, - if (get_mesh_errors_count(obj_idx) == 0) - // unmark all items in the object - m_objects_model->DeleteWarningIcon(vol_idx >= 0 ? m_objects_model->GetParent(item) : item, true); - else - // unmark fixed item only - m_objects_model->DeleteWarningIcon(item); - } - else { - auto obj = object(obj_idx); - m_objects_model->AddWarningIcon(item, get_warning_icon_name(vol_idx < 0 ? obj->mesh().stats() : obj->volumes[vol_idx]->mesh().stats())); + if (wxDataViewItem vol_item = m_objects_model->GetItemByVolumeId(obj_idx, vol_idx)) { + const std::string& icon_name = get_warning_icon_name(obj->volumes[vol_idx]->mesh().stats()); + m_objects_model->UpdateWarningIcon(vol_item, icon_name); } } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 54e3f5d45..cc619fc45 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -67,6 +67,12 @@ struct ItemForDelete } }; +struct MeshErrorsInfo +{ + wxString tooltip; + std::string warning_icon_name; +}; + class ObjectList : public wxDataViewCtrl { public: @@ -212,13 +218,13 @@ public: void get_selected_item_indexes(int& obj_idx, int& vol_idx, const wxDataViewItem& item = wxDataViewItem(0)); void get_selection_indexes(std::vector& obj_idxs, std::vector& vol_idxs); // Get count of errors in the mesh - int get_mesh_errors_count(const int obj_idx, const int vol_idx = -1) const; + int get_repaired_errors_count(const int obj_idx, const int vol_idx = -1) const; // Get list of errors in the mesh and name of the warning icon // Return value is a pair , used for the tooltip and related warning icon // Function without parameters is for a call from Manipulation panel, // when we don't know parameters of selected item - std::pair get_mesh_errors(const int obj_idx, const int vol_idx = -1, wxString* sidebar_info = nullptr) const; - std::pair get_mesh_errors(wxString* sidebar_info = nullptr); + MeshErrorsInfo get_mesh_errors_info(const int obj_idx, const int vol_idx = -1, wxString* sidebar_info = nullptr) const; + MeshErrorsInfo get_mesh_errors_info(wxString* sidebar_info = nullptr); void set_tooltip_for_item(const wxPoint& pt); void selection_changed(); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 7d5f80a30..d5a1a5659 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -1,5 +1,4 @@ #include "GUI_ObjectManipulation.hpp" -#include "GUI_ObjectList.hpp" #include "I18N.hpp" #include "BitmapComboBox.hpp" @@ -132,7 +131,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : return; wxGetApp().obj_list()->fix_through_netfabb(); - update_warning_icon_state(wxGetApp().obj_list()->get_mesh_errors()); + update_warning_icon_state(wxGetApp().obj_list()->get_mesh_errors_info()); }); sizer->Add(m_fix_throught_netfab_bitmap); @@ -548,8 +547,8 @@ void ObjectManipulation::update_settings_value(const Selection& selection) } else { m_new_rotation = volume->get_instance_rotation() * (180. / M_PI); - m_new_size = volume->get_instance_transformation().get_scaling_factor().cwiseProduct(wxGetApp().model().objects[volume->object_idx()]->raw_mesh_bounding_box().size()); - m_new_scale = volume->get_instance_scaling_factor() * 100.; + m_new_size = volume->get_instance_scaling_factor().cwiseProduct(wxGetApp().model().objects[volume->object_idx()]->raw_mesh_bounding_box().size()); + m_new_scale = volume->get_instance_scaling_factor() * 100.; } m_new_enabled = true; @@ -570,7 +569,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_position = volume->get_volume_offset(); m_new_rotation = volume->get_volume_rotation() * (180. / M_PI); m_new_scale = volume->get_volume_scaling_factor() * 100.; - m_new_size = volume->get_instance_transformation().get_scaling_factor().cwiseProduct(volume->get_volume_transformation().get_scaling_factor().cwiseProduct(volume->bounding_box().size())); + m_new_size = volume->get_instance_scaling_factor().cwiseProduct(volume->get_volume_scaling_factor().cwiseProduct(volume->bounding_box().size())); m_new_enabled = true; } else if (obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot)) { @@ -781,12 +780,12 @@ void ObjectManipulation::update_item_name(const wxString& item_name) m_item_name->SetLabel(item_name); } -void ObjectManipulation::update_warning_icon_state(const std::pair& warning) +void ObjectManipulation::update_warning_icon_state(const MeshErrorsInfo& warning) { - if (const std::string& warning_icon_name = warning.second; + if (const std::string& warning_icon_name = warning.warning_icon_name; !warning_icon_name.empty()) m_manifold_warning_bmp = ScalableBitmap(m_parent, warning_icon_name); - const wxString& tooltip = warning.first; + const wxString& tooltip = warning.tooltip; m_fix_throught_netfab_bitmap->SetBitmap(tooltip.IsEmpty() ? wxNullBitmap : m_manifold_warning_bmp.bmp()); m_fix_throught_netfab_bitmap->SetMinSize(tooltip.IsEmpty() ? wxSize(0,0) : m_manifold_warning_bmp.bmp().GetSize()); m_fix_throught_netfab_bitmap->SetToolTip(tooltip); @@ -862,7 +861,7 @@ void ObjectManipulation::change_scale_value(int axis, double value) Vec3d scale = m_cache.scale; scale(axis) = value; - this->do_scale(axis, scale); + this->do_scale(axis, 0.01 * scale); m_cache.scale = scale; m_cache.scale_rounded(axis) = DBL_MAX; @@ -881,14 +880,21 @@ void ObjectManipulation::change_size_value(int axis, double value) const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); Vec3d ref_size = m_cache.size; - if (selection.is_single_volume() || selection.is_single_modifier()) - ref_size = selection.get_volume(*selection.get_volume_idxs().begin())->bounding_box().size(); + if (selection.is_single_volume() || selection.is_single_modifier()) { + const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin()); + const Vec3d local_size = size.cwiseQuotient(v->get_instance_scaling_factor()); + const Vec3d local_ref_size = v->bounding_box().size().cwiseProduct(v->get_volume_scaling_factor()); + const Vec3d local_change = local_size.cwiseQuotient(local_ref_size); + + size = local_change.cwiseProduct(v->get_volume_scaling_factor()); + ref_size = Vec3d::Ones(); + } else if (selection.is_single_full_instance()) ref_size = m_world_coordinates ? selection.get_unscaled_instance_bounding_box().size() : wxGetApp().model().objects[selection.get_volume(*selection.get_volume_idxs().begin())->object_idx()]->raw_mesh_bounding_box().size(); - this->do_scale(axis, 100. * Vec3d(size(0) / ref_size(0), size(1) / ref_size(1), size(2) / ref_size(2))); + this->do_scale(axis, size.cwiseQuotient(ref_size)); m_cache.size = size; m_cache.size_rounded(axis) = DBL_MAX; @@ -911,7 +917,7 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const scaling_factor = scale(axis) * Vec3d::Ones(); selection.start_dragging(); - selection.scale(scaling_factor * 0.01, transformation_type); + selection.scale(scaling_factor, transformation_type); wxGetApp().plater()->canvas3D()->do_scale(L("Set Scale")); } diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index 9b77591be..a15c72fb8 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -4,6 +4,7 @@ #include #include "GUI_ObjectSettings.hpp" +#include "GUI_ObjectList.hpp" #include "libslic3r/Point.hpp" #include @@ -194,7 +195,7 @@ public: #endif // __APPLE__ void update_item_name(const wxString &item_name); - void update_warning_icon_state(const std::pair& warning); + void update_warning_icon_state(const MeshErrorsInfo& warning); void msw_rescale(); void sys_color_changed(); void on_change(const std::string& opt_key, int axis, double new_value); diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index 78735b925..ed4b477b8 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -1786,6 +1786,14 @@ bool ObjectDataViewModel::HasWarningIcon(const wxDataViewItem& item) const return node->has_warning_icon(); } +void ObjectDataViewModel::UpdateWarningIcon(const wxDataViewItem& item, const std::string& warning_icon_name) +{ + if (warning_icon_name.empty()) + DeleteWarningIcon(item, true); + else + AddWarningIcon(item, warning_icon_name); +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/ObjectDataViewModel.hpp b/src/slic3r/GUI/ObjectDataViewModel.hpp index ca7a0cde0..f8885b206 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.hpp +++ b/src/slic3r/GUI/ObjectDataViewModel.hpp @@ -389,6 +389,7 @@ public: const std::string& warning_icon_name = std::string()); void AddWarningIcon(const wxDataViewItem& item, const std::string& warning_name); void DeleteWarningIcon(const wxDataViewItem& item, const bool unmark_object = false); + void UpdateWarningIcon(const wxDataViewItem& item, const std::string& warning_name); bool HasWarningIcon(const wxDataViewItem& item) const; t_layer_height_range GetLayerRangeByItem(const wxDataViewItem& item) const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 274771864..52a84206b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1204,9 +1204,9 @@ void Sidebar::show_info_sizer() static_cast(model_object->facets_count()), stats.number_of_parts)); wxString info_manifold_label; - auto mesh_errors = obj_list()->get_mesh_errors(&info_manifold_label); - wxString tooltip = mesh_errors.first; - p->object_info->update_warning_icon(mesh_errors.second); + auto mesh_errors = obj_list()->get_mesh_errors_info(&info_manifold_label); + wxString tooltip = mesh_errors.tooltip; + p->object_info->update_warning_icon(mesh_errors.warning_icon_name); p->object_info->info_manifold->SetLabel(info_manifold_label); p->object_info->info_manifold->SetToolTip(tooltip); p->object_info->manifold_warning_icon->SetToolTip(tooltip); @@ -2440,6 +2440,14 @@ std::vector Plater::priv::load_files(const std::vector& input_ }; if (!is_project_file) { + if (int deleted_objects = model.removed_objects_with_zero_volume(); deleted_objects > 0) { + MessageDialog(q, format_wxstr(_L_PLURAL( + "Object size from file %s appears to be zero.\n" + "This object has been removed from the model", + "Objects size from file %s appear to be zero.\n" + "These objects have been removed from the model", deleted_objects), from_path(filename)) + "\n", + _L("Object size is zero"), wxICON_INFORMATION | wxOK).ShowModal(); + } if (imperial_units) // Convert even if the object is big. convert_from_imperial_units(model, false); @@ -4597,14 +4605,14 @@ bool Plater::priv::can_fix_through_netfabb() const // Fixing only if the model is not manifold. if (vol_idxs.empty()) { for (auto obj_idx : obj_idxs) - if (model.objects[obj_idx]->get_mesh_errors_count() > 0) + if (model.objects[obj_idx]->get_repaired_errors_count() > 0) return true; return false; } int obj_idx = obj_idxs.front(); for (auto vol_idx : vol_idxs) - if (model.objects[obj_idx]->get_mesh_errors_count(vol_idx) > 0) + if (model.objects[obj_idx]->get_repaired_errors_count(vol_idx) > 0) return true; return false; #endif // FIX_THROUGH_NETFABB_ALWAYS