mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-18 04:08:02 -06:00
Merge branch 'SoftFever:main' into main
This commit is contained in:
commit
a3d08e010d
16 changed files with 1604 additions and 1172 deletions
|
@ -80,7 +80,7 @@ fi
|
|||
|
||||
DISTRIBUTION=$(awk -F= '/^ID=/ {print $2}' /etc/os-release)
|
||||
# treat ubuntu as debian
|
||||
if [ "${DISTRIBUTION}" == "ubuntu" ]
|
||||
if [ "${DISTRIBUTION}" == "ubuntu" ] || [ "${DISTRIBUTION}" == "linuxmint" ]
|
||||
then
|
||||
DISTRIBUTION="debian"
|
||||
fi
|
||||
|
|
|
@ -119,11 +119,6 @@ Thank you! :)
|
|||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://peopoly.net/">
|
||||
<img src="SoftFever_doc\sponsor_logos\peopoly-standard-logo.png" alt="Peopoly" width="96" height="">
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="https://qidi3d.com/">
|
||||
<img src="SoftFever_doc\sponsor_logos\QIDI.png" alt="QIDI" width="96" height="">
|
||||
</a>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 9.9 KiB |
File diff suppressed because it is too large
Load diff
|
@ -36,6 +36,9 @@ uniform SlopeDetection slope;
|
|||
|
||||
//BBS: add outline_color
|
||||
uniform bool is_outline;
|
||||
uniform sampler2D depth_tex;
|
||||
uniform vec2 screen_size;
|
||||
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
uniform sampler2D environment_tex;
|
||||
|
@ -44,6 +47,9 @@ uniform bool is_outline;
|
|||
|
||||
uniform PrintVolumeDetection print_volume;
|
||||
|
||||
uniform float z_far;
|
||||
uniform float z_near;
|
||||
|
||||
varying vec3 clipping_planes_dots;
|
||||
varying float color_clip_plane_dot;
|
||||
|
||||
|
@ -54,6 +60,71 @@ varying vec4 world_pos;
|
|||
varying float world_normal_z;
|
||||
varying vec3 eye_normal;
|
||||
|
||||
vec3 getBackfaceColor(vec3 fill) {
|
||||
float brightness = 0.2126 * fill.r + 0.7152 * fill.g + 0.0722 * fill.b;
|
||||
return (brightness > 0.75) ? vec3(0.11, 0.165, 0.208) : vec3(0.988, 0.988, 0.988);
|
||||
}
|
||||
|
||||
// Silhouette edge detection & rendering algorithem by leoneruggiero
|
||||
// https://www.shadertoy.com/view/DslXz2
|
||||
#define INFLATE 1
|
||||
|
||||
float GetTolerance(float d, float k)
|
||||
{
|
||||
// -------------------------------------------
|
||||
// Find a tolerance for depth that is constant
|
||||
// in view space (k in view space).
|
||||
//
|
||||
// tol = k*ddx(ZtoDepth(z))
|
||||
// -------------------------------------------
|
||||
|
||||
float A=- (z_far+z_near)/(z_far-z_near);
|
||||
float B=-2.0*z_far*z_near /(z_far-z_near);
|
||||
|
||||
d = d*2.0-1.0;
|
||||
|
||||
return -k*(d+A)*(d+A)/B;
|
||||
}
|
||||
|
||||
float DetectSilho(vec2 fragCoord, vec2 dir)
|
||||
{
|
||||
// -------------------------------------------
|
||||
// x0 ___ x1----o
|
||||
// :\ :
|
||||
// r0 : \ : r1
|
||||
// : \ :
|
||||
// o---x2 ___ x3
|
||||
//
|
||||
// r0 and r1 are the differences between actual
|
||||
// and expected (as if x0..3 where on the same
|
||||
// plane) depth values.
|
||||
// -------------------------------------------
|
||||
|
||||
float x0 = abs(texture2D(depth_tex, (fragCoord + dir*-2.0) / screen_size).r);
|
||||
float x1 = abs(texture2D(depth_tex, (fragCoord + dir*-1.0) / screen_size).r);
|
||||
float x2 = abs(texture2D(depth_tex, (fragCoord + dir* 0.0) / screen_size).r);
|
||||
float x3 = abs(texture2D(depth_tex, (fragCoord + dir* 1.0) / screen_size).r);
|
||||
|
||||
float d0 = (x1-x0);
|
||||
float d1 = (x2-x3);
|
||||
|
||||
float r0 = x1 + d0 - x2;
|
||||
float r1 = x2 + d1 - x1;
|
||||
|
||||
float tol = GetTolerance(x2, 0.04);
|
||||
|
||||
return smoothstep(0.0, tol*tol, max( - r0*r1, 0.0));
|
||||
|
||||
}
|
||||
|
||||
float DetectSilho(vec2 fragCoord)
|
||||
{
|
||||
return max(
|
||||
DetectSilho(fragCoord, vec2(1,0)), // Horizontal
|
||||
DetectSilho(fragCoord, vec2(0,1)) // Vertical
|
||||
);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
if (any(lessThan(clipping_planes_dots, ZERO)))
|
||||
|
@ -96,8 +167,18 @@ void main()
|
|||
color.rgb = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color.rgb, ZERO, 0.3333) : color.rgb;
|
||||
|
||||
//BBS: add outline_color
|
||||
if (is_outline)
|
||||
gl_FragColor = uniform_color;
|
||||
if (is_outline) {
|
||||
color = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a);
|
||||
vec2 fragCoord = gl_FragCoord.xy;
|
||||
float s = DetectSilho(fragCoord);
|
||||
// Makes silhouettes thicker.
|
||||
for(int i=1;i<=INFLATE; i++)
|
||||
{
|
||||
s = max(s, DetectSilho(fragCoord.xy + vec2(i, 0)));
|
||||
s = max(s, DetectSilho(fragCoord.xy + vec2(0, i)));
|
||||
}
|
||||
gl_FragColor = vec4(mix(color.rgb, getBackfaceColor(color.rgb), s), color.a);
|
||||
}
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
else if (use_environment_tex)
|
||||
gl_FragColor = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x, color.a);
|
||||
|
|
|
@ -36,6 +36,8 @@ uniform SlopeDetection slope;
|
|||
|
||||
//BBS: add outline_color
|
||||
uniform bool is_outline;
|
||||
uniform sampler2D depth_tex;
|
||||
uniform vec2 screen_size;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
uniform sampler2D environment_tex;
|
||||
|
@ -44,6 +46,9 @@ uniform bool is_outline;
|
|||
|
||||
uniform PrintVolumeDetection print_volume;
|
||||
|
||||
uniform float z_far;
|
||||
uniform float z_near;
|
||||
|
||||
in vec3 clipping_planes_dots;
|
||||
in float color_clip_plane_dot;
|
||||
|
||||
|
@ -54,6 +59,71 @@ in vec4 world_pos;
|
|||
in float world_normal_z;
|
||||
in vec3 eye_normal;
|
||||
|
||||
vec3 getBackfaceColor(vec3 fill) {
|
||||
float brightness = 0.2126 * fill.r + 0.7152 * fill.g + 0.0722 * fill.b;
|
||||
return (brightness > 0.75) ? vec3(0.11, 0.165, 0.208) : vec3(0.988, 0.988, 0.988);
|
||||
}
|
||||
|
||||
// Silhouette edge detection & rendering algorithem by leoneruggiero
|
||||
// https://www.shadertoy.com/view/DslXz2
|
||||
#define INFLATE 1
|
||||
|
||||
float GetTolerance(float d, float k)
|
||||
{
|
||||
// -------------------------------------------
|
||||
// Find a tolerance for depth that is constant
|
||||
// in view space (k in view space).
|
||||
//
|
||||
// tol = k*ddx(ZtoDepth(z))
|
||||
// -------------------------------------------
|
||||
|
||||
float A=- (z_far+z_near)/(z_far-z_near);
|
||||
float B=-2.0*z_far*z_near /(z_far-z_near);
|
||||
|
||||
d = d*2.0-1.0;
|
||||
|
||||
return -k*(d+A)*(d+A)/B;
|
||||
}
|
||||
|
||||
float DetectSilho(vec2 fragCoord, vec2 dir)
|
||||
{
|
||||
// -------------------------------------------
|
||||
// x0 ___ x1----o
|
||||
// :\ :
|
||||
// r0 : \ : r1
|
||||
// : \ :
|
||||
// o---x2 ___ x3
|
||||
//
|
||||
// r0 and r1 are the differences between actual
|
||||
// and expected (as if x0..3 where on the same
|
||||
// plane) depth values.
|
||||
// -------------------------------------------
|
||||
|
||||
float x0 = abs(texture(depth_tex, (fragCoord + dir*-2.0) / screen_size).r);
|
||||
float x1 = abs(texture(depth_tex, (fragCoord + dir*-1.0) / screen_size).r);
|
||||
float x2 = abs(texture(depth_tex, (fragCoord + dir* 0.0) / screen_size).r);
|
||||
float x3 = abs(texture(depth_tex, (fragCoord + dir* 1.0) / screen_size).r);
|
||||
|
||||
float d0 = (x1-x0);
|
||||
float d1 = (x2-x3);
|
||||
|
||||
float r0 = x1 + d0 - x2;
|
||||
float r1 = x2 + d1 - x1;
|
||||
|
||||
float tol = GetTolerance(x2, 0.04);
|
||||
|
||||
return smoothstep(0.0, tol*tol, max( - r0*r1, 0.0));
|
||||
|
||||
}
|
||||
|
||||
float DetectSilho(vec2 fragCoord)
|
||||
{
|
||||
return max(
|
||||
DetectSilho(fragCoord, vec2(1,0)), // Horizontal
|
||||
DetectSilho(fragCoord, vec2(0,1)) // Vertical
|
||||
);
|
||||
}
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
|
@ -98,8 +168,18 @@ void main()
|
|||
color.rgb = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color.rgb, ZERO, 0.3333) : color.rgb;
|
||||
|
||||
//BBS: add outline_color
|
||||
if (is_outline)
|
||||
out_color = uniform_color;
|
||||
if (is_outline) {
|
||||
color = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a);
|
||||
vec2 fragCoord = gl_FragCoord.xy;
|
||||
float s = DetectSilho(fragCoord);
|
||||
// Makes silhouettes thicker.
|
||||
for(int i=1;i<=INFLATE; i++)
|
||||
{
|
||||
s = max(s, DetectSilho(fragCoord.xy + vec2(i, 0)));
|
||||
s = max(s, DetectSilho(fragCoord.xy + vec2(0, i)));
|
||||
}
|
||||
out_color = vec4(mix(color.rgb, getBackfaceColor(color.rgb), s), color.a);
|
||||
}
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
else if (use_environment_tex)
|
||||
out_color = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x, color.a);
|
||||
|
|
|
@ -200,6 +200,8 @@ void AppConfig::set_defaults()
|
|||
if (get("show_3d_navigator").empty())
|
||||
set_bool("show_3d_navigator", true);
|
||||
|
||||
if (get("show_outline").empty())
|
||||
set_bool("show_outline", false);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
|
|
|
@ -423,7 +423,7 @@ void GLVolume::render()
|
|||
}
|
||||
|
||||
//BBS: add outline related logic
|
||||
void GLVolume::render_with_outline(const Transform3d &view_model_matrix)
|
||||
void GLVolume::render_with_outline(const GUI::Size& cnv_size)
|
||||
{
|
||||
if (!is_active)
|
||||
return;
|
||||
|
@ -435,37 +435,79 @@ void GLVolume::render_with_outline(const Transform3d &view_model_matrix)
|
|||
ModelObjectPtrs &model_objects = GUI::wxGetApp().model().objects;
|
||||
std::vector<ColorRGBA> colors = get_extruders_colors();
|
||||
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilMask(0xFF);
|
||||
glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
glStencilFunc(GL_ALWAYS, 0xff, 0xFF);
|
||||
|
||||
const GUI::OpenGLManager::EFramebufferType framebuffers_type = GUI::OpenGLManager::get_framebuffers_type();
|
||||
if (framebuffers_type == GUI::OpenGLManager::EFramebufferType::Unknown) {
|
||||
// No supported, degrade to normal rendering
|
||||
simple_render(shader, model_objects, colors);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2nd. render pass: now draw slightly scaled versions of the objects, this time disabling stencil writing.
|
||||
// Because the stencil buffer is now filled with several 1s. The parts of the buffer that are 1 are not drawn, thus only drawing
|
||||
// the objects' size differences, making it look like borders.
|
||||
glStencilFunc(GL_NOTEQUAL, 0xff, 0xFF);
|
||||
glStencilMask(0x00);
|
||||
float scale = 1.02f;
|
||||
ColorRGBA body_color = { 1.0f, 1.0f, 1.0f, 1.0f }; //red
|
||||
// 1st. render pass, render the model into a separate render target that has only depth buffer
|
||||
GLuint depth_fbo = 0;
|
||||
GLuint depth_tex = 0;
|
||||
if (framebuffers_type == GUI::OpenGLManager::EFramebufferType::Arb) {
|
||||
glsafe(::glGenFramebuffers(1, &depth_fbo));
|
||||
glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo));
|
||||
|
||||
model.set_color(body_color);
|
||||
shader->set_uniform("is_outline", true);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glsafe(::glGenTextures(1, &depth_tex));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, depth_tex));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, cnv_size.get_width(), cnv_size.get_height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr));
|
||||
|
||||
Transform3d matrix = view_model_matrix;
|
||||
matrix.scale(scale);
|
||||
shader->set_uniform("view_model_matrix", matrix);
|
||||
glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0));
|
||||
} else {
|
||||
glsafe(::glGenFramebuffersEXT(1, &depth_fbo));
|
||||
glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, depth_fbo));
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glsafe(::glGenTextures(1, &depth_tex));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, depth_tex));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, cnv_size.get_width(), cnv_size.get_height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr));
|
||||
|
||||
glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_tex, 0));
|
||||
}
|
||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||
if (tverts_range == std::make_pair<size_t, size_t>(0, -1))
|
||||
model.render();
|
||||
else
|
||||
model.render(this->tverts_range);
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
// 2nd. render pass, just a normal render with the depth buffer passed as a texture
|
||||
if (framebuffers_type == GUI::OpenGLManager::EFramebufferType::Arb) {
|
||||
glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, 0));
|
||||
} else if (framebuffers_type == GUI::OpenGLManager::EFramebufferType::Ext) {
|
||||
glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||
}
|
||||
shader->set_uniform("is_outline", true);
|
||||
shader->set_uniform("screen_size", Vec2f{cnv_size.get_width(), cnv_size.get_height()});
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, depth_tex));
|
||||
shader->set_uniform("depth_tex", 0);
|
||||
simple_render(shader, model_objects, colors);
|
||||
|
||||
// Some clean up to do
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||
shader->set_uniform("is_outline", false);
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
if (framebuffers_type == GUI::OpenGLManager::EFramebufferType::Arb) {
|
||||
glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, 0));
|
||||
if (depth_fbo != 0)
|
||||
glsafe(::glDeleteFramebuffers(1, &depth_fbo));
|
||||
} else if (framebuffers_type == GUI::OpenGLManager::EFramebufferType::Ext) {
|
||||
glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||
if (depth_fbo != 0)
|
||||
glsafe(::glDeleteFramebuffersEXT(1, &depth_fbo));
|
||||
}
|
||||
if (depth_tex != 0)
|
||||
glsafe(::glDeleteTextures(1, &depth_tex));
|
||||
}
|
||||
|
||||
//BBS add render for simple case
|
||||
|
@ -847,8 +889,8 @@ int GLVolumeCollection::get_selection_support_threshold_angle(bool &enable_suppo
|
|||
}
|
||||
|
||||
//BBS: add outline drawing logic
|
||||
void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix,
|
||||
std::function<bool(const GLVolume&)> filter_func, bool with_outline) const
|
||||
void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix, const GUI::Size& cnv_size,
|
||||
std::function<bool(const GLVolume&)> filter_func) const
|
||||
{
|
||||
GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func);
|
||||
if (to_render.empty())
|
||||
|
@ -953,9 +995,9 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
|||
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||
shader->set_uniform("view_normal_matrix", view_normal_matrix);
|
||||
//BBS: add outline related logic
|
||||
//if (with_outline && volume.first->selected)
|
||||
// volume.first->render_with_outline(view_matrix * model_matrix);
|
||||
//else
|
||||
if (volume.first->selected && GUI::wxGetApp().show_outline())
|
||||
volume.first->render_with_outline(cnv_size);
|
||||
else
|
||||
volume.first->render();
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
|
|
|
@ -39,6 +39,10 @@ extern Slic3r::ColorRGBA adjust_color_for_rendering(const Slic3r::C
|
|||
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
class Size;
|
||||
}
|
||||
|
||||
class SLAPrintObject;
|
||||
enum SLAPrintObjectStep : unsigned int;
|
||||
class BuildVolume;
|
||||
|
@ -322,7 +326,7 @@ public:
|
|||
virtual void render();
|
||||
|
||||
//BBS: add outline related logic and add virtual specifier
|
||||
virtual void render_with_outline(const Transform3d &view_model_matrix);
|
||||
virtual void render_with_outline(const GUI::Size& cnv_size);
|
||||
|
||||
//BBS: add simple render function for thumbnail
|
||||
void simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector<ColorRGBA>& extruder_colors, bool ban_light =false);
|
||||
|
@ -355,7 +359,7 @@ class GLWipeTowerVolume : public GLVolume {
|
|||
public:
|
||||
GLWipeTowerVolume(const std::vector<ColorRGBA>& colors);
|
||||
void render() override;
|
||||
void render_with_outline(const Transform3d &view_model_matrix) override { render(); }
|
||||
void render_with_outline(const GUI::Size& cnv_size) override { render(); }
|
||||
|
||||
std::vector<GUI::GLModel> model_per_colors;
|
||||
bool IsTransparent();
|
||||
|
@ -465,8 +469,8 @@ public:
|
|||
int get_selection_support_threshold_angle(bool&) const;
|
||||
// Render the volumes by OpenGL.
|
||||
//BBS: add outline drawing logic
|
||||
void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix,
|
||||
std::function<bool(const GLVolume &)> filter_func = std::function<bool(const GLVolume &)>(), bool with_outline = true) const;
|
||||
void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix, const GUI::Size& cnv_size,
|
||||
std::function<bool(const GLVolume &)> filter_func = std::function<bool(const GLVolume &)>()) const;
|
||||
|
||||
// Clear the geometry
|
||||
void clear() { for (auto *v : volumes) delete v; volumes.clear(); }
|
||||
|
|
|
@ -143,6 +143,15 @@ static bool str_is_all_digit(const std::string &str) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Custom comparator for case-insensitive sorting
|
||||
static bool caseInsensitiveCompare(const std::string& a, const std::string& b) {
|
||||
std::string lowerA = a;
|
||||
std::string lowerB = b;
|
||||
std::transform(lowerA.begin(), lowerA.end(), lowerA.begin(), ::tolower);
|
||||
std::transform(lowerB.begin(), lowerB.end(), lowerB.begin(), ::tolower);
|
||||
return lowerA < lowerB;
|
||||
}
|
||||
|
||||
static bool delete_filament_preset_by_name(std::string delete_preset_name, std::string &selected_preset_name)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select preset, name %1%") % delete_preset_name;
|
||||
|
@ -692,11 +701,19 @@ wxBoxSizer *CreateFilamentPresetDialog::create_vendor_item()
|
|||
optionSizer->SetMinSize(OPTION_SIZE);
|
||||
horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
|
||||
|
||||
wxArrayString choices;
|
||||
for (const wxString vendor : filament_vendors) {
|
||||
choices.push_back(vendor);
|
||||
// Convert all std::any to std::string
|
||||
std::vector<std::string> string_vendors;
|
||||
for (const auto& vendor_any : filament_vendors) {
|
||||
string_vendors.push_back(std::any_cast<std::string>(vendor_any));
|
||||
}
|
||||
|
||||
// Sort the vendors alphabetically
|
||||
std::sort(string_vendors.begin(), string_vendors.end(), caseInsensitiveCompare);
|
||||
|
||||
wxArrayString choices;
|
||||
for (const std::string &vendor : string_vendors) {
|
||||
choices.push_back(wxString(vendor)); // Convert std::string to wxString before adding
|
||||
}
|
||||
choices.Sort();
|
||||
|
||||
wxBoxSizer *vendor_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_filament_vendor_combobox = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, NAME_OPTION_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
|
||||
|
|
|
@ -1244,7 +1244,7 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin)
|
|||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
render_shells();
|
||||
render_shells(canvas_width, canvas_height);
|
||||
|
||||
if (m_roles.empty())
|
||||
return;
|
||||
|
@ -4023,7 +4023,7 @@ void GCodeViewer::render_toolpaths()
|
|||
}
|
||||
}
|
||||
|
||||
void GCodeViewer::render_shells()
|
||||
void GCodeViewer::render_shells(int canvas_width, int canvas_height)
|
||||
{
|
||||
//BBS: add shell previewing logic
|
||||
if ((!m_shells.previewing && !m_shells.visible) || m_shells.volumes.empty())
|
||||
|
@ -4039,7 +4039,9 @@ void GCodeViewer::render_shells()
|
|||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.1f);
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, false, camera.get_view_matrix(), camera.get_projection_matrix());
|
||||
shader->set_uniform("z_far", camera.get_far_z());
|
||||
shader->set_uniform("z_near", camera.get_near_z());
|
||||
m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, false, camera.get_view_matrix(), camera.get_projection_matrix(), {canvas_width, canvas_height});
|
||||
shader->set_uniform("emission_factor", 0.0f);
|
||||
shader->stop_using();
|
||||
|
||||
|
|
|
@ -893,7 +893,7 @@ private:
|
|||
//void load_shells(const Print& print);
|
||||
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
|
||||
void render_toolpaths();
|
||||
void render_shells();
|
||||
void render_shells(int canvas_width, int canvas_height);
|
||||
|
||||
//BBS: GUI refactor: add canvas size
|
||||
void render_legend(float &legend_height, int canvas_width, int canvas_height, int right_margin);
|
||||
|
|
|
@ -7234,6 +7234,12 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
const Size& cvn_size = get_canvas_size();
|
||||
{
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("z_far", camera.get_far_z());
|
||||
shader->set_uniform("z_near", camera.get_near_z());
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
|
@ -7245,7 +7251,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
if (m_picking_enabled && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
|
||||
int object_id = m_layers_editing.last_object_id;
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix(), [object_id](const GLVolume& volume) {
|
||||
m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix(), cvn_size, [object_id](const GLVolume& volume) {
|
||||
// Which volume to paint without the layer height profile shader?
|
||||
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
|
||||
});
|
||||
|
@ -7261,14 +7267,14 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
//BBS:add assemble view related logic
|
||||
// do not cull backfaces to show broken geometry, if any
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
m_volumes.render(type, m_picking_enabled, camera.get_view_matrix(), camera.get_projection_matrix(), [this, canvas_type](const GLVolume& volume) {
|
||||
m_volumes.render(type, m_picking_enabled, camera.get_view_matrix(), camera.get_projection_matrix(), cvn_size, [this, canvas_type](const GLVolume& volume) {
|
||||
if (canvas_type == ECanvasType::CanvasAssembleView) {
|
||||
return !volume.is_modifier && !volume.is_wipe_tower;
|
||||
}
|
||||
else {
|
||||
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
|
||||
}
|
||||
}, with_outline);
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -7295,14 +7301,14 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
}*/
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
//BBS:add assemble view related logic
|
||||
m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix(), [this, canvas_type](const GLVolume& volume) {
|
||||
m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix(), cvn_size, [this, canvas_type](const GLVolume& volume) {
|
||||
if (canvas_type == ECanvasType::CanvasAssembleView) {
|
||||
return !volume.is_modifier;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}, with_outline);
|
||||
});
|
||||
if (m_canvas_type == CanvasAssembleView && m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position() > 0) {
|
||||
const GLGizmosManager& gm = get_gizmos_manager();
|
||||
shader->stop_using();
|
||||
|
|
|
@ -344,6 +344,9 @@ private:
|
|||
bool show_3d_navigator() const { return app_config->get_bool("show_3d_navigator"); }
|
||||
void toggle_show_3d_navigator() const { app_config->set_bool("show_3d_navigator", !show_3d_navigator()); }
|
||||
|
||||
bool show_outline() const { return app_config->get_bool("show_outline"); }
|
||||
void toggle_show_outline() const { app_config->set_bool("show_outline", !show_outline()); }
|
||||
|
||||
wxString get_inf_dialog_contect () {return m_info_dialog_content;};
|
||||
|
||||
std::vector<std::string> split_str(std::string src, std::string separator);
|
||||
|
|
|
@ -2642,6 +2642,16 @@ void MainFrame::init_menubar_as_editor()
|
|||
m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT));
|
||||
},
|
||||
this, [this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->is_view3D_overhang_shown(); }, this);
|
||||
|
||||
append_menu_check_item(
|
||||
viewMenu, wxID_ANY, _L("Show Selected Outline (Experimental)"), _L("Show outline around selected object in 3D scene"),
|
||||
[this](wxCommandEvent&) {
|
||||
wxGetApp().toggle_show_outline();
|
||||
m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT));
|
||||
},
|
||||
this, [this]() { return m_tabpanel->GetSelection() == TabPosition::tp3DEditor; },
|
||||
[this]() { return wxGetApp().show_outline(); }, this);
|
||||
|
||||
/*viewMenu->AppendSeparator();
|
||||
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &Wireframe") + "\tCtrl+Shift+Enter", _L("Show wireframes in 3D scene"),
|
||||
[this](wxCommandEvent&) { m_plater->toggle_show_wireframe(); m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT)); }, this,
|
||||
|
|
|
@ -4457,7 +4457,7 @@ void TabPrinter::toggle_options()
|
|||
toggle_line(el, is_BBL_printer);
|
||||
|
||||
// SoftFever: hide non-BBL settings
|
||||
for (auto el : {"use_firmware_retraction", "use_relative_e_distances", "support_multi_bed_types", "pellet_modded_printer"})
|
||||
for (auto el : {"use_firmware_retraction", "use_relative_e_distances", "support_multi_bed_types", "pellet_modded_printer", "bed_mesh_max", "bed_mesh_min", "bed_mesh_probe_distance", "adaptive_bed_mesh_margin", "thumbnails"})
|
||||
toggle_line(el, !is_BBL_printer);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue