diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 3e79b45156..29fb765e6f 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -71,28 +71,45 @@ void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char // BBS std::vector> get_extruders_colors() { - unsigned char rgb_color[3] = {}; - std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); + unsigned char rgba_color[4] = {}; + std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); std::vector> colors_out(colors.size()); - for (const std::string& color : colors) { - Slic3r::GUI::BitmapCache::parse_color(color, rgb_color); - size_t color_idx = &color - &colors.front(); - colors_out[color_idx] = { float(rgb_color[0]) / 255.f, float(rgb_color[1]) / 255.f, float(rgb_color[2]) / 255.f, 1.f }; + for (const std::string &color : colors) { + Slic3r::GUI::BitmapCache::parse_color4(color, rgba_color); + size_t color_idx = &color - &colors.front(); + colors_out[color_idx] = { + float(rgba_color[0]) / 255.f, + float(rgba_color[1]) / 255.f, + float(rgba_color[2]) / 255.f, + float(rgba_color[3]) / 255.f, + }; } return colors_out; } - -std::array adjust_color_for_rendering(const std::array& colors) +float FullyTransparentMaterialThreshold = 0.1f; +float FullTransparentModdifiedToFixAlpha = 0.3f; +std::array adjust_color_for_rendering(const std::array &colors, int whichView) { - if ((colors[0] < 0.1) && (colors[1] < 0.1) && (colors[2] < 0.1)) - { - std::array new_color; - new_color[0] = 0.1; - new_color[1] = 0.1; - new_color[2] = 0.1; - new_color[3] = colors[3]; - return new_color; + if (whichView == (int) Slic3r::GUI::GLCanvas3D::ECanvasType::CanvasView3D || + whichView == (int) Slic3r::GUI::GLCanvas3D::ECanvasType::CanvasAssembleView) { + if (colors[3] < FullyTransparentMaterialThreshold) { // completely transparent + std::array new_color; + new_color[0] = 1; + new_color[1] = 1; + new_color[2] = 1; + new_color[3] = FullTransparentModdifiedToFixAlpha; + return new_color; + } + } else { + if (colors[3] < FullyTransparentMaterialThreshold) { // completely transparent + std::array new_color; + new_color[0] = 1; + new_color[1] = 1; + new_color[2] = 1; + new_color[3] = 0.05f; + return new_color; + } } return colors; @@ -514,8 +531,13 @@ void GLVolume::set_render_color() } } - if (force_transparent) - render_color[3] = color[3]; + if (force_transparent) { + if (color[3] < FullyTransparentMaterialThreshold) { + render_color[3] = FullTransparentModdifiedToFixAlpha; + } else { + render_color[3] = color[3]; + } + } //BBS set unprintable color if (!printable) { @@ -1017,12 +1039,21 @@ void GLWipeTowerVolume::render(bool with_outline) const } this->iva_per_colors[i].render(); } - + glsafe(::glPopMatrix()); if (this->is_left_handed()) glFrontFace(GL_CCW); } +bool GLWipeTowerVolume::IsTransparent() { + for (size_t i = 0; i < m_colors.size(); i++) { + if (m_colors[i][3] < 1.0f) { + return true; + } + } + return false; +} + std::vector GLVolumeCollection::load_object( const ModelObject *model_object, int obj_idx, @@ -1211,8 +1242,12 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo for (unsigned int i = 0; i < (unsigned int)volumes.size(); ++i) { GLVolume* volume = volumes[i]; bool is_transparent = (volume->render_color[3] < 1.0f); - if (((type == GLVolumeCollection::ERenderType::Opaque && !is_transparent) || - (type == GLVolumeCollection::ERenderType::Transparent && is_transparent) || + auto tempGlwipeTowerVolume = dynamic_cast(volume); + if (tempGlwipeTowerVolume) { + is_transparent = tempGlwipeTowerVolume->IsTransparent(); + } + if (((type == GLVolumeCollection::ERenderType::Opaque && !is_transparent) || + (type == GLVolumeCollection::ERenderType::Transparent && is_transparent) || type == GLVolumeCollection::ERenderType::All) && (! filter_func || filter_func(*volume))) list.emplace_back(std::make_pair(volume, std::make_pair(i, 0.0))); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index a1f050df2b..fa599e61fb 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -31,7 +31,9 @@ #define glcheck() #endif // HAS_GLSAFE extern std::vector> get_extruders_colors(); -extern std::array adjust_color_for_rendering(const std::array& colors); +extern float FullyTransparentMaterialThreshold; +extern float FullTransparentModdifiedToFixAlpha; +extern std::array adjust_color_for_rendering(const std::array &colors, int whichView=0); namespace Slic3r { @@ -558,6 +560,7 @@ public: virtual void render(bool with_outline = false) const; std::vector iva_per_colors; + bool IsTransparent(); private: std::vector> m_colors; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index d2436d3be3..f7e2f541bf 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1152,6 +1152,9 @@ void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::v for (auto item : m_tools.m_tool_visibles) item = true; } + for (int i = 0; i < m_tools.m_tool_colors.size(); i++) { + m_tools.m_tool_colors[i] = adjust_color_for_rendering(m_tools.m_tool_colors[i], GLCanvas3D::ECanvasType::CanvasPreview); + } // ensure there are enough colors defined while (m_tools.m_tool_colors.size() < std::max(size_t(1), gcode_result.extruders_count)) { m_tools.m_tool_colors.push_back(decode_color("#FF8000")); @@ -3263,7 +3266,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool color = { 0.5f, 0.5f, 0.5f, 1.0f }; else { color = m_tools.m_tool_colors[path.cp_color_id]; - color = adjust_color_for_rendering(color); + color = adjust_color_for_rendering(color, GLCanvas3D::ECanvasType::CanvasPreview); } break; } @@ -3873,6 +3876,10 @@ void GCodeViewer::render_toolpaths() ](std::vector::reverse_iterator it_path, std::vector::reverse_iterator it_end, GLShaderProgram& shader, int uniform_color) { for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) { const RenderPath& path = *it; + if (path.color[3] < 1.0) { + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + } // Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415. assert(! path.sizes.empty()); assert(! path.offsets.empty()); @@ -3881,6 +3888,9 @@ void GCodeViewer::render_toolpaths() #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_triangles_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS + if (path.color[3] < 1.0) { + glsafe(::glDisable(GL_BLEND)); + } } }; @@ -4159,6 +4169,10 @@ void GCodeViewer::render_all_plates_stats(const std::vector filament_densities = gcode_result_list.front()->filament_densities; std::vector filament_colors = decode_colors(wxGetApp().plater()->get_extruder_colors_from_plater_config(gcode_result_list.back())); + for (int i = 0; i < filament_colors.size(); i++) { + filament_colors[i] = adjust_color_for_rendering(filament_colors[i], GLCanvas3D::ECanvasType::CanvasPreview); + } + bool imperial_units = wxGetApp().app_config->get("use_inches") == "1"; float window_padding = 4.0f * m_scale; const float icon_size = ImGui::GetTextLineHeight() * 0.7; @@ -4409,21 +4423,21 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv default: case EItemType::Rect: { draw_list->AddRectFilled({ pos.x + 1.0f * m_scale, pos.y + 3.0f * m_scale }, { pos.x + icon_size - 1.0f * m_scale, pos.y + icon_size + 1.0f * m_scale }, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); + ImGui::GetColorU32({color[0], color[1], color[2], color[3]})); break; } case EItemType::Circle: { ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size + 5.0f)); - draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({color[0], color[1], color[2], color[3]}), 16); break; } case EItemType::Hexagon: { ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size + 5.0f)); - draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); + draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({color[0], color[1], color[2], color[3]}), 6); break; } case EItemType::Line: { - draw_list->AddLine({ pos.x + 1, pos.y + icon_size + 2 }, { pos.x + icon_size - 1, pos.y + 4 }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f); + draw_list->AddLine({pos.x + 1, pos.y + icon_size + 2}, {pos.x + icon_size - 1, pos.y + 4}, ImGui::GetColorU32({color[0], color[1], color[2], color[3]}), 3.0f); break; case EItemType::None: break; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 21b11af97f..d09c38d590 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -734,7 +734,13 @@ public: //BBS ConflictResultOpt m_conflict_result; - + bool GetGcodeGenOk() + { + if (m_roles.empty()) + return false; + else + return true; + } private: std::vector m_plater_extruder; bool m_gl_data_initialized{ false }; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 3b9ee33cfe..8076eb56dd 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1888,32 +1888,34 @@ void GLCanvas3D::render(bool only_init) _render_selection(); if (!no_partplate) _render_bed(!camera.is_looking_downward(), show_axes); - //BBS: add outline logic - _render_objects(GLVolumeCollection::ERenderType::Transparent, !m_gizmos.is_running()); - if (!no_partplate) + if (!no_partplate) //BBS: add outline logic _render_platelist(!camera.is_looking_downward(), only_current, only_body, hover_id); + _render_objects(GLVolumeCollection::ERenderType::Transparent, !m_gizmos.is_running()); } /* preview render */ else if (m_canvas_type == ECanvasType::CanvasPreview && m_render_preview) { - //BBS: add outline logic _render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running()); - //BBS: GUI refactor: add canvas size as parameters - _render_gcode(cnv_size.get_width(), cnv_size.get_height()); _render_sla_slices(); _render_selection(); _render_bed(!camera.is_looking_downward(), show_axes); _render_platelist(!camera.is_looking_downward(), only_current, true, hover_id); + // BBS: add outline logic + if (m_gcode_viewer.GetGcodeGenOk()==false) { + _render_objects(GLVolumeCollection::ERenderType::Transparent, !m_gizmos.is_running()); + } + // BBS: GUI refactor: add canvas size as parameters + _render_gcode(cnv_size.get_width(), cnv_size.get_height()); } /* assemble render*/ else if (m_canvas_type == ECanvasType::CanvasAssembleView) { //BBS: add outline logic _render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running()); //_render_bed(!camera.is_looking_downward(), show_axes); - //BBS: add outline logic - _render_objects(GLVolumeCollection::ERenderType::Transparent, !m_gizmos.is_running()); _render_plane(); //BBS: add outline logic insteadof selection under assemble view //_render_selection(); + // BBS: add outline logic + _render_objects(GLVolumeCollection::ERenderType::Transparent, !m_gizmos.is_running()); } _render_sequential_clearance(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index fc6a8bdc6b..ca3a1af74f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3702,9 +3702,8 @@ std::vector Plater::priv::load_files(const std::vector& input_ if (!silence) wxGetApp().app_config->update_skein_dir(input_files[input_files.size() - 1].parent_path().make_preferred().string()); // XXX: Plater.pm had @loaded_files, but didn't seem to fill them with the filenames... } - // automatic selection of added objects - if (!obj_idxs.empty() && view3D != nullptr && !load_config) { + if (!obj_idxs.empty() && view3D != nullptr && load_config) { // update printable state for new volumes on canvas3D wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(obj_idxs);