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
This commit is contained in:
tamasmeszaros 2022-10-20 14:14:25 +02:00
parent 15fa4c42d6
commit 9bc3410474
16 changed files with 269 additions and 207 deletions

View File

@ -28,7 +28,6 @@ class AABBMesh {
class AABBImpl;
const indexed_triangle_set* m_tm;
// double m_ground_level = 0/*, m_gnd_offset = 0*/;
std::unique_ptr<AABBImpl> m_aabb;
VertexFaceIndex m_vfidx; // vertex-face index
@ -57,10 +56,6 @@ public:
~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<Vec3f>& vertices() const;
const std::vector<Vec3i>& indices() const;
const Vec3f& vertices(size_t idx) const;

View File

@ -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;

View File

@ -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());

View File

@ -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();

View File

@ -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<std::pair<std::string, std::string>> MenuFactory::ADD_VOLUME_MENU_ITEMS {
static const constexpr std::array<std::pair<const char *, const char *>, 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<std::pair<std::string, std::string>> 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)

View File

@ -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);

View File

@ -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::pair<Vec3f, V
normal,
clp_dist != 0. ? clp : nullptr))
{
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;
}
}
// 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);

View File

@ -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<double>());
@ -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<Vec3f, Vec3f>& 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::pair<Vec
// The raycaster query
Vec3f hit;
Vec3f normal;
if (m_c->raycaster()->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::pair<Vec
clp_dist != 0. ? clp : nullptr))
{
// Check whether the hit is in a hole
bool in_hole = false;
// bool in_hole = false;
// In case the hollowed and drilled mesh is available, we can allow
// placing points in holes, because they should never end up
// on surface that's been drilled away.
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) {
// 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<float>() * (m_editing_cache[idx].support_point.pos + m_editing_cache[idx].normal)).cast<float>());
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<double>()) * 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<double>());

View File

@ -25,7 +25,7 @@ private:
bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
const float RenderPointScale = 1.f;
static constexpr float RenderPointScale = 1.f;
class CacheEntry {
public:

View File

@ -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<HollowedMesh*>(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<HollowedMesh*>(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<TriangleMesh>(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<TriangleMesh>(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<const TriangleMesh*> 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<ModelVolume*>& 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<const TriangleMesh*> 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();

View File

@ -5,11 +5,11 @@
#include <map>
#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<TriangleMesh> m_hollowed_mesh_transformed;
std::unique_ptr<TriangleMesh> 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<TriangleMesh> m_hollowed_mesh_transformed;
// std::unique_ptr<TriangleMesh> 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;
//};

View File

@ -2649,17 +2649,6 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& 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());

View File

@ -88,7 +88,7 @@ void SceneRaycaster::remove_raycaster(std::shared_ptr<SceneRaycasterItem> 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<double>::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<std::shared_ptr<SceneRaycasterItem>>* raycasters = get_raycasters(type);
const std::vector<std::shared_ptr<SceneRaycasterItem>>* raycasters = get_raycasters(type);
const Vec3f camera_forward = camera.get_dir_forward().cast<float>();
HitResult current_hit = { type };
for (std::shared_ptr<SceneRaycasterItem> item : *raycasters) {
@ -214,6 +214,20 @@ std::vector<std::shared_ptr<SceneRaycasterItem>>* SceneRaycaster::get_raycasters
return ret;
}
const std::vector<std::shared_ptr<SceneRaycasterItem>>* SceneRaycaster::get_raycasters(EType type) const
{
const std::vector<std::shared_ptr<SceneRaycasterItem>>* 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)

View File

@ -89,10 +89,11 @@ public:
void remove_raycaster(std::shared_ptr<SceneRaycasterItem> item);
std::vector<std::shared_ptr<SceneRaycasterItem>>* get_raycasters(EType type);
const std::vector<std::shared_ptr<SceneRaycasterItem>>* 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);

View File

@ -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;
}

View File

@ -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;