Implemented reload of original mesh volume in case the SLA hollowing

step is no more valid.
This commit is contained in:
bubnikv 2020-02-03 12:55:38 +01:00 committed by Lukas Matena
parent 9ef65b23d8
commit f28d0ebc18
2 changed files with 72 additions and 59 deletions

View file

@ -313,33 +313,38 @@ public:
// Valid geometry_id should always be positive. // Valid geometry_id should always be positive.
std::pair<size_t, size_t> geometry_id; std::pair<size_t, size_t> geometry_id;
// An ID containing the extruder ID (used to select color). // An ID containing the extruder ID (used to select color).
int extruder_id; int extruder_id;
// Is this object selected?
bool selected; // Various boolean flags.
// Is this object disabled from selection? struct {
bool disabled; // Is this object selected?
// Is this object printable? bool selected : 1;
bool printable; // Is this object disabled from selection?
// Whether or not this volume is active for rendering bool disabled : 1;
bool is_active; // Is this object printable?
// Whether or not to use this volume when applying zoom_to_volumes() bool printable : 1;
bool zoom_to_volumes; // Whether or not this volume is active for rendering
// Wheter or not this volume is enabled for outside print volume detection in shader. bool is_active : 1;
bool shader_outside_printer_detection_enabled; // Whether or not to use this volume when applying zoom_to_volumes()
// Wheter or not this volume is outside print volume. bool zoom_to_volumes : 1;
bool is_outside; // Wheter or not this volume is enabled for outside print volume detection in shader.
bool shader_outside_printer_detection_enabled : 1;
// Wheter or not this volume is outside print volume.
bool is_outside : 1;
// Wheter or not this volume has been generated from a modifier
bool is_modifier : 1;
// Wheter or not this volume has been generated from the wipe tower
bool is_wipe_tower : 1;
// Wheter or not this volume has been generated from an extrusion path
bool is_extrusion_path : 1;
// Wheter or not to always render this volume using its own alpha
bool force_transparent : 1;
// Whether or not always use the volume's own color (not using SELECTED/HOVER/DISABLED/OUTSIDE)
bool force_native_color : 1;
};
// 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;
// Wheter or not this volume has been generated from a modifier
bool is_modifier;
// Wheter or not this volume has been generated from the wipe tower
bool is_wipe_tower;
// Wheter or not this volume has been generated from an extrusion path
bool is_extrusion_path;
// Wheter or not to always render this volume using its own alpha
bool force_transparent;
// Whether or not always use the volume's own color (not using SELECTED/HOVER/DISABLED/OUTSIDE)
bool force_native_color;
// Interleaved triangles & normals with indexed triangles & quads. // Interleaved triangles & normals with indexed triangles & quads.
GLIndexedVertexArray indexed_vertex_array; GLIndexedVertexArray indexed_vertex_array;

View file

@ -2143,8 +2143,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
const ModelObject *model_object = print_object->model_object(); const ModelObject *model_object = print_object->model_object();
// Find an index of the ModelObject // Find an index of the ModelObject
int object_idx; int object_idx;
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. // 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. // Find the object index of this print_object in the Model::objects list.
auto it = std::find(sla_print->model().objects.begin(), sla_print->model().objects.end(), model_object); auto it = std::find(sla_print->model().objects.begin(), sla_print->model().objects.end(), model_object);
@ -2163,39 +2161,49 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
assert(it != model_object->instances.end()); assert(it != model_object->instances.end());
int instance_idx = it - model_object->instances.begin(); int instance_idx = it - model_object->instances.begin();
for (size_t istep = 0; istep < sla_steps.size(); ++ istep) for (size_t istep = 0; istep < sla_steps.size(); ++ istep)
if (state.step[istep].state == PrintStateBase::DONE) { if (sla_steps[istep] == slaposHollowing) {
if (sla_steps[istep] == slaposHollowing) { // Hollowing is a special case, where the mesh from the backend is being loaded into the 1st volume of an instance,
// Check whether there is a main object mesh, which we may update with the hollowed mesh. // not into its own GLVolume.
ModelVolumeState key(model_object->volumes.front()->id(), instance.instance_id); // There shall always be such a GLVolume allocated.
auto it = std::lower_bound(model_volume_state.begin(), model_volume_state.end(), key, model_volume_state_lower); ModelVolumeState key(model_object->volumes.front()->id(), instance.instance_id);
assert(it != model_volume_state.end() && it->geometry_id == key.geometry_id); auto it = std::lower_bound(model_volume_state.begin(), model_volume_state.end(), key, model_volume_state_lower);
assert(!it->new_geometry()); assert(it != model_volume_state.end() && it->geometry_id == key.geometry_id);
GLVolume& volume = *m_volumes.volumes[it->volume_idx]; assert(!it->new_geometry());
TriangleMesh mesh = print_object->get_mesh(slaposHollowing); GLVolume &volume = *m_volumes.volumes[it->volume_idx];
if (!mesh.empty()) { if (! volume.offsets.empty() && state.step[istep].timestamp != volume.offsets.front()) {
Transform3d t = sla_print->sla_trafo(*m_model->objects[volume.object_idx()]); // The backend either produced a new hollowed mesh, or it invalidated the one that the front end has seen.
mesh.transform(t.inverse()); volume.indexed_vertex_array.release_geometry();
volume.indexed_vertex_array.release_geometry(); if (state.step[istep].state == PrintStateBase::DONE) {
TriangleMesh mesh = print_object->get_mesh(slaposHollowing);
assert(! mesh.empty());
mesh.transform(sla_print->sla_trafo(*m_model->objects[volume.object_idx()]).inverse());
volume.indexed_vertex_array.load_mesh(mesh); volume.indexed_vertex_array.load_mesh(mesh);
volume.finalize_geometry(true); } else {
} // Reload the original volume.
volume.indexed_vertex_array.load_mesh(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh());
}
volume.finalize_geometry(true);
}
//FIXME it is an ugly hack to write the timestamp into the "offsets" field to not have to add another member variable
// to the GLVolume. We should refactor GLVolume significantly, so that the GLVolume will not contain member variables
// of various concenrs (model vs. 3D print path).
volume.offsets = { state.step[istep].timestamp };
} else if (state.step[istep].state == PrintStateBase::DONE) {
// Check whether there is an existing auxiliary volume to be updated, or a new auxiliary volume to be created.
ModelVolumeState key(state.step[istep].timestamp, instance.instance_id.id);
auto it = std::lower_bound(aux_volume_state.begin(), aux_volume_state.end(), key, model_volume_state_lower);
assert(it != aux_volume_state.end() && it->geometry_id == key.geometry_id);
if (it->new_geometry()) {
// This can be an SLA support structure that should not be rendered (in case someone used undo
// to revert to before it was generated). If that's the case, we should not generate anything.
if (model_object->sla_points_status != sla::PointsStatus::NoPoints)
instances[istep].emplace_back(std::pair<size_t, size_t>(instance_idx, print_instance_idx));
else
shift_zs[object_idx] = 0.;
} else { } else {
// Check whether there is an existing auxiliary volume to be updated, or a new auxiliary volume to be created. // Recycling an old GLVolume. Update the Object/Instance indices into the current Model.
ModelVolumeState key(state.step[istep].timestamp, instance.instance_id.id); m_volumes.volumes[it->volume_idx]->composite_id = GLVolume::CompositeID(object_idx, m_volumes.volumes[it->volume_idx]->volume_idx(), instance_idx);
auto it = std::lower_bound(aux_volume_state.begin(), aux_volume_state.end(), key, model_volume_state_lower); m_volumes.volumes[it->volume_idx]->set_instance_transformation(model_object->instances[instance_idx]->get_transformation());
assert(it != aux_volume_state.end() && it->geometry_id == key.geometry_id);
if (it->new_geometry()) {
// This can be an SLA support structure that should not be rendered (in case someone used undo
// to revert to before it was generated). If that's the case, we should not generate anything.
if (model_object->sla_points_status != sla::PointsStatus::NoPoints)
instances[istep].emplace_back(std::pair<size_t, size_t>(instance_idx, print_instance_idx));
else
shift_zs[object_idx] = 0.;
} else {
// Recycling an old GLVolume. Update the Object/Instance indices into the current Model.
m_volumes.volumes[it->volume_idx]->composite_id = GLVolume::CompositeID(object_idx, m_volumes.volumes[it->volume_idx]->volume_idx(), instance_idx);
m_volumes.volumes[it->volume_idx]->set_instance_transformation(model_object->instances[instance_idx]->get_transformation());
}
} }
} }
} }