Use shared pointers for SLA preview data
To be able to survive a sudden cancellation and subsequent cleanup in the background thread
This commit is contained in:
parent
bb82ce90c9
commit
cf4f07c220
@ -1014,26 +1014,15 @@ const TriangleMesh& SLAPrintObject::pad_mesh() const
|
|||||||
return EMPTY_MESH;
|
return EMPTY_MESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TriangleMesh &SLAPrintObject::get_mesh_to_print() const
|
const std::shared_ptr<const indexed_triangle_set> &
|
||||||
|
SLAPrintObject::get_mesh_to_print() const
|
||||||
{
|
{
|
||||||
const TriangleMesh *ret = nullptr;
|
|
||||||
|
|
||||||
int s = last_completed_step();
|
int s = last_completed_step();
|
||||||
|
|
||||||
if (s == slaposCount)
|
while (s > 0 && ! m_preview_meshes[s])
|
||||||
ret = &EMPTY_MESH;
|
|
||||||
|
|
||||||
while (s >= 0 && !ret) {
|
|
||||||
if (!m_preview_meshes[s].empty())
|
|
||||||
ret = &m_preview_meshes[s];
|
|
||||||
|
|
||||||
--s;
|
--s;
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret)
|
return m_preview_meshes[s];
|
||||||
ret = &EMPTY_MESH;
|
|
||||||
|
|
||||||
return *ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<csg::CSGPart> SLAPrintObject::get_parts_to_slice() const
|
std::vector<csg::CSGPart> SLAPrintObject::get_parts_to_slice() const
|
||||||
|
@ -121,7 +121,7 @@ public:
|
|||||||
|
|
||||||
// Get the mesh that is going to be printed with all the modifications
|
// Get the mesh that is going to be printed with all the modifications
|
||||||
// like hollowing and drilled holes.
|
// like hollowing and drilled holes.
|
||||||
const TriangleMesh & get_mesh_to_print() const;
|
const std::shared_ptr<const indexed_triangle_set>& get_mesh_to_print() const;
|
||||||
|
|
||||||
std::vector<csg::CSGPart> get_parts_to_slice() const;
|
std::vector<csg::CSGPart> get_parts_to_slice() const;
|
||||||
|
|
||||||
@ -379,7 +379,7 @@ private:
|
|||||||
// all its holes and cavities, negatives and positive volumes unified.
|
// all its holes and cavities, negatives and positive volumes unified.
|
||||||
// Essentially this should be a m_mesh_to_slice after the CSG operations
|
// Essentially this should be a m_mesh_to_slice after the CSG operations
|
||||||
// or an approximation of that.
|
// or an approximation of that.
|
||||||
std::array<TriangleMesh, SLAPrintObjectStep::slaposCount> m_preview_meshes;
|
std::array<std::shared_ptr<const indexed_triangle_set>, SLAPrintObjectStep::slaposCount + 1> m_preview_meshes;
|
||||||
|
|
||||||
class HollowingData
|
class HollowingData
|
||||||
{
|
{
|
||||||
|
@ -228,7 +228,11 @@ void SLAPrint::Steps::generate_preview(SLAPrintObject &po, SLAPrintObjectStep st
|
|||||||
handled = true;
|
handled = true;
|
||||||
} else if (step == slaposDrillHoles && is_pure_model) {
|
} else if (step == slaposDrillHoles && is_pure_model) {
|
||||||
if (po.m_model_object->sla_drain_holes.empty()) {
|
if (po.m_model_object->sla_drain_holes.empty()) {
|
||||||
m = po.m_preview_meshes[slaposHollowing].its;
|
// Get the last printable preview
|
||||||
|
auto &meshp = po.get_mesh_to_print();
|
||||||
|
if (meshp)
|
||||||
|
m = *(meshp);
|
||||||
|
|
||||||
handled = true;
|
handled = true;
|
||||||
} else if (can_hollow) {
|
} else if (can_hollow) {
|
||||||
m = csgmesh_merge_positive_parts(r);
|
m = csgmesh_merge_positive_parts(r);
|
||||||
@ -286,7 +290,11 @@ void SLAPrint::Steps::generate_preview(SLAPrintObject &po, SLAPrintObjectStep st
|
|||||||
m = generate_preview_vdb(po, step);
|
m = generate_preview_vdb(po, step);
|
||||||
}
|
}
|
||||||
|
|
||||||
po.m_preview_meshes[step] = TriangleMesh{std::move(m)};
|
assert(po.m_preview_meshes[step].empty());
|
||||||
|
|
||||||
|
if (!m.empty())
|
||||||
|
po.m_preview_meshes[step] =
|
||||||
|
std::make_shared<const indexed_triangle_set>(std::move(m));
|
||||||
|
|
||||||
for (size_t i = size_t(step) + 1; i < slaposCount; ++i)
|
for (size_t i = size_t(step) + 1; i < slaposCount; ++i)
|
||||||
{
|
{
|
||||||
@ -604,11 +612,12 @@ void SLAPrint::Steps::support_points(SLAPrintObject &po)
|
|||||||
// If supports are disabled, we can skip the model scan.
|
// If supports are disabled, we can skip the model scan.
|
||||||
if(!po.m_config.supports_enable.getBool()) return;
|
if(!po.m_config.supports_enable.getBool()) return;
|
||||||
|
|
||||||
if (!po.m_supportdata)
|
if (!po.m_supportdata) {
|
||||||
|
auto &meshp = po.get_mesh_to_print();
|
||||||
|
assert(meshp);
|
||||||
po.m_supportdata =
|
po.m_supportdata =
|
||||||
std::make_unique<SLAPrintObject::SupportData>(
|
std::make_unique<SLAPrintObject::SupportData>(*meshp);
|
||||||
po.get_mesh_to_print()
|
}
|
||||||
);
|
|
||||||
|
|
||||||
po.m_supportdata->input.zoffset = csgmesh_positive_bb(po.m_mesh_to_slice)
|
po.m_supportdata->input.zoffset = csgmesh_positive_bb(po.m_mesh_to_slice)
|
||||||
.min.z();
|
.min.z();
|
||||||
@ -750,11 +759,12 @@ void SLAPrint::Steps::generate_pad(SLAPrintObject &po) {
|
|||||||
// repeated)
|
// repeated)
|
||||||
|
|
||||||
if(po.m_config.pad_enable.getBool()) {
|
if(po.m_config.pad_enable.getBool()) {
|
||||||
if (!po.m_supportdata)
|
if (!po.m_supportdata) {
|
||||||
|
auto &meshp = po.get_mesh_to_print();
|
||||||
|
assert(meshp);
|
||||||
po.m_supportdata =
|
po.m_supportdata =
|
||||||
std::make_unique<SLAPrintObject::SupportData>(
|
std::make_unique<SLAPrintObject::SupportData>(*meshp);
|
||||||
po.get_mesh_to_print()
|
}
|
||||||
);
|
|
||||||
|
|
||||||
// Get the distilled pad configuration from the config
|
// Get the distilled pad configuration from the config
|
||||||
// (Again, despite it was retrieved in the previous step. Note that
|
// (Again, despite it was retrieved in the previous step. Note that
|
||||||
|
@ -6628,7 +6628,7 @@ void GLCanvas3D::_load_sla_shells()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
auto add_volume = [this](const SLAPrintObject &object, int volume_id, const SLAPrintObject::Instance& instance,
|
auto add_volume = [this](const SLAPrintObject &object, int volume_id, const SLAPrintObject::Instance& instance,
|
||||||
const TriangleMesh& mesh, const ColorRGBA& color, bool outside_printer_detection_enabled) {
|
const indexed_triangle_set& mesh, const ColorRGBA& color, bool outside_printer_detection_enabled) {
|
||||||
m_volumes.volumes.emplace_back(new GLVolume(color));
|
m_volumes.volumes.emplace_back(new GLVolume(color));
|
||||||
GLVolume& v = *m_volumes.volumes.back();
|
GLVolume& v = *m_volumes.volumes.back();
|
||||||
#if ENABLE_SMOOTH_NORMALS
|
#if ENABLE_SMOOTH_NORMALS
|
||||||
@ -6641,22 +6641,22 @@ void GLCanvas3D::_load_sla_shells()
|
|||||||
v.set_instance_offset(unscale(instance.shift.x(), instance.shift.y(), 0.0));
|
v.set_instance_offset(unscale(instance.shift.x(), instance.shift.y(), 0.0));
|
||||||
v.set_instance_rotation({ 0.0, 0.0, (double)instance.rotation });
|
v.set_instance_rotation({ 0.0, 0.0, (double)instance.rotation });
|
||||||
v.set_instance_mirror(X, object.is_left_handed() ? -1. : 1.);
|
v.set_instance_mirror(X, object.is_left_handed() ? -1. : 1.);
|
||||||
v.set_convex_hull(mesh.convex_hull_3d());
|
v.set_convex_hull(TriangleMesh{its_convex_hull(mesh)});
|
||||||
};
|
};
|
||||||
|
|
||||||
// adds objects' volumes
|
// adds objects' volumes
|
||||||
for (const SLAPrintObject* obj : print->objects()) {
|
for (const SLAPrintObject* obj : print->objects()) {
|
||||||
unsigned int initial_volumes_count = (unsigned int)m_volumes.volumes.size();
|
unsigned int initial_volumes_count = (unsigned int)m_volumes.volumes.size();
|
||||||
for (const SLAPrintObject::Instance& instance : obj->instances()) {
|
for (const SLAPrintObject::Instance& instance : obj->instances()) {
|
||||||
auto & m = obj->get_mesh_to_print();
|
std::shared_ptr<const indexed_triangle_set> m = obj->get_mesh_to_print();
|
||||||
if (!m.empty()) {
|
if (m && !m->empty()) {
|
||||||
add_volume(*obj, 0, instance, m, GLVolume::MODEL_COLOR[0], true);
|
add_volume(*obj, 0, instance, *m, GLVolume::MODEL_COLOR[0], true);
|
||||||
// Set the extruder_id and volume_id to achieve the same color as in the 3D scene when
|
// Set the extruder_id and volume_id to achieve the same color as in the 3D scene when
|
||||||
// through the update_volumes_colors_by_extruder() call.
|
// through the update_volumes_colors_by_extruder() call.
|
||||||
m_volumes.volumes.back()->extruder_id = obj->model_object()->volumes.front()->extruder_id();
|
m_volumes.volumes.back()->extruder_id = obj->model_object()->volumes.front()->extruder_id();
|
||||||
if (auto &tree_mesh = obj->support_mesh(); !tree_mesh.empty())
|
if (auto &tree_mesh = obj->support_mesh().its; !tree_mesh.empty())
|
||||||
add_volume(*obj, -int(slaposSupportTree), instance, tree_mesh, GLVolume::SLA_SUPPORT_COLOR, true);
|
add_volume(*obj, -int(slaposSupportTree), instance, tree_mesh, GLVolume::SLA_SUPPORT_COLOR, true);
|
||||||
if (auto &pad_mesh = obj->pad_mesh(); !pad_mesh.empty())
|
if (auto &pad_mesh = obj->pad_mesh().its; !pad_mesh.empty())
|
||||||
add_volume(*obj, -int(slaposPad), instance, pad_mesh, GLVolume::SLA_PAD_COLOR, false);
|
add_volume(*obj, -int(slaposPad), instance, pad_mesh, GLVolume::SLA_PAD_COLOR, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,8 @@ void GLGizmoHollow::data_changed()
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SLAPrintObject* po = m_c->selection_info()->print_object();
|
const SLAPrintObject* po = m_c->selection_info()->print_object();
|
||||||
if (po != nullptr && po->get_mesh_to_print().empty())
|
std::shared_ptr<const indexed_triangle_set> preview_mesh_ptr = po->get_mesh_to_print();
|
||||||
|
if (po != nullptr && (!preview_mesh_ptr || preview_mesh_ptr->empty()))
|
||||||
reslice_until_step(slaposAssembly);
|
reslice_until_step(slaposAssembly);
|
||||||
|
|
||||||
update_volumes();
|
update_volumes();
|
||||||
|
@ -48,7 +48,11 @@ void GLGizmoSlaBase::update_volumes()
|
|||||||
|
|
||||||
m_input_enabled = false;
|
m_input_enabled = false;
|
||||||
|
|
||||||
TriangleMesh backend_mesh = po->get_mesh_to_print();
|
TriangleMesh backend_mesh;
|
||||||
|
std::shared_ptr<const indexed_triangle_set> preview_mesh_ptr = po->get_mesh_to_print();
|
||||||
|
if (preview_mesh_ptr)
|
||||||
|
backend_mesh = TriangleMesh{*preview_mesh_ptr};
|
||||||
|
|
||||||
if (!backend_mesh.empty()) {
|
if (!backend_mesh.empty()) {
|
||||||
// The backend has generated a valid mesh. Use it
|
// The backend has generated a valid mesh. Use it
|
||||||
backend_mesh.transform(po->trafo().inverse());
|
backend_mesh.transform(po->trafo().inverse());
|
||||||
|
@ -261,7 +261,10 @@ void Raycaster::on_update()
|
|||||||
// For sla printers we use the mesh generated by the backend
|
// For sla printers we use the mesh generated by the backend
|
||||||
const SLAPrintObject* po = get_pool()->selection_info()->print_object();
|
const SLAPrintObject* po = get_pool()->selection_info()->print_object();
|
||||||
assert(po != nullptr);
|
assert(po != nullptr);
|
||||||
m_sla_mesh_cache = po->get_mesh_to_print();
|
std::shared_ptr<const indexed_triangle_set> preview_mesh_ptr = po->get_mesh_to_print();
|
||||||
|
if (preview_mesh_ptr)
|
||||||
|
m_sla_mesh_cache = TriangleMesh{*preview_mesh_ptr};
|
||||||
|
|
||||||
if (!m_sla_mesh_cache.empty()) {
|
if (!m_sla_mesh_cache.empty()) {
|
||||||
m_sla_mesh_cache.transform(po->trafo().inverse());
|
m_sla_mesh_cache.transform(po->trafo().inverse());
|
||||||
meshes.emplace_back(&m_sla_mesh_cache);
|
meshes.emplace_back(&m_sla_mesh_cache);
|
||||||
|
@ -6115,7 +6115,7 @@ void Plater::export_stl_obj(bool extended, bool selection_only)
|
|||||||
|
|
||||||
const SLAPrintObject *object = this->p->sla_print.get_print_object_by_model_object_id(mo.id());
|
const SLAPrintObject *object = this->p->sla_print.get_print_object_by_model_object_id(mo.id());
|
||||||
|
|
||||||
if (object->get_mesh_to_print().empty())
|
if (auto m = object->get_mesh_to_print(); !m || m->empty())
|
||||||
mesh = mesh_to_export_fff(mo, instance_id);
|
mesh = mesh_to_export_fff(mo, instance_id);
|
||||||
else {
|
else {
|
||||||
const Transform3d mesh_trafo_inv = object->trafo().inverse();
|
const Transform3d mesh_trafo_inv = object->trafo().inverse();
|
||||||
@ -6155,7 +6155,11 @@ void Plater::export_stl_obj(bool extended, bool selection_only)
|
|||||||
inst_mesh.merge(inst_supports_mesh);
|
inst_mesh.merge(inst_supports_mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
TriangleMesh inst_object_mesh = object->get_mesh_to_print();
|
std::shared_ptr<const indexed_triangle_set> m = object->get_mesh_to_print();
|
||||||
|
TriangleMesh inst_object_mesh;
|
||||||
|
if (m)
|
||||||
|
inst_object_mesh = TriangleMesh{*m};
|
||||||
|
|
||||||
inst_object_mesh.transform(mesh_trafo_inv);
|
inst_object_mesh.transform(mesh_trafo_inv);
|
||||||
inst_object_mesh.transform(inst_transform, is_left_handed);
|
inst_object_mesh.transform(inst_transform, is_left_handed);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user