ENH: rendering: refine the rendering logic of GLVolume

1. set the unprintable volume to black even if it is mmu painted
2. add the bounding check logic when the object is partly inside of current plate

Change-Id: I69ce25eb85a71398ed8fb1d275136c5d943796d6
This commit is contained in:
lane.wei 2022-08-23 15:28:59 +08:00 committed by Lane.Wei
parent 3911344495
commit 5a2b0e845e
4 changed files with 41 additions and 12 deletions

View File

@ -64,6 +64,23 @@ void main()
alpha = 1.0; alpha = 1.0;
} }
// if the fragment is outside the print volume -> use darker color
vec3 pv_check_min = ZERO;
vec3 pv_check_max = ZERO;
if (print_volume.type == 0) {
// rectangle
pv_check_min = world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, print_volume.z_data.x);
pv_check_max = world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, print_volume.z_data.y);
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
}
else if (print_volume.type == 1) {
// circle
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
}
//BBS: add outline_color //BBS: add outline_color
if (is_outline) if (is_outline)
gl_FragColor = uniform_color; gl_FragColor = uniform_color;

View File

@ -434,6 +434,7 @@ GLVolume::GLVolume(float r, float g, float b, float a)
, zoom_to_volumes(true) , zoom_to_volumes(true)
, shader_outside_printer_detection_enabled(false) , shader_outside_printer_detection_enabled(false)
, is_outside(false) , is_outside(false)
, partly_inside(false)
, hover(HS_None) , hover(HS_None)
, is_modifier(false) , is_modifier(false)
, is_wipe_tower(false) , is_wipe_tower(false)
@ -679,7 +680,7 @@ void GLVolume::render(bool with_outline) const
bool color_volume = false; bool color_volume = false;
ModelObjectPtrs& model_objects = GUI::wxGetApp().model().objects; ModelObjectPtrs& model_objects = GUI::wxGetApp().model().objects;
do { do {
if (object_idx() >= model_objects.size()) if ((!printable) || object_idx() >= model_objects.size())
break; break;
ModelObject* mo = model_objects[object_idx()]; ModelObject* mo = model_objects[object_idx()];
@ -907,7 +908,7 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj
ModelObject* model_object = nullptr; ModelObject* model_object = nullptr;
ModelVolume* model_volume = nullptr; ModelVolume* model_volume = nullptr;
do { do {
if (object_idx() >= model_objects.size()) if ((!printable) || object_idx() >= model_objects.size())
break; break;
model_object = model_objects[object_idx()]; model_object = model_objects[object_idx()];
@ -1290,9 +1291,16 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
//shader->set_uniform("print_volume.xy_data", m_render_volume.data); //shader->set_uniform("print_volume.xy_data", m_render_volume.data);
//shader->set_uniform("print_volume.z_data", m_render_volume.zs); //shader->set_uniform("print_volume.z_data", m_render_volume.zs);
/*shader->set_uniform("print_volume.type", static_cast<int>(m_print_volume.type)); if (volume.first->partly_inside) {
//only partly inside volume need to be painted with boundary check
shader->set_uniform("print_volume.type", static_cast<int>(m_print_volume.type));
shader->set_uniform("print_volume.xy_data", m_print_volume.data); shader->set_uniform("print_volume.xy_data", m_print_volume.data);
shader->set_uniform("print_volume.z_data", m_print_volume.zs);*/ shader->set_uniform("print_volume.z_data", m_print_volume.zs);
}
else {
//use -1 ad a invalid type
shader->set_uniform("print_volume.type", -1);
}
shader->set_uniform("volume_world_matrix", volume.first->world_matrix()); shader->set_uniform("volume_world_matrix", volume.first->world_matrix());
shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower); shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower);
shader->set_uniform("slope.volume_world_normal_matrix", static_cast<Matrix3f>(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>())); shader->set_uniform("slope.volume_world_normal_matrix", static_cast<Matrix3f>(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>()));
@ -1405,6 +1413,7 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
int64_t comp_id = ((int64_t)volume->composite_id.object_id << 32) | ((int64_t)volume->composite_id.instance_id); int64_t comp_id = ((int64_t)volume->composite_id.object_id << 32) | ((int64_t)volume->composite_id.instance_id);
volume->is_outside = state != BuildVolume::ObjectState::Inside; volume->is_outside = state != BuildVolume::ObjectState::Inside;
volume->partly_inside = (state == BuildVolume::ObjectState::Colliding);
if (volume->printable) { if (volume->printable) {
if (overall_state == ModelInstancePVS_Inside && volume->is_outside) { if (overall_state == ModelInstancePVS_Inside && volume->is_outside) {
overall_state = ModelInstancePVS_Fully_Outside; overall_state = ModelInstancePVS_Fully_Outside;
@ -1459,8 +1468,10 @@ void GLVolumeCollection::reset_outside_state()
{ {
for (GLVolume* volume : this->volumes) for (GLVolume* volume : this->volumes)
{ {
if (volume != nullptr) if (volume != nullptr) {
volume->is_outside = false; volume->is_outside = false;
volume->partly_inside = false;
}
} }
} }

View File

@ -371,6 +371,7 @@ public:
bool shader_outside_printer_detection_enabled : 1; bool shader_outside_printer_detection_enabled : 1;
// Wheter or not this volume is outside print volume. // Wheter or not this volume is outside print volume.
bool is_outside : 1; bool is_outside : 1;
bool partly_inside : 1;
// Wheter or not this volume has been generated from a modifier // Wheter or not this volume has been generated from a modifier
bool is_modifier : 1; bool is_modifier : 1;
// Wheter or not this volume has been generated from the wipe tower // Wheter or not this volume has been generated from the wipe tower

View File

@ -5670,13 +5670,13 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
switch (build_volume.type()) { switch (build_volume.type()) {
case BuildVolume::Type::Rectangle: { case BuildVolume::Type::Rectangle: {
const BoundingBox3Base<Vec3d> bed_bb = build_volume.bounding_volume().inflated(BuildVolume::SceneEpsilon); const BoundingBox3Base<Vec3d> bed_bb = build_volume.bounding_volume().inflated(BuildVolume::SceneEpsilon);
m_volumes.set_print_volume({ 0, // circle m_volumes.set_print_volume({ 0, // Rectangle
{ float(bed_bb.min.x()), float(bed_bb.min.y()), float(bed_bb.max.x()), float(bed_bb.max.y()) }, { float(bed_bb.min.x()), float(bed_bb.min.y()), float(bed_bb.max.x()), float(bed_bb.max.y()) },
{ 0.0f, float(build_volume.printable_height()) } }); { 0.0f, float(build_volume.printable_height()) } });
break; break;
} }
case BuildVolume::Type::Circle: { case BuildVolume::Type::Circle: {
m_volumes.set_print_volume({ 1, // rectangle m_volumes.set_print_volume({ 1, // Circle
{ unscaled<float>(build_volume.circle().center.x()), unscaled<float>(build_volume.circle().center.y()), unscaled<float>(build_volume.circle().radius + BuildVolume::SceneEpsilon), 0.0f }, { unscaled<float>(build_volume.circle().center.x()), unscaled<float>(build_volume.circle().center.y()), unscaled<float>(build_volume.circle().radius + BuildVolume::SceneEpsilon), 0.0f },
{ 0.0f, float(build_volume.printable_height() + BuildVolume::SceneEpsilon) } }); { 0.0f, float(build_volume.printable_height() + BuildVolume::SceneEpsilon) } });
break; break;