diff --git a/resources/shaders/variable_layer_height.fs b/resources/shaders/variable_layer_height.fs index 934eb77583..693c1c6a0b 100644 --- a/resources/shaders/variable_layer_height.fs +++ b/resources/shaders/variable_layer_height.fs @@ -24,7 +24,7 @@ void main() float z_texture_col = object_z_row - z_texture_row; float z_blend = 0.25 * cos(min(M_PI, abs(M_PI * (object_z - z_cursor) * 1.8 / z_cursor_band_width))) + 0.25; // Calculate level of detail from the object Z coordinate. - // This makes the slowly sloping surfaces to be show with high detail (with stripes), + // This makes the slowly sloping surfaces to be shown with high detail (with stripes), // and the vertical surfaces to be shown with low detail (no stripes) float z_in_cells = object_z_row * 190.; // Gradient of Z projected on the screen. @@ -32,9 +32,10 @@ void main() float dy_vtc = dFdy(z_in_cells); float lod = clamp(0.5 * log2(max(dx_vtc * dx_vtc, dy_vtc * dy_vtc)), 0., 1.); // Sample the Z texture. Texture coordinates are normalized to <0, 1>. - vec4 color = mix(texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.), - texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.), lod); - + vec4 color = vec4(0.25, 0.25, 0.25, 1.0); + if (z_texture_row >= 0.0) + color = mix(texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.), + texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.), lod); // Mix the final color. gl_FragColor = vec4(vec3(intensity.y), 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend); } diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index cbf3e71ab7..ab39fbbdeb 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1639,9 +1639,15 @@ PrintRegionConfig PrintObject::region_config_from_model_volume(const PrintRegion void PrintObject::update_slicing_parameters() { +#if ENABLE_ALLOW_NEGATIVE_Z + if (!m_slicing_params.valid) + m_slicing_params = SlicingParameters::create_from_config( + this->print()->config(), m_config, this->model_object()->bounding_box().max.z(), this->object_extruders()); +#else if (! m_slicing_params.valid) m_slicing_params = SlicingParameters::create_from_config( this->print()->config(), m_config, unscale(this->height()), this->object_extruders()); +#endif // ENABLE_ALLOW_NEGATIVE_Z } SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full_config, const ModelObject& model_object, float object_max_z) @@ -1703,6 +1709,15 @@ bool PrintObject::update_layer_height_profile(const ModelObject &model_object, c updated = true; } +#if ENABLE_ALLOW_NEGATIVE_Z + // Verify the layer_height_profile. + if (!layer_height_profile.empty() && + // Must not be of even length. + ((layer_height_profile.size() & 1) != 0 || + // Last entry must be at the top of the object. + std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_parameters.object_print_z_max) > 1e-3)) + layer_height_profile.clear(); +#else // Verify the layer_height_profile. if (! layer_height_profile.empty() && // Must not be of even length. @@ -1710,6 +1725,7 @@ bool PrintObject::update_layer_height_profile(const ModelObject &model_object, c // Last entry must be at the top of the object. std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_parameters.object_print_z_height()) > 1e-3)) layer_height_profile.clear(); +#endif // ENABLE_ALLOW_NEGATIVE_Z if (layer_height_profile.empty()) { //layer_height_profile = layer_height_profile_adaptive(slicing_parameters, model_object.layer_config_ranges, model_object.volumes); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index fcd6da83f0..cc8658fc27 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -169,11 +169,18 @@ void GLCanvas3D::LayersEditing::set_config(const DynamicPrintConfig* config) void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id) { const ModelObject *model_object_new = (object_id >= 0) ? model.objects[object_id] : nullptr; +#if ENABLE_ALLOW_NEGATIVE_Z + // Maximum height of an object changes when the object gets rotated or scaled. + // Changing maximum height of an object will invalidate the layer heigth editing profile. + // m_model_object->bounding_box() is cached, therefore it is cheap even if this method is called frequently. + const float new_max_z = (model_object_new == nullptr) ? 0.0f : static_cast(model_object_new->bounding_box().max.z()); +#else // Maximum height of an object changes when the object gets rotated or scaled. // Changing maximum height of an object will invalidate the layer heigth editing profile. // m_model_object->raw_bounding_box() is cached, therefore it is cheap even if this method is called frequently. float new_max_z = (model_object_new == nullptr) ? 0.f : model_object_new->raw_bounding_box().size().z(); - if (m_model_object != model_object_new || this->last_object_id != object_id || m_object_max_z != new_max_z || +#endif // ENABLE_ALLOW_NEGATIVE_Z + if (m_model_object != model_object_new || this->last_object_id != object_id || m_object_max_z != new_max_z || (model_object_new != nullptr && m_model_object->id() != model_object_new->id())) { m_layer_height_profile.clear(); m_layer_height_profile_modified = false; @@ -348,11 +355,12 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con float h = 0.0f; for (size_t i = m_layer_height_profile.size() - 2; i >= 2; i -= 2) { - float zi = m_layer_height_profile[i]; - float zi_1 = m_layer_height_profile[i - 2]; + const float zi = static_cast(m_layer_height_profile[i]); + const float zi_1 = static_cast(m_layer_height_profile[i - 2]); if (zi_1 <= z && z <= zi) { float dz = zi - zi_1; - h = (dz != 0.0f) ? lerp(m_layer_height_profile[i - 1], m_layer_height_profile[i + 1], (z - zi_1) / dz) : m_layer_height_profile[i + 1]; + h = (dz != 0.0f) ? static_cast(lerp(m_layer_height_profile[i - 1], m_layer_height_profile[i + 1], (z - zi_1) / dz)) : + static_cast(m_layer_height_profile[i + 1]); break; } } @@ -381,10 +389,10 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); // Render the color bar - float l = bar_rect.get_left(); - float r = bar_rect.get_right(); - float t = bar_rect.get_top(); - float b = bar_rect.get_bottom(); + const float l = bar_rect.get_left(); + const float r = bar_rect.get_right(); + const float t = bar_rect.get_top(); + const float b = bar_rect.get_bottom(); ::glBegin(GL_QUADS); ::glNormal3f(0.0f, 0.0f, 1.0f); @@ -560,7 +568,7 @@ void GLCanvas3D::LayersEditing::update_slicing_parameters() { if (m_slicing_parameters == nullptr) { m_slicing_parameters = new SlicingParameters(); - *m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object, m_object_max_z); + *m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object, m_object_max_z); } } @@ -3575,6 +3583,13 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) #endif // ENABLE_ALLOW_NEGATIVE_Z } +#if ENABLE_ALLOW_NEGATIVE_Z + // if the selection is not valid to allow for layer editing after the move, we need to turn off the tool if it is running + // similar to void Plater::priv::selection_changed() + if (!wxGetApp().plater()->can_layers_editing() && is_layers_editing_enabled()) + post_event(SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); +#endif // ENABLE_ALLOW_NEGATIVE_Z + if (object_moved) post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_MOVED)); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 690ffdb169..05090399d9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2630,11 +2630,8 @@ int Plater::priv::get_selected_volume_idx() const void Plater::priv::selection_changed() { // if the selection is not valid to allow for layer editing, we need to turn off the tool if it is running - bool enable_layer_editing = layers_height_allowed(); - if (!enable_layer_editing && view3D->is_layers_editing_enabled()) { - SimpleEvent evt(EVT_GLTOOLBAR_LAYERSEDITING); - on_action_layersediting(evt); - } + if (!layers_height_allowed() && view3D->is_layers_editing_enabled()) + on_action_layersediting(SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); // forces a frame render to update the view (to avoid a missed update if, for example, the context menu appears) view3D->render(); @@ -4024,7 +4021,7 @@ void Plater::priv::reset_gcode_toolpaths() bool Plater::priv::can_set_instance_to_object() const { const int obj_idx = get_selected_object_idx(); - return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && (model.objects[obj_idx]->instances.size() > 1); + return 0 <= obj_idx && obj_idx < (int)model.objects.size() && model.objects[obj_idx]->instances.size() > 1; } bool Plater::priv::can_split(bool to_objects) const @@ -4038,7 +4035,12 @@ bool Plater::priv::layers_height_allowed() const return false; int obj_idx = get_selected_object_idx(); - return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && config->opt_bool("variable_layer_height") && view3D->is_layers_editing_allowed(); +#if ENABLE_ALLOW_NEGATIVE_Z + return 0 <= obj_idx && obj_idx < (int)model.objects.size() && model.objects[obj_idx]->bounding_box().max.z() > 0.0 && + config->opt_bool("variable_layer_height") && view3D->is_layers_editing_allowed(); +#else + return 0 <= obj_idx && obj_idx < (int)model.objects.size() && config->opt_bool("variable_layer_height") && view3D->is_layers_editing_allowed(); +#endif // ENABLE_ALLOW_NEGATIVE_Z } bool Plater::priv::can_mirror() const diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index f52e2f0aa9..3ab546abe5 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -169,7 +169,7 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection, bool chec if (!already_contained || needs_reset) { - wxGetApp().plater()->take_snapshot(_(L("Selection-Add"))); + wxGetApp().plater()->take_snapshot(_L("Selection-Add")); if (needs_reset) clear(); @@ -210,7 +210,7 @@ void Selection::remove(unsigned int volume_idx) if (!contains_volume(volume_idx)) return; - wxGetApp().plater()->take_snapshot(_(L("Selection-Remove"))); + wxGetApp().plater()->take_snapshot(_L("Selection-Remove")); GLVolume* volume = (*m_volumes)[volume_idx]; @@ -242,7 +242,7 @@ void Selection::add_object(unsigned int object_idx, bool as_single_selection) (as_single_selection && matches(volume_idxs))) return; - wxGetApp().plater()->take_snapshot(_(L("Selection-Add Object"))); + wxGetApp().plater()->take_snapshot(_L("Selection-Add Object")); // resets the current list if needed if (as_single_selection) @@ -261,7 +261,7 @@ void Selection::remove_object(unsigned int object_idx) if (!m_valid) return; - wxGetApp().plater()->take_snapshot(_(L("Selection-Remove Object"))); + wxGetApp().plater()->take_snapshot(_L("Selection-Remove Object")); do_remove_object(object_idx); @@ -274,12 +274,12 @@ void Selection::add_instance(unsigned int object_idx, unsigned int instance_idx, if (!m_valid) return; - std::vector volume_idxs = get_volume_idxs_from_instance(object_idx, instance_idx); + const std::vector volume_idxs = get_volume_idxs_from_instance(object_idx, instance_idx); if ((!as_single_selection && contains_all_volumes(volume_idxs)) || (as_single_selection && matches(volume_idxs))) return; - wxGetApp().plater()->take_snapshot(_(L("Selection-Add Instance"))); + wxGetApp().plater()->take_snapshot(_L("Selection-Add Instance")); // resets the current list if needed if (as_single_selection) @@ -298,7 +298,7 @@ void Selection::remove_instance(unsigned int object_idx, unsigned int instance_i if (!m_valid) return; - wxGetApp().plater()->take_snapshot(_(L("Selection-Remove Instance"))); + wxGetApp().plater()->take_snapshot(_L("Selection-Remove Instance")); do_remove_instance(object_idx, instance_idx);