From 9bc34104743f5b158a6c0f98a2413753836387dc Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 20 Oct 2022 14:14:25 +0200 Subject: [PATCH] Re-enable volumes in SLA, use raycasters from canvas in supports gizmo Got rid of HollowedMesh and Raycaster usage from GizmosCommon pool to prevent crashes --- src/libslic3r/AABBMesh.hpp | 19 +- src/slic3r/GUI/3DScene.hpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 5 +- src/slic3r/GUI/GLCanvas3D.hpp | 2 + src/slic3r/GUI/GUI_Factories.cpp | 70 ++++++-- src/slic3r/GUI/GUI_Factories.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 38 ++-- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 42 +++-- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 177 ++++++++++--------- src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 50 +++--- src/slic3r/GUI/Plater.cpp | 11 -- src/slic3r/GUI/SceneRaycaster.cpp | 18 +- src/slic3r/GUI/SceneRaycaster.hpp | 3 +- src/slic3r/GUI/Selection.cpp | 32 ++-- src/slic3r/GUI/Tab.cpp | 4 +- 16 files changed, 269 insertions(+), 207 deletions(-) diff --git a/src/libslic3r/AABBMesh.hpp b/src/libslic3r/AABBMesh.hpp index 179bf8c4c1..337935839d 100644 --- a/src/libslic3r/AABBMesh.hpp +++ b/src/libslic3r/AABBMesh.hpp @@ -26,10 +26,9 @@ class TriangleMesh; // casting and other higher level operations. class AABBMesh { class AABBImpl; - + const indexed_triangle_set* m_tm; -// double m_ground_level = 0/*, m_gnd_offset = 0*/; - + std::unique_ptr m_aabb; VertexFaceIndex m_vfidx; // vertex-face index std::vector m_fnidx; // face-neighbor index @@ -43,7 +42,7 @@ class AABBMesh { template void init(const M &mesh, bool calculate_epsilon); public: - + // calculate_epsilon ... calculate epsilon for triangle-ray intersection from an average triangle edge length. // If set to false, a default epsilon is used, which works for "reasonable" meshes. explicit AABBMesh(const indexed_triangle_set &tmesh, bool calculate_epsilon = false); @@ -51,21 +50,17 @@ public: AABBMesh(const AABBMesh& other); AABBMesh& operator=(const AABBMesh&); - + AABBMesh(AABBMesh &&other); AABBMesh& operator=(AABBMesh &&other); - + ~AABBMesh(); - -// inline double ground_level() const { return m_ground_level /*+ m_gnd_offset*/; } -// inline void ground_level_offset(double o) { m_gnd_offset = o; } -// inline double ground_level_offset() const { return m_gnd_offset; } - + const std::vector& vertices() const; const std::vector& indices() const; const Vec3f& vertices(size_t idx) const; const Vec3i& indices(size_t idx) const; - + // Result of a raycast class hit_result { // m_t holds a distance from m_source to the intersection. diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index e63f095e47..abf3e9264c 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -386,7 +386,7 @@ public: bool force_neutral_color : 1; // Whether or not to force rendering of sinking contours bool force_sinking_contours : 1; - }; + }; // this gets instantiated automatically in the parent struct // Is mouse or rectangle selection over this object to select/deselect it ? EHoverState hover; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d20e53643c..a698633a84 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2188,6 +2188,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re } } } + if (printer_technology == ptSLA) { // size_t idx = 0; // const SLAPrint *sla_print = this->sla_print(); @@ -3846,7 +3847,7 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) #else model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); #endif // ENABLE_WORLD_COORDINATE - else if (selection_mode == Selection::Volume) + else if (volume_idx >= 0 && selection_mode == Selection::Volume) #if ENABLE_WORLD_COORDINATE model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); #else @@ -4020,7 +4021,7 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type) model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); #endif // ENABLE_WORLD_COORDINATE } - else if (selection_mode == Selection::Volume) { + else if (selection_mode == Selection::Volume && volume_idx >= 0) { #if ENABLE_WORLD_COORDINATE model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation()); model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index a519a26a19..140cbaf748 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -688,6 +688,8 @@ public: void set_raycaster_gizmos_on_top(bool value) { m_scene_raycaster.set_gizmos_on_top(value); } + + const SceneRaycaster & raycaster() const { return m_scene_raycaster; } #endif // ENABLE_RAYCAST_PICKING void set_as_dirty(); diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index 0ae1b8870a..39cf44eb4e 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -44,7 +44,6 @@ static bool is_improper_category(const std::string& category, const int extruder (!is_object_settings && category == "Support material"); } - //------------------------------------- // SettingsFactory //------------------------------------- @@ -155,14 +154,14 @@ wxBitmapBundle* SettingsFactory::get_category_bitmap(const std::string& category //------------------------------------- // Note: id accords to type of the sub-object (adding volume), so sequence of the menu items is important -const std::vector> MenuFactory::ADD_VOLUME_MENU_ITEMS { -// menu_item Name menu_item bitmap name - {L("Add part"), "add_part" }, // ~ModelVolumeType::MODEL_PART - {L("Add negative volume"), "add_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME - {L("Add modifier"), "add_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER - {L("Add support blocker"), "support_blocker"}, // ~ModelVolumeType::SUPPORT_BLOCKER - {L("Add support enforcer"), "support_enforcer"}, // ~ModelVolumeType::SUPPORT_ENFORCER -}; +static const constexpr std::array, 5> ADD_VOLUME_MENU_ITEMS = {{ + // menu_item Name menu_item bitmap name + {L("Add part"), "add_part" }, // ~ModelVolumeType::MODEL_PART + {L("Add negative volume"), "add_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME + {L("Add modifier"), "add_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER + {L("Add support blocker"), "support_blocker"}, // ~ModelVolumeType::SUPPORT_BLOCKER + {L("Add support enforcer"), "support_enforcer"}, // ~ModelVolumeType::SUPPORT_ENFORCER +}}; // Note: id accords to type of the sub-object (adding volume), so sequence of the menu items is important const std::vector> MenuFactory::TEXT_VOLUME_ICONS { @@ -583,6 +582,55 @@ void MenuFactory::append_menu_items_add_volume(wxMenu* menu) append_menu_item_layers_editing(menu); } +void MenuFactory::append_menu_items_add_sla_volume(wxMenu *menu) +{ + // Update "add" items(delete old & create new) settings popupmenu + for (auto& item : ADD_VOLUME_MENU_ITEMS) { + const auto settings_id = menu->FindItem(_(item.first)); + if (settings_id != wxNOT_FOUND) + menu->Destroy(settings_id); + } + + const ConfigOptionMode mode = wxGetApp().get_mode(); + + if (mode == comAdvanced) { + append_menu_item(menu, wxID_ANY, _(ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::MODEL_PART)].first), "", + [](wxCommandEvent&) { obj_list()->load_subobject(ModelVolumeType::MODEL_PART); }, + ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::MODEL_PART)].second, nullptr, + []() { return obj_list()->is_instance_or_object_selected(); }, m_parent); + } else { + auto& item = ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::MODEL_PART)]; + + wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType::MODEL_PART); + append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second, + []() { return obj_list()->is_instance_or_object_selected(); }, m_parent); + } + + { + auto& item = ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::NEGATIVE_VOLUME)]; + + wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType::NEGATIVE_VOLUME); + append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second, + []() { return obj_list()->is_instance_or_object_selected(); }, m_parent); + } + + { + auto& item = ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_ENFORCER)]; + + wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType::SUPPORT_ENFORCER); + append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second, + []() { return obj_list()->is_instance_or_object_selected(); }, m_parent); + } + + { + auto& item = ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_BLOCKER)]; + + wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType::SUPPORT_BLOCKER); + append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second, + []() { return obj_list()->is_instance_or_object_selected(); }, m_parent); + } +} + wxMenuItem* MenuFactory::append_menu_item_layers_editing(wxMenu* menu) { return append_menu_item(menu, wxID_ANY, _L("Height range Modifier"), "", @@ -631,7 +679,7 @@ wxMenuItem* MenuFactory::append_menu_item_settings(wxMenu* menu_) // If there are selected more then one instance but not all of them // don't add settings menu items const Selection& selection = get_selection(); - if ((selection.is_multiple_full_instance() && !selection.is_single_full_object()) || + if ((selection.is_multiple_full_instance() && !selection.is_single_full_object()) || (printer_technology() == ptSLA && selection.is_single_volume()) || selection.is_multiple_volume() || selection.is_mixed()) // more than one volume(part) is selected on the scene return nullptr; @@ -1066,6 +1114,8 @@ void MenuFactory::create_sla_object_menu() []() { return plater()->can_split(true); }, m_parent); m_sla_object_menu.AppendSeparator(); + append_menu_items_add_sla_volume(&m_sla_object_menu); + m_sla_object_menu.AppendSeparator(); } void MenuFactory::append_immutable_part_menu_items(wxMenu* menu) diff --git a/src/slic3r/GUI/GUI_Factories.hpp b/src/slic3r/GUI/GUI_Factories.hpp index ed27655be0..e418cf6751 100644 --- a/src/slic3r/GUI/GUI_Factories.hpp +++ b/src/slic3r/GUI/GUI_Factories.hpp @@ -92,6 +92,7 @@ private: wxMenu* append_submenu_add_generic(wxMenu* menu, ModelVolumeType type); void append_menu_item_add_text(wxMenu* menu, ModelVolumeType type, bool is_submenu_item = true); void append_menu_items_add_volume(wxMenu* menu); + void append_menu_items_add_sla_volume(wxMenu* menu); wxMenuItem* append_menu_item_layers_editing(wxMenu* menu); wxMenuItem* append_menu_item_settings(wxMenu* menu); wxMenuItem* append_menu_item_change_type(wxMenu* menu); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 1ce118d71d..52aed6bfc8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -53,8 +53,8 @@ void GLGizmoHollow::data_changed() reload_cache(); m_old_mo_id = mo->id(); } - if (m_c->hollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh()) - m_holes_in_drilled_mesh = mo->sla_drain_holes; +// if (m_c->hollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh()) +// m_holes_in_drilled_mesh = mo->sla_drain_holes; #if ENABLE_RAYCAST_PICKING if (m_raycasters.empty()) on_register_raycasters_for_picking(); @@ -206,11 +206,11 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) #endif // !ENABLE_RAYCAST_PICKING if (size_t(m_hover_id) == i) render_color = ColorRGBA::CYAN(); - else if (m_c->hollowed_mesh() && - i < m_c->hollowed_mesh()->get_drainholes().size() && - m_c->hollowed_mesh()->get_drainholes()[i].failed) { - render_color = { 1.0f, 0.0f, 0.0f, 0.5f }; - } +// else if (m_c->hollowed_mesh() && +// i < m_c->hollowed_mesh()->get_drainholes().size() && +// m_c->hollowed_mesh()->get_drainholes()[i].failed) { +// render_color = { 1.0f, 0.0f, 0.0f, 0.5f }; +// } else render_color = point_selected ? ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f) : ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f); #if !ENABLE_RAYCAST_PICKING @@ -314,18 +314,18 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pairhollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh()) { - // in this case the raycaster sees the hollowed and drilled mesh. - // if the point lies on the surface created by the hole, we want - // to ignore it. - for (const sla::DrainHole& hole : m_holes_in_drilled_mesh) { - sla::DrainHole outer(hole); - outer.radius *= 1.001f; - outer.height *= 1.001f; - if (outer.is_inside(hit)) - return false; - } - } +// if (m_c->hollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh()) { +// // in this case the raycaster sees the hollowed and drilled mesh. +// // if the point lies on the surface created by the hole, we want +// // to ignore it. +// for (const sla::DrainHole& hole : m_holes_in_drilled_mesh) { +// sla::DrainHole outer(hole); +// outer.radius *= 1.001f; +// outer.height *= 1.001f; +// if (outer.is_inside(hit)) +// return false; +// } +// } // Return both the point and the facet normal. pos_and_normal = std::make_pair(hit, normal); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 1646f31c7f..d0dd3baa08 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -86,6 +86,8 @@ void GLGizmoSlaSupports::data_changed() update_raycasters_for_picking_transform(); #endif // ENABLE_RAYCAST_PICKING } + +// m_parent.toggle_model_objects_visibility(false); } @@ -179,8 +181,8 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) const size_t cache_size = m_editing_mode ? m_editing_cache.size() : m_normal_cache.size(); const bool has_points = (cache_size != 0); - const bool has_holes = (! m_c->hollowed_mesh()->get_hollowed_mesh() - && ! m_c->selection_info()->model_object()->sla_drain_holes.empty()); + const bool has_holes = (/*! m_c->hollowed_mesh()->get_hollowed_mesh() + &&*/ ! m_c->selection_info()->model_object()->sla_drain_holes.empty()); if (! has_points && ! has_holes) return; @@ -304,7 +306,8 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) if (m_editing_mode) { // in case the normal is not yet cached, find and cache it if (m_editing_cache[i].normal == Vec3f::Zero()) - m_c->raycaster()->raycaster()->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal); + m_parent.raycaster().get_raycasters(SceneRaycaster::EType::Volume)->front()->get_raycaster()->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal); + //m_c->raycaster()->raycaster()->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal); Eigen::Quaterniond q; q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast()); @@ -453,7 +456,7 @@ bool GLGizmoSlaSupports::is_mesh_point_clipped(const Vec3d& point) const // Return false if no intersection was found, true otherwise. bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair& pos_and_normal) { - if (! m_c->raycaster()->raycaster()) + if (m_parent.raycaster().get_raycasters(SceneRaycaster::EType::Volume)->empty()) return false; const Camera& camera = wxGetApp().plater()->get_camera(); @@ -468,7 +471,7 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pairraycaster()->raycaster()->unproject_on_mesh( + if (m_parent.raycaster().get_raycasters(SceneRaycaster::EType::Volume)->front()->get_raycaster()->unproject_on_mesh( mouse_pos, trafo.get_matrix(), camera, @@ -477,24 +480,24 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pairhollowed_mesh()->get_hollowed_mesh()) { - sla::DrainHoles drain_holes = m_c->selection_info()->model_object()->sla_drain_holes; - for (const sla::DrainHole& hole : drain_holes) { - if (hole.is_inside(hit)) { - in_hole = true; - break; - } - } - } - if (! in_hole) { +// if (! m_c->hollowed_mesh()->get_hollowed_mesh()) { +// sla::DrainHoles drain_holes = m_c->selection_info()->model_object()->sla_drain_holes; +// for (const sla::DrainHole& hole : drain_holes) { +// if (hole.is_inside(hit)) { +// in_hole = true; +// break; +// } +// } +// } +// if (! in_hole) { // Return both the point and the facet normal. pos_and_normal = std::make_pair(hit, normal); return true; - } +// } } return false; @@ -589,7 +592,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous for (size_t idx : points_idxs) points_inside.emplace_back((trafo.get_matrix().cast() * (m_editing_cache[idx].support_point.pos + m_editing_cache[idx].normal)).cast()); - for (size_t idx : m_c->raycaster()->raycaster()->get_unobscured_idxs( + assert(!m_parent.raycaster().get_raycasters(SceneRaycaster::EType::Volume).emtpy()); + for (size_t idx : m_parent.raycaster().get_raycasters(SceneRaycaster::EType::Volume)->front()->get_raycaster()->get_unobscured_idxs( trafo, wxGetApp().plater()->get_camera(), points_inside, m_c->object_clipper()->get_clipping_plane())) { @@ -1457,7 +1461,7 @@ void GLGizmoSlaSupports::update_raycasters_for_picking_transform() const Transform3d support_matrix = Geometry::translation_transform(m_editing_cache[i].support_point.pos.cast()) * instance_scaling_matrix_inverse; if (m_editing_cache[i].normal == Vec3f::Zero()) - m_c->raycaster()->raycaster()->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal); + m_parent.raycaster().get_raycasters(SceneRaycaster::EType::Volume)->front()->get_raycaster()->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal); Eigen::Quaterniond q; q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 136276803e..c4232ed48f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -25,7 +25,7 @@ private: bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair& pos_and_normal); - const float RenderPointScale = 1.f; + static constexpr float RenderPointScale = 1.f; class CacheEntry { public: diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index 52ae9b25b4..31fbb0f7ab 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -23,7 +23,7 @@ CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas) using c = CommonGizmosDataID; m_data[c::SelectionInfo].reset( new SelectionInfo(this)); m_data[c::InstancesHider].reset( new InstancesHider(this)); - m_data[c::HollowedMesh].reset( new HollowedMesh(this)); +// m_data[c::HollowedMesh].reset( new HollowedMesh(this)); m_data[c::Raycaster].reset( new Raycaster(this)); m_data[c::ObjectClipper].reset( new ObjectClipper(this)); m_data[c::SupportsClipper].reset( new SupportsClipper(this)); @@ -59,12 +59,12 @@ InstancesHider* CommonGizmosDataPool::instances_hider() const return inst_hider->is_valid() ? inst_hider : nullptr; } -HollowedMesh* CommonGizmosDataPool::hollowed_mesh() const -{ - HollowedMesh* hol_mesh = dynamic_cast(m_data.at(CommonGizmosDataID::HollowedMesh).get()); - assert(hol_mesh); - return hol_mesh->is_valid() ? hol_mesh : nullptr; -} +//HollowedMesh* CommonGizmosDataPool::hollowed_mesh() const +//{ +// HollowedMesh* hol_mesh = dynamic_cast(m_data.at(CommonGizmosDataID::HollowedMesh).get()); +// assert(hol_mesh); +// return hol_mesh->is_valid() ? hol_mesh : nullptr; +//} Raycaster* CommonGizmosDataPool::raycaster() const { @@ -117,16 +117,18 @@ bool CommonGizmosDataPool::check_dependencies(CommonGizmosDataID required) const void SelectionInfo::on_update() { const Selection& selection = get_pool()->get_canvas()->get_selection(); + + m_model_object = nullptr; + m_print_object = nullptr; + if (selection.is_single_full_instance()) { m_model_object = selection.get_model()->objects[selection.get_object_idx()]; - m_model_volume = nullptr; + + if (m_model_object) + m_print_object = get_pool()->get_canvas()->sla_print()->get_object(m_model_object->id()); + m_z_shift = selection.get_first_volume()->get_sla_shift_z(); } - else { - m_model_object = nullptr; - if (selection.is_single_volume()) - m_model_volume = selection.get_model()->objects[selection.get_object_idx()]->volumes[selection.get_first_volume()->volume_idx()]; - } } void SelectionInfo::on_release() @@ -253,78 +255,78 @@ void InstancesHider::render_cut() const -void HollowedMesh::on_update() -{ - const ModelObject* mo = get_pool()->selection_info()->model_object(); - bool is_sla = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA; - if (! mo || ! is_sla) - return; +//void HollowedMesh::on_update() +//{ +// const ModelObject* mo = get_pool()->selection_info()->model_object(); +// bool is_sla = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA; +// if (! mo || ! is_sla) +// return; - const GLCanvas3D* canvas = get_pool()->get_canvas(); - const PrintObjects& print_objects = canvas->sla_print()->objects(); - const SLAPrintObject* print_object = (m_print_object_idx >= 0 && m_print_object_idx < int(print_objects.size())) - ? print_objects[m_print_object_idx] - : nullptr; +// const GLCanvas3D* canvas = get_pool()->get_canvas(); +// const PrintObjects& print_objects = canvas->sla_print()->objects(); +// const SLAPrintObject* print_object = (m_print_object_idx >= 0 && m_print_object_idx < int(print_objects.size())) +// ? print_objects[m_print_object_idx] +// : nullptr; - // Find the respective SLAPrintObject. - if (m_print_object_idx < 0 || m_print_objects_count != int(print_objects.size())) { - m_print_objects_count = print_objects.size(); - m_print_object_idx = -1; - for (const SLAPrintObject* po : print_objects) { - ++m_print_object_idx; - if (po->model_object()->id() == mo->id()) { - print_object = po; - break; - } - } - } +// // Find the respective SLAPrintObject. +// if (m_print_object_idx < 0 || m_print_objects_count != int(print_objects.size())) { +// m_print_objects_count = print_objects.size(); +// m_print_object_idx = -1; +// for (const SLAPrintObject* po : print_objects) { +// ++m_print_object_idx; +// if (po->model_object()->id() == mo->id()) { +// print_object = po; +// break; +// } +// } +// } - // If there is a valid SLAPrintObject, check state of Hollowing step. - if (print_object) { - if (print_object->is_step_done(slaposDrillHoles) && !print_object->get_mesh_to_print().empty()) { - size_t timestamp = print_object->step_state_with_timestamp(slaposDrillHoles).timestamp; - if (timestamp > m_old_hollowing_timestamp) { - const TriangleMesh& backend_mesh = print_object->get_mesh_to_print(); - if (! backend_mesh.empty()) { - m_hollowed_mesh_transformed.reset(new TriangleMesh(backend_mesh)); - Transform3d trafo_inv = (canvas->sla_print()->sla_trafo(*mo) * print_object->model_object()->volumes.front()->get_transformation().get_matrix()).inverse(); - m_hollowed_mesh_transformed->transform(trafo_inv); - m_drainholes = print_object->model_object()->sla_drain_holes; - m_old_hollowing_timestamp = timestamp; +// // If there is a valid SLAPrintObject, check state of Hollowing step. +// if (print_object) { +// if (print_object->is_step_done(slaposDrillHoles) && !print_object->get_mesh_to_print().empty()) { +// size_t timestamp = print_object->step_state_with_timestamp(slaposDrillHoles).timestamp; +// if (timestamp > m_old_hollowing_timestamp) { +// const TriangleMesh& backend_mesh = print_object->get_mesh_to_print(); +// if (! backend_mesh.empty()) { +// m_hollowed_mesh_transformed.reset(new TriangleMesh(backend_mesh)); +// Transform3d trafo_inv = (canvas->sla_print()->sla_trafo(*mo) * print_object->model_object()->volumes.front()->get_transformation().get_matrix()).inverse(); +// m_hollowed_mesh_transformed->transform(trafo_inv); +// m_drainholes = print_object->model_object()->sla_drain_holes; +// m_old_hollowing_timestamp = timestamp; -// indexed_triangle_set interior = print_object->hollowed_interior_mesh(); -// its_flip_triangles(interior); -// m_hollowed_interior_transformed = std::make_unique(std::move(interior)); -// m_hollowed_interior_transformed->transform(trafo_inv); - } - else { - m_hollowed_mesh_transformed.reset(nullptr); - } - } - } - else - m_hollowed_mesh_transformed.reset(nullptr); - } -} +//// indexed_triangle_set interior = print_object->hollowed_interior_mesh(); +//// its_flip_triangles(interior); +//// m_hollowed_interior_transformed = std::make_unique(std::move(interior)); +//// m_hollowed_interior_transformed->transform(trafo_inv); +// } +// else { +// m_hollowed_mesh_transformed.reset(nullptr); +// } +// } +// } +// else +// m_hollowed_mesh_transformed.reset(nullptr); +// } +//} -void HollowedMesh::on_release() -{ - m_hollowed_mesh_transformed.reset(); - m_old_hollowing_timestamp = 0; - m_print_object_idx = -1; -} +//void HollowedMesh::on_release() +//{ +// m_hollowed_mesh_transformed.reset(); +// m_old_hollowing_timestamp = 0; +// m_print_object_idx = -1; +//} -const TriangleMesh* HollowedMesh::get_hollowed_mesh() const -{ - return m_hollowed_mesh_transformed.get(); -} +//const TriangleMesh* HollowedMesh::get_hollowed_mesh() const +//{ +// return m_hollowed_mesh_transformed.get(); +//} -const TriangleMesh* HollowedMesh::get_hollowed_interior() const -{ - return m_hollowed_interior_transformed.get(); -} +//const TriangleMesh* HollowedMesh::get_hollowed_interior() const +//{ +// return m_hollowed_interior_transformed.get(); +//} @@ -345,12 +347,13 @@ void Raycaster::on_update() mvs = mo->volumes; std::vector meshes; - if (mvs.size() == 1) { - assert(mvs.front()->is_model_part()); - const HollowedMesh* hollowed_mesh_tracker = get_pool()->hollowed_mesh(); - if (hollowed_mesh_tracker && hollowed_mesh_tracker->get_hollowed_mesh()) - meshes.push_back(hollowed_mesh_tracker->get_hollowed_mesh()); - } + const std::vector& mvs = mo->volumes; +// if (mvs.size() == 1) { +// assert(mvs.front()->is_model_part()); +// const HollowedMesh* hollowed_mesh_tracker = get_pool()->hollowed_mesh(); +// if (hollowed_mesh_tracker && hollowed_mesh_tracker->get_hollowed_mesh()) +// meshes.push_back(hollowed_mesh_tracker->get_hollowed_mesh()); +// } if (meshes.empty()) { for (const ModelVolume* v : mvs) { if (v->is_model_part()) @@ -396,9 +399,9 @@ void ObjectClipper::on_update() // which mesh should be cut? std::vector meshes; - bool has_hollowed = get_pool()->hollowed_mesh() && get_pool()->hollowed_mesh()->get_hollowed_mesh(); - if (has_hollowed) - meshes.push_back(get_pool()->hollowed_mesh()->get_hollowed_mesh()); +// bool has_hollowed = get_pool()->hollowed_mesh() && get_pool()->hollowed_mesh()->get_hollowed_mesh(); +// if (has_hollowed) +// meshes.push_back(get_pool()->hollowed_mesh()->get_hollowed_mesh()); if (meshes.empty()) for (const ModelVolume* mv : mo->volumes) @@ -412,8 +415,8 @@ void ObjectClipper::on_update() } m_old_meshes = meshes; - if (has_hollowed) - m_clippers.front()->set_negative_mesh(*get_pool()->hollowed_mesh()->get_hollowed_interior()); +// if (has_hollowed) +// m_clippers.front()->set_negative_mesh(*get_pool()->hollowed_mesh()->get_hollowed_interior()); m_active_inst_bb_radius = mo->instance_bounding_box(get_pool()->selection_info()->get_active_instance()).radius(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index 42faa25f84..d6c5801230 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -5,11 +5,11 @@ #include #include "slic3r/GUI/MeshUtils.hpp" -#include "libslic3r/SLA/Hollowing.hpp" namespace Slic3r { class ModelObject; +class SLAPrintObject; class ModelVolume; namespace GUI { @@ -85,7 +85,7 @@ public: // Getters for the data that need to be accessed from the gizmos directly. CommonGizmosDataObjects::SelectionInfo* selection_info() const; CommonGizmosDataObjects::InstancesHider* instances_hider() const; - CommonGizmosDataObjects::HollowedMesh* hollowed_mesh() const; +// CommonGizmosDataObjects::HollowedMesh* hollowed_mesh() const; CommonGizmosDataObjects::Raycaster* raycaster() const; CommonGizmosDataObjects::ObjectClipper* object_clipper() const; CommonGizmosDataObjects::SupportsClipper* supports_clipper() const; @@ -158,6 +158,7 @@ public: // Returns a non-null pointer if the selection is a single full instance ModelObject* model_object() const { return m_model_object; } + const SLAPrintObject *print_object() const { return m_print_object; } // Returns a non-null pointer if the selection is a single volume ModelVolume* model_volume() const { return m_model_volume; } int get_active_instance() const; @@ -169,6 +170,7 @@ protected: private: ModelObject* m_model_object = nullptr; + const SLAPrintObject *m_print_object = nullptr; ModelVolume* m_model_volume = nullptr; // int m_active_inst = -1; float m_z_shift = 0.f; @@ -201,32 +203,32 @@ private: -class HollowedMesh : public CommonGizmosDataBase -{ -public: - explicit HollowedMesh(CommonGizmosDataPool* cgdp) - : CommonGizmosDataBase(cgdp) {} -#ifndef NDEBUG - CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; } -#endif // NDEBUG +//class HollowedMesh : public CommonGizmosDataBase +//{ +//public: +// explicit HollowedMesh(CommonGizmosDataPool* cgdp) +// : CommonGizmosDataBase(cgdp) {} +//#ifndef NDEBUG +// CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; } +//#endif // NDEBUG - const sla::DrainHoles &get_drainholes() const { return m_drainholes; } +// const sla::DrainHoles &get_drainholes() const { return m_drainholes; } - const TriangleMesh* get_hollowed_mesh() const; - const TriangleMesh* get_hollowed_interior() const; +// const TriangleMesh* get_hollowed_mesh() const; +// const TriangleMesh* get_hollowed_interior() const; -protected: - void on_update() override; - void on_release() override; +//protected: +// void on_update() override; +// void on_release() override; -private: - std::unique_ptr m_hollowed_mesh_transformed; - std::unique_ptr m_hollowed_interior_transformed; - size_t m_old_hollowing_timestamp = 0; - int m_print_object_idx = -1; - int m_print_objects_count = 0; - sla::DrainHoles m_drainholes; -}; +//private: +// std::unique_ptr m_hollowed_mesh_transformed; +// std::unique_ptr m_hollowed_interior_transformed; +// size_t m_old_hollowing_timestamp = 0; +// int m_print_object_idx = -1; +// int m_print_objects_count = 0; +// sla::DrainHoles m_drainholes; +//}; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d4b279f606..d57963e258 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2649,17 +2649,6 @@ std::vector Plater::priv::load_files(const std::vector& input_ model_object->ensure_on_bed(is_project_file); } - // check multi-part object adding for the SLA-printing - if (printer_technology == ptSLA) { - for (auto obj : model.objects) - if ( obj->volumes.size()>1 ) { - Slic3r::GUI::show_error(nullptr, - format_wxstr(_L("You can't to add the object(s) from %s because of one or some of them is(are) multi-part"), - from_path(filename))); - return obj_idxs; - } - } - if (one_by_one) { if ((type_3mf && !is_project_file) || (type_any_amf && !type_zip_amf)) model.center_instances_around_point(this->bed.build_volume().bed_center()); diff --git a/src/slic3r/GUI/SceneRaycaster.cpp b/src/slic3r/GUI/SceneRaycaster.cpp index a92c622c1b..f309d6eaaa 100644 --- a/src/slic3r/GUI/SceneRaycaster.cpp +++ b/src/slic3r/GUI/SceneRaycaster.cpp @@ -88,7 +88,7 @@ void SceneRaycaster::remove_raycaster(std::shared_ptr item) } } -SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Camera& camera, const ClippingPlane* clipping_plane) +SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Camera& camera, const ClippingPlane* clipping_plane) const { double closest_hit_squared_distance = std::numeric_limits::max(); auto is_closest = [&closest_hit_squared_distance](const Camera& camera, const Vec3f& hit) { @@ -107,7 +107,7 @@ SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Came auto test_raycasters = [this, is_closest, clipping_plane](EType type, const Vec2d& mouse_pos, const Camera& camera, HitResult& ret) { const ClippingPlane* clip_plane = (clipping_plane != nullptr && type == EType::Volume) ? clipping_plane : nullptr; - std::vector>* raycasters = get_raycasters(type); + const std::vector>* raycasters = get_raycasters(type); const Vec3f camera_forward = camera.get_dir_forward().cast(); HitResult current_hit = { type }; for (std::shared_ptr item : *raycasters) { @@ -214,6 +214,20 @@ std::vector>* SceneRaycaster::get_raycasters return ret; } +const std::vector>* SceneRaycaster::get_raycasters(EType type) const +{ + const std::vector>* ret = nullptr; + switch (type) + { + case EType::Bed: { ret = &m_bed; break; } + case EType::Volume: { ret = &m_volumes; break; } + case EType::Gizmo: { ret = &m_gizmos; break; } + default: { break; } + } + assert(ret != nullptr); + return ret; +} + int SceneRaycaster::base_id(EType type) { switch (type) diff --git a/src/slic3r/GUI/SceneRaycaster.hpp b/src/slic3r/GUI/SceneRaycaster.hpp index 2254a2022d..bf8ab2b1bf 100644 --- a/src/slic3r/GUI/SceneRaycaster.hpp +++ b/src/slic3r/GUI/SceneRaycaster.hpp @@ -89,10 +89,11 @@ public: void remove_raycaster(std::shared_ptr item); std::vector>* get_raycasters(EType type); + const std::vector>* get_raycasters(EType type) const; void set_gizmos_on_top(bool value) { m_gizmos_on_top = value; } - HitResult hit(const Vec2d& mouse_pos, const Camera& camera, const ClippingPlane* clipping_plane = nullptr); + HitResult hit(const Vec2d& mouse_pos, const Camera& camera, const ClippingPlane* clipping_plane = nullptr) const; #if ENABLE_RAYCAST_PICKING_DEBUG void render_hit(const Camera& camera); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index b27f7a7381..7caf2d9ea7 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -62,18 +62,18 @@ Selection::VolumeCache::VolumeCache(const Geometry::Transformation& volume_trans bool Selection::Clipboard::is_sla_compliant() const { - if (m_mode == Selection::Volume) - return false; +// if (m_mode == Selection::Volume) +// return false; - for (const ModelObject* o : m_model->objects) { - if (o->is_multiparts()) - return false; +// for (const ModelObject* o : m_model->objects) { +// if (o->is_multiparts()) +// return false; - for (const ModelVolume* v : o->volumes) { - if (v->is_modifier()) - return false; - } - } +// for (const ModelVolume* v : o->volumes) { +// if (v->is_modifier()) +// return false; +// } +// } return true; } @@ -571,13 +571,13 @@ bool Selection::is_from_single_object() const bool Selection::is_sla_compliant() const { - if (m_mode == Volume) - return false; +// if (m_mode == Volume) +// return false; - for (unsigned int i : m_list) { - if ((*m_volumes)[i]->is_modifier) - return false; - } +// for (unsigned int i : m_list) { +// if ((*m_volumes)[i]->is_modifier) +// return false; +// } return true; } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index d5b909f370..9515fa2b6b 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3279,9 +3279,9 @@ void Tab::select_preset(std::string preset_name, bool delete_current /*=false*/, const PresetWithVendorProfile new_printer_preset_with_vendor_profile = m_presets->get_preset_with_vendor_profile(new_printer_preset); PrinterTechnology old_printer_technology = m_presets->get_edited_preset().printer_technology(); PrinterTechnology new_printer_technology = new_printer_preset.printer_technology(); - if (new_printer_technology == ptSLA && old_printer_technology == ptFFF && !wxGetApp().may_switch_to_SLA_preset(_L("New printer preset selected"))) + /*if (new_printer_technology == ptSLA && old_printer_technology == ptFFF && !wxGetApp().may_switch_to_SLA_preset(_L("New printer preset selected"))) canceled = true; - else { + else */{ struct PresetUpdate { Preset::Type tab_type; PresetCollection *presets;