mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 06:29:00 +08:00
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:
parent
15fa4c42d6
commit
9bc3410474
@ -28,7 +28,6 @@ class AABBMesh {
|
|||||||
class AABBImpl;
|
class AABBImpl;
|
||||||
|
|
||||||
const indexed_triangle_set* m_tm;
|
const indexed_triangle_set* m_tm;
|
||||||
// double m_ground_level = 0/*, m_gnd_offset = 0*/;
|
|
||||||
|
|
||||||
std::unique_ptr<AABBImpl> m_aabb;
|
std::unique_ptr<AABBImpl> m_aabb;
|
||||||
VertexFaceIndex m_vfidx; // vertex-face index
|
VertexFaceIndex m_vfidx; // vertex-face index
|
||||||
@ -57,10 +56,6 @@ public:
|
|||||||
|
|
||||||
~AABBMesh();
|
~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<Vec3f>& vertices() const;
|
||||||
const std::vector<Vec3i>& indices() const;
|
const std::vector<Vec3i>& indices() const;
|
||||||
const Vec3f& vertices(size_t idx) const;
|
const Vec3f& vertices(size_t idx) const;
|
||||||
|
@ -386,7 +386,7 @@ public:
|
|||||||
bool force_neutral_color : 1;
|
bool force_neutral_color : 1;
|
||||||
// Whether or not to force rendering of sinking contours
|
// Whether or not to force rendering of sinking contours
|
||||||
bool force_sinking_contours : 1;
|
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 ?
|
// Is mouse or rectangle selection over this object to select/deselect it ?
|
||||||
EHoverState hover;
|
EHoverState hover;
|
||||||
|
@ -2188,6 +2188,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (printer_technology == ptSLA) {
|
if (printer_technology == ptSLA) {
|
||||||
// size_t idx = 0;
|
// size_t idx = 0;
|
||||||
// const SLAPrint *sla_print = this->sla_print();
|
// const SLAPrint *sla_print = this->sla_print();
|
||||||
@ -3846,7 +3847,7 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
|
|||||||
#else
|
#else
|
||||||
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
||||||
#endif // ENABLE_WORLD_COORDINATE
|
#endif // ENABLE_WORLD_COORDINATE
|
||||||
else if (selection_mode == Selection::Volume)
|
else if (volume_idx >= 0 && selection_mode == Selection::Volume)
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#if ENABLE_WORLD_COORDINATE
|
||||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
||||||
#else
|
#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());
|
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
||||||
#endif // ENABLE_WORLD_COORDINATE
|
#endif // ENABLE_WORLD_COORDINATE
|
||||||
}
|
}
|
||||||
else if (selection_mode == Selection::Volume) {
|
else if (selection_mode == Selection::Volume && volume_idx >= 0) {
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#if ENABLE_WORLD_COORDINATE
|
||||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
||||||
|
@ -688,6 +688,8 @@ public:
|
|||||||
void set_raycaster_gizmos_on_top(bool value) {
|
void set_raycaster_gizmos_on_top(bool value) {
|
||||||
m_scene_raycaster.set_gizmos_on_top(value);
|
m_scene_raycaster.set_gizmos_on_top(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SceneRaycaster & raycaster() const { return m_scene_raycaster; }
|
||||||
#endif // ENABLE_RAYCAST_PICKING
|
#endif // ENABLE_RAYCAST_PICKING
|
||||||
|
|
||||||
void set_as_dirty();
|
void set_as_dirty();
|
||||||
|
@ -44,7 +44,6 @@ static bool is_improper_category(const std::string& category, const int extruder
|
|||||||
(!is_object_settings && category == "Support material");
|
(!is_object_settings && category == "Support material");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
// SettingsFactory
|
// 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
|
// 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
|
// menu_item Name menu_item bitmap name
|
||||||
{L("Add part"), "add_part" }, // ~ModelVolumeType::MODEL_PART
|
{L("Add part"), "add_part" }, // ~ModelVolumeType::MODEL_PART
|
||||||
{L("Add negative volume"), "add_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME
|
{L("Add negative volume"), "add_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME
|
||||||
{L("Add modifier"), "add_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER
|
{L("Add modifier"), "add_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER
|
||||||
{L("Add support blocker"), "support_blocker"}, // ~ModelVolumeType::SUPPORT_BLOCKER
|
{L("Add support blocker"), "support_blocker"}, // ~ModelVolumeType::SUPPORT_BLOCKER
|
||||||
{L("Add support enforcer"), "support_enforcer"}, // ~ModelVolumeType::SUPPORT_ENFORCER
|
{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
|
// 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 {
|
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);
|
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)
|
wxMenuItem* MenuFactory::append_menu_item_layers_editing(wxMenu* menu)
|
||||||
{
|
{
|
||||||
return append_menu_item(menu, wxID_ANY, _L("Height range Modifier"), "",
|
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
|
// If there are selected more then one instance but not all of them
|
||||||
// don't add settings menu items
|
// don't add settings menu items
|
||||||
const Selection& selection = get_selection();
|
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
|
selection.is_multiple_volume() || selection.is_mixed()) // more than one volume(part) is selected on the scene
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@ -1066,6 +1114,8 @@ void MenuFactory::create_sla_object_menu()
|
|||||||
[]() { return plater()->can_split(true); }, m_parent);
|
[]() { return plater()->can_split(true); }, m_parent);
|
||||||
|
|
||||||
m_sla_object_menu.AppendSeparator();
|
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)
|
void MenuFactory::append_immutable_part_menu_items(wxMenu* menu)
|
||||||
|
@ -92,6 +92,7 @@ private:
|
|||||||
wxMenu* append_submenu_add_generic(wxMenu* menu, ModelVolumeType type);
|
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_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_volume(wxMenu* menu);
|
||||||
|
void append_menu_items_add_sla_volume(wxMenu* menu);
|
||||||
wxMenuItem* append_menu_item_layers_editing(wxMenu* menu);
|
wxMenuItem* append_menu_item_layers_editing(wxMenu* menu);
|
||||||
wxMenuItem* append_menu_item_settings(wxMenu* menu);
|
wxMenuItem* append_menu_item_settings(wxMenu* menu);
|
||||||
wxMenuItem* append_menu_item_change_type(wxMenu* menu);
|
wxMenuItem* append_menu_item_change_type(wxMenu* menu);
|
||||||
|
@ -53,8 +53,8 @@ void GLGizmoHollow::data_changed()
|
|||||||
reload_cache();
|
reload_cache();
|
||||||
m_old_mo_id = mo->id();
|
m_old_mo_id = mo->id();
|
||||||
}
|
}
|
||||||
if (m_c->hollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh())
|
// if (m_c->hollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh())
|
||||||
m_holes_in_drilled_mesh = mo->sla_drain_holes;
|
// m_holes_in_drilled_mesh = mo->sla_drain_holes;
|
||||||
#if ENABLE_RAYCAST_PICKING
|
#if ENABLE_RAYCAST_PICKING
|
||||||
if (m_raycasters.empty())
|
if (m_raycasters.empty())
|
||||||
on_register_raycasters_for_picking();
|
on_register_raycasters_for_picking();
|
||||||
@ -206,11 +206,11 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
|
|||||||
#endif // !ENABLE_RAYCAST_PICKING
|
#endif // !ENABLE_RAYCAST_PICKING
|
||||||
if (size_t(m_hover_id) == i)
|
if (size_t(m_hover_id) == i)
|
||||||
render_color = ColorRGBA::CYAN();
|
render_color = ColorRGBA::CYAN();
|
||||||
else if (m_c->hollowed_mesh() &&
|
// else if (m_c->hollowed_mesh() &&
|
||||||
i < m_c->hollowed_mesh()->get_drainholes().size() &&
|
// i < m_c->hollowed_mesh()->get_drainholes().size() &&
|
||||||
m_c->hollowed_mesh()->get_drainholes()[i].failed) {
|
// m_c->hollowed_mesh()->get_drainholes()[i].failed) {
|
||||||
render_color = { 1.0f, 0.0f, 0.0f, 0.5f };
|
// render_color = { 1.0f, 0.0f, 0.0f, 0.5f };
|
||||||
}
|
// }
|
||||||
else
|
else
|
||||||
render_color = point_selected ? ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f) : ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f);
|
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
|
#if !ENABLE_RAYCAST_PICKING
|
||||||
@ -314,18 +314,18 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, V
|
|||||||
normal,
|
normal,
|
||||||
clp_dist != 0. ? clp : nullptr))
|
clp_dist != 0. ? clp : nullptr))
|
||||||
{
|
{
|
||||||
if (m_c->hollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh()) {
|
// if (m_c->hollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh()) {
|
||||||
// in this case the raycaster sees the hollowed and drilled 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
|
// // if the point lies on the surface created by the hole, we want
|
||||||
// to ignore it.
|
// // to ignore it.
|
||||||
for (const sla::DrainHole& hole : m_holes_in_drilled_mesh) {
|
// for (const sla::DrainHole& hole : m_holes_in_drilled_mesh) {
|
||||||
sla::DrainHole outer(hole);
|
// sla::DrainHole outer(hole);
|
||||||
outer.radius *= 1.001f;
|
// outer.radius *= 1.001f;
|
||||||
outer.height *= 1.001f;
|
// outer.height *= 1.001f;
|
||||||
if (outer.is_inside(hit))
|
// if (outer.is_inside(hit))
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Return both the point and the facet normal.
|
// Return both the point and the facet normal.
|
||||||
pos_and_normal = std::make_pair(hit, normal);
|
pos_and_normal = std::make_pair(hit, normal);
|
||||||
|
@ -86,6 +86,8 @@ void GLGizmoSlaSupports::data_changed()
|
|||||||
update_raycasters_for_picking_transform();
|
update_raycasters_for_picking_transform();
|
||||||
#endif // ENABLE_RAYCAST_PICKING
|
#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 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_points = (cache_size != 0);
|
||||||
const bool has_holes = (! m_c->hollowed_mesh()->get_hollowed_mesh()
|
const bool has_holes = (/*! m_c->hollowed_mesh()->get_hollowed_mesh()
|
||||||
&& ! m_c->selection_info()->model_object()->sla_drain_holes.empty());
|
&&*/ ! m_c->selection_info()->model_object()->sla_drain_holes.empty());
|
||||||
|
|
||||||
if (! has_points && ! has_holes)
|
if (! has_points && ! has_holes)
|
||||||
return;
|
return;
|
||||||
@ -304,7 +306,8 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
|||||||
if (m_editing_mode) {
|
if (m_editing_mode) {
|
||||||
// in case the normal is not yet cached, find and cache it
|
// in case the normal is not yet cached, find and cache it
|
||||||
if (m_editing_cache[i].normal == Vec3f::Zero())
|
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;
|
Eigen::Quaterniond q;
|
||||||
q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast<double>());
|
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.
|
// 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)
|
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;
|
return false;
|
||||||
|
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
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
|
// The raycaster query
|
||||||
Vec3f hit;
|
Vec3f hit;
|
||||||
Vec3f normal;
|
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,
|
mouse_pos,
|
||||||
trafo.get_matrix(),
|
trafo.get_matrix(),
|
||||||
camera,
|
camera,
|
||||||
@ -477,24 +480,24 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec
|
|||||||
clp_dist != 0. ? clp : nullptr))
|
clp_dist != 0. ? clp : nullptr))
|
||||||
{
|
{
|
||||||
// Check whether the hit is in a hole
|
// 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
|
// In case the hollowed and drilled mesh is available, we can allow
|
||||||
// placing points in holes, because they should never end up
|
// placing points in holes, because they should never end up
|
||||||
// on surface that's been drilled away.
|
// on surface that's been drilled away.
|
||||||
if (! m_c->hollowed_mesh()->get_hollowed_mesh()) {
|
// if (! m_c->hollowed_mesh()->get_hollowed_mesh()) {
|
||||||
sla::DrainHoles drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
|
// sla::DrainHoles drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
|
||||||
for (const sla::DrainHole& hole : drain_holes) {
|
// for (const sla::DrainHole& hole : drain_holes) {
|
||||||
if (hole.is_inside(hit)) {
|
// if (hole.is_inside(hit)) {
|
||||||
in_hole = true;
|
// in_hole = true;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (! in_hole) {
|
// if (! in_hole) {
|
||||||
// Return both the point and the facet normal.
|
// Return both the point and the facet normal.
|
||||||
pos_and_normal = std::make_pair(hit, normal);
|
pos_and_normal = std::make_pair(hit, normal);
|
||||||
return true;
|
return true;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -589,7 +592,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||||||
for (size_t idx : points_idxs)
|
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>());
|
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,
|
trafo, wxGetApp().plater()->get_camera(), points_inside,
|
||||||
m_c->object_clipper()->get_clipping_plane()))
|
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;
|
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())
|
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;
|
Eigen::Quaterniond q;
|
||||||
q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast<double>());
|
q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast<double>());
|
||||||
|
@ -25,7 +25,7 @@ private:
|
|||||||
|
|
||||||
bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
|
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 {
|
class CacheEntry {
|
||||||
public:
|
public:
|
||||||
|
@ -23,7 +23,7 @@ CommonGizmosDataPool::CommonGizmosDataPool(GLCanvas3D* canvas)
|
|||||||
using c = CommonGizmosDataID;
|
using c = CommonGizmosDataID;
|
||||||
m_data[c::SelectionInfo].reset( new SelectionInfo(this));
|
m_data[c::SelectionInfo].reset( new SelectionInfo(this));
|
||||||
m_data[c::InstancesHider].reset( new InstancesHider(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::Raycaster].reset( new Raycaster(this));
|
||||||
m_data[c::ObjectClipper].reset( new ObjectClipper(this));
|
m_data[c::ObjectClipper].reset( new ObjectClipper(this));
|
||||||
m_data[c::SupportsClipper].reset( new SupportsClipper(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;
|
return inst_hider->is_valid() ? inst_hider : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HollowedMesh* CommonGizmosDataPool::hollowed_mesh() const
|
//HollowedMesh* CommonGizmosDataPool::hollowed_mesh() const
|
||||||
{
|
//{
|
||||||
HollowedMesh* hol_mesh = dynamic_cast<HollowedMesh*>(m_data.at(CommonGizmosDataID::HollowedMesh).get());
|
// HollowedMesh* hol_mesh = dynamic_cast<HollowedMesh*>(m_data.at(CommonGizmosDataID::HollowedMesh).get());
|
||||||
assert(hol_mesh);
|
// assert(hol_mesh);
|
||||||
return hol_mesh->is_valid() ? hol_mesh : nullptr;
|
// return hol_mesh->is_valid() ? hol_mesh : nullptr;
|
||||||
}
|
//}
|
||||||
|
|
||||||
Raycaster* CommonGizmosDataPool::raycaster() const
|
Raycaster* CommonGizmosDataPool::raycaster() const
|
||||||
{
|
{
|
||||||
@ -117,16 +117,18 @@ bool CommonGizmosDataPool::check_dependencies(CommonGizmosDataID required) const
|
|||||||
void SelectionInfo::on_update()
|
void SelectionInfo::on_update()
|
||||||
{
|
{
|
||||||
const Selection& selection = get_pool()->get_canvas()->get_selection();
|
const Selection& selection = get_pool()->get_canvas()->get_selection();
|
||||||
|
|
||||||
|
m_model_object = nullptr;
|
||||||
|
m_print_object = nullptr;
|
||||||
|
|
||||||
if (selection.is_single_full_instance()) {
|
if (selection.is_single_full_instance()) {
|
||||||
m_model_object = selection.get_model()->objects[selection.get_object_idx()];
|
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();
|
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()
|
void SelectionInfo::on_release()
|
||||||
@ -253,78 +255,78 @@ void InstancesHider::render_cut() const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void HollowedMesh::on_update()
|
//void HollowedMesh::on_update()
|
||||||
{
|
//{
|
||||||
const ModelObject* mo = get_pool()->selection_info()->model_object();
|
// const ModelObject* mo = get_pool()->selection_info()->model_object();
|
||||||
bool is_sla = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA;
|
// bool is_sla = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA;
|
||||||
if (! mo || ! is_sla)
|
// if (! mo || ! is_sla)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
const GLCanvas3D* canvas = get_pool()->get_canvas();
|
// const GLCanvas3D* canvas = get_pool()->get_canvas();
|
||||||
const PrintObjects& print_objects = canvas->sla_print()->objects();
|
// 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()))
|
// const SLAPrintObject* print_object = (m_print_object_idx >= 0 && m_print_object_idx < int(print_objects.size()))
|
||||||
? print_objects[m_print_object_idx]
|
// ? print_objects[m_print_object_idx]
|
||||||
: nullptr;
|
// : nullptr;
|
||||||
|
|
||||||
// Find the respective SLAPrintObject.
|
// // Find the respective SLAPrintObject.
|
||||||
if (m_print_object_idx < 0 || m_print_objects_count != int(print_objects.size())) {
|
// if (m_print_object_idx < 0 || m_print_objects_count != int(print_objects.size())) {
|
||||||
m_print_objects_count = print_objects.size();
|
// m_print_objects_count = print_objects.size();
|
||||||
m_print_object_idx = -1;
|
// m_print_object_idx = -1;
|
||||||
for (const SLAPrintObject* po : print_objects) {
|
// for (const SLAPrintObject* po : print_objects) {
|
||||||
++m_print_object_idx;
|
// ++m_print_object_idx;
|
||||||
if (po->model_object()->id() == mo->id()) {
|
// if (po->model_object()->id() == mo->id()) {
|
||||||
print_object = po;
|
// print_object = po;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// If there is a valid SLAPrintObject, check state of Hollowing step.
|
// // If there is a valid SLAPrintObject, check state of Hollowing step.
|
||||||
if (print_object) {
|
// if (print_object) {
|
||||||
if (print_object->is_step_done(slaposDrillHoles) && !print_object->get_mesh_to_print().empty()) {
|
// 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;
|
// size_t timestamp = print_object->step_state_with_timestamp(slaposDrillHoles).timestamp;
|
||||||
if (timestamp > m_old_hollowing_timestamp) {
|
// if (timestamp > m_old_hollowing_timestamp) {
|
||||||
const TriangleMesh& backend_mesh = print_object->get_mesh_to_print();
|
// const TriangleMesh& backend_mesh = print_object->get_mesh_to_print();
|
||||||
if (! backend_mesh.empty()) {
|
// if (! backend_mesh.empty()) {
|
||||||
m_hollowed_mesh_transformed.reset(new TriangleMesh(backend_mesh));
|
// 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();
|
// 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_hollowed_mesh_transformed->transform(trafo_inv);
|
||||||
m_drainholes = print_object->model_object()->sla_drain_holes;
|
// m_drainholes = print_object->model_object()->sla_drain_holes;
|
||||||
m_old_hollowing_timestamp = timestamp;
|
// m_old_hollowing_timestamp = timestamp;
|
||||||
|
|
||||||
// indexed_triangle_set interior = print_object->hollowed_interior_mesh();
|
//// indexed_triangle_set interior = print_object->hollowed_interior_mesh();
|
||||||
// its_flip_triangles(interior);
|
//// its_flip_triangles(interior);
|
||||||
// m_hollowed_interior_transformed = std::make_unique<TriangleMesh>(std::move(interior));
|
//// m_hollowed_interior_transformed = std::make_unique<TriangleMesh>(std::move(interior));
|
||||||
// m_hollowed_interior_transformed->transform(trafo_inv);
|
//// m_hollowed_interior_transformed->transform(trafo_inv);
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
m_hollowed_mesh_transformed.reset(nullptr);
|
// m_hollowed_mesh_transformed.reset(nullptr);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
m_hollowed_mesh_transformed.reset(nullptr);
|
// m_hollowed_mesh_transformed.reset(nullptr);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
void HollowedMesh::on_release()
|
//void HollowedMesh::on_release()
|
||||||
{
|
//{
|
||||||
m_hollowed_mesh_transformed.reset();
|
// m_hollowed_mesh_transformed.reset();
|
||||||
m_old_hollowing_timestamp = 0;
|
// m_old_hollowing_timestamp = 0;
|
||||||
m_print_object_idx = -1;
|
// m_print_object_idx = -1;
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
const TriangleMesh* HollowedMesh::get_hollowed_mesh() const
|
//const TriangleMesh* HollowedMesh::get_hollowed_mesh() const
|
||||||
{
|
//{
|
||||||
return m_hollowed_mesh_transformed.get();
|
// return m_hollowed_mesh_transformed.get();
|
||||||
}
|
//}
|
||||||
|
|
||||||
const TriangleMesh* HollowedMesh::get_hollowed_interior() const
|
//const TriangleMesh* HollowedMesh::get_hollowed_interior() const
|
||||||
{
|
//{
|
||||||
return m_hollowed_interior_transformed.get();
|
// return m_hollowed_interior_transformed.get();
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -345,12 +347,13 @@ void Raycaster::on_update()
|
|||||||
mvs = mo->volumes;
|
mvs = mo->volumes;
|
||||||
|
|
||||||
std::vector<const TriangleMesh*> meshes;
|
std::vector<const TriangleMesh*> meshes;
|
||||||
if (mvs.size() == 1) {
|
const std::vector<ModelVolume*>& mvs = mo->volumes;
|
||||||
assert(mvs.front()->is_model_part());
|
// if (mvs.size() == 1) {
|
||||||
const HollowedMesh* hollowed_mesh_tracker = get_pool()->hollowed_mesh();
|
// assert(mvs.front()->is_model_part());
|
||||||
if (hollowed_mesh_tracker && hollowed_mesh_tracker->get_hollowed_mesh())
|
// const HollowedMesh* hollowed_mesh_tracker = get_pool()->hollowed_mesh();
|
||||||
meshes.push_back(hollowed_mesh_tracker->get_hollowed_mesh());
|
// if (hollowed_mesh_tracker && hollowed_mesh_tracker->get_hollowed_mesh())
|
||||||
}
|
// meshes.push_back(hollowed_mesh_tracker->get_hollowed_mesh());
|
||||||
|
// }
|
||||||
if (meshes.empty()) {
|
if (meshes.empty()) {
|
||||||
for (const ModelVolume* v : mvs) {
|
for (const ModelVolume* v : mvs) {
|
||||||
if (v->is_model_part())
|
if (v->is_model_part())
|
||||||
@ -396,9 +399,9 @@ void ObjectClipper::on_update()
|
|||||||
|
|
||||||
// which mesh should be cut?
|
// which mesh should be cut?
|
||||||
std::vector<const TriangleMesh*> meshes;
|
std::vector<const TriangleMesh*> meshes;
|
||||||
bool has_hollowed = get_pool()->hollowed_mesh() && get_pool()->hollowed_mesh()->get_hollowed_mesh();
|
// bool has_hollowed = get_pool()->hollowed_mesh() && get_pool()->hollowed_mesh()->get_hollowed_mesh();
|
||||||
if (has_hollowed)
|
// if (has_hollowed)
|
||||||
meshes.push_back(get_pool()->hollowed_mesh()->get_hollowed_mesh());
|
// meshes.push_back(get_pool()->hollowed_mesh()->get_hollowed_mesh());
|
||||||
|
|
||||||
if (meshes.empty())
|
if (meshes.empty())
|
||||||
for (const ModelVolume* mv : mo->volumes)
|
for (const ModelVolume* mv : mo->volumes)
|
||||||
@ -412,8 +415,8 @@ void ObjectClipper::on_update()
|
|||||||
}
|
}
|
||||||
m_old_meshes = meshes;
|
m_old_meshes = meshes;
|
||||||
|
|
||||||
if (has_hollowed)
|
// if (has_hollowed)
|
||||||
m_clippers.front()->set_negative_mesh(*get_pool()->hollowed_mesh()->get_hollowed_interior());
|
// m_clippers.front()->set_negative_mesh(*get_pool()->hollowed_mesh()->get_hollowed_interior());
|
||||||
|
|
||||||
m_active_inst_bb_radius =
|
m_active_inst_bb_radius =
|
||||||
mo->instance_bounding_box(get_pool()->selection_info()->get_active_instance()).radius();
|
mo->instance_bounding_box(get_pool()->selection_info()->get_active_instance()).radius();
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "slic3r/GUI/MeshUtils.hpp"
|
#include "slic3r/GUI/MeshUtils.hpp"
|
||||||
#include "libslic3r/SLA/Hollowing.hpp"
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
class ModelObject;
|
class ModelObject;
|
||||||
|
class SLAPrintObject;
|
||||||
class ModelVolume;
|
class ModelVolume;
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
@ -85,7 +85,7 @@ public:
|
|||||||
// Getters for the data that need to be accessed from the gizmos directly.
|
// Getters for the data that need to be accessed from the gizmos directly.
|
||||||
CommonGizmosDataObjects::SelectionInfo* selection_info() const;
|
CommonGizmosDataObjects::SelectionInfo* selection_info() const;
|
||||||
CommonGizmosDataObjects::InstancesHider* instances_hider() const;
|
CommonGizmosDataObjects::InstancesHider* instances_hider() const;
|
||||||
CommonGizmosDataObjects::HollowedMesh* hollowed_mesh() const;
|
// CommonGizmosDataObjects::HollowedMesh* hollowed_mesh() const;
|
||||||
CommonGizmosDataObjects::Raycaster* raycaster() const;
|
CommonGizmosDataObjects::Raycaster* raycaster() const;
|
||||||
CommonGizmosDataObjects::ObjectClipper* object_clipper() const;
|
CommonGizmosDataObjects::ObjectClipper* object_clipper() const;
|
||||||
CommonGizmosDataObjects::SupportsClipper* supports_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
|
// Returns a non-null pointer if the selection is a single full instance
|
||||||
ModelObject* model_object() const { return m_model_object; }
|
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
|
// Returns a non-null pointer if the selection is a single volume
|
||||||
ModelVolume* model_volume() const { return m_model_volume; }
|
ModelVolume* model_volume() const { return m_model_volume; }
|
||||||
int get_active_instance() const;
|
int get_active_instance() const;
|
||||||
@ -169,6 +170,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ModelObject* m_model_object = nullptr;
|
ModelObject* m_model_object = nullptr;
|
||||||
|
const SLAPrintObject *m_print_object = nullptr;
|
||||||
ModelVolume* m_model_volume = nullptr;
|
ModelVolume* m_model_volume = nullptr;
|
||||||
// int m_active_inst = -1;
|
// int m_active_inst = -1;
|
||||||
float m_z_shift = 0.f;
|
float m_z_shift = 0.f;
|
||||||
@ -201,32 +203,32 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HollowedMesh : public CommonGizmosDataBase
|
//class HollowedMesh : public CommonGizmosDataBase
|
||||||
{
|
//{
|
||||||
public:
|
//public:
|
||||||
explicit HollowedMesh(CommonGizmosDataPool* cgdp)
|
// explicit HollowedMesh(CommonGizmosDataPool* cgdp)
|
||||||
: CommonGizmosDataBase(cgdp) {}
|
// : CommonGizmosDataBase(cgdp) {}
|
||||||
#ifndef NDEBUG
|
//#ifndef NDEBUG
|
||||||
CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
|
// CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
|
||||||
#endif // NDEBUG
|
//#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_mesh() const;
|
||||||
const TriangleMesh* get_hollowed_interior() const;
|
// const TriangleMesh* get_hollowed_interior() const;
|
||||||
|
|
||||||
protected:
|
//protected:
|
||||||
void on_update() override;
|
// void on_update() override;
|
||||||
void on_release() override;
|
// void on_release() override;
|
||||||
|
|
||||||
private:
|
//private:
|
||||||
std::unique_ptr<TriangleMesh> m_hollowed_mesh_transformed;
|
// std::unique_ptr<TriangleMesh> m_hollowed_mesh_transformed;
|
||||||
std::unique_ptr<TriangleMesh> m_hollowed_interior_transformed;
|
// std::unique_ptr<TriangleMesh> m_hollowed_interior_transformed;
|
||||||
size_t m_old_hollowing_timestamp = 0;
|
// size_t m_old_hollowing_timestamp = 0;
|
||||||
int m_print_object_idx = -1;
|
// int m_print_object_idx = -1;
|
||||||
int m_print_objects_count = 0;
|
// int m_print_objects_count = 0;
|
||||||
sla::DrainHoles m_drainholes;
|
// sla::DrainHoles m_drainholes;
|
||||||
};
|
//};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
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 (one_by_one) {
|
||||||
if ((type_3mf && !is_project_file) || (type_any_amf && !type_zip_amf))
|
if ((type_3mf && !is_project_file) || (type_any_amf && !type_zip_amf))
|
||||||
model.center_instances_around_point(this->bed.build_volume().bed_center());
|
model.center_instances_around_point(this->bed.build_volume().bed_center());
|
||||||
|
@ -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();
|
double closest_hit_squared_distance = std::numeric_limits<double>::max();
|
||||||
auto is_closest = [&closest_hit_squared_distance](const Camera& camera, const Vec3f& hit) {
|
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) {
|
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;
|
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>();
|
const Vec3f camera_forward = camera.get_dir_forward().cast<float>();
|
||||||
HitResult current_hit = { type };
|
HitResult current_hit = { type };
|
||||||
for (std::shared_ptr<SceneRaycasterItem> item : *raycasters) {
|
for (std::shared_ptr<SceneRaycasterItem> item : *raycasters) {
|
||||||
@ -214,6 +214,20 @@ std::vector<std::shared_ptr<SceneRaycasterItem>>* SceneRaycaster::get_raycasters
|
|||||||
return ret;
|
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)
|
int SceneRaycaster::base_id(EType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -89,10 +89,11 @@ public:
|
|||||||
void remove_raycaster(std::shared_ptr<SceneRaycasterItem> item);
|
void remove_raycaster(std::shared_ptr<SceneRaycasterItem> item);
|
||||||
|
|
||||||
std::vector<std::shared_ptr<SceneRaycasterItem>>* get_raycasters(EType type);
|
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; }
|
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
|
#if ENABLE_RAYCAST_PICKING_DEBUG
|
||||||
void render_hit(const Camera& camera);
|
void render_hit(const Camera& camera);
|
||||||
|
@ -62,18 +62,18 @@ Selection::VolumeCache::VolumeCache(const Geometry::Transformation& volume_trans
|
|||||||
|
|
||||||
bool Selection::Clipboard::is_sla_compliant() const
|
bool Selection::Clipboard::is_sla_compliant() const
|
||||||
{
|
{
|
||||||
if (m_mode == Selection::Volume)
|
// if (m_mode == Selection::Volume)
|
||||||
return false;
|
// return false;
|
||||||
|
|
||||||
for (const ModelObject* o : m_model->objects) {
|
// for (const ModelObject* o : m_model->objects) {
|
||||||
if (o->is_multiparts())
|
// if (o->is_multiparts())
|
||||||
return false;
|
// return false;
|
||||||
|
|
||||||
for (const ModelVolume* v : o->volumes) {
|
// for (const ModelVolume* v : o->volumes) {
|
||||||
if (v->is_modifier())
|
// if (v->is_modifier())
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -571,13 +571,13 @@ bool Selection::is_from_single_object() const
|
|||||||
|
|
||||||
bool Selection::is_sla_compliant() const
|
bool Selection::is_sla_compliant() const
|
||||||
{
|
{
|
||||||
if (m_mode == Volume)
|
// if (m_mode == Volume)
|
||||||
return false;
|
// return false;
|
||||||
|
|
||||||
for (unsigned int i : m_list) {
|
// for (unsigned int i : m_list) {
|
||||||
if ((*m_volumes)[i]->is_modifier)
|
// if ((*m_volumes)[i]->is_modifier)
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
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 old_printer_technology = m_presets->get_edited_preset().printer_technology();
|
||||||
PrinterTechnology new_printer_technology = new_printer_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;
|
canceled = true;
|
||||||
else {
|
else */{
|
||||||
struct PresetUpdate {
|
struct PresetUpdate {
|
||||||
Preset::Type tab_type;
|
Preset::Type tab_type;
|
||||||
PresetCollection *presets;
|
PresetCollection *presets;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user