WIP: Support of SLA suport & pad GLVolumes, couple of fixes.

This commit is contained in:
bubnikv 2018-11-17 17:23:56 +01:00
parent b59d5d083f
commit 74ba1eaa16
9 changed files with 75 additions and 14 deletions

View file

@ -79,7 +79,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model,
// Grab the lock for the Print / PrintObject milestones.
tbb::mutex::scoped_lock lock(this->state_mutex());
if(m_objects.empty() && model.objects.empty())
if (m_objects.empty() && model.objects.empty() && m_model.objects.empty())
return APPLY_STATUS_UNCHANGED;
// Temporary: just to have to correct layer height for the rasterization
@ -437,6 +437,32 @@ SLAPrintObject::SLAPrintObject(SLAPrint *print, ModelObject *model_object):
SLAPrintObject::~SLAPrintObject() {}
bool SLAPrintObject::has_mesh(SLAPrintObjectStep step) const
{
switch (step) {
case slaposSupportTree:
// return m_supportdata && m_supportdata->support_tree_ptr && ! m_supportdata->support_tree_ptr->get().merged_mesh().empty();
return ! this->support_mesh().empty();
case slaposBasePool:
// return m_supportdata && m_supportdata->support_tree_ptr && ! m_supportdata->support_tree_ptr->get_pad().empty();
return ! this->pad_mesh().empty();
default:
return false;
}
}
TriangleMesh SLAPrintObject::get_mesh(SLAPrintObjectStep step) const
{
switch (step) {
case slaposSupportTree:
return this->support_mesh();
case slaposBasePool:
return this->pad_mesh();
default:
return TriangleMesh();
}
}
TriangleMesh SLAPrintObject::support_mesh() const
{
TriangleMesh trm;

View file

@ -48,6 +48,9 @@ public:
};
const std::vector<Instance>& instances() const { return m_instances; }
bool has_mesh(SLAPrintObjectStep step) const;
TriangleMesh get_mesh(SLAPrintObjectStep step) const;
// Get a support mesh centered around origin in XY, and with zero rotation around Z applied.
// Support mesh is only valid if this->is_step_done(slaposSupportTree) is true.
TriangleMesh support_mesh() const;

View file

@ -521,6 +521,7 @@ BoundingBoxf3 TriangleMesh::transformed_bounding_box(const Transform3d& t) const
if (stl.stats.shared_vertices > 0)
{
assert(stl.v_shared != nullptr);
stl_vertex* vertex_ptr = stl.v_shared;
for (int i = 0; i < stl.stats.shared_vertices; ++i)
{

View file

@ -65,6 +65,7 @@ public:
void reset_repair_stats();
bool needed_repair() const;
size_t facets_count() const { return this->stl.stats.number_of_facets; }
bool empty() const { return this->facets_count() == 0; }
// Returns true, if there are two and more connected patches in the mesh.
// Returns false, if one or zero connected patch is in the mesh.

View file

@ -216,6 +216,7 @@ GLVolume::GLVolume(float r, float g, float b, float a)
#endif // ENABLE_MODELVOLUME_TRANSFORM
, m_transformed_convex_hull_bounding_box_dirty(true)
, m_convex_hull(nullptr)
, m_convex_hull_owned(false)
// geometry_id == 0 -> invalid
, geometry_id(std::pair<size_t, size_t>(0, 0))
, extruder_id(0)
@ -239,6 +240,12 @@ GLVolume::GLVolume(float r, float g, float b, float a)
set_render_color(r, g, b, a);
}
GLVolume::~GLVolume()
{
if (m_convex_hull_owned)
delete m_convex_hull;
}
void GLVolume::set_render_color(float r, float g, float b, float a)
{
render_color[0] = r;
@ -365,9 +372,10 @@ void GLVolume::set_mirror(Axis axis, double mirror)
}
#endif // !ENABLE_MODELVOLUME_TRANSFORM
void GLVolume::set_convex_hull(const TriangleMesh& convex_hull)
void GLVolume::set_convex_hull(const TriangleMesh *convex_hull, bool owned)
{
m_convex_hull = &convex_hull;
m_convex_hull = convex_hull;
m_convex_hull_owned = owned;
}
#if !ENABLE_MODELVOLUME_TRANSFORM
@ -779,7 +787,8 @@ int GLVolumeCollection::load_object_volume(
v.composite_id = GLVolume::CompositeID(obj_idx, volume_idx, instance_idx);
if (model_volume->is_model_part())
{
v.set_convex_hull(model_volume->get_convex_hull());
// GLVolume will reference a convex hull from model_volume!
v.set_convex_hull(&model_volume->get_convex_hull(), false);
if (extruder_id != -1)
v.extruder_id = extruder_id;
v.layer_height_texture = layer_height_texture;
@ -808,6 +817,8 @@ void GLVolumeCollection::load_object_auxiliary(
// pairs of <instance_idx, print_instance_idx>
const std::vector<std::pair<size_t, size_t>> &instances,
SLAPrintObjectStep milestone,
// Timestamp of the last change of the milestone
size_t timestamp,
bool use_VBOs)
{
assert(print_object->is_step_done(milestone));
@ -835,7 +846,9 @@ void GLVolumeCollection::load_object_auxiliary(
v.bounding_box = v.indexed_vertex_array.bounding_box();
v.indexed_vertex_array.finalize_geometry(use_VBOs);
v.composite_id = GLVolume::CompositeID(obj_idx, -1, (int)instance_idx.first);
v.set_convex_hull(convex_hull);
v.geometry_id = std::pair<size_t, size_t>(timestamp, model_instance.id().id);
// Create a copy of the convex hull mesh for each instance. Use a move operator on the last instance.
v.set_convex_hull((&instance_idx == &instances.back()) ? new TriangleMesh(std::move(convex_hull)) : new TriangleMesh(convex_hull), true);
v.is_modifier = false;
v.shader_outside_printer_detection_enabled = true;
//FIXME adjust with print_instance?

View file

@ -256,6 +256,7 @@ public:
GLVolume(float r = 1.f, float g = 1.f, float b = 1.f, float a = 1.f);
GLVolume(const float *rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {}
~GLVolume();
private:
#if ENABLE_MODELVOLUME_TRANSFORM
@ -280,7 +281,9 @@ private:
// Whether or not is needed to recalculate the transformed bounding box.
mutable bool m_transformed_bounding_box_dirty;
// Pointer to convex hull of the original mesh, if any.
// This object may or may not own the convex hull instance based on m_convex_hull_owned
const TriangleMesh* m_convex_hull;
bool m_convex_hull_owned;
// Bounding box of this volume, in unscaled coordinates.
mutable BoundingBoxf3 m_transformed_convex_hull_bounding_box;
// Whether or not is needed to recalculate the transformed convex hull bounding box.
@ -422,7 +425,7 @@ public:
void set_offset(const Vec3d& offset);
#endif // ENABLE_MODELVOLUME_TRANSFORM
void set_convex_hull(const TriangleMesh& convex_hull);
void set_convex_hull(const TriangleMesh *convex_hull, bool owned);
int object_idx() const { return this->composite_id.object_id; }
int volume_idx() const { return this->composite_id.volume_id; }
@ -525,6 +528,8 @@ public:
// pairs of <instance_idx, print_instance_idx>
const std::vector<std::pair<size_t, size_t>> &instances,
SLAPrintObjectStep milestone,
// Timestamp of the last change of the milestone
size_t timestamp,
bool use_VBOs);
int load_wipe_tower_preview(

View file

@ -1867,7 +1867,10 @@ void GLCanvas3D::Selection::erase()
for (unsigned int i : m_list)
{
const GLVolume* v = (*m_volumes)[i];
volumes_idxs.insert(std::make_pair(v->object_idx(), v->volume_idx()));
// Only remove volumes associated with ModelVolumes from the object list.
// Temporary meshes (SLA supports or pads) are not managed by the object list.
if (v->volume_idx() >= 0)
volumes_idxs.insert(std::make_pair(v->object_idx(), v->volume_idx()));
}
std::vector<ItemForDelete> items;
@ -3803,9 +3806,15 @@ void GLCanvas3D::reload_scene(bool force)
SLASupportState state;
for (size_t istep = 0; istep < sla_steps.size(); ++ istep) {
state.step[istep] = print_object->step_state_with_timestamp(sla_steps[istep]);
if (state.step[istep].state == PrintStateBase::DONE)
for (const ModelInstance *model_instance : print_object->model_object()->instances)
aux_volume_state.emplace_back(state.step[istep].timestamp, model_instance->id());
if (state.step[istep].state == PrintStateBase::DONE) {
if (! print_object->has_mesh(sla_steps[istep]))
// Consider the DONE step without a valid mesh as invalid for the purpose
// of mesh visualization.
state.step[istep].state = PrintStateBase::INVALID;
else
for (const ModelInstance *model_instance : print_object->model_object()->instances)
aux_volume_state.emplace_back(state.step[istep].timestamp, model_instance->id());
}
}
sla_support_state.emplace_back(state);
}
@ -3911,7 +3920,7 @@ void GLCanvas3D::reload_scene(bool force)
const ModelObject *model_object = print_object->model_object();
// Find an index of the ModelObject
int object_idx;
if (! std::all_of(state.step.begin(), state.step.end(), [](const PrintStateBase::StateWithTimeStamp &state){ return state.state != PrintStateBase::DONE; }))
if (std::all_of(state.step.begin(), state.step.end(), [](const PrintStateBase::StateWithTimeStamp &state){ return state.state != PrintStateBase::DONE; }))
continue;
// There may be new SLA volumes added to the scene for this print_object.
// Find the object index of this print_object in the Model::objects list.
@ -3942,7 +3951,7 @@ void GLCanvas3D::reload_scene(bool force)
}
for (size_t istep = 0; istep < sla_steps.size(); ++ istep)
if (! instances[istep].empty())
m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], m_use_VBOs && m_initialized);
m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp, m_use_VBOs && m_initialized);
}
}

View file

@ -1304,7 +1304,10 @@ void ObjectList::update_selections()
const auto gl_vol = selection.get_volume(idx);
if (selection.is_multiple_full_object())
sels.Add(m_objects_model->GetItemById(gl_vol->object_idx()));
else
else if (gl_vol->volume_idx() >= 0)
// Only add GLVolumes with non-negative volume_ids. GLVolumes with negative volume ids
// are not associated with ModelVolumes, but they are temporarily generated by the backend
// (for example, SLA supports or SLA pad).
sels.Add(m_objects_model->GetItemByVolumeId(gl_vol->object_idx(), gl_vol->volume_idx()));
}
}

View file

@ -200,7 +200,7 @@ DECLARE_VARIANT_OBJECT(PrusaDataViewBitmapText)
// PrusaObjectDataViewModelNode: a node inside PrusaObjectDataViewModel
// ----------------------------------------------------------------------------
enum ItemType{
enum ItemType {
itUndef = 0,
itObject = 1,
itVolume = 2,