SPE-1654 - Out of printbed detection applied only to selected volumes when the selection is not empty
This commit is contained in:
parent
00e35807ab
commit
15bd82edc3
@ -833,64 +833,6 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, ModelInstanceEPrintVolumeState *out_state) const
|
|
||||||
{
|
|
||||||
const Model& model = GUI::wxGetApp().plater()->model();
|
|
||||||
auto volume_below = [](GLVolume& volume) -> bool
|
|
||||||
{ return volume.object_idx() != -1 && volume.volume_idx() != -1 && volume.is_below_printbed(); };
|
|
||||||
// Volume is partially below the print bed, thus a pre-calculated convex hull cannot be used.
|
|
||||||
auto volume_sinking = [](GLVolume& volume) -> bool
|
|
||||||
{ return volume.object_idx() != -1 && volume.volume_idx() != -1 && volume.is_sinking(); };
|
|
||||||
// Cached bounding box of a volume above the print bed.
|
|
||||||
auto volume_bbox = [volume_sinking](GLVolume& volume) -> BoundingBoxf3
|
|
||||||
{ return volume_sinking(volume) ? volume.transformed_non_sinking_bounding_box() : volume.transformed_convex_hull_bounding_box(); };
|
|
||||||
// Cached 3D convex hull of a volume above the print bed.
|
|
||||||
auto volume_convex_mesh = [volume_sinking, &model](GLVolume& volume) -> const TriangleMesh&
|
|
||||||
{ return volume_sinking(volume) ? model.objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : *volume.convex_hull(); };
|
|
||||||
|
|
||||||
ModelInstanceEPrintVolumeState overall_state = ModelInstancePVS_Inside;
|
|
||||||
bool contained_min_one = false;
|
|
||||||
|
|
||||||
for (GLVolume* volume : this->volumes)
|
|
||||||
if (! volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (! volume->is_wipe_tower && volume->composite_id.volume_id >= 0))) {
|
|
||||||
BuildVolume::ObjectState state;
|
|
||||||
if (volume_below(*volume))
|
|
||||||
state = BuildVolume::ObjectState::Below;
|
|
||||||
else {
|
|
||||||
switch (build_volume.type()) {
|
|
||||||
case BuildVolume::Type::Rectangle:
|
|
||||||
//FIXME this test does not evaluate collision of a build volume bounding box with non-convex objects.
|
|
||||||
state = build_volume.volume_state_bbox(volume_bbox(*volume));
|
|
||||||
break;
|
|
||||||
case BuildVolume::Type::Circle:
|
|
||||||
case BuildVolume::Type::Convex:
|
|
||||||
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
|
|
||||||
case BuildVolume::Type::Custom:
|
|
||||||
state = build_volume.object_state(volume_convex_mesh(*volume).its, volume->world_matrix().cast<float>(), volume_sinking(*volume));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Ignore, don't produce any collision.
|
|
||||||
state = BuildVolume::ObjectState::Inside;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert(state != BuildVolume::ObjectState::Below);
|
|
||||||
}
|
|
||||||
volume->is_outside = state != BuildVolume::ObjectState::Inside;
|
|
||||||
if (volume->printable) {
|
|
||||||
if (overall_state == ModelInstancePVS_Inside && volume->is_outside)
|
|
||||||
overall_state = ModelInstancePVS_Fully_Outside;
|
|
||||||
if (overall_state == ModelInstancePVS_Fully_Outside && volume->is_outside && state == BuildVolume::ObjectState::Colliding)
|
|
||||||
overall_state = ModelInstancePVS_Partly_Outside;
|
|
||||||
contained_min_one |= !volume->is_outside;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_state != nullptr)
|
|
||||||
*out_state = overall_state;
|
|
||||||
|
|
||||||
return contained_min_one;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLVolumeCollection::reset_outside_state()
|
void GLVolumeCollection::reset_outside_state()
|
||||||
{
|
{
|
||||||
for (GLVolume* volume : this->volumes) {
|
for (GLVolume* volume : this->volumes) {
|
||||||
|
@ -450,9 +450,6 @@ public:
|
|||||||
void set_show_sinking_contours(bool show) { m_show_sinking_contours = show; }
|
void set_show_sinking_contours(bool show) { m_show_sinking_contours = show; }
|
||||||
void set_show_non_manifold_edges(bool show) { m_show_non_manifold_edges = show; }
|
void set_show_non_manifold_edges(bool show) { m_show_non_manifold_edges = show; }
|
||||||
|
|
||||||
// returns true if all the volumes are completely contained in the print volume
|
|
||||||
// returns the containment state in the given out_state, if non-null
|
|
||||||
bool check_outside_state(const Slic3r::BuildVolume& build_volume, ModelInstanceEPrintVolumeState* out_state) const;
|
|
||||||
void reset_outside_state();
|
void reset_outside_state();
|
||||||
|
|
||||||
void update_colors_by_extruder(const DynamicPrintConfig* config);
|
void update_colors_by_extruder(const DynamicPrintConfig* config);
|
||||||
|
@ -1511,11 +1511,85 @@ void GLCanvas3D::reset_volumes()
|
|||||||
ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state() const
|
ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state() const
|
||||||
{
|
{
|
||||||
ModelInstanceEPrintVolumeState state = ModelInstanceEPrintVolumeState::ModelInstancePVS_Inside;
|
ModelInstanceEPrintVolumeState state = ModelInstanceEPrintVolumeState::ModelInstancePVS_Inside;
|
||||||
if (m_initialized)
|
if (m_initialized && !m_volumes.empty())
|
||||||
m_volumes.check_outside_state(m_bed.build_volume(), &state);
|
check_volumes_outside_state(m_bed.build_volume(), &state);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GLCanvas3D::check_volumes_outside_state(const Slic3r::BuildVolume& build_volume, ModelInstanceEPrintVolumeState* out_state) const
|
||||||
|
{
|
||||||
|
auto volume_below = [](GLVolume& volume) -> bool
|
||||||
|
{ return volume.object_idx() != -1 && volume.volume_idx() != -1 && volume.is_below_printbed(); };
|
||||||
|
// Volume is partially below the print bed, thus a pre-calculated convex hull cannot be used.
|
||||||
|
auto volume_sinking = [](GLVolume& volume) -> bool
|
||||||
|
{ return volume.object_idx() != -1 && volume.volume_idx() != -1 && volume.is_sinking(); };
|
||||||
|
// Cached bounding box of a volume above the print bed.
|
||||||
|
auto volume_bbox = [volume_sinking](GLVolume& volume) -> BoundingBoxf3
|
||||||
|
{ return volume_sinking(volume) ? volume.transformed_non_sinking_bounding_box() : volume.transformed_convex_hull_bounding_box(); };
|
||||||
|
// Cached 3D convex hull of a volume above the print bed.
|
||||||
|
auto volume_convex_mesh = [this, volume_sinking](GLVolume& volume) -> const TriangleMesh&
|
||||||
|
{ return volume_sinking(volume) ? m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : *volume.convex_hull(); };
|
||||||
|
|
||||||
|
auto volumes_to_process_idxs = [this]() {
|
||||||
|
std::vector<unsigned int> ret;
|
||||||
|
if (m_selection.is_empty()) {
|
||||||
|
ret = std::vector<unsigned int>(m_volumes.volumes.size());
|
||||||
|
std::iota(ret.begin(), ret.end(), 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const GUI::Selection::IndicesList& selected_volume_idxs = m_selection.get_volume_idxs();
|
||||||
|
ret.assign(selected_volume_idxs.begin(), selected_volume_idxs.end());
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
ModelInstanceEPrintVolumeState overall_state = ModelInstancePVS_Inside;
|
||||||
|
bool contained_min_one = false;
|
||||||
|
|
||||||
|
const std::vector<unsigned int> volumes_idxs = volumes_to_process_idxs();
|
||||||
|
|
||||||
|
for (unsigned int vol_idx : volumes_idxs) {
|
||||||
|
GLVolume* volume = m_volumes.volumes[vol_idx];
|
||||||
|
if (!volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (!volume->is_wipe_tower && volume->composite_id.volume_id >= 0))) {
|
||||||
|
BuildVolume::ObjectState state;
|
||||||
|
if (volume_below(*volume))
|
||||||
|
state = BuildVolume::ObjectState::Below;
|
||||||
|
else {
|
||||||
|
switch (build_volume.type()) {
|
||||||
|
case BuildVolume::Type::Rectangle:
|
||||||
|
//FIXME this test does not evaluate collision of a build volume bounding box with non-convex objects.
|
||||||
|
state = build_volume.volume_state_bbox(volume_bbox(*volume));
|
||||||
|
break;
|
||||||
|
case BuildVolume::Type::Circle:
|
||||||
|
case BuildVolume::Type::Convex:
|
||||||
|
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
|
||||||
|
case BuildVolume::Type::Custom:
|
||||||
|
state = build_volume.object_state(volume_convex_mesh(*volume).its, volume->world_matrix().cast<float>(), volume_sinking(*volume));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Ignore, don't produce any collision.
|
||||||
|
state = BuildVolume::ObjectState::Inside;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert(state != BuildVolume::ObjectState::Below);
|
||||||
|
}
|
||||||
|
volume->is_outside = state != BuildVolume::ObjectState::Inside;
|
||||||
|
if (volume->printable) {
|
||||||
|
if (overall_state == ModelInstancePVS_Inside && volume->is_outside)
|
||||||
|
overall_state = ModelInstancePVS_Fully_Outside;
|
||||||
|
if (overall_state == ModelInstancePVS_Fully_Outside && volume->is_outside && state == BuildVolume::ObjectState::Colliding)
|
||||||
|
overall_state = ModelInstancePVS_Partly_Outside;
|
||||||
|
contained_min_one |= !volume->is_outside;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out_state != nullptr)
|
||||||
|
*out_state = overall_state;
|
||||||
|
|
||||||
|
return contained_min_one;
|
||||||
|
}
|
||||||
|
|
||||||
void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo, int instance_idx)
|
void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo, int instance_idx)
|
||||||
{
|
{
|
||||||
if (current_printer_technology() != ptSLA)
|
if (current_printer_technology() != ptSLA)
|
||||||
@ -2520,7 +2594,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||||||
// checks for geometry outside the print volume to render it accordingly
|
// checks for geometry outside the print volume to render it accordingly
|
||||||
if (!m_volumes.empty()) {
|
if (!m_volumes.empty()) {
|
||||||
ModelInstanceEPrintVolumeState state;
|
ModelInstanceEPrintVolumeState state;
|
||||||
const bool contained_min_one = m_volumes.check_outside_state(m_bed.build_volume(), &state);
|
const bool contained_min_one = check_volumes_outside_state(m_bed.build_volume(), &state);
|
||||||
const bool partlyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Partly_Outside);
|
const bool partlyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Partly_Outside);
|
||||||
const bool fullyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Fully_Outside);
|
const bool fullyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Fully_Outside);
|
||||||
|
|
||||||
@ -6044,7 +6118,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_requires_check_outside_state) {
|
if (m_requires_check_outside_state) {
|
||||||
m_volumes.check_outside_state(build_volume, nullptr);
|
check_volumes_outside_state(build_volume, nullptr);
|
||||||
m_requires_check_outside_state = false;
|
m_requires_check_outside_state = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -737,6 +737,9 @@ public:
|
|||||||
const GLVolumeCollection& get_volumes() const { return m_volumes; }
|
const GLVolumeCollection& get_volumes() const { return m_volumes; }
|
||||||
void reset_volumes();
|
void reset_volumes();
|
||||||
ModelInstanceEPrintVolumeState check_volumes_outside_state() const;
|
ModelInstanceEPrintVolumeState check_volumes_outside_state() const;
|
||||||
|
// returns true if all the volumes are completely contained in the print volume
|
||||||
|
// returns the containment state in the given out_state, if non-null
|
||||||
|
bool check_volumes_outside_state(const Slic3r::BuildVolume& build_volume, ModelInstanceEPrintVolumeState* out_state) const;
|
||||||
|
|
||||||
void init_gcode_viewer() { m_gcode_viewer.init(); }
|
void init_gcode_viewer() { m_gcode_viewer.init(); }
|
||||||
void reset_gcode_toolpaths() { m_gcode_viewer.reset(); }
|
void reset_gcode_toolpaths() { m_gcode_viewer.reset(); }
|
||||||
|
Loading…
Reference in New Issue
Block a user