mirror of
https://git.mirrors.martin98.com/https://github.com/bambulab/BambuStudio.git
synced 2025-08-06 05:39:17 +08:00
ENH:Add sinking render in the paint gizmo
jira: STUDIO-11649 Change-Id: I5edadc0107dd6ab8fc4e28d478135796463ee64b
This commit is contained in:
parent
fa642e8d66
commit
255ada5ff2
@ -1624,6 +1624,36 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo
|
||||
return list;
|
||||
}
|
||||
|
||||
GLVolumeWithIdAndZList volumes_to_render_for_sinking(const GLVolumePtrs & volumes,
|
||||
GLVolumeCollection::ERenderType type,
|
||||
const Transform3d & view_matrix)
|
||||
{
|
||||
GLVolumeWithIdAndZList list;
|
||||
list.reserve(volumes.size());
|
||||
|
||||
for (unsigned int i = 0; i < (unsigned int) volumes.size(); ++i) {
|
||||
GLVolume *volume = volumes[i];
|
||||
bool is_transparent = (volume->render_color[3] < 1.0f);
|
||||
auto tempGlwipeTowerVolume = dynamic_cast<GLWipeTowerVolume *>(volume);
|
||||
if (tempGlwipeTowerVolume) {
|
||||
continue;
|
||||
}
|
||||
if (!volume->selected)
|
||||
continue;
|
||||
list.emplace_back(std::make_pair(volume, std::make_pair(i, 0.0)));
|
||||
}
|
||||
|
||||
if (type == GLVolumeCollection::ERenderType::Transparent && list.size() > 1) {
|
||||
for (GLVolumeWithIdAndZ &volume : list) { volume.second.second = volume.first->bounding_box().transformed(view_matrix * volume.first->world_matrix()).max(2); }
|
||||
|
||||
std::sort(list.begin(), list.end(), [](const GLVolumeWithIdAndZ &v1, const GLVolumeWithIdAndZ &v2) -> bool { return v1.second.second < v2.second.second; });
|
||||
} else if (type == GLVolumeCollection::ERenderType::Opaque && list.size() > 1) {
|
||||
std::sort(list.begin(), list.end(), [](const GLVolumeWithIdAndZ &v1, const GLVolumeWithIdAndZ &v2) -> bool { return v1.first->selected && !v2.first->selected; });
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
int GLVolumeCollection::get_selection_support_threshold_angle(bool &enable_support) const
|
||||
{
|
||||
const DynamicPrintConfig& glb_cfg = GUI::wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
@ -1805,6 +1835,55 @@ void GLVolumeCollection::render(GUI::ERenderPipelineStage render_pip
|
||||
glsafe(::glDisable(GL_BLEND));
|
||||
}
|
||||
|
||||
void GLVolumeCollection::only_render_sinking(GUI::ERenderPipelineStage render_pipeline_stage,
|
||||
ERenderType type,
|
||||
bool disable_cullface,
|
||||
const GUI::Camera & camera,
|
||||
const std::vector<std::array<float, 4>> &colors,
|
||||
Model & model,
|
||||
std::function<bool(const GLVolume &)> filter_func,
|
||||
bool with_outline,
|
||||
const std::array<float, 4> & body_color,
|
||||
bool partly_inside_enable,
|
||||
std::vector<double> * printable_heights)
|
||||
{
|
||||
auto view_matrix = camera.get_view_matrix();
|
||||
auto projection_matrix = camera.get_projection_matrix();
|
||||
GLVolumeWithIdAndZList to_render = volumes_to_render_for_sinking(volumes, type, view_matrix);
|
||||
if (to_render.empty())
|
||||
return;
|
||||
|
||||
const auto shader = GUI::wxGetApp().get_current_shader();
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
if (type == ERenderType::Transparent) {
|
||||
glsafe(::glEnable(GL_BLEND));
|
||||
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
}
|
||||
|
||||
glsafe(::glDisable(GL_CULL_FACE));
|
||||
if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) {
|
||||
if (m_show_sinking_contours) {
|
||||
for (GLVolumeWithIdAndZ &volume : to_render) {
|
||||
if (volume.first->is_sinking() && !volume.first->is_below_printbed()) {
|
||||
GUI::wxGetApp().unbind_shader();
|
||||
glsafe(::glDepthFunc(GL_ALWAYS));
|
||||
volume.first->render_sinking_contours(camera, model);
|
||||
glsafe(::glDepthFunc(GL_LESS));
|
||||
GUI::wxGetApp().bind_shader(shader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (disable_cullface)
|
||||
glsafe(::glEnable(GL_CULL_FACE));
|
||||
|
||||
if (type == ERenderType::Transparent)
|
||||
glsafe(::glDisable(GL_BLEND));
|
||||
}
|
||||
|
||||
bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, ModelInstanceEPrintVolumeState *out_state, ObjectFilamentResults *object_results, Model &model) const
|
||||
{
|
||||
if (GUI::wxGetApp().plater() == NULL)
|
||||
|
@ -747,7 +747,17 @@ public:
|
||||
const std::array<float, 4> & body_color = {1.0f, 1.0f, 1.0f, 1.0f},
|
||||
bool partly_inside_enable = true,
|
||||
std::vector<double> * printable_heights = nullptr);
|
||||
|
||||
void only_render_sinking(GUI::ERenderPipelineStage render_pipeline_stage,
|
||||
ERenderType type,
|
||||
bool disable_cullface,
|
||||
const GUI::Camera & camera,
|
||||
const std::vector<std::array<float, 4>> &colors,
|
||||
Model & model,
|
||||
std::function<bool(const GLVolume &)> filter_func = std::function<bool(const GLVolume &)>(),
|
||||
bool with_outline = true,
|
||||
const std::array<float, 4> & body_color = {1.0f, 1.0f, 1.0f, 1.0f},
|
||||
bool partly_inside_enable = true,
|
||||
std::vector<double> * printable_heights = nullptr);
|
||||
// Finalize the initialization of the geometry & indices,
|
||||
// upload the geometry and indices to OpenGL VBO objects
|
||||
// and shrink the allocated data, possibly relasing it if it has been loaded into the VBOs.
|
||||
|
@ -1724,6 +1724,15 @@ ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state(ObjectFil
|
||||
return state;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::is_volumes_selected_and_sinking() const {
|
||||
for (GLVolume *volume : m_volumes.volumes) {
|
||||
if (volume->selected && volume->is_sinking() && !volume->is_below_printbed()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GLCanvas3D::toggle_selected_volume_visibility(bool selected_visible)
|
||||
{
|
||||
m_render_sla_auxiliaries = !selected_visible;
|
||||
@ -7570,6 +7579,18 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
||||
gm.render_painter_assemble_view();
|
||||
wxGetApp().bind_shader(shader);
|
||||
}
|
||||
if (m_canvas_type == CanvasView3D && m_gizmos.is_paint_gizmo()) {
|
||||
m_volumes.only_render_sinking(
|
||||
render_pipeline_stage, type, false, camera, colors, *m_model,
|
||||
[this, canvas_type](const GLVolume &volume) {
|
||||
if (canvas_type == ECanvasType::CanvasAssembleView) {
|
||||
return !volume.is_modifier;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
with_outline, body_color, partly_inside_enable, printable_height_option ? &printable_height_option->values : nullptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -807,6 +807,7 @@ public:
|
||||
void reset_volumes(bool set_notice = true);
|
||||
ModelInstanceEPrintVolumeState check_volumes_outside_state(ObjectFilamentResults* object_results = nullptr) const;
|
||||
bool is_all_plates_selected() { return m_sel_plate_toolbar.m_all_plates_stats_item && m_sel_plate_toolbar.m_all_plates_stats_item->selected; }
|
||||
bool is_volumes_selected_and_sinking() const;
|
||||
const float get_scale() const;
|
||||
|
||||
//BBS
|
||||
|
@ -283,7 +283,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
||||
|
||||
const float sliders_width = m_imgui->scaled(7.0f);
|
||||
const float drag_left_width = ImGui::GetStyle().WindowPadding.x + sliders_left_width + sliders_width - space_size;
|
||||
|
||||
float window_width = minimal_slider_width + sliders_left_width + slider_icon_width;
|
||||
float drag_pos_times = 0.7;
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
@ -462,6 +462,11 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
if (m_parent.is_volumes_selected_and_sinking()) {
|
||||
m_imgui->warning_text_wrapped(_L("Warning") + ":" + _L("Painting below the build plate is not allowed.") +
|
||||
_L("The white outline indicates the position of the build plate at Z = 0."),
|
||||
window_width+ m_imgui->scaled(3));
|
||||
}
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f));
|
||||
float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y;
|
||||
show_tooltip_information(caption_max, x, get_cur_y);
|
||||
|
@ -479,7 +479,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
|
||||
|
||||
window_width = std::max(window_width, total_text_max);
|
||||
window_width = std::max(window_width, buttons_width);
|
||||
window_width = std::max(window_width, max_filament_items_per_line * filament_item_width + +m_imgui->scaled(0.5f));
|
||||
window_width = std::max(window_width, max_filament_items_per_line * filament_item_width + m_imgui->scaled(0.5f));
|
||||
|
||||
const float sliders_width = m_imgui->scaled(7.0f);
|
||||
const float drag_left_width = ImGui::GetStyle().WindowPadding.x + sliders_width - space_size;
|
||||
@ -840,7 +840,11 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
|
||||
m_imgui->disabled_end();
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
if (m_parent.is_volumes_selected_and_sinking()) {
|
||||
m_imgui->warning_text_wrapped(_L("Warning") + ":" + _L("Painting below the build plate is not allowed.") +
|
||||
_L("The white outline indicates the position of the build plate at Z = 0."),
|
||||
window_width + m_imgui->scaled(1));
|
||||
}
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f));
|
||||
float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y;
|
||||
show_tooltip_information(caption_max, x, get_cur_y);
|
||||
|
@ -65,7 +65,7 @@ GLGizmoPainterBase::ClippingPlaneDataWrapper GLGizmoPainterBase::get_clipping_pl
|
||||
// z_range is calculated in the same way as in GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
|
||||
if (m_c->get_canvas()->get_use_clipping_planes()) {
|
||||
const std::array<ClippingPlane, 2> &clps = m_c->get_canvas()->get_clipping_planes();
|
||||
clp_data_out.z_range = {float(-clps[0].get_data()[3]), float(clps[1].get_data()[3])};
|
||||
clp_data_out.z_range = {-FLT_MAX, float(clps[1].get_data()[3])};
|
||||
}
|
||||
|
||||
return clp_data_out;
|
||||
|
@ -230,10 +230,10 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
|
||||
|
||||
const float sliders_left_width = std::max(cursor_size_slider_left, clipping_slider_left);
|
||||
const float slider_icon_width = m_imgui->get_slider_icon_size().x;
|
||||
|
||||
const float minimal_slider_width = m_imgui->scaled(4.f);
|
||||
const float sliders_width = m_imgui->scaled(7.0f);
|
||||
const float drag_left_width = ImGui::GetStyle().WindowPadding.x + sliders_left_width + sliders_width - space_size;
|
||||
|
||||
float window_width = minimal_slider_width + sliders_left_width + slider_icon_width;
|
||||
const float max_tooltip_width = ImGui::GetFontSize() * 20.0f;
|
||||
|
||||
float textbox_width = 1.5 * slider_icon_width;
|
||||
@ -353,6 +353,11 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
ImGui::Separator();
|
||||
if (m_parent.is_volumes_selected_and_sinking()) {
|
||||
m_imgui->warning_text_wrapped(_L("Warning") + ":" + _L("Painting below the build plate is not allowed.") +
|
||||
_L("The white outline indicates the position of the build plate at Z = 0."),
|
||||
window_width + m_imgui->scaled(3));
|
||||
}
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f));
|
||||
float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y;
|
||||
show_tooltip_information(caption_max, x, get_cur_y);
|
||||
|
@ -154,8 +154,13 @@ void InstancesHider::on_update()
|
||||
double z_min;
|
||||
if (canvas->get_canvas_type() == GLCanvas3D::CanvasAssembleView)
|
||||
z_min = std::numeric_limits<double>::max();
|
||||
else
|
||||
z_min = -SINKING_Z_THRESHOLD;
|
||||
else {
|
||||
if (canvas->get_gizmos_manager().is_paint_gizmo()) {
|
||||
z_min = -FLT_MAX;
|
||||
} else {
|
||||
z_min = -SINKING_Z_THRESHOLD;
|
||||
}
|
||||
}
|
||||
|
||||
if (mo && active_inst != -1) {
|
||||
canvas->toggle_model_objects_visibility(false);
|
||||
@ -420,7 +425,8 @@ void CommonGizmosDataObjects::ObjectClipper::render_cut(const std::vector<size_t
|
||||
//consider normal view or assemble view
|
||||
const ModelObject * mo = sel_info->model_object();
|
||||
Geometry::Transformation inst_trafo;
|
||||
bool is_assem_cnv = get_pool()->get_canvas()->get_canvas_type() == GLCanvas3D::CanvasAssembleView;
|
||||
GLCanvas3D * canvas = get_pool()->get_canvas();
|
||||
bool is_assem_cnv = canvas->get_canvas_type() == GLCanvas3D::CanvasAssembleView;
|
||||
inst_trafo = is_assem_cnv ? mo->instances[sel_info->get_active_instance()]->get_assemble_transformation() :
|
||||
mo->instances[sel_info->get_active_instance()]->get_transformation();
|
||||
auto offset_to_assembly = mo->instances[0]->get_offset_to_assembly();
|
||||
@ -428,6 +434,14 @@ void CommonGizmosDataObjects::ObjectClipper::render_cut(const std::vector<size_t
|
||||
auto debug = sel_info->get_sla_shift();
|
||||
std::vector<size_t> ignore_idxs_local = ignore_idxs ? *ignore_idxs : std::vector<size_t>();
|
||||
|
||||
|
||||
double z_min;
|
||||
if (canvas->get_gizmos_manager().is_paint_gizmo()) {
|
||||
z_min = -FLT_MAX;
|
||||
} else {
|
||||
z_min = -SINKING_Z_THRESHOLD;
|
||||
}
|
||||
|
||||
for (auto &clipper : m_clippers) {
|
||||
auto vol_trafo = clipper.second;
|
||||
Geometry::Transformation trafo = inst_trafo * vol_trafo;
|
||||
@ -438,7 +452,7 @@ void CommonGizmosDataObjects::ObjectClipper::render_cut(const std::vector<size_t
|
||||
}
|
||||
clipper.first->set_plane(*m_clp);
|
||||
clipper.first->set_transformation(trafo);
|
||||
clipper.first->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD));
|
||||
clipper.first->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), z_min));
|
||||
clipper.first->render_cut(OpenGLManager::get_cut_plane_color(), &ignore_idxs_local);
|
||||
clipper.first->render_contour({1.f, 1.f, 1.f, 1.f}, &ignore_idxs_local);
|
||||
|
||||
|
@ -727,7 +727,7 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GLGizmosManager::is_paint_gizmo()
|
||||
bool GLGizmosManager::is_paint_gizmo() const
|
||||
{
|
||||
return m_current == EType::FdmSupports ||
|
||||
m_current == EType::MmuSegmentation ||
|
||||
@ -1912,6 +1912,9 @@ bool GLGizmosManager::is_in_editing_mode(bool error_notification) const
|
||||
|
||||
bool GLGizmosManager::is_hiding_instances() const
|
||||
{
|
||||
if (is_paint_gizmo()) {
|
||||
return false;
|
||||
}
|
||||
return (m_common_gizmos_data
|
||||
&& m_common_gizmos_data->instances_hider()
|
||||
&& m_common_gizmos_data->instances_hider()->is_valid());
|
||||
|
@ -291,7 +291,7 @@ public:
|
||||
void check_object_located_outside_plate(bool change_plate =true);
|
||||
bool get_object_located_outside_plate() { return m_object_located_outside_plate; }
|
||||
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false, bool alt_down = false, bool control_down = false);
|
||||
bool is_paint_gizmo();
|
||||
bool is_paint_gizmo()const;
|
||||
bool is_allow_select_all();
|
||||
ClippingPlane get_clipping_plane() const;
|
||||
ClippingPlane get_assemble_view_clipping_plane() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user