This commit is contained in:
enricoturri1966 2022-12-08 10:06:35 +01:00
commit ef9cd8cc31
120 changed files with 1881 additions and 9617 deletions

View File

@ -13,8 +13,8 @@ AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false

View File

@ -1,11 +0,0 @@
#version 110
uniform vec4 top_color;
uniform vec4 bottom_color;
varying vec2 tex_coord;
void main()
{
gl_FragColor = mix(bottom_color, top_color, tex_coord.y);
}

View File

@ -1,9 +0,0 @@
#version 110
varying vec2 tex_coord;
void main()
{
gl_Position = gl_Vertex;
tex_coord = gl_MultiTexCoord0.xy;
}

View File

@ -1,8 +0,0 @@
#version 110
uniform vec4 uniform_color;
void main()
{
gl_FragColor = uniform_color;
}

View File

@ -1,6 +0,0 @@
#version 110
void main()
{
gl_Position = ftransform();
}

View File

@ -1,10 +0,0 @@
#version 110
uniform sampler2D uniform_texture;
varying vec2 tex_coord;
void main()
{
gl_FragColor = texture2D(uniform_texture, tex_coord);
}

View File

@ -1,9 +0,0 @@
#version 110
varying vec2 tex_coord;
void main()
{
gl_Position = ftransform();
tex_coord = gl_MultiTexCoord0.xy;
}

View File

@ -1,79 +0,0 @@
#version 110
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
const float EPSILON = 0.0001;
struct PrintVolumeDetection
{
// 0 = rectangle, 1 = circle, 2 = custom, 3 = invalid
int type;
// type = 0 (rectangle):
// x = min.x, y = min.y, z = max.x, w = max.y
// type = 1 (circle):
// x = center.x, y = center.y, z = radius
vec4 xy_data;
// x = min z, y = max z
vec2 z_data;
};
struct SlopeDetection
{
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
};
uniform vec4 uniform_color;
uniform SlopeDetection slope;
#ifdef ENABLE_ENVIRONMENT_MAP
uniform sampler2D environment_tex;
uniform bool use_environment_tex;
#endif // ENABLE_ENVIRONMENT_MAP
varying vec3 clipping_planes_dots;
// x = diffuse, y = specular;
varying vec2 intensity;
uniform PrintVolumeDetection print_volume;
varying vec4 world_pos;
varying float world_normal_z;
varying vec3 eye_normal;
void main()
{
if (any(lessThan(clipping_planes_dots, ZERO)))
discard;
vec3 color = uniform_color.rgb;
float alpha = uniform_color.a;
if (slope.actived && world_normal_z < slope.normal_z - EPSILON) {
color = vec3(0.7, 0.7, 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);
}
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;
#ifdef ENABLE_ENVIRONMENT_MAP
if (use_environment_tex)
gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
else
#endif
gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
}

View File

@ -1,71 +0,0 @@
#version 110
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SHININESS 5.0
#define INTENSITY_AMBIENT 0.3
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
struct SlopeDetection
{
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
};
uniform mat4 volume_world_matrix;
uniform SlopeDetection slope;
// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane.
uniform vec2 z_range;
// Clipping plane - general orientation. Used by the SLA gizmo.
uniform vec4 clipping_plane;
// x = diffuse, y = specular;
varying vec2 intensity;
varying vec3 clipping_planes_dots;
varying vec4 world_pos;
varying float world_normal_z;
varying vec3 eye_normal;
void main()
{
// First transform the normal into camera space and normalize the result.
eye_normal = normalize(gl_NormalMatrix * gl_Normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
// Point in homogenous coordinates.
world_pos = volume_world_matrix * gl_Vertex;
// z component of normal vector in world coordinate used for slope shading
world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * gl_Normal)).z : 0.0;
gl_Position = ftransform();
// Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z);
}

View File

@ -1,12 +0,0 @@
#version 110
uniform vec4 uniform_color;
uniform float emission_factor;
// x = tainted, y = specular;
varying vec2 intensity;
void main()
{
gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
}

View File

@ -1,38 +0,0 @@
#version 110
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
// x = tainted, y = specular;
varying vec2 intensity;
void main()
{
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
gl_Position = ftransform();
}

View File

@ -1,12 +0,0 @@
#version 110
uniform vec4 uniform_color;
uniform float emission_factor;
// x = tainted, y = specular;
varying vec2 intensity;
void main()
{
gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
}

View File

@ -1,46 +0,0 @@
#version 110
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
// vertex attributes
attribute vec3 v_position;
attribute vec3 v_normal;
// instance attributes
attribute vec3 i_offset;
attribute vec2 i_scales;
// x = tainted, y = specular;
varying vec2 intensity;
void main()
{
// First transform the normal into camera space and normalize the result.
vec3 eye_normal = normalize(gl_NormalMatrix * v_normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec4 world_position = vec4(v_position * vec3(vec2(1.5 * i_scales.x), 1.5 * i_scales.y) + i_offset - vec3(0.0, 0.0, 0.5 * i_scales.y), 1.0);
vec3 eye_position = (gl_ModelViewMatrix * world_position).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
gl_Position = gl_ProjectionMatrix * vec4(eye_position, 1.0);
}

View File

@ -1,6 +0,0 @@
#version 110
void main()
{
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}

View File

@ -1,11 +0,0 @@
#version 110
uniform float offset;
void main()
{
// Add small epsilon to z to solve z-fighting between painted triangles and contour lines.
vec4 clip_position = gl_ModelViewProjectionMatrix * gl_Vertex;
clip_position.z -= offset * abs(clip_position.w);
gl_Position = clip_position;
}

View File

@ -1,60 +0,0 @@
#version 110
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
const float EPSILON = 0.0001;
uniform vec4 uniform_color;
varying vec3 clipping_planes_dots;
varying vec4 model_pos;
uniform bool volume_mirrored;
void main()
{
if (any(lessThan(clipping_planes_dots, ZERO)))
discard;
vec3 color = uniform_color.rgb;
float alpha = uniform_color.a;
vec3 triangle_normal = normalize(cross(dFdx(model_pos.xyz), dFdy(model_pos.xyz)));
#ifdef FLIP_TRIANGLE_NORMALS
triangle_normal = -triangle_normal;
#endif
if (volume_mirrored)
triangle_normal = -triangle_normal;
// First transform the normal into camera space and normalize the result.
vec3 eye_normal = normalize(gl_NormalMatrix * triangle_normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
// x = diffuse, y = specular;
vec2 intensity = vec2(0.0, 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec3 position = (gl_ModelViewMatrix * model_pos).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
}

View File

@ -1,23 +0,0 @@
#version 110
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
uniform mat4 volume_world_matrix;
// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane.
uniform vec2 z_range;
// Clipping plane - general orientation. Used by the SLA gizmo.
uniform vec4 clipping_plane;
varying vec3 clipping_planes_dots;
varying vec4 model_pos;
void main()
{
model_pos = gl_Vertex;
// Point in homogenous coordinates.
vec4 world_pos = volume_world_matrix * gl_Vertex;
gl_Position = ftransform();
// Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z);
}

View File

@ -1,36 +0,0 @@
#version 110
const vec3 back_color_dark = vec3(0.235, 0.235, 0.235);
const vec3 back_color_light = vec3(0.365, 0.365, 0.365);
uniform sampler2D texture;
uniform bool transparent_background;
uniform bool svg_source;
varying vec2 tex_coord;
vec4 svg_color()
{
// takes foreground from texture
vec4 fore_color = texture2D(texture, tex_coord);
// calculates radial gradient
vec3 back_color = vec3(mix(back_color_light, back_color_dark, smoothstep(0.0, 0.5, length(abs(tex_coord.xy) - vec2(0.5)))));
// blends foreground with background
return vec4(mix(back_color, fore_color.rgb, fore_color.a), transparent_background ? fore_color.a : 1.0);
}
vec4 non_svg_color()
{
// takes foreground from texture
vec4 color = texture2D(texture, tex_coord);
return vec4(color.rgb, transparent_background ? color.a * 0.25 : color.a);
}
void main()
{
vec4 color = svg_source ? svg_color() : non_svg_color();
color.a = transparent_background ? color.a * 0.5 : color.a;
gl_FragColor = color;
}

View File

@ -1,9 +0,0 @@
#version 110
varying vec2 tex_coord;
void main()
{
gl_Position = ftransform();
tex_coord = gl_MultiTexCoord0.xy;
}

View File

@ -1,18 +0,0 @@
#version 110
const vec4 BLACK = vec4(vec3(0.1), 1.0);
const vec4 WHITE = vec4(vec3(1.0), 1.0);
const float emission_factor = 0.25;
// x = tainted, y = specular;
varying vec2 intensity;
varying vec3 world_position;
uniform vec3 world_center;
void main()
{
vec3 delta = world_position - world_center;
vec4 color = delta.x * delta.y * delta.z > 0.0 ? BLACK : WHITE;
gl_FragColor = vec4(vec3(intensity.y) + color.rgb * (intensity.x + emission_factor), 1.0);
}

View File

@ -1,40 +0,0 @@
#version 110
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
// x = tainted, y = specular;
varying vec2 intensity;
varying vec3 world_position;
void main()
{
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
world_position = gl_Vertex.xyz;
gl_Position = ftransform();
}

View File

@ -1,28 +0,0 @@
#version 110
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0);
// x = ambient, y = top diffuse, z = front diffuse, w = global
uniform vec4 light_intensity;
uniform vec4 uniform_color;
varying vec3 eye_normal;
void main()
{
vec3 normal = normalize(eye_normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. Take the abs value to light the lines no matter in which direction the normal points.
float NdotL = abs(dot(normal, LIGHT_TOP_DIR));
float intensity = light_intensity.x + NdotL * light_intensity.y;
// Perform the same lighting calculation for the 2nd light source.
NdotL = abs(dot(normal, LIGHT_FRONT_DIR));
intensity += NdotL * light_intensity.z;
gl_FragColor = vec4(uniform_color.rgb * light_intensity.w * intensity, uniform_color.a);
}

View File

@ -1,9 +0,0 @@
#version 110
varying vec3 eye_normal;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
eye_normal = gl_NormalMatrix * gl_Normal;
}

View File

@ -1,41 +0,0 @@
#version 110
#define M_PI 3.1415926535897932384626433832795
// 2D texture (1D texture split by the rows) of color along the object Z axis.
uniform sampler2D z_texture;
// Scaling from the Z texture rows coordinate to the normalized texture row coordinate.
uniform float z_to_texture_row;
uniform float z_texture_row_to_normalized;
uniform float z_cursor;
uniform float z_cursor_band_width;
// x = tainted, y = specular;
varying vec2 intensity;
varying float object_z;
void main()
{
float object_z_row = z_to_texture_row * object_z;
// Index of the row in the texture.
float z_texture_row = floor(object_z_row);
// Normalized coordinate from 0. to 1.
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 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.
float dx_vtc = dFdx(z_in_cells);
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 = 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);
}

View File

@ -1,52 +0,0 @@
#version 110
#define INTENSITY_CORRECTION 0.6
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SHININESS 5.0
#define INTENSITY_AMBIENT 0.3
uniform mat4 volume_world_matrix;
uniform float object_max_z;
// x = tainted, y = specular;
varying vec2 intensity;
varying float object_z;
void main()
{
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular)
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
// Scaled to widths of the Z texture.
if (object_max_z > 0.0)
// when rendering the overlay
object_z = object_max_z * gl_MultiTexCoord0.y;
else
// when rendering the volumes
object_z = (volume_world_matrix * gl_Vertex).z;
gl_Position = ftransform();
}

View File

@ -920,28 +920,34 @@ template<class G> auto within(const G &g) { return Within<G>{g}; }
namespace detail {
// Returns true in case traversal should continue,
// returns false if traversal should stop (for example if the first hit was found).
template<int Dims, typename T, typename Pred, typename Fn>
void traverse_recurse(const Tree<Dims, T> &tree,
bool traverse_recurse(const Tree<Dims, T> &tree,
size_t idx,
Pred && pred,
Fn && callback)
{
assert(tree.node(idx).is_valid());
if (!pred(tree.node(idx))) return;
if (!pred(tree.node(idx)))
// Continue traversal.
return true;
if (tree.node(idx).is_leaf()) {
callback(tree.node(idx));
// Callback returns true to continue traversal, false to stop traversal.
return callback(tree.node(idx));
} else {
// call this with left and right node idx:
auto trv = [&](size_t idx) {
traverse_recurse(tree, idx, std::forward<Pred>(pred),
auto trv = [&](size_t idx) -> bool {
return traverse_recurse(tree, idx, std::forward<Pred>(pred),
std::forward<Fn>(callback));
};
// Left / right child node index.
trv(Tree<Dims, T>::left_child_idx(idx));
// Returns true if both children allow the traversal to continue.
return trv(Tree<Dims, T>::left_child_idx(idx)) &&
trv(Tree<Dims, T>::right_child_idx(idx));
}
}
@ -952,6 +958,7 @@ void traverse_recurse(const Tree<Dims, T> &tree,
// traverse(tree, intersecting(QueryBox), [](size_t face_idx) {
// /* ... */
// });
// Callback shall return true to continue traversal, false if it wants to stop traversal, for example if it found the answer.
template<int Dims, typename T, typename Predicate, typename Fn>
void traverse(const Tree<Dims, T> &tree, Predicate &&pred, Fn &&callback)
{

View File

@ -95,10 +95,8 @@ public:
bool all_paths_inside_vertices_and_normals_interleaved(const std::vector<float>& paths, const Eigen::AlignedBox<float, 3>& bbox, bool ignore_bottom = true) const;
#if ENABLE_LEGACY_OPENGL_REMOVAL
const std::pair<std::vector<Vec2d>, std::vector<Vec2d>>& top_bottom_convex_hull_decomposition_scene() const { return m_top_bottom_convex_hull_decomposition_scene; }
const std::pair<std::vector<Vec2d>, std::vector<Vec2d>>& top_bottom_convex_hull_decomposition_bed() const { return m_top_bottom_convex_hull_decomposition_bed; }
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
private:
// Source definition of the print bed geometry (PrintConfig::bed_shape)

View File

@ -130,6 +130,8 @@ set(SLIC3R_SOURCES
GCode/PressureEqualizer.hpp
GCode/PrintExtents.cpp
GCode/PrintExtents.hpp
GCode/RetractWhenCrossingPerimeters.cpp
GCode/RetractWhenCrossingPerimeters.hpp
GCode/SpiralVase.cpp
GCode/SpiralVase.hpp
GCode/SeamPlacer.cpp

View File

@ -140,6 +140,21 @@ namespace ClipperUtils {
out.reserve(src.size());
for (const Polygon &p : src)
out.emplace_back(clip_clipper_polygon_with_subject_bbox(p, bbox));
out.erase(
std::remove_if(out.begin(), out.end(), [](const Polygon &polygon) { return polygon.empty(); }),
out.end());
return out;
}
[[nodiscard]] Polygons clip_clipper_polygons_with_subject_bbox(const ExPolygon &src, const BoundingBox &bbox)
{
Polygons out;
out.reserve(src.num_contours());
out.emplace_back(clip_clipper_polygon_with_subject_bbox(src.contour, bbox));
for (const Polygon &p : src.holes)
out.emplace_back(clip_clipper_polygon_with_subject_bbox(p, bbox));
out.erase(
std::remove_if(out.begin(), out.end(), [](const Polygon &polygon) { return polygon.empty(); }),
out.end());
return out;
}
}
@ -794,6 +809,8 @@ Polylines _clipper_pl_closed(ClipperLib::ClipType clipType, PathProvider1 &&subj
return retval;
}
Slic3r::Polylines diff_pl(const Slic3r::Polyline &subject, const Slic3r::Polygons &clip)
{ return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::SinglePathProvider(subject.points), ClipperUtils::PolygonsProvider(clip)); }
Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip)
{ return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::PolylinesProvider(subject), ClipperUtils::PolygonsProvider(clip)); }
Slic3r::Polylines diff_pl(const Slic3r::Polyline &subject, const Slic3r::ExPolygon &clip)

View File

@ -323,6 +323,7 @@ namespace ClipperUtils {
void clip_clipper_polygon_with_subject_bbox(const Polygon &src, const BoundingBox &bbox, Polygon &out);
[[nodiscard]] Polygon clip_clipper_polygon_with_subject_bbox(const Polygon &src, const BoundingBox &bbox);
[[nodiscard]] Polygons clip_clipper_polygons_with_subject_bbox(const Polygons &src, const BoundingBox &bbox);
[[nodiscard]] Polygons clip_clipper_polygons_with_subject_bbox(const ExPolygon &src, const BoundingBox &bbox);
}
// offset Polygons
@ -427,6 +428,7 @@ Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::ExPoly
Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Surfaces &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfaces &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::ExPolygons diff_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polylines diff_pl(const Slic3r::Polyline &subject, const Slic3r::Polygons &clip);
Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip);
Slic3r::Polylines diff_pl(const Slic3r::Polyline &subject, const Slic3r::ExPolygon &clip);
Slic3r::Polylines diff_pl(const Slic3r::Polyline &subject, const Slic3r::ExPolygons &clip);

View File

@ -3090,7 +3090,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role)
}
if (m_config.only_retract_when_crossing_perimeters && m_layer != nullptr &&
m_config.fill_density.value > 0 && m_layer->any_internal_region_slice_contains(travel))
m_config.fill_density.value > 0 && m_retract_when_crossing_perimeters.travel_inside_internal_regions(*m_layer, travel))
// Skip retraction if travel is contained in an internal slice *and*
// internal infill is enabled (so that stringing is entirely not visible).
//FIXME any_internal_region_slice_contains() is potentionally very slow, it shall test for the bounding boxes first.

View File

@ -12,6 +12,7 @@
#include "GCode/AvoidCrossingPerimeters.hpp"
#include "GCode/CoolingBuffer.hpp"
#include "GCode/FindReplace.hpp"
#include "GCode/RetractWhenCrossingPerimeters.hpp"
#include "GCode/SpiralVase.hpp"
#include "GCode/ToolOrdering.hpp"
#include "GCode/WipeTower.hpp"
@ -349,6 +350,7 @@ private:
Wipe m_wipe;
AvoidCrossingPerimeters m_avoid_crossing_perimeters;
JPSPathFinder m_avoid_curled_filaments;
RetractWhenCrossingPerimeters m_retract_when_crossing_perimeters;
bool m_enable_loop_clipping;
// If enabled, the G-code generator will put following comments at the ends
// of the G-code lines: _EXTRUDE_SET_SPEED, _WIPE, _BRIDGE_FAN_START, _BRIDGE_FAN_END

View File

@ -35,16 +35,12 @@ static const float DEFAULT_TRAVEL_ACCELERATION = 1250.0f;
static const size_t MIN_EXTRUDERS_COUNT = 5;
static const float DEFAULT_FILAMENT_DIAMETER = 1.75f;
static const float DEFAULT_FILAMENT_DENSITY = 1.245f;
#if ENABLE_USED_FILAMENT_POST_PROCESS
static const float DEFAULT_FILAMENT_COST = 0.0f;
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
static const Slic3r::Vec3f DEFAULT_EXTRUDER_OFFSET = Slic3r::Vec3f::Zero();
// taken from PrusaResearch.ini - [printer:Original Prusa i3 MK2.5 MMU2]
static const std::vector<std::string> DEFAULT_EXTRUDER_COLORS = { "#FF8000", "#DB5182", "#3EC0FF", "#FF4F4F", "#FBEB7D" };
#if ENABLE_PROCESS_G2_G3_LINES
static const std::string INTERNAL_G2G3_TAG = "!#!#! internal only - from G2/G3 expansion !#!#!";
#endif // ENABLE_PROCESS_G2_G3_LINES
namespace Slic3r {
@ -357,314 +353,6 @@ void GCodeProcessor::TimeProcessor::reset()
machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].enabled = true;
}
#if !ENABLE_USED_FILAMENT_POST_PROCESS
void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, std::vector<GCodeProcessorResult::MoveVertex>& moves, std::vector<size_t>& lines_ends)
{
FilePtr in{ boost::nowide::fopen(filename.c_str(), "rb") };
if (in.f == nullptr)
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nCannot open file for reading.\n"));
// temporary file to contain modified gcode
std::string out_path = filename + ".postprocess";
FilePtr out{ boost::nowide::fopen(out_path.c_str(), "wb") };
if (out.f == nullptr) {
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nCannot open file for writing.\n"));
}
auto time_in_minutes = [](float time_in_seconds) {
assert(time_in_seconds >= 0.f);
return int((time_in_seconds + 0.5f) / 60.0f);
};
auto time_in_last_minute = [](float time_in_seconds) {
assert(time_in_seconds <= 60.0f);
return time_in_seconds / 60.0f;
};
auto format_line_M73_main = [](const std::string& mask, int percent, int time) {
char line_M73[64];
sprintf(line_M73, mask.c_str(),
std::to_string(percent).c_str(),
std::to_string(time).c_str());
return std::string(line_M73);
};
auto format_line_M73_stop_int = [](const std::string& mask, int time) {
char line_M73[64];
sprintf(line_M73, mask.c_str(), std::to_string(time).c_str());
return std::string(line_M73);
};
auto format_time_float = [](float time) {
return Slic3r::float_to_string_decimal_point(time, 2);
};
auto format_line_M73_stop_float = [format_time_float](const std::string& mask, float time) {
char line_M73[64];
sprintf(line_M73, mask.c_str(), format_time_float(time).c_str());
return std::string(line_M73);
};
std::string gcode_line;
size_t g1_lines_counter = 0;
// keeps track of last exported pair <percent, remaining time>
std::array<std::pair<int, int>, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> last_exported_main;
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
last_exported_main[i] = { 0, time_in_minutes(machines[i].time) };
}
// keeps track of last exported remaining time to next printer stop
std::array<int, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> last_exported_stop;
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
last_exported_stop[i] = time_in_minutes(machines[i].time);
}
// buffer line to export only when greater than 64K to reduce writing calls
std::string export_line;
// replace placeholder lines with the proper final value
// gcode_line is in/out parameter, to reduce expensive memory allocation
auto process_placeholders = [&](std::string& gcode_line) {
unsigned int extra_lines_count = 0;
// remove trailing '\n'
auto line = std::string_view(gcode_line).substr(0, gcode_line.length() - 1);
std::string ret;
if (line.length() > 1) {
line = line.substr(1);
if (export_remaining_time_enabled &&
(line == reserved_tag(ETags::First_Line_M73_Placeholder) || line == reserved_tag(ETags::Last_Line_M73_Placeholder))) {
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
if (machine.enabled) {
// export pair <percent, remaining time>
ret += format_line_M73_main(machine.line_m73_main_mask.c_str(),
(line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? 0 : 100,
(line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? time_in_minutes(machine.time) : 0);
++extra_lines_count;
// export remaining time to next printer stop
if (line == reserved_tag(ETags::First_Line_M73_Placeholder) && !machine.stop_times.empty()) {
int to_export_stop = time_in_minutes(machine.stop_times.front().elapsed_time);
ret += format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop);
last_exported_stop[i] = to_export_stop;
++extra_lines_count;
}
}
}
}
else if (line == reserved_tag(ETags::Estimated_Printing_Time_Placeholder)) {
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
PrintEstimatedStatistics::ETimeMode mode = static_cast<PrintEstimatedStatistics::ETimeMode>(i);
if (mode == PrintEstimatedStatistics::ETimeMode::Normal || machine.enabled) {
char buf[128];
sprintf(buf, "; estimated printing time (%s mode) = %s\n",
(mode == PrintEstimatedStatistics::ETimeMode::Normal) ? "normal" : "silent",
get_time_dhms(machine.time).c_str());
ret += buf;
}
}
}
}
if (! ret.empty())
// Not moving the move operator on purpose, so that the gcode_line allocation will grow and it will not be reallocated after handful of lines are processed.
gcode_line = ret;
return std::tuple(!ret.empty(), (extra_lines_count == 0) ? extra_lines_count : extra_lines_count - 1);
};
// check for temporary lines
auto is_temporary_decoration = [](const std::string_view gcode_line) {
// remove trailing '\n'
assert(! gcode_line.empty());
assert(gcode_line.back() == '\n');
// return true for decorations which are used in processing the gcode but that should not be exported into the final gcode
// i.e.:
// bool ret = gcode_line.substr(0, gcode_line.length() - 1) == ";" + Layer_Change_Tag;
// ...
// return ret;
return false;
};
// Iterators for the normal and silent cached time estimate entry recently processed, used by process_line_G1.
auto g1_times_cache_it = Slic3r::reserve_vector<std::vector<TimeMachine::G1LinesCacheItem>::const_iterator>(machines.size());
for (const auto& machine : machines)
g1_times_cache_it.emplace_back(machine.g1_times_cache.begin());
// add lines M73 to exported gcode
auto process_line_G1 = [
// Lambdas, mostly for string formatting, all with an empty capture block.
time_in_minutes, format_time_float, format_line_M73_main, format_line_M73_stop_int, format_line_M73_stop_float, time_in_last_minute,
&self = std::as_const(*this),
// Caches, to be modified
&g1_times_cache_it, &last_exported_main, &last_exported_stop,
// String output
&export_line]
(const size_t g1_lines_counter) {
unsigned int exported_lines_count = 0;
if (self.export_remaining_time_enabled) {
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = self.machines[i];
if (machine.enabled) {
// export pair <percent, remaining time>
// Skip all machine.g1_times_cache below g1_lines_counter.
auto& it = g1_times_cache_it[i];
while (it != machine.g1_times_cache.end() && it->id < g1_lines_counter)
++it;
if (it != machine.g1_times_cache.end() && it->id == g1_lines_counter) {
std::pair<int, int> to_export_main = { int(100.0f * it->elapsed_time / machine.time),
time_in_minutes(machine.time - it->elapsed_time) };
if (last_exported_main[i] != to_export_main) {
export_line += format_line_M73_main(machine.line_m73_main_mask.c_str(),
to_export_main.first, to_export_main.second);
last_exported_main[i] = to_export_main;
++exported_lines_count;
}
// export remaining time to next printer stop
auto it_stop = std::upper_bound(machine.stop_times.begin(), machine.stop_times.end(), it->elapsed_time,
[](float value, const TimeMachine::StopTime& t) { return value < t.elapsed_time; });
if (it_stop != machine.stop_times.end()) {
int to_export_stop = time_in_minutes(it_stop->elapsed_time - it->elapsed_time);
if (last_exported_stop[i] != to_export_stop) {
if (to_export_stop > 0) {
if (last_exported_stop[i] != to_export_stop) {
export_line += format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop);
last_exported_stop[i] = to_export_stop;
++exported_lines_count;
}
}
else {
bool is_last = false;
auto next_it = it + 1;
is_last |= (next_it == machine.g1_times_cache.end());
if (next_it != machine.g1_times_cache.end()) {
auto next_it_stop = std::upper_bound(machine.stop_times.begin(), machine.stop_times.end(), next_it->elapsed_time,
[](float value, const TimeMachine::StopTime& t) { return value < t.elapsed_time; });
is_last |= (next_it_stop != it_stop);
std::string time_float_str = format_time_float(time_in_last_minute(it_stop->elapsed_time - it->elapsed_time));
std::string next_time_float_str = format_time_float(time_in_last_minute(it_stop->elapsed_time - next_it->elapsed_time));
is_last |= (string_to_double_decimal_point(time_float_str) > 0. && string_to_double_decimal_point(next_time_float_str) == 0.);
}
if (is_last) {
if (std::distance(machine.stop_times.begin(), it_stop) == static_cast<ptrdiff_t>(machine.stop_times.size() - 1))
export_line += format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop);
else
export_line += format_line_M73_stop_float(machine.line_m73_stop_mask.c_str(), time_in_last_minute(it_stop->elapsed_time - it->elapsed_time));
last_exported_stop[i] = to_export_stop;
++exported_lines_count;
}
}
}
}
}
}
}
}
return exported_lines_count;
};
// helper function to write to disk
size_t out_file_pos = 0;
lines_ends.clear();
auto write_string = [&export_line, &out, &out_path, &out_file_pos, &lines_ends](const std::string& str) {
fwrite((const void*)export_line.c_str(), 1, export_line.length(), out.f);
if (ferror(out.f)) {
out.close();
boost::nowide::remove(out_path.c_str());
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nIs the disk full?\n"));
}
for (size_t i = 0; i < export_line.size(); ++ i)
if (export_line[i] == '\n')
lines_ends.emplace_back(out_file_pos + i + 1);
out_file_pos += export_line.size();
export_line.clear();
};
unsigned int line_id = 0;
std::vector<std::pair<unsigned int, unsigned int>> offsets;
{
// Read the input stream 64kB at a time, extract lines and process them.
std::vector<char> buffer(65536 * 10, 0);
// Line buffer.
assert(gcode_line.empty());
for (;;) {
size_t cnt_read = ::fread(buffer.data(), 1, buffer.size(), in.f);
if (::ferror(in.f))
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nError while reading from file.\n"));
bool eof = cnt_read == 0;
auto it = buffer.begin();
auto it_bufend = buffer.begin() + cnt_read;
while (it != it_bufend || (eof && ! gcode_line.empty())) {
// Find end of line.
bool eol = false;
auto it_end = it;
for (; it_end != it_bufend && ! (eol = *it_end == '\r' || *it_end == '\n'); ++ it_end) ;
// End of line is indicated also if end of file was reached.
eol |= eof && it_end == it_bufend;
gcode_line.insert(gcode_line.end(), it, it_end);
if (eol) {
++line_id;
gcode_line += "\n";
// replace placeholder lines
auto [processed, lines_added_count] = process_placeholders(gcode_line);
if (processed && lines_added_count > 0)
offsets.push_back({ line_id, lines_added_count });
if (! processed && ! is_temporary_decoration(gcode_line) && GCodeReader::GCodeLine::cmd_is(gcode_line, "G1")) {
// remove temporary lines, add lines M73 where needed
unsigned int extra_lines_count = process_line_G1(g1_lines_counter ++);
if (extra_lines_count > 0)
offsets.push_back({ line_id, extra_lines_count });
}
export_line += gcode_line;
if (export_line.length() > 65535)
write_string(export_line);
gcode_line.clear();
}
// Skip EOL.
it = it_end;
if (it != it_bufend && *it == '\r')
++ it;
if (it != it_bufend && *it == '\n')
++ it;
}
if (eof)
break;
}
}
if (!export_line.empty())
write_string(export_line);
out.close();
in.close();
// updates moves' gcode ids which have been modified by the insertion of the M73 lines
unsigned int curr_offset_id = 0;
unsigned int total_offset = 0;
for (GCodeProcessorResult::MoveVertex& move : moves) {
while (curr_offset_id < static_cast<unsigned int>(offsets.size()) && offsets[curr_offset_id].first <= move.gcode_id) {
total_offset += offsets[curr_offset_id].second;
++curr_offset_id;
}
move.gcode_id += total_offset;
}
if (rename_file(out_path, filename))
throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + filename + '\n' +
"Is " + out_path + " locked?" + '\n');
}
#endif // !ENABLE_USED_FILAMENT_POST_PROCESS
void GCodeProcessor::UsedFilaments::reset()
{
color_change_cache = 0.0;
@ -755,9 +443,7 @@ void GCodeProcessorResult::reset() {
extruder_colors = std::vector<std::string>();
filament_diameters = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER);
filament_densities = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY);
#if ENABLE_USED_FILAMENT_POST_PROCESS
filament_cost = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_COST);
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
spiral_vase_layers = std::vector<std::pair<float, std::pair<size_t, size_t>>>();
time = 0;
@ -774,9 +460,7 @@ void GCodeProcessorResult::reset() {
extruder_colors = std::vector<std::string>();
filament_diameters = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER);
filament_densities = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY);
#if ENABLE_USED_FILAMENT_POST_PROCESS
filament_cost = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_COST);
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
spiral_vase_layers = std::vector<std::pair<float, std::pair<size_t, size_t>>>();
}
@ -873,9 +557,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
m_extruder_colors.resize(extruders_count);
m_result.filament_diameters.resize(extruders_count);
m_result.filament_densities.resize(extruders_count);
#if ENABLE_USED_FILAMENT_POST_PROCESS
m_result.filament_cost.resize(extruders_count);
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
m_extruder_temps.resize(extruders_count);
for (size_t i = 0; i < extruders_count; ++ i) {
@ -883,9 +565,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
m_extruder_colors[i] = static_cast<unsigned char>(i);
m_result.filament_diameters[i] = static_cast<float>(config.filament_diameter.get_at(i));
m_result.filament_densities[i] = static_cast<float>(config.filament_density.get_at(i));
#if ENABLE_USED_FILAMENT_POST_PROCESS
m_result.filament_cost[i] = static_cast<float>(config.filament_cost.get_at(i));
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
}
if ((m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware || m_flavor == gcfRepRapFirmware) && config.machine_limits_usage.value != MachineLimitsUsage::Ignore) {
@ -1006,7 +686,6 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
}
}
#if ENABLE_USED_FILAMENT_POST_PROCESS
const ConfigOptionFloats* filament_cost = config.option<ConfigOptionFloats>("filament_cost");
if (filament_cost != nullptr) {
m_result.filament_cost.clear();
@ -1021,7 +700,6 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
m_result.filament_cost.emplace_back(DEFAULT_FILAMENT_COST);
}
}
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
const ConfigOptionPoints* extruder_offset = config.option<ConfigOptionPoints>("extruder_offset");
if (extruder_offset != nullptr) {
@ -1438,11 +1116,7 @@ void GCodeProcessor::finalize(bool perform_post_process)
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
if (perform_post_process)
#if ENABLE_USED_FILAMENT_POST_PROCESS
post_process();
#else
m_time_processor.post_process(m_result.filename, m_result.moves, m_result.lines_ends);
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
#if ENABLE_GCODE_VIEWER_STATISTICS
m_result.time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - m_start_time).count();
#endif // ENABLE_GCODE_VIEWER_STATISTICS
@ -1688,12 +1362,10 @@ void GCodeProcessor::apply_config_simplify3d(const std::string& filename)
} else if (comment.find("filamentDensities") != comment.npos) {
m_result.filament_densities.clear();
extract_floats(comment, "filamentDensities", m_result.filament_densities);
#if ENABLE_USED_FILAMENT_POST_PROCESS
}
else if (comment.find("filamentPricesPerKg") != comment.npos) {
m_result.filament_cost.clear();
extract_floats(comment, "filamentPricesPerKg", m_result.filament_cost);
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
} else if (comment.find("extruderDiameter") != comment.npos) {
std::vector<float> extruder_diameters;
extract_floats(comment, "extruderDiameter", extruder_diameters);
@ -1709,14 +1381,9 @@ void GCodeProcessor::apply_config_simplify3d(const std::string& filename)
}
});
#if ENABLE_USED_FILAMENT_POST_PROCESS
if (m_result.extruders_count == 0)
m_result.extruders_count = std::max<size_t>(1, std::min(m_result.filament_diameters.size(),
std::min(m_result.filament_densities.size(), m_result.filament_cost.size())));
#else
if (m_result.extruders_count == 0)
m_result.extruders_count = std::max<size_t>(1, std::min(m_result.filament_diameters.size(), m_result.filament_densities.size()));
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
if (bed_size.is_defined()) {
m_result.bed_shape = {
@ -1749,10 +1416,8 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line, bool
switch (cmd[1]) {
case '0': { process_G0(line); break; } // Move
case '1': { process_G1(line); break; } // Move
#if ENABLE_PROCESS_G2_G3_LINES
case '2': { process_G2_G3(line, true); break; } // CW Arc Move
case '3': { process_G2_G3(line, false); break; } // CCW Arc Move
#endif // ENABLE_PROCESS_G2_G3_LINES
default: break;
}
break;
@ -2668,23 +2333,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
const float filament_diameter = (static_cast<size_t>(m_extruder_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[m_extruder_id] : m_result.filament_diameters.back();
const float filament_radius = 0.5f * filament_diameter;
const float area_filament_cross_section = static_cast<float>(M_PI) * sqr(filament_radius);
#if !ENABLE_PROCESS_G2_G3_LINES
auto absolute_position = [this, area_filament_cross_section](Axis axis, const GCodeReader::GCodeLine& lineG1) {
bool is_relative = (m_global_positioning_type == EPositioningType::Relative);
if (axis == E)
is_relative |= (m_e_local_positioning_type == EPositioningType::Relative);
if (lineG1.has(Slic3r::Axis(axis))) {
float lengthsScaleFactor = (m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f;
float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor;
if (axis == E && m_use_volumetric_e)
ret /= area_filament_cross_section;
return is_relative ? m_start_position[axis] + ret : m_origin[axis] + ret;
}
else
return m_start_position[axis];
};
#endif // !ENABLE_PROCESS_G2_G3_LINES
auto move_type = [this](const AxisCoords& delta_pos) {
EMoveType type = EMoveType::Noop;
@ -2712,11 +2360,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
// updates axes positions from line
for (unsigned char a = X; a <= E; ++a) {
#if ENABLE_PROCESS_G2_G3_LINES
m_end_position[a] = extract_absolute_position_on_axis((Axis)a, line, double(area_filament_cross_section));
#else
m_end_position[a] = absolute_position((Axis)a, line);
#endif // ENABLE_PROCESS_G2_G3_LINES
}
// updates feedrate from line, if present
@ -2749,7 +2393,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
m_mm3_per_mm_compare.update(area_toolpath_cross_section, m_extrusion_role);
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
#if ENABLE_PROCESS_G2_G3_LINES
if (m_forced_height > 0.0f)
m_height = m_forced_height;
else if (m_layer_id == 0)
@ -2758,16 +2401,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
if (m_end_position[Z] > m_extruded_last_z + EPSILON && delta_pos[Z] == 0.0)
m_height = m_end_position[Z] - m_extruded_last_z;
}
#else
if (m_forced_height > 0.0f)
m_height = m_forced_height;
else if (m_layer_id == 0)
m_height = (m_end_position[Z] <= double(m_first_layer_height)) ? m_end_position[Z] : m_first_layer_height;
else {
if (m_end_position[Z] > m_extruded_last_z + EPSILON)
m_height = m_end_position[Z] - m_extruded_last_z;
}
#endif // ENABLE_PROCESS_G2_G3_LINES
if (m_height == 0.0f)
m_height = DEFAULT_TOOLPATH_HEIGHT;
@ -2775,9 +2408,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
if (m_end_position[Z] == 0.0f || (m_extrusion_role == erCustom && m_layer_id == 0))
m_end_position[Z] = m_height;
#if ENABLE_PROCESS_G2_G3_LINES
if (line.comment() != INTERNAL_G2G3_TAG)
#endif // ENABLE_PROCESS_G2_G3_LINES
m_extruded_last_z = m_end_position[Z];
m_options_z_corrector.update(m_height);
@ -3010,14 +2641,9 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
}
// store move
#if ENABLE_PROCESS_G2_G3_LINES
store_move_vertex(type, line.comment() == INTERNAL_G2G3_TAG);
#else
store_move_vertex(type);
#endif // ENABLE_PROCESS_G2_G3_LINES
}
#if ENABLE_PROCESS_G2_G3_LINES
void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise)
{
if (!line.has('I') || !line.has('J'))
@ -3219,7 +2845,6 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc
process_gcode_line(line, false);
});
}
#endif // ENABLE_PROCESS_G2_G3_LINES
void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line)
{
@ -3757,7 +3382,6 @@ void GCodeProcessor::process_T(const std::string_view command)
}
}
#if ENABLE_USED_FILAMENT_POST_PROCESS
void GCodeProcessor::post_process()
{
FilePtr in{ boost::nowide::fopen(m_result.filename.c_str(), "rb") };
@ -4110,13 +3734,8 @@ void GCodeProcessor::post_process()
throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + m_result.filename + '\n' +
"Is " + out_path + " locked?" + '\n');
}
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
#if ENABLE_PROCESS_G2_G3_LINES
void GCodeProcessor::store_move_vertex(EMoveType type, bool internal_only)
#else
void GCodeProcessor::store_move_vertex(EMoveType type)
#endif // ENABLE_PROCESS_G2_G3_LINES
{
m_last_line_id = (type == EMoveType::Color_change || type == EMoveType::Pause_Print || type == EMoveType::Custom_GCode) ?
m_line_id + 1 :
@ -4136,12 +3755,8 @@ void GCodeProcessor::store_move_vertex(EMoveType type)
m_mm3_per_mm,
m_fan_speed,
m_extruder_temps[m_extruder_id],
#if ENABLE_PROCESS_G2_G3_LINES
static_cast<float>(m_result.moves.size()),
internal_only
#else
static_cast<float>(m_result.moves.size())
#endif // ENABLE_PROCESS_G2_G3_LINES
});
// stores stop time placeholders for later use
@ -4336,7 +3951,6 @@ void GCodeProcessor::update_estimated_times_stats()
m_result.print_statistics.used_filaments_per_role = m_used_filaments.filaments_per_role;
}
#if ENABLE_PROCESS_G2_G3_LINES
double GCodeProcessor::extract_absolute_position_on_axis(Axis axis, const GCodeReader::GCodeLine& line, double area_filament_cross_section)
{
if (line.has(Slic3r::Axis(axis))) {
@ -4353,7 +3967,6 @@ double GCodeProcessor::extract_absolute_position_on_axis(Axis axis, const GCodeR
else
return m_start_position[axis];
}
#endif // ENABLE_PROCESS_G2_G3_LINES
} /* namespace Slic3r */

View File

@ -63,9 +63,7 @@ namespace Slic3r {
std::vector<double> volumes_per_color_change;
std::map<size_t, double> volumes_per_extruder;
std::map<ExtrusionRole, std::pair<double, double>> used_filaments_per_role;
#if ENABLE_USED_FILAMENT_POST_PROCESS
std::map<size_t, double> cost_per_extruder;
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
std::array<Mode, static_cast<size_t>(ETimeMode::Count)> modes;
@ -78,9 +76,7 @@ namespace Slic3r {
volumes_per_color_change.clear();
volumes_per_extruder.clear();
used_filaments_per_role.clear();
#if ENABLE_USED_FILAMENT_POST_PROCESS
cost_per_extruder.clear();
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
}
};
@ -115,9 +111,7 @@ namespace Slic3r {
float fan_speed{ 0.0f }; // percentage
float temperature{ 0.0f }; // Celsius degrees
float time{ 0.0f }; // s
#if ENABLE_PROCESS_G2_G3_LINES
bool internal_only{ false };
#endif // ENABLE_PROCESS_G2_G3_LINES
float volumetric_rate() const { return feedrate * mm3_per_mm; }
};
@ -134,9 +128,7 @@ namespace Slic3r {
std::vector<std::string> extruder_colors;
std::vector<float> filament_diameters;
std::vector<float> filament_densities;
#if ENABLE_USED_FILAMENT_POST_PROCESS
std::vector<float> filament_cost;
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
PrintEstimatedStatistics print_statistics;
std::vector<CustomGCode::Item> custom_gcode_per_print_z;
@ -356,13 +348,7 @@ namespace Slic3r {
void reset();
#if ENABLE_USED_FILAMENT_POST_PROCESS
friend class GCodeProcessor;
#else
// post process the file with the given filename to add remaining time lines M73
// and updates moves' gcode ids accordingly
void post_process(const std::string& filename, std::vector<GCodeProcessorResult::MoveVertex>& moves, std::vector<size_t>& lines_ends);
#endif // !ENABLE_USED_FILAMENT_POST_PROCESS
};
struct UsedFilaments // filaments per ColorChange
@ -661,10 +647,8 @@ namespace Slic3r {
void process_G0(const GCodeReader::GCodeLine& line);
void process_G1(const GCodeReader::GCodeLine& line);
#if ENABLE_PROCESS_G2_G3_LINES
// Arc Move
void process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise);
#endif // ENABLE_PROCESS_G2_G3_LINES
// Retract or Set tool temperature
void process_G10(const GCodeReader::GCodeLine& line);
@ -766,18 +750,12 @@ namespace Slic3r {
void process_T(const GCodeReader::GCodeLine& line);
void process_T(const std::string_view command);
#if ENABLE_USED_FILAMENT_POST_PROCESS
// post process the file with the given filename to:
// 1) add remaining time lines M73 and update moves' gcode ids accordingly
// 2) update used filament data
void post_process();
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
#if ENABLE_PROCESS_G2_G3_LINES
void store_move_vertex(EMoveType type, bool internal_only = false);
#else
void store_move_vertex(EMoveType type);
#endif // ENABLE_PROCESS_G2_G3_LINES
void set_extrusion_role(ExtrusionRole role);
@ -803,9 +781,7 @@ namespace Slic3r {
void update_estimated_times_stats();
#if ENABLE_PROCESS_G2_G3_LINES
double extract_absolute_position_on_axis(Axis axis, const GCodeReader::GCodeLine& line, double area_filament_cross_section);
#endif // ENABLE_PROCESS_G2_G3_LINES
};
} /* namespace Slic3r */

View File

@ -0,0 +1,67 @@
#include "../ClipperUtils.hpp"
#include "../Layer.hpp"
#include "../Polyline.hpp"
#include "RetractWhenCrossingPerimeters.hpp"
namespace Slic3r {
bool RetractWhenCrossingPerimeters::travel_inside_internal_regions(const Layer &layer, const Polyline &travel)
{
if (m_layer != &layer) {
// Update cache.
m_layer = &layer;
m_internal_islands.clear();
m_aabbtree_internal_islands.clear();
// Collect expolygons of internal slices.
for (const LayerRegion *layerm : layer.regions())
for (const Surface &surface : layerm->slices().surfaces)
if (surface.is_internal())
m_internal_islands.emplace_back(&surface.expolygon);
// Calculate bounding boxes of internal slices.
class BBoxWrapper {
public:
BBoxWrapper(const size_t idx, const BoundingBox &bbox) :
m_idx(idx),
// Inflate the bounding box a bit to account for numerical issues.
m_bbox(bbox.min - Point(SCALED_EPSILON, SCALED_EPSILON), bbox.max + Point(SCALED_EPSILON, SCALED_EPSILON)) {}
size_t idx() const { return m_idx; }
const AABBTree::BoundingBox& bbox() const { return m_bbox; }
Point centroid() const { return ((m_bbox.min().cast<int64_t>() + m_bbox.max().cast<int64_t>()) / 2).cast<int32_t>(); }
private:
size_t m_idx;
AABBTree::BoundingBox m_bbox;
};
std::vector<BBoxWrapper> bboxes;
bboxes.reserve(m_internal_islands.size());
for (size_t i = 0; i < m_internal_islands.size(); ++ i)
bboxes.emplace_back(i, get_extents(*m_internal_islands[i]));
// Build AABB tree over bounding boxes of internal slices.
m_aabbtree_internal_islands.build_modify_input(bboxes);
}
BoundingBox bbox_travel = get_extents(travel);
AABBTree::BoundingBox bbox_travel_eigen{ bbox_travel.min, bbox_travel.max };
int result = -1;
bbox_travel.offset(SCALED_EPSILON);
AABBTreeIndirect::traverse(m_aabbtree_internal_islands,
[&bbox_travel_eigen](const AABBTree::Node &node) {
return bbox_travel_eigen.intersects(node.bbox);
},
[&travel, &bbox_travel, &result, &islands = m_internal_islands](const AABBTree::Node &node) {
assert(node.is_leaf());
assert(node.is_valid());
Polygons clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*islands[node.idx], bbox_travel);
if (diff_pl(travel, clipped).empty()) {
// Travel path is completely inside an "internal" island. Don't retract.
result = int(node.idx);
// Stop traversal.
return false;
}
// Continue traversal.
return true;
});
return result != -1;
}
} // namespace Slic3r

View File

@ -0,0 +1,32 @@
#ifndef slic3r_RetractWhenCrossingPerimeters_hpp_
#define slic3r_RetractWhenCrossingPerimeters_hpp_
#include <vector>
#include "../AABBTreeIndirect.hpp"
namespace Slic3r {
// Forward declarations.
class ExPolygon;
class Layer;
class Polyline;
class RetractWhenCrossingPerimeters
{
public:
bool travel_inside_internal_regions(const Layer &layer, const Polyline &travel);
private:
// Last object layer visited, for which a cache of internal islands was created.
const Layer *m_layer;
// Internal islands only, referencing data owned by m_layer->regions()->surfaces().
std::vector<const ExPolygon*> m_internal_islands;
// Search structure over internal islands.
using AABBTree = AABBTreeIndirect::Tree<2, coord_t>;
AABBTree m_aabbtree_internal_islands;
};
} // namespace Slic3r
#endif // slic3r_RetractWhenCrossingPerimeters_hpp_

View File

@ -108,7 +108,7 @@ Circled circle_taubin_newton(const Vec2ds& input, size_t cycles)
return out;
}
Circled circle_ransac(const Vec2ds& input, size_t iterations)
Circled circle_ransac(const Vec2ds& input, size_t iterations, double* min_error)
{
if (input.size() < 3)
return Circled::make_invalid();
@ -132,6 +132,8 @@ Circled circle_ransac(const Vec2ds& input, size_t iterations)
circle_best = c;
}
}
if (min_error)
*min_error = err_min;
return circle_best;
}

View File

@ -102,7 +102,7 @@ inline Vec2d circle_center_taubin_newton(const Vec2ds& input, size_t cycles = 20
Circled circle_taubin_newton(const Vec2ds& input, size_t cycles = 20);
// Find circle using RANSAC randomized algorithm.
Circled circle_ransac(const Vec2ds& input, size_t iterations = 20);
Circled circle_ransac(const Vec2ds& input, size_t iterations = 20, double* min_error = nullptr);
// Randomized algorithm by Emo Welzl, working with squared radii for efficiency. The returned circle radius is inflated by epsilon.
template<typename Vector, typename Points>

View File

@ -8,29 +8,53 @@
#include <numeric>
#define DEBUG_EXTRACT_ALL_FEATURES_AT_ONCE 0
namespace Slic3r {
namespace Measure {
constexpr double feature_hover_limit = 0.5; // how close to a feature the mouse must be to highlight it
static std::pair<Vec3d, double> get_center_and_radius(const std::vector<Vec3d>& border, int start_idx, int end_idx, const Transform3d& trafo)
static std::tuple<Vec3d, double, double> get_center_and_radius(const std::vector<Vec3d>& points, const Transform3d& trafo, const Transform3d& trafo_inv)
{
Vec2ds pts;
Vec2ds out;
double z = 0.;
for (int i=start_idx; i<=end_idx; ++i) {
Vec3d pt_transformed = trafo * border[i];
for (const Vec3d& pt : points) {
Vec3d pt_transformed = trafo * pt;
z = pt_transformed.z();
pts.emplace_back(pt_transformed.x(), pt_transformed.y());
out.emplace_back(pt_transformed.x(), pt_transformed.y());
}
auto circle = Geometry::circle_ransac(pts, 20); // FIXME: iterations?
const int iter = points.size() < 10 ? 2 :
points.size() < 100 ? 4 :
6;
return std::make_pair(trafo.inverse() * Vec3d(circle.center.x(), circle.center.y(), z), circle.radius);
double error = std::numeric_limits<double>::max();
auto circle = Geometry::circle_ransac(out, iter, &error);
return std::make_tuple(trafo.inverse() * Vec3d(circle.center.x(), circle.center.y(), z), circle.radius, error);
}
static std::array<Vec3d, 3> orthonormal_basis(const Vec3d& v)
{
std::array<Vec3d, 3> ret;
ret[2] = v.normalized();
int index;
ret[2].cwiseAbs().maxCoeff(&index);
switch (index)
{
case 0: { ret[0] = Vec3d(ret[2].y(), -ret[2].x(), 0.0).normalized(); break; }
case 1: { ret[0] = Vec3d(0.0, ret[2].z(), -ret[2].y()).normalized(); break; }
case 2: { ret[0] = Vec3d(-ret[2].z(), 0.0, ret[2].x()).normalized(); break; }
}
ret[1] = ret[2].cross(ret[0]).normalized();
return ret;
}
class MeasuringImpl {
public:
@ -41,20 +65,22 @@ public:
std::vector<SurfaceFeature> surface_features;
Vec3d normal;
float area;
bool features_extracted = false;
};
std::vector<SurfaceFeature> get_all_features() const;
std::optional<SurfaceFeature> get_feature(size_t face_idx, const Vec3d& point) const;
std::vector<std::vector<int>> get_planes_triangle_indices() const;
const std::vector<SurfaceFeature>& get_plane_features(unsigned int plane_id) const;
std::optional<SurfaceFeature> get_feature(size_t face_idx, const Vec3d& point);
int get_num_of_planes() const;
const std::vector<int>& get_plane_triangle_indices(int idx) const;
const std::vector<SurfaceFeature>& get_plane_features(unsigned int plane_id);
const TriangleMesh& get_mesh() const;
private:
void update_planes();
void extract_features();
void extract_features(int plane_idx);
std::vector<PlaneData> m_planes;
std::vector<size_t> m_face_to_plane;
const indexed_triangle_set& m_its;
TriangleMesh m_mesh;
};
@ -63,10 +89,16 @@ private:
MeasuringImpl::MeasuringImpl(const indexed_triangle_set& its)
: m_its{its}
: m_mesh(its)
{
update_planes();
extract_features();
// Extracting features will be done as needed.
// To extract all planes at once, run the following:
#if DEBUG_EXTRACT_ALL_FEATURES_AT_ONCE
for (int i=0; i<int(m_planes.size()); ++i)
extract_features(i);
#endif
}
@ -76,10 +108,10 @@ void MeasuringImpl::update_planes()
// Now we'll go through all the facets and append Points of facets sharing the same normal.
// This part is still performed in mesh coordinate system.
const size_t num_of_facets = m_its.indices.size();
const size_t num_of_facets = m_mesh.its.indices.size();
m_face_to_plane.resize(num_of_facets, size_t(-1));
const std::vector<Vec3f> face_normals = its_face_normals(m_its);
const std::vector<Vec3i> face_neighbors = its_face_neighbors(m_its);
const std::vector<Vec3f> face_normals = its_face_normals(m_mesh.its);
const std::vector<Vec3i> face_neighbors = its_face_neighbors(m_mesh.its);
std::vector<int> facet_queue(num_of_facets, 0);
int facet_queue_cnt = 0;
const stl_normal* normal_ptr = nullptr;
@ -128,7 +160,7 @@ void MeasuringImpl::update_planes()
assert(std::none_of(m_face_to_plane.begin(), m_face_to_plane.end(), [](size_t val) { return val == size_t(-1); }));
// Now we will walk around each of the planes and save vertices which form the border.
SurfaceMesh sm(m_its);
SurfaceMesh sm(m_mesh.its);
for (int plane_id=0; plane_id < int(m_planes.size()); ++plane_id) {
const auto& facets = m_planes[plane_id].facets;
m_planes[plane_id].borders.clear();
@ -173,9 +205,15 @@ void MeasuringImpl::update_planes()
he = sm.next_around_target(he);
if (he.is_invalid())
goto PLANE_FAILURE;
// For broken meshes, the iteration might never get back to he_orig.
// Remember all halfedges we saw to break out of such infinite loops.
boost::container::small_vector<Halfedge_index, 10> he_seen;
while ( (int)m_face_to_plane[sm.face(he)] == plane_id && he != he_orig) {
he_seen.emplace_back(he);
he = sm.next_around_target(he);
if (he.is_invalid())
if (he.is_invalid() || std::find(he_seen.begin(), he_seen.end(), he) != he_seen.end())
goto PLANE_FAILURE;
}
he = sm.opposite(he);
@ -194,12 +232,19 @@ void MeasuringImpl::update_planes()
visited[face_it - facets.begin()][he.side()] = true;
last_border.emplace_back(sm.point(sm.source(he)).cast<double>());
// In case of broken meshes, this loop might be infinite. Break
// out in case it is clearly going bad.
if (last_border.size() > 3*facets.size()+1)
goto PLANE_FAILURE;
} while (he != he_start);
if (last_border.size() == 1)
m_planes[plane_id].borders.pop_back();
else {
assert(last_border.front() == last_border.back());
last_border.pop_back();
}
}
}
@ -215,14 +260,11 @@ void MeasuringImpl::update_planes()
void MeasuringImpl::extract_features()
void MeasuringImpl::extract_features(int plane_idx)
{
std::vector<double> angles;
std::vector<double> lengths;
assert(! m_planes[plane_idx].features_extracted);
for (int i=0; i<(int)m_planes.size(); ++i) {
PlaneData& plane = m_planes[i];
PlaneData& plane = m_planes[plane_idx];
plane.surface_features.clear();
const Vec3d& normal = plane.normal;
@ -230,152 +272,179 @@ void MeasuringImpl::extract_features()
q.setFromTwoVectors(plane.normal, Vec3d::UnitZ());
Transform3d trafo = Transform3d::Identity();
trafo.rotate(q);
const Transform3d trafo_inv = trafo.inverse();
std::vector<double> angles; // placed in outer scope to prevent reallocations
std::vector<double> lengths;
for (const std::vector<Vec3d>& border : plane.borders) {
if (border.size() <= 1)
continue;
assert(border.front() == border.back());
int start_idx = -1;
std::vector<SurfaceFeature> edges;
bool done = false;
if (border.size() > 4) {
const auto& [center, radius, err] = get_center_and_radius(border, trafo, trafo_inv);
if (err < 0.05) {
// The whole border is one circle. Just add it into the list of features
// and we are done.
bool is_polygon = border.size()>4 && border.size()<=8;
bool lengths_match = std::all_of(border.begin()+2, border.end(), [is_polygon](const Vec3d& pt) {
return Slic3r::is_approx((pt - *((&pt)-1)).squaredNorm(), (*((&pt)-1) - *((&pt)-2)).squaredNorm(), is_polygon ? 0.01 : 0.01);
});
if (lengths_match && (is_polygon || border.size() > 8)) {
if (is_polygon) {
// This is a polygon, add the separate edges with the center.
for (int j=0; j<int(border.size()); ++j)
plane.surface_features.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge,
border[j==0 ? border.size()-1 : j-1], border[j],
std::make_optional(center)));
} else {
// The fit went well and it has more than 8 points - let's consider this a circle.
plane.surface_features.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius));
}
done = true;
}
}
}
if (! done) {
// In this case, the border is not a circle and may contain circular
// segments. Try to find them and then add all remaining edges as edges.
auto are_angles_same = [](double a, double b) { return Slic3r::is_approx(a,b,0.01); };
auto are_lengths_same = [](double a, double b) { return Slic3r::is_approx(a,b,0.01); };
// Given an idx into border, return the index that is idx+offset position,
// while taking into account the need for wrap-around and the fact that
// the first and last point are the same.
auto offset_to_index = [border_size = int(border.size())](int idx, int offset) -> int {
assert(std::abs(offset) < border_size);
int out = idx+offset;
if (out >= border_size)
out = out - border_size;
else if (out < 0)
out = border_size + out;
return out;
};
// First calculate angles at all the vertices.
angles.clear();
lengths.clear();
for (int i=0; i<int(border.size()); ++i) { // front is the same as back, hence the weird indexing
const Vec3d& v2 = (i == 0 ? border[0] - border[border.size()-2]
: border[i] - border[i-1]);
const Vec3d& v1 = i == (int)border.size()-1 ? border[1] - border.back()
: border[i+1] - border[i];
int first_different_angle_idx = 0;
for (int i=0; i<int(border.size()); ++i) {
const Vec3d& v2 = border[i] - (i == 0 ? border[border.size()-1] : border[i-1]);
const Vec3d& v1 = (i == int(border.size()-1) ? border[0] : border[i+1]) - border[i];
double angle = atan2(-normal.dot(v1.cross(v2)), -v1.dot(v2)) + M_PI;
if (angle > M_PI)
angle = 2*M_PI - angle;
angles.push_back(angle);
lengths.push_back(v2.norm());
if (first_different_angle_idx == 0 && angles.size() > 1) {
if (! are_angles_same(angles.back(), angles[angles.size()-2]))
first_different_angle_idx = angles.size()-1;
}
}
assert(border.size() == angles.size());
assert(border.size() == lengths.size());
// First go around the border and pick what might be circular segments.
// Save pair of indices to where such potential segments start and end.
// Also remember the length of these segments.
int start_idx = -1;
bool circle = false;
bool first_iter = true;
std::vector<SurfaceFeature> circles;
std::vector<SurfaceFeature> edges;
std::vector<std::pair<int, int>> circles_idxs;
std::vector<double> circles_lengths;
for (int i=1; i<(int)angles.size(); ++i) {
if (Slic3r::is_approx(lengths[i], lengths[i-1])
&& Slic3r::is_approx(angles[i], angles[i-1])
&& i != (int)angles.size()-1 ) {
//std::vector<double> circles_lengths;
std::vector<Vec3d> single_circle; // could be in loop-scope, but reallocations
double single_circle_length = 0.;
int first_pt_idx = offset_to_index(first_different_angle_idx, 1);
int i = first_pt_idx;
while (i != first_pt_idx || first_iter) {
if (are_angles_same(angles[i], angles[offset_to_index(i,-1)])
&& i != offset_to_index(first_pt_idx, -1) // not the last point
&& i != start_idx ) {
// circle
if (! circle) {
circle = true;
start_idx = std::max(0, i-2);
single_circle.clear();
single_circle_length = 0.;
start_idx = offset_to_index(i, -2);
single_circle = { border[start_idx], border[offset_to_index(start_idx,1)] };
single_circle_length += lengths[offset_to_index(i, -1)];
}
single_circle.emplace_back(border[i]);
single_circle_length += lengths[i];
} else {
if (circle) {
const auto& [center, radius] = get_center_and_radius(border, start_idx, i, trafo);
if (circle && single_circle.size() >= 5) { // Less than 5 vertices? Not a circle.
single_circle.emplace_back(border[i]);
single_circle_length += lengths[i];
bool accept_circle = true;
{
// Check that lengths of internal (!!!) edges match.
int j = offset_to_index(start_idx, 3);
while (j != i) {
if (! are_lengths_same(lengths[offset_to_index(j,-1)], lengths[j])) {
accept_circle = false;
break;
}
j = offset_to_index(j, 1);
}
}
if (accept_circle) {
const auto& [center, radius, err] = get_center_and_radius(single_circle, trafo, trafo_inv);
// Check that the fit went well. The tolerance is high, only to
// reject complete failures.
accept_circle &= err < 0.05;
// If the segment subtends less than 90 degrees, throw it away.
accept_circle &= single_circle_length / radius > 0.9*M_PI/2.;
if (accept_circle) {
// Add the circle and remember indices into borders.
circles_idxs.emplace_back(start_idx, i);
circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius));
circles_lengths.emplace_back(std::accumulate(lengths.begin() + start_idx + 1, lengths.begin() + i + 1, 0.));
}
}
}
circle = false;
}
// Take care of the wrap around.
first_iter = false;
i = offset_to_index(i, 1);
}
}
// At this point we might need to merge the first and last segment, if the starting
// point happened to be inside the segment. The discrimination of too small segments
// will follow, so we need a complete picture before that.
if (circles_idxs.size() > 1
&& circles_idxs.back().second == angles.size()-1
&& circles_idxs.front().first == 0) {
// Possibly the same circle. Check that the angle and length criterion holds along the combined segment.
bool same = true;
double last_len = -1.;
double last_angle = 0.;
for (int i=circles_idxs.back().first + 1; i != circles_idxs.front().second; ++i) {
if (i == angles.size())
i = 1;
if (last_len == -1.) {
last_len = lengths[i];
last_angle = angles[i];
} else {
if (! Slic3r::is_approx(lengths[i], last_len) || ! Slic3r::is_approx(angles[i], last_angle)) {
same = false;
break;
}
}
}
if (same) {
// This seems to really be the same circle. Better apply ransac again. The parts can be small and inexact.
std::vector<Vec3d> points(border.begin() + circles_idxs.back().first, border.end());
points.insert(points.end(), border.begin(), border.begin() + circles_idxs.front().second+1);
auto [c, radius] = get_center_and_radius(points, 0, points.size()-1, trafo);
// Now replace the first circle with the combined one, remove the last circle.
// First index of the first circle is saved negative - we are going to pick edges
// from the border later, we will need to know where the merged in segment was.
// The sign simplifies the algorithm that picks the remaining edges - see below.
circles.front() = SurfaceFeature(SurfaceFeatureType::Circle, c, plane.normal, std::nullopt, radius);
circles_idxs.front().first = - circles_idxs.back().first;
circles_lengths.front() += circles_lengths.back();
circles.pop_back();
circles_idxs.pop_back();
circles_lengths.pop_back();
}
}
// Now throw away all circles that subtend less than 90 deg.
assert(circles.size() == circles_lengths.size());
for (int i=0; i<int(circles.size()); ++i) {
double r = std::get<1>(circles[i].get_circle());
if (circles_lengths[i] / r < 0.9*M_PI/2.) {
circles_lengths.erase(circles_lengths.begin() + i);
circles.erase(circles.begin() + i);
circles_idxs.erase(circles_idxs.begin() + i);
--i;
}
}
circles_lengths.clear(); // no longer needed, make it obvious
// Anything under 5 vertices shall not be considered a circle.
assert(circles_idxs.size() == circles.size());
for (int i=int(circles_idxs.size())-1; i>=0; --i) {
const auto& [start, end] = circles_idxs[i];
int N = start >= 0
? end - start + (start == 0 && end == border.size()-1 ? 0 : 1) // last point is the same as first
: end + (border.size() + start);
if (N < 5) {
circles.erase(circles.begin() + i);
circles_idxs.erase(circles_idxs.begin() + i);
} else if (N <= 8 && start == 0 && end == border.size()-1) {
// This is a regular 5-8 polygon. Add the edges as edges with a special
// point and remove the circle. Leave the indices in circles_idxs, so
// the edges are not picked up again later.
const Vec3d center = std::get<0>(circles[i].get_circle());
for (int j=1; j<=end; ++j)
edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge,
border[j - 1], border[j], std::make_optional(center)));
circles.erase(circles.begin() + i);
}
}
// We have the circles. Now go around again and pick edges, while jumping over circles.
// If the first index of the first circle is negative, it means that it was merged
// with a segment that was originally at the back and is no longer there. Ressurect
// its pair of indices so that edges are not picked again.
if (! circles_idxs.empty() && circles_idxs.front().first < 0)
circles_idxs.emplace_back(-circles_idxs.front().first, int(border.size()));
int cidx = 0; // index of next circle to jump over
for (int i=1; i<int(border.size()); ++i) {
if (cidx < (int)circles_idxs.size() && i > (int)circles_idxs[cidx].first)
i = circles_idxs[cidx++].second;
else
edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, border[i - 1], border[i]));
if (circles_idxs.empty()) {
// Just add all edges.
for (int i=1; i<int(border.size()); ++i)
edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, border[i-1], border[i]));
edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, border[0], border[border.size()-1]));
} else if (circles_idxs.size() > 1 || circles_idxs.front().first != circles_idxs.front().second) {
// There is at least one circular segment. Start at its end and add edges until the start of the next one.
int i = circles_idxs.front().second;
int circle_idx = 1;
while (true) {
i = offset_to_index(i, 1);
edges.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, border[offset_to_index(i,-1)], border[i]));
if (circle_idx < int(circles_idxs.size()) && i == circles_idxs[circle_idx].first) {
i = circles_idxs[circle_idx].second;
++circle_idx;
}
if (i == circles_idxs.front().first)
break;
}
}
// Merge adjacent edges where needed.
@ -405,6 +474,7 @@ void MeasuringImpl::extract_features()
plane.surface_features.insert(plane.surface_features.end(), std::make_move_iterator(edges.begin()),
std::make_move_iterator(edges.end()));
}
}
// The last surface feature is the plane itself.
Vec3d cog = Vec3d::Zero();
@ -417,23 +487,12 @@ void MeasuringImpl::extract_features()
}
cog /= double(counter);
plane.surface_features.emplace_back(SurfaceFeature(SurfaceFeatureType::Plane,
plane.normal, cog, std::optional<Vec3d>(), i + 0.0001));
plane.normal, cog, std::optional<Vec3d>(), plane_idx + 0.0001));
plane.borders.clear();
plane.borders.shrink_to_fit();
}
}
std::vector<SurfaceFeature> MeasuringImpl::get_all_features() const
{
std::vector<SurfaceFeature> features;
//PlaneData& plane = m_planes[0];
for (const PlaneData& plane : m_planes)
for (const SurfaceFeature& feature : plane.surface_features)
features.emplace_back(feature);
return features;
plane.features_extracted = true;
}
@ -441,13 +500,18 @@ std::vector<SurfaceFeature> MeasuringImpl::get_all_features() const
std::optional<SurfaceFeature> MeasuringImpl::get_feature(size_t face_idx, const Vec3d& point) const
std::optional<SurfaceFeature> MeasuringImpl::get_feature(size_t face_idx, const Vec3d& point)
{
if (face_idx >= m_face_to_plane.size())
return std::optional<SurfaceFeature>();
const PlaneData& plane = m_planes[m_face_to_plane[face_idx]];
if (! plane.features_extracted)
extract_features(m_face_to_plane[face_idx]);
size_t closest_feature_idx = size_t(-1);
double min_dist = std::numeric_limits<double>::max();
@ -496,20 +560,31 @@ std::optional<SurfaceFeature> MeasuringImpl::get_feature(size_t face_idx, const
std::vector<std::vector<int>> MeasuringImpl::get_planes_triangle_indices() const
int MeasuringImpl::get_num_of_planes() const
{
std::vector<std::vector<int>> out;
for (const PlaneData& plane : m_planes)
out.emplace_back(plane.facets);
return out;
return (m_planes.size());
}
const std::vector<SurfaceFeature>& MeasuringImpl::get_plane_features(unsigned int plane_id) const
const std::vector<int>& MeasuringImpl::get_plane_triangle_indices(int idx) const
{
assert(idx >= 0 && idx < int(m_planes.size()));
return m_planes[idx].facets;
}
const std::vector<SurfaceFeature>& MeasuringImpl::get_plane_features(unsigned int plane_id)
{
assert(plane_id < m_planes.size());
if (! m_planes[plane_id].features_extracted)
extract_features(plane_id);
return m_planes[plane_id].surface_features;
}
const TriangleMesh& MeasuringImpl::get_mesh() const
{
return this->m_mesh;
}
@ -528,11 +603,6 @@ Measuring::Measuring(const indexed_triangle_set& its)
Measuring::~Measuring() {}
std::vector<SurfaceFeature> Measuring::get_all_features() const
{
return priv->get_all_features();
}
std::optional<SurfaceFeature> Measuring::get_feature(size_t face_idx, const Vec3d& point) const
{
@ -540,10 +610,15 @@ std::optional<SurfaceFeature> Measuring::get_feature(size_t face_idx, const Vec3
}
std::vector<std::vector<int>> Measuring::get_planes_triangle_indices() const
int Measuring::get_num_of_planes() const
{
return priv->get_planes_triangle_indices();
return priv->get_num_of_planes();
}
const std::vector<int>& Measuring::get_plane_triangle_indices(int idx) const
{
return priv->get_plane_triangle_indices(idx);
}
const std::vector<SurfaceFeature>& Measuring::get_plane_features(unsigned int plane_id) const
@ -551,6 +626,11 @@ const std::vector<SurfaceFeature>& Measuring::get_plane_features(unsigned int pl
return priv->get_plane_features(plane_id);
}
const TriangleMesh& Measuring::get_mesh() const
{
return priv->get_mesh();
}
const AngleAndEdges AngleAndEdges::Dummy = { 0.0, Vec3d::Zero(), { Vec3d::Zero(), Vec3d::Zero() }, { Vec3d::Zero(), Vec3d::Zero() }, 0.0, true };
static AngleAndEdges angle_edge_edge(const std::pair<Vec3d, Vec3d>& e1, const std::pair<Vec3d, Vec3d>& e2)
@ -620,8 +700,8 @@ static AngleAndEdges angle_edge_edge(const std::pair<Vec3d, Vec3d>& e1, const st
static AngleAndEdges angle_edge_plane(const std::pair<Vec3d, Vec3d>& e, const std::tuple<int, Vec3d, Vec3d>& p)
{
const auto& [idx, normal, origin] = p;
const Vec3d e1e2_unit = edge_direction(e);
if (are_parallel(e1e2_unit, normal) || are_perpendicular(e1e2_unit, normal))
Vec3d e1e2_unit = edge_direction(e);
if (are_perpendicular(e1e2_unit, normal))
return AngleAndEdges::Dummy;
// ensure the edge is pointing away from the intersection
@ -633,8 +713,22 @@ static AngleAndEdges angle_edge_plane(const std::pair<Vec3d, Vec3d>& e, const st
// then verify edge direction and revert it, if needed
Vec3d e1 = e.first;
Vec3d e2 = e.second;
if ((e1 - inters).squaredNorm() > (e2 - inters).squaredNorm())
if ((e1 - inters).squaredNorm() > (e2 - inters).squaredNorm()) {
std::swap(e1, e2);
e1e2_unit = -e1e2_unit;
}
if (are_parallel(e1e2_unit, normal)) {
const std::array<Vec3d, 3> basis = orthonormal_basis(e1e2_unit);
const double radius = (0.5 * (e1 + e2) - inters).norm();
const Vec3d edge_on_plane_dir = (basis[1].dot(origin - inters) >= 0.0) ? basis[1] : -basis[1];
std::pair<Vec3d, Vec3d> edge_on_plane = std::make_pair(inters, inters + radius * edge_on_plane_dir);
if (!inters.isApprox(e1)) {
edge_on_plane.first += radius * edge_on_plane_dir;
edge_on_plane.second += radius * edge_on_plane_dir;
}
return AngleAndEdges(0.5 * double(PI), inters, std::make_pair(e1, e2), edge_on_plane, radius, inters.isApprox(e1));
}
const Vec3d e1e2 = e2 - e1;
const double e1e2_len = e1e2.norm();
@ -763,7 +857,8 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature&
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
} else if (f1.get_type() == SurfaceFeatureType::Edge) {
}
else if (f1.get_type() == SurfaceFeatureType::Edge) {
if (f2.get_type() == SurfaceFeatureType::Edge) {
std::vector<DistAndPoints> distances;
@ -890,21 +985,6 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature&
const Vec3d D = c1 - c0;
if (!are_parallel(n0, n1)) {
auto orthonormal_basis = [](const Vec3d& v) {
std::array<Vec3d, 3> ret;
ret[2] = v.normalized();
int index;
ret[2].maxCoeff(&index);
switch (index)
{
case 0: { ret[0] = Vec3d(ret[2].y(), -ret[2].x(), 0.0).normalized(); break; }
case 1: { ret[0] = Vec3d(0.0, ret[2].z(), -ret[2].y()).normalized(); break; }
case 2: { ret[0] = Vec3d(-ret[2].z(), 0.0, ret[2].x()).normalized(); break; }
}
ret[1] = ret[2].cross(ret[0]).normalized();
return ret;
};
// Get parameters for constructing the degree-8 polynomial phi.
const double one = 1.0;
const double two = 2.0;
@ -1149,27 +1229,6 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature&
return result;
}
void DistAndPoints::transform(const Transform3d& trafo) {
from = trafo * from;
to = trafo * to;
dist = (to - from).norm();
}
void AngleAndEdges::transform(const Transform3d& trafo) {
const Vec3d old_e1 = e1.second - e1.first;
const Vec3d old_e2 = e2.second - e2.first;
center = trafo * center;
e1.first = trafo * e1.first;
e1.second = trafo * e1.second;
e2.first = trafo * e2.first;
e2.second = trafo * e2.second;
angle = std::acos(std::clamp(Measure::edge_direction(e1).dot(Measure::edge_direction(e2)), -1.0, 1.0));
const Vec3d new_e1 = e1.second - e1.first;
const Vec3d new_e2 = e2.second - e2.first;
const double average_scale = 0.5 * (new_e1.norm() / old_e1.norm() + new_e2.norm() / old_e2.norm());
radius = average_scale * radius;
}

View File

@ -12,6 +12,9 @@ struct indexed_triangle_set;
namespace Slic3r {
class TriangleMesh;
namespace Measure {
@ -87,27 +90,27 @@ class MeasuringImpl;
class Measuring {
public:
// Construct the measurement object on a given its. The its must remain
// valid and unchanged during the whole lifetime of the object.
// Construct the measurement object on a given its.
explicit Measuring(const indexed_triangle_set& its);
~Measuring();
// Return a reference to a list of all features identified on the its.
// Use only for debugging. Expensive, do not call often.
std::vector<SurfaceFeature> get_all_features() const;
// Given a face_idx where the mouse cursor points, return a feature that
// should be highlighted (if any).
std::optional<SurfaceFeature> get_feature(size_t face_idx, const Vec3d& point) const;
// Returns a list of triangle indices for each identified plane. Each
// Plane object contains an index into this vector. Expensive, do not
// call too often.
std::vector<std::vector<int>> get_planes_triangle_indices() const;
// Return total number of planes.
int get_num_of_planes() const;
// Returns a list of triangle indices for given plane.
const std::vector<int>& get_plane_triangle_indices(int idx) const;
// Returns the surface features of the plane with the given index
const std::vector<SurfaceFeature>& get_plane_features(unsigned int plane_id) const;
// Returns the mesh used for measuring
const TriangleMesh& get_mesh() const;
private:
std::unique_ptr<MeasuringImpl> priv;
};
@ -118,8 +121,6 @@ struct DistAndPoints {
double dist;
Vec3d from;
Vec3d to;
void transform(const Transform3d& trafo);
};
struct AngleAndEdges {
@ -132,8 +133,6 @@ struct AngleAndEdges {
double radius;
bool coplanar;
void transform(const Transform3d& trafo);
static const AngleAndEdges Dummy;
};
@ -150,17 +149,6 @@ struct MeasurementResult {
bool has_any_data() const {
return angle.has_value() || distance_infinite.has_value() || distance_strict.has_value() || distance_xyz.has_value();
}
void transform(const Transform3d& trafo) {
if (angle.has_value())
angle->transform(trafo);
if (distance_infinite.has_value())
distance_infinite->transform(trafo);
if (distance_strict.has_value()) {
distance_strict->transform(trafo);
distance_xyz = (distance_strict->to - distance_strict->from).cwiseAbs();
}
}
};
// Returns distance/angle between two SurfaceFeatures.

View File

@ -762,9 +762,7 @@ public:
// The triangular model.
const TriangleMesh& mesh() const { return *m_mesh.get(); }
#if ENABLE_RAYCAST_PICKING
std::shared_ptr<const TriangleMesh> mesh_ptr() const { return m_mesh; }
#endif // ENABLE_RAYCAST_PICKING
void set_mesh(const TriangleMesh &mesh) { m_mesh = std::make_shared<const TriangleMesh>(mesh); }
void set_mesh(TriangleMesh &&mesh) { m_mesh = std::make_shared<const TriangleMesh>(std::move(mesh)); }
void set_mesh(const indexed_triangle_set &mesh) { m_mesh = std::make_shared<const TriangleMesh>(mesh); }

View File

@ -11,11 +11,6 @@
namespace Slic3r { namespace sla {
const RasterBase::TMirroring RasterBase::NoMirror = {false, false};
const RasterBase::TMirroring RasterBase::MirrorX = {true, false};
const RasterBase::TMirroring RasterBase::MirrorY = {false, true};
const RasterBase::TMirroring RasterBase::MirrorXY = {true, true};
EncodedRaster PNGRasterEncoder::operator()(const void *ptr, size_t w, size_t h,
size_t num_components)
{

View File

@ -60,10 +60,10 @@ public:
enum Orientation { roLandscape, roPortrait };
using TMirroring = std::array<bool, 2>;
static const TMirroring NoMirror;
static const TMirroring MirrorX;
static const TMirroring MirrorY;
static const TMirroring MirrorXY;
static const constexpr TMirroring NoMirror = {false, false};
static const constexpr TMirroring MirrorX = {true, false};
static const constexpr TMirroring MirrorY = {false, true};
static const constexpr TMirroring MirrorXY = {true, true};
struct Trafo {
bool mirror_x = false, mirror_y = false, flipXY = false;

View File

@ -413,6 +413,8 @@ void SLAPrint::Steps::drill_holes(SLAPrintObject &po)
[&part_to_drill, &hollowed_mesh](const auto& node)
{
part_to_drill.indices.emplace_back(hollowed_mesh.its.indices[node.idx]);
// continue traversal
return true;
});
auto cgal_meshpart = MeshBoolean::cgal::triangle_mesh_to_cgal(

View File

@ -4,6 +4,8 @@
#include <admesh/stl.h>
#include <libslic3r/TriangleMesh.hpp>
#include "boost/container/small_vector.hpp"
namespace Slic3r {
class TriangleMesh;
@ -115,11 +117,18 @@ public:
size_t degree(Vertex_index v) const
{
// In case the mesh is broken badly, the loop might end up to be infinite,
// never getting back to the first halfedge. Remember list of all half-edges
// and trip if any is encountered for the second time.
Halfedge_index h_first = halfedge(v);
boost::container::small_vector<Halfedge_index, 10> he_visited;
Halfedge_index h = next_around_target(h_first);
size_t degree = 2;
while (! h.is_invalid() && h != h_first) {
he_visited.emplace_back(h);
h = next_around_target(h);
if (std::find(he_visited.begin(), he_visited.end(), h) == he_visited.end())
return 0;
++degree;
}
return h.is_invalid() ? 0 : degree - 1;

View File

@ -28,6 +28,10 @@
#define DISABLE_GCODEVIEWER_INSTANCED_MODELS 1
// Enable Measure Gizmo debug window
#define ENABLE_MEASURE_GIZMO_DEBUG 0
// Enable scene raycast picking debug window
#define ENABLE_RAYCAST_PICKING_DEBUG 0
// Shows an imgui dialog with GLModel statistics data
#define ENABLE_GLMODEL_STATISTICS 0
// Enable rendering of objects using environment map
@ -41,29 +45,18 @@
//====================
#define ENABLE_2_6_0_ALPHA1 1
// Enable removal of legacy OpenGL calls
#define ENABLE_LEGACY_OPENGL_REMOVAL (1 && ENABLE_2_6_0_ALPHA1)
// Enable OpenGL ES
#define ENABLE_OPENGL_ES (0 && ENABLE_LEGACY_OPENGL_REMOVAL)
#define ENABLE_OPENGL_ES 0
// Enable OpenGL core profile context (tested against Mesa 20.1.8 on Windows)
#define ENABLE_GL_CORE_PROFILE (1 && ENABLE_LEGACY_OPENGL_REMOVAL && !ENABLE_OPENGL_ES)
#define ENABLE_GL_CORE_PROFILE (1 && !ENABLE_OPENGL_ES)
// Enable OpenGL debug messages using debug context
#define ENABLE_OPENGL_DEBUG_OPTION (1 && ENABLE_GL_CORE_PROFILE)
// Shows an imgui dialog with GLModel statistics data
#define ENABLE_GLMODEL_STATISTICS (0 && ENABLE_LEGACY_OPENGL_REMOVAL)
// Enable rework of Reload from disk command
#define ENABLE_RELOAD_FROM_DISK_REWORK (1 && ENABLE_2_6_0_ALPHA1)
// Enable editing volumes transformation in world coordinates and instances in local coordinates
#define ENABLE_WORLD_COORDINATE (1 && ENABLE_2_6_0_ALPHA1)
// Enable alternative version of file_wildcards()
#define ENABLE_ALTERNATIVE_FILE_WILDCARDS_GENERATOR (1 && ENABLE_2_6_0_ALPHA1)
// Enable processing of gcode G2 and G3 lines
#define ENABLE_PROCESS_G2_G3_LINES (1 && ENABLE_2_6_0_ALPHA1)
// Enable fix of used filament data exported to gcode file
#define ENABLE_USED_FILAMENT_POST_PROCESS (1 && ENABLE_2_6_0_ALPHA1)
// Enable picking using raytracing
#define ENABLE_RAYCAST_PICKING (1 && ENABLE_LEGACY_OPENGL_REMOVAL)
#define ENABLE_RAYCAST_PICKING_DEBUG (0 && ENABLE_RAYCAST_PICKING)
#endif // _prusaslicer_technologies_h_

View File

@ -622,7 +622,7 @@ std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, std::funct
return its_face_edge_ids_impl(its, [](const uint32_t){ return true; }, throw_on_cancel_callback);
}
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, const std::vector<bool> &face_mask)
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, const std::vector<char> &face_mask)
{
return its_face_edge_ids_impl(its, [&face_mask](const uint32_t idx){ return face_mask[idx]; }, [](){});
}
@ -738,6 +738,13 @@ void its_flip_triangles(indexed_triangle_set &its)
std::swap(face(1), face(2));
}
int its_num_degenerate_faces(const indexed_triangle_set &its)
{
return std::count_if(its.indices.begin(), its.indices.end(), [](auto &face) {
return face(0) == face(1) || face(0) == face(2) || face(1) == face(2);
});
}
int its_remove_degenerate_faces(indexed_triangle_set &its, bool shrink_to_fit)
{
auto it = std::remove_if(its.indices.begin(), its.indices.end(), [](auto &face) {

View File

@ -188,7 +188,7 @@ private:
// Used for chaining slice lines into polygons.
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its);
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, std::function<void()> throw_on_cancel_callback);
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, const std::vector<bool> &face_mask);
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, const std::vector<char> &face_mask);
// Having the face neighbors available, assign unique edge IDs to face edges for chaining of polygons over slices.
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, std::vector<Vec3i> &face_neighbors, bool assign_unbound_edges = false, int *num_edges = nullptr);
@ -204,6 +204,8 @@ void its_flip_triangles(indexed_triangle_set &its);
// or more than two faces share the same edge position!
int its_merge_vertices(indexed_triangle_set &its, bool shrink_to_fit = true);
// Calculate number of degenerate faces. There should be no degenerate faces in a nice mesh.
int its_num_degenerate_faces(const indexed_triangle_set &its);
// Remove degenerate faces, return number of faces removed.
int its_remove_degenerate_faces(indexed_triangle_set &its, bool shrink_to_fit = true);

View File

@ -242,7 +242,12 @@ static FacetSliceType slice_facet(
std::swap(a, b);
}
IntersectionPoint &point = points[num_points];
double t = (double(slice_z) - double(b->z())) / (double(a->z()) - double(b->z()));
double t = (double(slice_z) - double(a->z())) / (double(b->z()) - double(a->z()));
#if 0
// If the intersection point falls into one of the end points, mark it with the end point identifier.
// While this sounds like a good idea, it likely breaks the chaining by logical addresses of the intersection points
// and the branch for 0 < t < 1 does not guarantee uniqness of the interection point anyways.
// Thus this branch is only kept for reference and it is not used in production code.
if (t <= 0.) {
if (point_on_layer == size_t(-1) || points[point_on_layer].point_id != a_id) {
point.x() = a->x();
@ -258,11 +263,26 @@ static FacetSliceType slice_facet(
point.point_id = b_id;
}
} else {
point.x() = coord_t(floor(double(b->x()) + (double(a->x()) - double(b->x())) * t + 0.5));
point.y() = coord_t(floor(double(b->y()) + (double(a->y()) - double(b->y())) * t + 0.5));
point.x() = coord_t(floor(double(a->x()) + (double(b->x()) - double(a->x())) * t + 0.5));
point.y() = coord_t(floor(double(a->y()) + (double(b->y()) - double(a->y())) * t + 0.5));
point.edge_id = edge_id;
++ num_points;
}
#else
// Just clamp the intersection point to source triangle edge.
if (t <= 0.) {
point.x() = a->x();
point.y() = a->y();
} else if (t >= 1.) {
point.x() = b->x();
point.y() = b->y();
} else {
point.x() = coord_t(floor(double(a->x()) + (double(b->x()) - double(a->x())) * t + 0.5));
point.y() = coord_t(floor(double(a->y()) + (double(b->y()) - double(a->y())) * t + 0.5));
}
point.edge_id = edge_id;
++ num_points;
#endif
}
}
@ -284,6 +304,11 @@ static FacetSliceType slice_facet(
assert(line_out.edge_a_id != -1 || line_out.edge_b_id != -1);
// General slicing position, use the segment for both slicing and object cutting.
#if 0
// See the discussion on calculating the intersection point on a triangle edge.
// Even if the intersection point is clamped to one of the end points of the triangle edge,
// the intersection point is still marked as "on edge", not "on vertex". Such implementation
// may produce degenerate triangles, but is topologically correct.
// Therefore this block for solving snapping of an intersection edge to triangle vertices is not used.
if (line_out.a_id != -1 && line_out.b_id != -1) {
// Solving a degenerate case, where both the intersections snapped to an edge.
// Correctly classify the face as below or above based on the position of the 3rd point.
@ -1780,7 +1805,7 @@ Polygons slice_mesh(
{
bool trafo_identity = is_identity(params.trafo);
Transform3f tf;
std::vector<bool> face_mask(mesh.indices.size(), false);
std::vector<char> face_mask(mesh.indices.size(), 0);
{
// 1) Mark vertices as below or above the slicing plane.
@ -2009,6 +2034,7 @@ static void triangulate_slice(
(l.first.y() == r.first.y() && l.second < r.second))); });
// 2) Discover duplicate points on the slice. Remap duplicate vertices to a vertex with a lowest index.
// Remove denegerate triangles, if they happen to be created by merging duplicate vertices.
{
std::vector<int> map_duplicate_vertex(int(its.vertices.size()) - num_original_vertices, -1);
int i = 0;
@ -2031,10 +2057,20 @@ static void triangulate_slice(
i = j;
}
map_vertex_to_index.erase(map_vertex_to_index.begin() + k, map_vertex_to_index.end());
for (stl_triangle_vertex_indices &f : its.indices)
for (i = 0; i < 3; ++ i)
if (f(i) >= num_original_vertices)
f(i) = map_duplicate_vertex[f(i) - num_original_vertices];
for (i = 0; i < int(its.indices.size());) {
stl_triangle_vertex_indices &f = its.indices[i];
// Remap the newly added face vertices.
for (k = 0; k < 3; ++ k)
if (f(k) >= num_original_vertices)
f(k) = map_duplicate_vertex[f(k) - num_original_vertices];
if (f(0) == f(1) || f(0) == f(2) || f(1) == f(2)) {
// Remove degenerate face.
f = its.indices.back();
its.indices.pop_back();
} else
// Keep the face.
++ i;
}
}
if (triangulate) {
@ -2108,6 +2144,10 @@ void cut_mesh(const indexed_triangle_set &mesh, float z, indexed_triangle_set *u
if (upper == nullptr && lower == nullptr)
return;
#ifndef NDEBUG
const size_t had_degenerate_faces = its_num_degenerate_faces(mesh);
#endif // NDEBUG
BOOST_LOG_TRIVIAL(trace) << "cut_mesh - slicing object";
if (upper) {
@ -2251,8 +2291,27 @@ void cut_mesh(const indexed_triangle_set &mesh, float z, indexed_triangle_set *u
new_face(lower, iv0, iv0v1_lower, iv2v0_lower);
}
}
/*
char buf[2048];
static int irun = 0;
++irun;
temp.indices.emplace_back(int(temp.vertices.size()), int(temp.vertices.size() + 1), int(temp.vertices.size() + 2));
temp.vertices.emplace_back(vertices[0]);
temp.vertices.emplace_back(vertices[1]);
temp.vertices.emplace_back(vertices[2]);
sprintf(buf, "D:\\temp\\test\\temp-%d.obj", irun);
its_write_obj(temp, buf);
sprintf(buf, "D:\\temp\\test\\upper-%d.obj", irun);
its_write_obj(*upper, buf);
sprintf(buf, "D:\\temp\\test\\lower-%d.obj", irun);
its_write_obj(*lower, buf);
*/
}
assert(had_degenerate_faces || ! upper || its_num_degenerate_faces(*upper) == 0);
assert(had_degenerate_faces || ! lower || its_num_degenerate_faces(*lower) == 0);
if (upper != nullptr) {
triangulate_slice(*upper, upper_lines, upper_slice_vertices, int(mesh.vertices.size()), z, triangulate_caps, NORMALS_DOWN);
#ifndef NDEBUG
@ -2272,6 +2331,9 @@ void cut_mesh(const indexed_triangle_set &mesh, float z, indexed_triangle_set *u
}
#endif // NDEBUG
}
assert(had_degenerate_faces || ! upper || its_num_degenerate_faces(*upper) == 0);
assert(had_degenerate_faces || ! lower || its_num_degenerate_faces(*lower) == 0);
}
} // namespace Slic3r

View File

@ -130,6 +130,6 @@ void cut_mesh(
indexed_triangle_set *lower,
bool triangulate_caps = true);
}
} // namespace Slic3r
#endif // slic3r_TriangleMeshSlicer_hpp_

View File

@ -11,10 +11,8 @@
#include "GUI_App.hpp"
#include "GLCanvas3D.hpp"
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "Plater.hpp"
#include "Camera.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include <GL/glew.h>
@ -31,77 +29,6 @@ static const Slic3r::ColorRGBA DEFAULT_TRANSPARENT_GRID_COLOR = { 0.9f, 0.9f, 0
namespace Slic3r {
namespace GUI {
#if !ENABLE_LEGACY_OPENGL_REMOVAL
bool GeometryBuffer::set_from_triangles(const std::vector<Vec2f> &triangles, float z)
{
if (triangles.empty()) {
m_vertices.clear();
return false;
}
assert(triangles.size() % 3 == 0);
m_vertices = std::vector<Vertex>(triangles.size(), Vertex());
Vec2f min = triangles.front();
Vec2f max = min;
for (size_t v_count = 0; v_count < triangles.size(); ++ v_count) {
const Vec2f &p = triangles[v_count];
Vertex &v = m_vertices[v_count];
v.position = Vec3f(p.x(), p.y(), z);
v.tex_coords = p;
min = min.cwiseMin(p).eval();
max = max.cwiseMax(p).eval();
}
Vec2f size = max - min;
if (size.x() != 0.f && size.y() != 0.f) {
Vec2f inv_size = size.cwiseInverse();
inv_size.y() *= -1;
for (Vertex& v : m_vertices) {
v.tex_coords -= min;
v.tex_coords.x() *= inv_size.x();
v.tex_coords.y() *= inv_size.y();
}
}
return true;
}
bool GeometryBuffer::set_from_lines(const Lines& lines, float z)
{
m_vertices.clear();
unsigned int v_size = 2 * (unsigned int)lines.size();
if (v_size == 0)
return false;
m_vertices = std::vector<Vertex>(v_size, Vertex());
unsigned int v_count = 0;
for (const Line& l : lines) {
Vertex& v1 = m_vertices[v_count];
v1.position[0] = unscale<float>(l.a(0));
v1.position[1] = unscale<float>(l.a(1));
v1.position[2] = z;
++v_count;
Vertex& v2 = m_vertices[v_count];
v2.position[0] = unscale<float>(l.b(0));
v2.position[1] = unscale<float>(l.b(1));
v2.position[2] = z;
++v_count;
}
return true;
}
const float* GeometryBuffer::get_vertices_data() const
{
return (m_vertices.size() > 0) ? (const float*)m_vertices.data() : nullptr;
}
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#if !ENABLE_WORLD_COORDINATE
const float Bed3D::Axes::DefaultStemRadius = 0.5f;
const float Bed3D::Axes::DefaultStemLength = 25.0f;
@ -110,7 +37,6 @@ const float Bed3D::Axes::DefaultTipLength = 5.0f;
void Bed3D::Axes::render()
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
auto render_axis = [this](GLShaderProgram* shader, const Transform3d& transform) {
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
@ -118,15 +44,7 @@ void Bed3D::Axes::render()
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * transform.matrix().block(0, 0, 3, 3).inverse().transpose();
shader->set_uniform("view_normal_matrix", view_normal_matrix);
#else
auto render_axis = [this](const Transform3f& transform) {
glsafe(::glPushMatrix());
glsafe(::glMultMatrixf(transform.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_arrow.render();
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
};
if (!m_arrow.is_initialized())
@ -142,31 +60,16 @@ void Bed3D::Axes::render()
shader->set_uniform("emission_factor", 0.0f);
// x axis
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_arrow.set_color(ColorRGBA::X());
render_axis(shader, Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }));
#else
m_arrow.set_color(-1, ColorRGBA::X());
render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }).cast<float>());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// y axis
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_arrow.set_color(ColorRGBA::Y());
render_axis(shader, Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }));
#else
m_arrow.set_color(-1, ColorRGBA::Y());
render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }).cast<float>());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// z axis
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_arrow.set_color(ColorRGBA::Z());
render_axis(shader, Geometry::assemble_transform(m_origin));
#else
m_arrow.set_color(-1, ColorRGBA::Z());
render_axis(Geometry::assemble_transform(m_origin).cast<float>());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
@ -221,7 +124,6 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c
m_model_filename = model_filename;
m_extended_bounding_box = this->calc_extended_bounding_box();
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_contour = ExPolygon(Polygon::new_scale(bed_shape));
const BoundingBox bbox = m_contour.contour.bounding_box();
if (!bbox.defined)
@ -231,20 +133,6 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c
m_triangles.reset();
m_gridlines.reset();
m_contourlines.reset();
#else
ExPolygon poly{ Polygon::new_scale(bed_shape) };
calc_triangles(poly);
const BoundingBox& bed_bbox = poly.contour.bounding_box();
calc_gridlines(poly, bed_bbox);
calc_contourlines(poly);
m_polygon = offset(poly.contour, (float)bed_bbox.radius() * 1.7f, jtRound, scale_(0.5)).front();
this->release_VBOs();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_texture.reset();
m_model.reset();
@ -252,10 +140,8 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c
m_axes.set_origin({ 0.0, 0.0, static_cast<double>(GROUND_Z) });
m_axes.set_stem_length(0.1f * static_cast<float>(m_build_volume.bounding_volume().max_size()));
#if ENABLE_RAYCAST_PICKING
// unregister from picking
wxGetApp().plater()->canvas3D()->remove_raycasters_for_picking(SceneRaycaster::EType::Bed);
#endif // ENABLE_RAYCAST_PICKING
// Let the calee to update the UI.
return true;
@ -271,7 +157,6 @@ Point Bed3D::point_projection(const Point& point) const
return m_polygon.point_projection(point);
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes, bool show_texture)
{
render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, show_axes, show_texture, false);
@ -281,25 +166,9 @@ void Bed3D::render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matri
{
render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, false, false, true);
}
#else
void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture)
{
render_internal(canvas, bottom, scale_factor, show_axes, show_texture, false);
}
void Bed3D::render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor)
{
render_internal(canvas, bottom, scale_factor, false, false, true);
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor,
bool show_axes, bool show_texture, bool picking)
#else
void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
bool show_axes, bool show_texture, bool picking)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
m_scale_factor = scale_factor;
@ -308,27 +177,13 @@ void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
glsafe(::glEnable(GL_DEPTH_TEST));
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
m_model.model.set_color(picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR);
#else
m_model.set_color(picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR);
#endif // ENABLE_RAYCAST_PICKING
#else
m_model.set_color(-1, picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
switch (m_type)
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
case Type::System: { render_system(canvas, view_matrix, projection_matrix, bottom, show_texture); break; }
default:
case Type::Custom: { render_custom(canvas, view_matrix, projection_matrix, bottom, show_texture, picking); break; }
#else
case Type::System: { render_system(canvas, bottom, show_texture); break; }
default:
case Type::Custom: { render_custom(canvas, bottom, show_texture, picking); break; }
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
glsafe(::glDisable(GL_DEPTH_TEST));
@ -355,11 +210,7 @@ BoundingBoxf3 Bed3D::calc_extended_bounding_box() const
out.merge(out.min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, out.max.z()));
#endif // ENABLE_WORLD_COORDINATE
// extend to contain model, if any
#if ENABLE_RAYCAST_PICKING
BoundingBoxf3 model_bb = m_model.model.get_bounding_box();
#else
BoundingBoxf3 model_bb = m_model.get_bounding_box();
#endif // ENABLE_RAYCAST_PICKING
if (model_bb.defined) {
model_bb.translate(m_model_offset);
out.merge(model_bb);
@ -367,7 +218,6 @@ BoundingBoxf3 Bed3D::calc_extended_bounding_box() const
return out;
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::init_triangles()
{
if (m_triangles.is_initialized())
@ -409,16 +259,12 @@ void Bed3D::init_triangles()
init_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
}
#if ENABLE_RAYCAST_PICKING
if (m_model.model.get_filename().empty() && m_model.mesh_raycaster == nullptr)
// register for picking
register_raycasters_for_picking(init_data, Transform3d::Identity());
#endif // ENABLE_RAYCAST_PICKING
m_triangles.init_from(std::move(init_data));
#if ENABLE_RAYCAST_PICKING
m_triangles.set_color(DEFAULT_MODEL_COLOR);
#endif // ENABLE_RAYCAST_PICKING
}
void Bed3D::init_gridlines()
@ -467,42 +313,7 @@ void Bed3D::init_gridlines()
m_gridlines.init_from(std::move(init_data));
}
#else
void Bed3D::calc_triangles(const ExPolygon& poly)
{
if (! m_triangles.set_from_triangles(triangulate_expolygon_2f(poly, NORMALS_UP), GROUND_Z))
BOOST_LOG_TRIVIAL(error) << "Unable to create bed triangles";
}
void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox)
{
Polylines axes_lines;
for (coord_t x = bed_bbox.min.x(); x <= bed_bbox.max.x(); x += scale_(10.0)) {
Polyline line;
line.append(Point(x, bed_bbox.min.y()));
line.append(Point(x, bed_bbox.max.y()));
axes_lines.push_back(line);
}
for (coord_t y = bed_bbox.min.y(); y <= bed_bbox.max.y(); y += scale_(10.0)) {
Polyline line;
line.append(Point(bed_bbox.min.x(), y));
line.append(Point(bed_bbox.max.x(), y));
axes_lines.push_back(line);
}
// clip with a slightly grown expolygon because our lines lay on the contours and may get erroneously clipped
Lines gridlines = to_lines(intersection_pl(axes_lines, offset(poly, (float)SCALED_EPSILON)));
// append bed contours
Lines contour_lines = to_lines(poly);
std::copy(contour_lines.begin(), contour_lines.end(), std::back_inserter(gridlines));
if (!m_gridlines.set_from_lines(gridlines, GROUND_Z))
BOOST_LOG_TRIVIAL(error) << "Unable to create bed grid lines\n";
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::init_contourlines()
{
if (m_contourlines.is_initialized())
@ -528,14 +339,6 @@ void Bed3D::init_contourlines()
m_contourlines.init_from(std::move(init_data));
m_contourlines.set_color({ 1.0f, 1.0f, 1.0f, 0.5f });
}
#else
void Bed3D::calc_contourlines(const ExPolygon& poly)
{
const Lines contour_lines = to_lines(poly);
if (!m_contourlines.set_from_lines(contour_lines, GROUND_Z))
BOOST_LOG_TRIVIAL(error) << "Unable to create bed contour lines\n";
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Try to match the print bed shape with the shape of an active profile. If such a match exists,
// return the print bed model.
@ -565,17 +368,12 @@ void Bed3D::render_axes()
{
if (m_build_volume.valid())
#if ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_axes.render(Transform3d::Identity(), 0.25f);
#else
m_axes.render(0.25f);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#else
m_axes.render();
#endif // ENABLE_WORLD_COORDINATE
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture)
{
if (!bottom)
@ -586,32 +384,12 @@ void Bed3D::render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, co
else if (bottom)
render_contour(view_matrix, projection_matrix);
}
#else
void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture)
{
if (!bottom)
render_model();
if (show_texture)
render_texture(bottom, canvas);
else if (bottom)
render_contour();
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix)
#else
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (m_texture_filename.empty()) {
m_texture.reset();
#if ENABLE_LEGACY_OPENGL_REMOVAL
render_default(bottom, false, true, view_matrix, projection_matrix);
#else
render_default(bottom, false, true);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return;
}
@ -624,11 +402,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
if (m_temp_texture.get_id() == 0 || m_temp_texture.get_source() != m_texture_filename) {
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
if (!m_temp_texture.load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
render_default(bottom, false, true, view_matrix, projection_matrix);
#else
render_default(bottom, false, true);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return;
}
canvas.request_extra_frame();
@ -636,11 +410,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
// starts generating the main texture, compression will run asynchronously
if (!m_texture.load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
render_default(bottom, false, true, view_matrix, projection_matrix);
#else
render_default(bottom, false, true);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return;
}
}
@ -648,11 +418,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
if (m_temp_texture.get_id() == 0 || m_temp_texture.get_source() != m_texture_filename) {
if (!m_temp_texture.load_from_file(m_texture_filename, false, GLTexture::None, false)) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
render_default(bottom, false, true, view_matrix, projection_matrix);
#else
render_default(bottom, false, true);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return;
}
canvas.request_extra_frame();
@ -660,20 +426,12 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
// starts generating the main texture, compression will run asynchronously
if (!m_texture.load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
render_default(bottom, false, true, view_matrix, projection_matrix);
#else
render_default(bottom, false, true);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return;
}
}
else {
#if ENABLE_LEGACY_OPENGL_REMOVAL
render_default(bottom, false, true, view_matrix, projection_matrix);
#else
render_default(bottom, false, true);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return;
}
}
@ -688,7 +446,6 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
canvas.request_extra_frame();
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
init_triangles();
GLShaderProgram* shader = wxGetApp().get_shader("printbed");
@ -727,152 +484,49 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
shader->stop_using();
}
#else
if (m_triangles.get_vertices_count() > 0) {
GLShaderProgram* shader = wxGetApp().get_shader("printbed");
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("transparent_background", bottom);
shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg"));
if (m_vbo_id == 0) {
glsafe(::glGenBuffers(1, &m_vbo_id));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
glsafe(::glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_triangles.get_vertices_data_size(), (const GLvoid*)m_triangles.get_vertices_data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
glsafe(::glEnable(GL_DEPTH_TEST));
if (bottom)
glsafe(::glDepthMask(GL_FALSE));
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
if (bottom)
glsafe(::glFrontFace(GL_CW));
const unsigned int stride = m_triangles.get_vertex_data_size();
// show the temporary texture while no compressed data is available
GLuint tex_id = (GLuint)m_temp_texture.get_id();
if (tex_id == 0)
tex_id = (GLuint)m_texture.get_id();
glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
glsafe(::glVertexPointer(3, GL_FLOAT, stride, (const void*)(intptr_t)m_triangles.get_position_offset()));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glTexCoordPointer(2, GL_FLOAT, stride, (const void*)(intptr_t)m_triangles.get_tex_coords_offset()));
glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY));
glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)m_triangles.get_vertices_count()));
glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
if (bottom)
glsafe(::glFrontFace(GL_CCW));
glsafe(::glDisable(GL_BLEND));
if (bottom)
glsafe(::glDepthMask(GL_TRUE));
shader->stop_using();
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix)
#else
void Bed3D::render_model()
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (m_model_filename.empty())
return;
#if ENABLE_RAYCAST_PICKING
if (m_model.model.get_filename() != m_model_filename && m_model.model.init_from_file(m_model_filename)) {
#else
if (m_model.get_filename() != m_model_filename && m_model.init_from_file(m_model_filename)) {
#endif // ENABLE_RAYCAST_PICKING
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
m_model.model.set_color(DEFAULT_MODEL_COLOR);
#else
m_model.set_color(DEFAULT_MODEL_COLOR);
#endif // ENABLE_RAYCAST_PICKING
#else
m_model.set_color(-1, DEFAULT_MODEL_COLOR);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad
m_model_offset = to_3d(m_build_volume.bounding_volume2d().center(), -0.03);
#if ENABLE_RAYCAST_PICKING
// register for picking
register_raycasters_for_picking(m_model.model.get_geometry(), Geometry::translation_transform(m_model_offset));
#endif // ENABLE_RAYCAST_PICKING
// update extended bounding box
m_extended_bounding_box = this->calc_extended_bounding_box();
}
#if ENABLE_RAYCAST_PICKING
if (!m_model.model.get_filename().empty()) {
#else
if (!m_model.get_filename().empty()) {
#endif // ENABLE_RAYCAST_PICKING
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.0f);
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Transform3d model_matrix = Geometry::translation_transform(m_model_offset);
shader->set_uniform("view_model_matrix", view_matrix * model_matrix);
shader->set_uniform("projection_matrix", projection_matrix);
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);
#else
glsafe(::glPushMatrix());
glsafe(::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
m_model.model.render();
#else
m_model.render();
#endif // ENABLE_RAYCAST_PICKING
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
}
}
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture, bool picking)
#else
void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (m_texture_filename.empty() && m_model_filename.empty()) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
render_default(bottom, picking, show_texture, view_matrix, projection_matrix);
#else
render_default(bottom, picking, show_texture);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return;
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (!bottom)
render_model(view_matrix, projection_matrix);
@ -880,26 +534,12 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bo
render_texture(bottom, canvas, view_matrix, projection_matrix);
else if (bottom)
render_contour(view_matrix, projection_matrix);
#else
if (!bottom)
render_model();
if (show_texture)
render_texture(bottom, canvas);
else if (bottom)
render_contour();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::render_default(bool bottom, bool picking, bool show_texture, const Transform3d& view_matrix, const Transform3d& projection_matrix)
#else
void Bed3D::render_default(bool bottom, bool picking, bool show_texture)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
m_texture.reset();
#if ENABLE_LEGACY_OPENGL_REMOVAL
init_gridlines();
init_triangles();
@ -914,23 +554,14 @@ void Bed3D::render_default(bool bottom, bool picking, bool show_texture)
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
#if ENABLE_RAYCAST_PICKING
const bool has_model = !m_model.model.get_filename().empty();
#else
const bool has_model = !m_model.get_filename().empty();
#endif // ENABLE_RAYCAST_PICKING
if (!has_model && !bottom) {
// draw background
glsafe(::glDepthMask(GL_FALSE));
#if !ENABLE_RAYCAST_PICKING
m_triangles.set_color(picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR);
#endif // !ENABLE_RAYCAST_PICKING
m_triangles.render();
glsafe(::glDepthMask(GL_TRUE));
}
#if ENABLE_RAYCAST_PICKING
if (show_texture) {
// draw grid
#if ENABLE_GL_CORE_PROFILE
@ -942,63 +573,13 @@ void Bed3D::render_default(bool bottom, bool picking, bool show_texture)
}
else
render_contour(view_matrix, projection_matrix);
#else
if (!picking && show_texture) {
// draw grid
#if ENABLE_GL_CORE_PROFILE
if (!OpenGLManager::get_gl_info().is_core_profile())
#endif // ENABLE_GL_CORE_PROFILE
glsafe(::glLineWidth(1.5f * m_scale_factor));
m_gridlines.set_color(has_model && !bottom ? DEFAULT_SOLID_GRID_COLOR : DEFAULT_TRANSPARENT_GRID_COLOR);
m_gridlines.render();
}
else if (!show_texture)
render_contour(view_matrix, projection_matrix);
#endif // ENABLE_RAYCAST_PICKING
glsafe(::glDisable(GL_BLEND));
shader->stop_using();
}
#else
const unsigned int triangles_vcount = m_triangles.get_vertices_count();
if (triangles_vcount > 0) {
const bool has_model = !m_model.get_filename().empty();
glsafe(::glEnable(GL_DEPTH_TEST));
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
if (!has_model && !bottom) {
// draw background
glsafe(::glDepthMask(GL_FALSE));
glsafe(::glColor4fv(picking ? PICKING_MODEL_COLOR.data() : DEFAULT_MODEL_COLOR.data()));
glsafe(::glNormal3d(0.0f, 0.0f, 1.0f));
glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_triangles.get_vertices_data()));
glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount));
glsafe(::glDepthMask(GL_TRUE));
}
if (!picking && show_texture) {
// draw grid
glsafe(::glLineWidth(1.5f * m_scale_factor));
glsafe(::glColor4fv(has_model && !bottom ? DEFAULT_SOLID_GRID_COLOR.data() : DEFAULT_TRANSPARENT_GRID_COLOR.data()));
glsafe(::glVertexPointer(3, GL_FLOAT, m_gridlines.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data()));
glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count()));
}
else if (!show_texture)
render_contour();
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisable(GL_BLEND));
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::render_contour(const Transform3d& view_matrix, const Transform3d& projection_matrix)
{
init_contourlines();
@ -1025,29 +606,7 @@ void Bed3D::render_contour(const Transform3d& view_matrix, const Transform3d& pr
shader->stop_using();
}
}
#else
void Bed3D::render_contour()
{
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glLineWidth(1.5f * m_scale_factor));
glsafe(::glColor4f(1.0f, 1.0f, 1.0f, 0.5f));
glsafe(::glVertexPointer(3, GL_FLOAT, m_contourlines.get_vertex_data_size(), (GLvoid*)m_contourlines.get_vertices_data()));
glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_contourlines.get_vertices_count()));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::release_VBOs()
{
if (m_vbo_id > 0) {
glsafe(::glDeleteBuffers(1, &m_vbo_id));
m_vbo_id = 0;
}
}
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
void Bed3D::register_raycasters_for_picking(const GLModel::Geometry& geometry, const Transform3d& trafo)
{
assert(m_model.mesh_raycaster == nullptr);
@ -1066,7 +625,6 @@ void Bed3D::register_raycasters_for_picking(const GLModel::Geometry& geometry, c
m_model.mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
wxGetApp().plater()->canvas3D()->add_raycaster_for_picking(SceneRaycaster::EType::Bed, 0, *m_model.mesh_raycaster, trafo);
}
#endif // ENABLE_RAYCAST_PICKING
} // GUI
} // Slic3r

View File

@ -8,14 +8,10 @@
#else
#include "GLModel.hpp"
#endif // ENABLE_WORLD_COORDINATE
#if ENABLE_RAYCAST_PICKING
#include "MeshUtils.hpp"
#endif // ENABLE_RAYCAST_PICKING
#include "libslic3r/BuildVolume.hpp"
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "libslic3r/ExPolygon.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include <tuple>
#include <array>
@ -25,30 +21,6 @@ namespace GUI {
class GLCanvas3D;
#if !ENABLE_LEGACY_OPENGL_REMOVAL
class GeometryBuffer
{
struct Vertex
{
Vec3f position{ Vec3f::Zero() };
Vec2f tex_coords{ Vec2f::Zero() };
};
std::vector<Vertex> m_vertices;
public:
bool set_from_triangles(const std::vector<Vec2f> &triangles, float z);
bool set_from_lines(const Lines& lines, float z);
const float* get_vertices_data() const;
unsigned int get_vertices_data_size() const { return (unsigned int)m_vertices.size() * get_vertex_data_size(); }
unsigned int get_vertex_data_size() const { return (unsigned int)(5 * sizeof(float)); }
size_t get_position_offset() const { return 0; }
size_t get_tex_coords_offset() const { return (size_t)(3 * sizeof(float)); }
unsigned int get_vertices_count() const { return (unsigned int)m_vertices.size(); }
};
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
class Bed3D
{
#if !ENABLE_WORLD_COORDINATE
@ -93,33 +65,18 @@ private:
std::string m_model_filename;
// Print volume bounding box exteded with axes and model.
BoundingBoxf3 m_extended_bounding_box;
#if ENABLE_LEGACY_OPENGL_REMOVAL
// Print bed polygon
ExPolygon m_contour;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Slightly expanded print bed polygon, for collision detection.
Polygon m_polygon;
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_triangles;
GLModel m_gridlines;
GLModel m_contourlines;
#else
GeometryBuffer m_triangles;
GeometryBuffer m_gridlines;
GeometryBuffer m_contourlines;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
GLTexture m_texture;
// temporary texture shown until the main texture has still no levels compressed
GLTexture m_temp_texture;
#if ENABLE_RAYCAST_PICKING
PickingModel m_model;
#else
GLModel m_model;
#endif // ENABLE_RAYCAST_PICKING
Vec3d m_model_offset{ Vec3d::Zero() };
#if !ENABLE_LEGACY_OPENGL_REMOVAL
unsigned int m_vbo_id{ 0 };
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WORLD_COORDINATE
CoordAxes m_axes;
#else
@ -130,11 +87,7 @@ private:
public:
Bed3D() = default;
#if ENABLE_LEGACY_OPENGL_REMOVAL
~Bed3D() = default;
#else
~Bed3D() { release_VBOs(); }
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Update print bed model from configuration.
// Return true if the bed shape changed, so the calee will update the UI.
@ -158,56 +111,27 @@ public:
bool contains(const Point& point) const;
Point point_projection(const Point& point) const;
#if ENABLE_LEGACY_OPENGL_REMOVAL
void render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes, bool show_texture);
void render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor);
#else
void render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture);
void render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
private:
// Calculate an extended bounding box from axes and current model for visualization purposes.
BoundingBoxf3 calc_extended_bounding_box() const;
#if ENABLE_LEGACY_OPENGL_REMOVAL
void init_triangles();
void init_gridlines();
void init_contourlines();
#else
void calc_triangles(const ExPolygon& poly);
void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox);
void calc_contourlines(const ExPolygon& poly);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
static std::tuple<Type, std::string, std::string> detect_type(const Pointfs& shape);
#if ENABLE_LEGACY_OPENGL_REMOVAL
void render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor,
bool show_axes, bool show_texture, bool picking);
#else
void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
bool show_axes, bool show_texture, bool picking);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void render_axes();
#if ENABLE_LEGACY_OPENGL_REMOVAL
void render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture);
void render_texture(bool bottom, GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix);
void render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix);
void render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture, bool picking);
void render_default(bool bottom, bool picking, bool show_texture, const Transform3d& view_matrix, const Transform3d& projection_matrix);
void render_contour(const Transform3d& view_matrix, const Transform3d& projection_matrix);
#else
void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture);
void render_texture(bool bottom, GLCanvas3D& canvas);
void render_model();
void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking);
void render_default(bool bottom, bool picking, bool show_texture);
void render_contour();
void release_VBOs();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
void register_raycasters_for_picking(const GLModel::Geometry& geometry, const Transform3d& trafo);
#endif // ENABLE_RAYCAST_PICKING
};
} // GUI

File diff suppressed because it is too large Load Diff

View File

@ -10,9 +10,7 @@
#include "libslic3r/Color.hpp"
#include "GLModel.hpp"
#if ENABLE_RAYCAST_PICKING
#include "MeshUtils.hpp"
#endif // ENABLE_RAYCAST_PICKING
#include <functional>
#include <optional>
@ -49,209 +47,6 @@ enum ModelInstanceEPrintVolumeState : unsigned char;
// Return appropriate color based on the ModelVolume.
extern ColorRGBA color_from_model_volume(const ModelVolume& model_volume);
#if !ENABLE_LEGACY_OPENGL_REMOVAL
// A container for interleaved arrays of 3D vertices and normals,
// possibly indexed by triangles and / or quads.
class GLIndexedVertexArray {
public:
// Only Eigen types of Nx16 size are vectorized. This bounding box will not be vectorized.
static_assert(sizeof(Eigen::AlignedBox<float, 3>) == 24, "Eigen::AlignedBox<float, 3> is not being vectorized, thus it does not need to be aligned");
using BoundingBox = Eigen::AlignedBox<float, 3>;
GLIndexedVertexArray() { m_bounding_box.setEmpty(); }
GLIndexedVertexArray(const GLIndexedVertexArray &rhs) :
vertices_and_normals_interleaved(rhs.vertices_and_normals_interleaved),
triangle_indices(rhs.triangle_indices),
quad_indices(rhs.quad_indices),
m_bounding_box(rhs.m_bounding_box)
{ assert(! rhs.has_VBOs()); m_bounding_box.setEmpty(); }
GLIndexedVertexArray(GLIndexedVertexArray &&rhs) :
vertices_and_normals_interleaved(std::move(rhs.vertices_and_normals_interleaved)),
triangle_indices(std::move(rhs.triangle_indices)),
quad_indices(std::move(rhs.quad_indices)),
m_bounding_box(rhs.m_bounding_box)
{ assert(! rhs.has_VBOs()); }
~GLIndexedVertexArray() { release_geometry(); }
GLIndexedVertexArray& operator=(const GLIndexedVertexArray &rhs)
{
assert(vertices_and_normals_interleaved_VBO_id == 0);
assert(triangle_indices_VBO_id == 0);
assert(quad_indices_VBO_id == 0);
assert(rhs.vertices_and_normals_interleaved_VBO_id == 0);
assert(rhs.triangle_indices_VBO_id == 0);
assert(rhs.quad_indices_VBO_id == 0);
this->vertices_and_normals_interleaved = rhs.vertices_and_normals_interleaved;
this->triangle_indices = rhs.triangle_indices;
this->quad_indices = rhs.quad_indices;
this->m_bounding_box = rhs.m_bounding_box;
this->vertices_and_normals_interleaved_size = rhs.vertices_and_normals_interleaved_size;
this->triangle_indices_size = rhs.triangle_indices_size;
this->quad_indices_size = rhs.quad_indices_size;
return *this;
}
GLIndexedVertexArray& operator=(GLIndexedVertexArray &&rhs)
{
assert(vertices_and_normals_interleaved_VBO_id == 0);
assert(triangle_indices_VBO_id == 0);
assert(quad_indices_VBO_id == 0);
assert(rhs.vertices_and_normals_interleaved_VBO_id == 0);
assert(rhs.triangle_indices_VBO_id == 0);
assert(rhs.quad_indices_VBO_id == 0);
this->vertices_and_normals_interleaved = std::move(rhs.vertices_and_normals_interleaved);
this->triangle_indices = std::move(rhs.triangle_indices);
this->quad_indices = std::move(rhs.quad_indices);
this->m_bounding_box = rhs.m_bounding_box;
this->vertices_and_normals_interleaved_size = rhs.vertices_and_normals_interleaved_size;
this->triangle_indices_size = rhs.triangle_indices_size;
this->quad_indices_size = rhs.quad_indices_size;
return *this;
}
// Vertices and their normals, interleaved to be used by void glInterleavedArrays(GL_N3F_V3F, 0, x)
std::vector<float> vertices_and_normals_interleaved;
std::vector<int> triangle_indices;
std::vector<int> quad_indices;
// When the geometry data is loaded into the graphics card as Vertex Buffer Objects,
// the above mentioned std::vectors are cleared and the following variables keep their original length.
size_t vertices_and_normals_interleaved_size{ 0 };
size_t triangle_indices_size{ 0 };
size_t quad_indices_size{ 0 };
// IDs of the Vertex Array Objects, into which the geometry has been loaded.
// Zero if the VBOs are not sent to GPU yet.
unsigned int vertices_and_normals_interleaved_VBO_id{ 0 };
unsigned int triangle_indices_VBO_id{ 0 };
unsigned int quad_indices_VBO_id{ 0 };
#if ENABLE_SMOOTH_NORMALS
void load_mesh_full_shading(const TriangleMesh& mesh, bool smooth_normals = false);
void load_mesh(const TriangleMesh& mesh, bool smooth_normals = false) { this->load_mesh_full_shading(mesh, smooth_normals); }
#else
void load_mesh_full_shading(const TriangleMesh& mesh);
void load_mesh(const TriangleMesh& mesh) { this->load_mesh_full_shading(mesh); }
#endif // ENABLE_SMOOTH_NORMALS
void load_its_flat_shading(const indexed_triangle_set &its);
inline bool has_VBOs() const { return vertices_and_normals_interleaved_VBO_id != 0; }
inline void reserve(size_t sz) {
this->vertices_and_normals_interleaved.reserve(sz * 6);
this->triangle_indices.reserve(sz * 3);
this->quad_indices.reserve(sz * 4);
}
inline void push_geometry(float x, float y, float z, float nx, float ny, float nz) {
assert(this->vertices_and_normals_interleaved_VBO_id == 0);
if (this->vertices_and_normals_interleaved_VBO_id != 0)
return;
if (this->vertices_and_normals_interleaved.size() + 6 > this->vertices_and_normals_interleaved.capacity())
this->vertices_and_normals_interleaved.reserve(next_highest_power_of_2(this->vertices_and_normals_interleaved.size() + 6));
this->vertices_and_normals_interleaved.emplace_back(nx);
this->vertices_and_normals_interleaved.emplace_back(ny);
this->vertices_and_normals_interleaved.emplace_back(nz);
this->vertices_and_normals_interleaved.emplace_back(x);
this->vertices_and_normals_interleaved.emplace_back(y);
this->vertices_and_normals_interleaved.emplace_back(z);
this->vertices_and_normals_interleaved_size = this->vertices_and_normals_interleaved.size();
m_bounding_box.extend(Vec3f(x, y, z));
};
inline void push_geometry(double x, double y, double z, double nx, double ny, double nz) {
push_geometry(float(x), float(y), float(z), float(nx), float(ny), float(nz));
}
template<typename Derived, typename Derived2>
inline void push_geometry(const Eigen::MatrixBase<Derived>& p, const Eigen::MatrixBase<Derived2>& n) {
push_geometry(float(p(0)), float(p(1)), float(p(2)), float(n(0)), float(n(1)), float(n(2)));
}
inline void push_triangle(int idx1, int idx2, int idx3) {
assert(this->vertices_and_normals_interleaved_VBO_id == 0);
if (this->vertices_and_normals_interleaved_VBO_id != 0)
return;
if (this->triangle_indices.size() + 3 > this->vertices_and_normals_interleaved.capacity())
this->triangle_indices.reserve(next_highest_power_of_2(this->triangle_indices.size() + 3));
this->triangle_indices.emplace_back(idx1);
this->triangle_indices.emplace_back(idx2);
this->triangle_indices.emplace_back(idx3);
this->triangle_indices_size = this->triangle_indices.size();
};
inline void push_quad(int idx1, int idx2, int idx3, int idx4) {
assert(this->vertices_and_normals_interleaved_VBO_id == 0);
if (this->vertices_and_normals_interleaved_VBO_id != 0)
return;
if (this->quad_indices.size() + 4 > this->vertices_and_normals_interleaved.capacity())
this->quad_indices.reserve(next_highest_power_of_2(this->quad_indices.size() + 4));
this->quad_indices.emplace_back(idx1);
this->quad_indices.emplace_back(idx2);
this->quad_indices.emplace_back(idx3);
this->quad_indices.emplace_back(idx4);
this->quad_indices_size = this->quad_indices.size();
};
// 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.
void finalize_geometry(bool opengl_initialized);
// Release the geometry data, release OpenGL VBOs.
void release_geometry();
void render() const;
void render(const std::pair<size_t, size_t>& tverts_range, const std::pair<size_t, size_t>& qverts_range) const;
// Is there any geometry data stored?
bool empty() const { return vertices_and_normals_interleaved_size == 0; }
void clear() {
this->vertices_and_normals_interleaved.clear();
this->triangle_indices.clear();
this->quad_indices.clear();
vertices_and_normals_interleaved_size = 0;
triangle_indices_size = 0;
quad_indices_size = 0;
m_bounding_box.setEmpty();
}
// Shrink the internal storage to tighly fit the data stored.
void shrink_to_fit() {
this->vertices_and_normals_interleaved.shrink_to_fit();
this->triangle_indices.shrink_to_fit();
this->quad_indices.shrink_to_fit();
}
const BoundingBox& bounding_box() const { return m_bounding_box; }
// Return an estimate of the memory consumed by this class.
size_t cpu_memory_used() const { return sizeof(*this) + vertices_and_normals_interleaved.capacity() * sizeof(float) + triangle_indices.capacity() * sizeof(int) + quad_indices.capacity() * sizeof(int); }
// Return an estimate of the memory held by GPU vertex buffers.
size_t gpu_memory_used() const
{
size_t memsize = 0;
if (this->vertices_and_normals_interleaved_VBO_id != 0)
memsize += this->vertices_and_normals_interleaved_size * 4;
if (this->triangle_indices_VBO_id != 0)
memsize += this->triangle_indices_size * 4;
if (this->quad_indices_VBO_id != 0)
memsize += this->quad_indices_size * 4;
return memsize;
}
size_t total_memory_used() const { return this->cpu_memory_used() + this->gpu_memory_used(); }
private:
BoundingBox m_bounding_box;
};
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
class GLVolume {
public:
static const ColorRGBA SELECTED_COLOR;
@ -391,21 +186,11 @@ public:
// Is mouse or rectangle selection over this object to select/deselect it ?
EHoverState hover;
#if ENABLE_LEGACY_OPENGL_REMOVAL
GUI::GLModel model;
#if ENABLE_RAYCAST_PICKING
// raycaster used for picking
std::unique_ptr<GUI::MeshRaycaster> mesh_raycaster;
#endif // ENABLE_RAYCAST_PICKING
#else
// Interleaved triangles & normals with indexed triangles & quads.
GLIndexedVertexArray indexed_vertex_array;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Ranges of triangle and quad indices to be rendered.
std::pair<size_t, size_t> tverts_range;
#if !ENABLE_LEGACY_OPENGL_REMOVAL
std::pair<size_t, size_t> qverts_range;
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
// If the qverts or tverts contain thick extrusions, then offsets keeps pointers of the starts
// of the extrusions per layer.
@ -415,17 +200,7 @@ public:
// Bounding box of this volume, in unscaled coordinates.
BoundingBoxf3 bounding_box() const {
#if ENABLE_LEGACY_OPENGL_REMOVAL
return this->model.get_bounding_box();
#else
BoundingBoxf3 out;
if (!this->indexed_vertex_array.bounding_box().isEmpty()) {
out.min = this->indexed_vertex_array.bounding_box().min().cast<double>();
out.max = this->indexed_vertex_array.bounding_box().max().cast<double>();
out.defined = true;
}
return out;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void set_color(const ColorRGBA& rgba) { color = rgba; }
@ -545,21 +320,12 @@ public:
// convex hull
const TriangleMesh* convex_hull() const { return m_convex_hull.get(); }
#if ENABLE_LEGACY_OPENGL_REMOVAL
bool empty() const { return this->model.is_empty(); }
#else
bool empty() const { return this->indexed_vertex_array.empty(); }
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void set_range(double low, double high);
void render();
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void finalize_geometry(bool opengl_initialized) { this->indexed_vertex_array.finalize_geometry(opengl_initialized); }
void release_geometry() { this->indexed_vertex_array.release_geometry(); }
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
void set_bounding_boxes_as_dirty() {
m_transformed_bounding_box.reset();
m_transformed_convex_hull_bounding_box.reset();
@ -576,19 +342,11 @@ public:
// Return an estimate of the memory consumed by this class.
size_t cpu_memory_used() const {
#if ENABLE_LEGACY_OPENGL_REMOVAL
return sizeof(*this) + this->model.cpu_memory_used() + this->print_zs.capacity() * sizeof(coordf_t) +
this->offsets.capacity() * sizeof(size_t);
}
// Return an estimate of the memory held by GPU vertex buffers.
size_t gpu_memory_used() const { return this->model.gpu_memory_used(); }
#else
//FIXME what to do wih m_convex_hull?
return sizeof(*this) - sizeof(this->indexed_vertex_array) + this->indexed_vertex_array.cpu_memory_used() + this->print_zs.capacity() * sizeof(coordf_t) + this->offsets.capacity() * sizeof(size_t);
}
// Return an estimate of the memory held by GPU vertex buffers.
size_t gpu_memory_used() const { return this->indexed_vertex_array.gpu_memory_used(); }
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
size_t total_memory_used() const { return this->cpu_memory_used() + this->gpu_memory_used(); }
};
@ -646,7 +404,6 @@ public:
GLVolumeCollection() { set_default_slope_normal_z(); }
~GLVolumeCollection() { clear(); }
#if ENABLE_LEGACY_OPENGL_REMOVAL
std::vector<int> load_object(
const ModelObject* model_object,
int obj_idx,
@ -675,54 +432,12 @@ public:
int load_wipe_tower_preview(
float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width);
#endif // ENABLE_OPENGL_ES
#else
std::vector<int> load_object(
const ModelObject *model_object,
int obj_idx,
const std::vector<int> &instance_idxs,
bool opengl_initialized);
int load_object_volume(
const ModelObject *model_object,
int obj_idx,
int volume_idx,
int instance_idx,
bool opengl_initialized);
// Load SLA auxiliary GLVolumes (for support trees or pad).
void load_object_auxiliary(
const SLAPrintObject *print_object,
int obj_idx,
// pairs of <instance_idx, print_instance_idx>
const std::vector<std::pair<size_t, size_t>>& instances,
SLAPrintObjectStep milestone,
// Timestamp of the last change of the milestone
size_t timestamp,
bool opengl_initialized);
int load_wipe_tower_preview(
float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLVolume* new_toolpath_volume(const ColorRGBA& rgba);
GLVolume* new_nontoolpath_volume(const ColorRGBA& rgba);
// Render the volumes by OpenGL.
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&)>()) const;
#else
GLVolume* new_toolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats = 0);
GLVolume* new_nontoolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats = 0);
// Render the volumes by OpenGL.
void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const;
// 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.
void finalize_geometry(bool opengl_initialized) { for (auto* v : volumes) v->finalize_geometry(opengl_initialized); }
// Release the geometry data assigned to the volumes.
// If OpenGL VBOs were allocated, an OpenGL context has to be active to release them.
void release_geometry() { for (auto* v : volumes) v->release_geometry(); }
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Clear the geometry
void clear() { for (auto *v : volumes) delete v; volumes.clear(); }
@ -774,7 +489,6 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo
struct _3DScene
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
static void thick_lines_to_verts(const Lines& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, double top_z, GUI::GLModel::Geometry& geometry);
static void thick_lines_to_verts(const Lines3& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, GUI::GLModel::Geometry& geometry);
static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry);
@ -782,19 +496,6 @@ struct _3DScene
static void extrusionentity_to_verts(const ExtrusionMultiPath& extrusion_multi_path, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry);
static void extrusionentity_to_verts(const ExtrusionEntityCollection& extrusion_entity_collection, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry);
static void extrusionentity_to_verts(const ExtrusionEntity* extrusion_entity, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry);
#else
static void thick_lines_to_verts(const Lines& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, double top_z, GLVolume& volume);
static void thick_lines_to_verts(const Lines3& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, GLVolume& volume);
static void extrusionentity_to_verts(const Polyline& polyline, float width, float height, float print_z, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, const Point& copy, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionLoop& extrusion_loop, float print_z, const Point& copy, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionMultiPath& extrusion_multi_path, float print_z, const Point& copy, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionEntityCollection& extrusion_entity_collection, float print_z, const Point& copy, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionEntity* extrusion_entity, float print_z, const Point& copy, GLVolume& volume);
static void polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume);
static void point3_to_verts(const Vec3crd& point, double width, double height, GLVolume& volume);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
}

View File

@ -91,7 +91,6 @@ void Camera::select_view(const std::string& direction)
look_at(m_target + m_distance * Vec3d::UnitY(), m_target, Vec3d::UnitZ());
}
#if ENABLE_RAYCAST_PICKING
double Camera::get_near_left() const
{
switch (m_type)
@ -163,7 +162,6 @@ double Camera::get_near_height() const
return 2.0 / m_projection_matrix.matrix()(1, 1);
}
}
#endif // ENABLE_RAYCAST_PICKING
double Camera::get_fov() const
{
@ -177,55 +175,22 @@ double Camera::get_fov() const
};
}
#if ENABLE_RAYCAST_PICKING
void Camera::set_viewport(int x, int y, unsigned int w, unsigned int h)
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_viewport = { 0, 0, int(w), int(h) };
#else
glsafe(::glGetIntegerv(GL_VIEWPORT, m_viewport.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void Camera::apply_viewport() const
{
glsafe(::glViewport(m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3]));
}
#else
void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h)
{
glsafe(::glViewport(0, 0, w, h));
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_viewport = { 0, 0, int(w), int(h) };
#else
glsafe(::glGetIntegerv(GL_VIEWPORT, m_viewport.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#endif // ENABLE_RAYCAST_PICKING
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void Camera::apply_view_matrix()
{
glsafe(::glMatrixMode(GL_MODELVIEW));
glsafe(::glLoadIdentity());
glsafe(::glMultMatrixd(m_view_matrix.data()));
}
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double far_z)
{
double w = 0.0;
double h = 0.0;
#if !ENABLE_LEGACY_OPENGL_REMOVAL
const double old_distance = m_distance;
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
m_frustrum_zs = calc_tight_frustrum_zs_around(box);
#if !ENABLE_LEGACY_OPENGL_REMOVAL
if (m_distance != old_distance)
// the camera has been moved re-apply view matrix
apply_view_matrix();
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
if (near_z > 0.0)
m_frustrum_zs.first = std::max(std::min(m_frustrum_zs.first, near_z), FrustrumMinNearZ);
@ -259,63 +224,9 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
}
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
apply_projection(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second);
#else
switch (m_type)
{
default:
case EType::Ortho:
{
const double dz = m_frustrum_zs.second - m_frustrum_zs.first;
const double zz = m_frustrum_zs.first + m_frustrum_zs.second;
m_projection_matrix.matrix() << 1.0 / w, 0.0, 0.0, 0.0,
0.0, 1.0 / h, 0.0, 0.0,
0.0, 0.0, -2.0 / dz, -zz / dz,
0.0, 0.0, 0.0, 1.0;
break;
}
case EType::Perspective:
{
const double n = m_frustrum_zs.first;
const double f = m_frustrum_zs.second;
const double dz = f - n;
const double zz = n + f;
const double fn = n * f;
m_projection_matrix.matrix() << n / w, 0.0, 0.0, 0.0,
0.0, n / h, 0.0, 0.0,
0.0, 0.0, -zz / dz, -2.0 * fn / dz,
0.0, 0.0, -1.0, 0.0;
break;
}
}
#endif // ENABLE_RAYCAST_PICKING
#else
glsafe(::glMatrixMode(GL_PROJECTION));
glsafe(::glLoadIdentity());
switch (m_type)
{
default:
case EType::Ortho:
{
glsafe(::glOrtho(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
break;
}
case EType::Perspective:
{
glsafe(::glFrustum(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
break;
}
}
glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, m_projection_matrix.data()));
glsafe(::glMatrixMode(GL_MODELVIEW));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_RAYCAST_PICKING
void Camera::apply_projection(double left, double right, double bottom, double top, double near_z, double far_z)
{
assert(left != right && bottom != top && near_z != far_z);
@ -344,7 +255,6 @@ void Camera::apply_projection(double left, double right, double bottom, double t
}
}
}
#endif // ENABLE_RAYCAST_PICKING
void Camera::zoom_to_box(const BoundingBoxf3& box, double margin_factor)
{

View File

@ -89,33 +89,21 @@ public:
double get_far_z() const { return m_frustrum_zs.second; }
const std::pair<double, double>& get_z_range() const { return m_frustrum_zs; }
#if ENABLE_RAYCAST_PICKING
double get_near_left() const;
double get_near_right() const;
double get_near_top() const;
double get_near_bottom() const;
double get_near_width() const;
double get_near_height() const;
#endif // ENABLE_RAYCAST_PICKING
double get_fov() const;
#if ENABLE_RAYCAST_PICKING
void set_viewport(int x, int y, unsigned int w, unsigned int h);
void apply_viewport() const;
#else
void apply_viewport(int x, int y, unsigned int w, unsigned int h);
#endif // ENABLE_RAYCAST_PICKING
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void apply_view_matrix();
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
// Calculates and applies the projection matrix tighting the frustrum z range around the given box.
// If larger z span is needed, pass the desired values of near and far z (negative values are ignored)
void apply_projection(const BoundingBoxf3& box, double near_z = -1.0, double far_z = -1.0);
#if ENABLE_RAYCAST_PICKING
void apply_projection(double left, double right, double bottom, double top, double near_z, double far_z);
#endif // ENABLE_RAYCAST_PICKING
void zoom_to_box(const BoundingBoxf3& box, double margin_factor = DefaultZoomToBoxMarginFactor);
void zoom_to_volumes(const GLVolumePtrs& volumes, double margin_factor = DefaultZoomToVolumesMarginFactor);

View File

@ -3,10 +3,8 @@
#include "CoordAxes.hpp"
#include "GUI_App.hpp"
#include "3DScene.hpp"
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "Plater.hpp"
#include "Camera.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include <GL/glew.h>
@ -20,13 +18,8 @@ const float CoordAxes::DefaultStemLength = 25.0f;
const float CoordAxes::DefaultTipRadius = 2.5f * CoordAxes::DefaultStemRadius;
const float CoordAxes::DefaultTipLength = 5.0f;
#if ENABLE_LEGACY_OPENGL_REMOVAL
void CoordAxes::render(const Transform3d& trafo, float emission_factor)
#else
void CoordAxes::render(float emission_factor)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
auto render_axis = [this](GLShaderProgram& shader, const Transform3d& transform) {
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
@ -35,13 +28,6 @@ void CoordAxes::render(float emission_factor)
shader.set_uniform("projection_matrix", camera.get_projection_matrix());
shader.set_uniform("view_normal_matrix", (Matrix3d)(view_matrix.matrix().block(0, 0, 3, 3) * transform.matrix().block(0, 0, 3, 3).inverse().transpose()));
m_arrow.render();
#else
auto render_axis = [this](const Transform3f& transform) {
glsafe(::glPushMatrix());
glsafe(::glMultMatrixf(transform.data()));
m_arrow.render();
glsafe(::glPopMatrix());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
if (!m_arrow.is_initialized())
@ -59,31 +45,16 @@ void CoordAxes::render(float emission_factor)
shader->set_uniform("emission_factor", emission_factor);
// x axis
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_arrow.set_color(ColorRGBA::X());
render_axis(*shader, trafo * Geometry::translation_transform(m_origin) * Geometry::rotation_transform({ 0.0, 0.5 * M_PI, 0.0 }));
#else
m_arrow.set_color(-1, ColorRGBA::X());
render_axis(Geometry::translation_transform(m_origin) * Geometry::rotation_transform({ 0.0, 0.5 * M_PI, 0.0 }).cast<float>());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// y axis
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_arrow.set_color(ColorRGBA::Y());
render_axis(*shader, trafo * Geometry::translation_transform(m_origin) * Geometry::rotation_transform({ -0.5 * M_PI, 0.0, 0.0 }));
#else
m_arrow.set_color(-1, ColorRGBA::Y());
render_axis(Geometry::translation_transform(m_origin) * Geometry::rotation_transform({ -0.5 * M_PI, 0.0, 0.0 }).cast<float>());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// z axis
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_arrow.set_color(ColorRGBA::Z());
render_axis(*shader, trafo * Geometry::translation_transform(m_origin));
#else
m_arrow.set_color(-1, ColorRGBA::Z());
render_axis(Geometry::translation_transform(m_origin).cast<float>());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
if (curr_shader != nullptr)

View File

@ -49,11 +49,7 @@ public:
float get_tip_length() const { return m_tip_length; }
float get_total_length() const { return m_stem_length + m_tip_length; }
#if ENABLE_LEGACY_OPENGL_REMOVAL
void render(const Transform3d& trafo, float emission_factor = 0.0f);
#else
void render(float emission_factor = 0.0f);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
} // GUI

View File

@ -1416,6 +1416,14 @@ void ColourPicker::sys_color_changed()
#endif
}
PointCtrl::~PointCtrl()
{
if (sizer && sizer->IsEmpty()) {
delete sizer;
sizer = nullptr;
}
}
void PointCtrl::BUILD()
{
auto temp = new wxBoxSizer(wxHORIZONTAL);

View File

@ -425,7 +425,7 @@ class PointCtrl : public Field {
public:
PointCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
PointCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
~PointCtrl() {}
~PointCtrl();
wxSizer* sizer{ nullptr };
wxTextCtrl* x_textctrl{ nullptr };

View File

@ -193,7 +193,6 @@ void GCodeViewer::COG::render()
glsafe(::glDisable(GL_DEPTH_TEST));
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
Transform3d model_matrix = Geometry::translation_transform(cog());
if (m_fixed_size) {
@ -206,17 +205,6 @@ void GCodeViewer::COG::render()
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);
m_model.render();
#else
glsafe(::glPushMatrix());
const Vec3d position = cog();
glsafe(::glTranslated(position.x(), position.y(), position.z()));
if (m_fixed_size) {
const double inv_zoom = wxGetApp().plater()->get_camera().get_inv_zoom();
glsafe(::glScaled(inv_zoom, inv_zoom, inv_zoom));
}
m_model.render();
glsafe(::glPopMatrix());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
@ -305,11 +293,7 @@ void GCodeViewer::SequentialRangeCap::reset() {
void GCodeViewer::SequentialView::Marker::init()
{
m_model.init_from(stilized_arrow(16, 2.0f, 4.0f, 1.0f, 8.0f));
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_model.set_color({ 1.0f, 1.0f, 1.0f, 0.5f });
#else
m_model.set_color(-1, { 1.0f, 1.0f, 1.0f, 0.5f });
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& position)
@ -333,7 +317,6 @@ void GCodeViewer::SequentialView::Marker::render()
shader->start_using();
shader->set_uniform("emission_factor", 0.0f);
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
const Transform3d model_matrix = m_world_transform.cast<double>();
@ -341,17 +324,9 @@ void GCodeViewer::SequentialView::Marker::render()
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
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);
#else
glsafe(::glPushMatrix());
glsafe(::glMultMatrixf(m_world_transform.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_model.render();
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
glsafe(::glDisable(GL_BLEND));
@ -721,17 +696,12 @@ void GCodeViewer::init()
}
case EMoveType::Travel: {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line;
#if ENABLE_LEGACY_OPENGL_REMOVAL
buffer.vertices.format = VBuffer::EFormat::Position;
#if ENABLE_GL_CORE_PROFILE
buffer.shader = OpenGLManager::get_gl_info().is_core_profile() ? "dashed_thick_lines" : "flat";
#else
buffer.shader = "flat";
#endif // ENABLE_GL_CORE_PROFILE
#else
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
buffer.shader = "toolpaths_lines";
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
break;
}
}
@ -745,11 +715,7 @@ void GCodeViewer::init()
m_gl_data_initialized = true;
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print)
#else
void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print, bool initialized)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
// avoid processing if called with the same gcode_result
if (m_last_result_id == gcode_result.id &&
@ -779,11 +745,7 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr
m_filament_densities = gcode_result.filament_densities;
if (wxGetApp().is_editor())
#if ENABLE_LEGACY_OPENGL_REMOVAL
load_shells(print);
#else
load_shells(print, initialized);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
else {
Pointfs bed_shape;
std::string texture;
@ -1281,30 +1243,12 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
// format data into the buffers to be rendered as lines
auto add_vertices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, VertexBuffer& vertices) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
auto add_vertex = [&vertices](const GCodeProcessorResult::MoveVertex& vertex) {
// add position
vertices.push_back(vertex.position.x());
vertices.push_back(vertex.position.y());
vertices.push_back(vertex.position.z());
};
#else
// x component of the normal to the current segment (the normal is parallel to the XY plane)
const Vec3f dir = (curr.position - prev.position).normalized();
Vec3f normal(dir.y(), -dir.x(), 0.0);
normal.normalize();
auto add_vertex = [&vertices, &normal](const GCodeProcessorResult::MoveVertex& vertex) {
// add position
vertices.push_back(vertex.position.x());
vertices.push_back(vertex.position.y());
vertices.push_back(vertex.position.z());
// add normal
vertices.push_back(normal.x());
vertices.push_back(normal.y());
vertices.push_back(normal.z());
};
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// add previous vertex
add_vertex(prev);
@ -1555,7 +1499,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
Geometry::scale_transform({ width, width, height });
const Eigen::Matrix<double, 3, 3, Eigen::DontAlign> normal_matrix = trafo.matrix().template block<3, 3>(0, 0).inverse().transpose();
#if ENABLE_LEGACY_OPENGL_REMOVAL
// append vertices
const size_t vertices_count = data.vertices_count();
for (size_t i = 0; i < vertices_count; ++i) {
@ -1571,24 +1514,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
vertices.push_back(float(normal.y()));
vertices.push_back(float(normal.z()));
}
#else
for (const auto& entity : data.entities) {
// append vertices
for (size_t i = 0; i < entity.positions.size(); ++i) {
// append position
const Vec3d position = trafo * entity.positions[i].cast<double>();
vertices.push_back(static_cast<float>(position.x()));
vertices.push_back(static_cast<float>(position.y()));
vertices.push_back(static_cast<float>(position.z()));
// append normal
const Vec3d normal = normal_matrix * entity.normals[i].cast<double>();
vertices.push_back(static_cast<float>(normal.x()));
vertices.push_back(static_cast<float>(normal.y()));
vertices.push_back(static_cast<float>(normal.z()));
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// append instance position
instances.push_back(curr.position.x());
@ -1599,18 +1524,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
};
auto add_indices_as_model_batch = [](const GLModel::Geometry& data, IndexBuffer& indices, IBufferType base_index) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
const size_t indices_count = data.indices_count();
for (size_t i = 0; i < indices_count; ++i) {
indices.push_back(static_cast<IBufferType>(data.extract_index(i) + base_index));
}
#else
for (const auto& entity : data.entities) {
for (size_t i = 0; i < entity.indices.size(); ++i) {
indices.push_back(static_cast<IBufferType>(entity.indices[i] + base_index));
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
#if ENABLE_GCODE_VIEWER_STATISTICS
@ -2236,9 +2153,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
size_t move_id = i - seams_count;
if (move.type == EMoveType::Extrude) {
#if ENABLE_PROCESS_G2_G3_LINES
if (!move.internal_only) {
#endif // ENABLE_PROCESS_G2_G3_LINES
// layers zs
const double* const last_z = m_layers.empty() ? nullptr : &m_layers.get_zs().back();
const double z = static_cast<double>(move.position.z());
@ -2246,9 +2161,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
m_layers.append(z, { last_travel_s_id, move_id });
else
m_layers.get_ranges().back().last = move_id;
#if ENABLE_PROCESS_G2_G3_LINES
}
#endif // ENABLE_PROCESS_G2_G3_LINES
// extruder ids
m_extruder_ids.emplace_back(move.extruder_id);
// roles
@ -2301,11 +2214,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
progress_dialog->Destroy();
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GCodeViewer::load_shells(const Print& print)
#else
void GCodeViewer::load_shells(const Print& print, bool initialized)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (print.objects().empty())
// no shells, return
@ -2322,11 +2231,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized)
}
size_t current_volumes_count = m_shells.volumes.volumes.size();
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_shells.volumes.load_object(model_obj, object_id, instance_ids);
#else
m_shells.volumes.load_object(model_obj, object_id, instance_ids, initialized);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// adjust shells' z if raft is present
const SlicingParameters& slicing_parameters = obj->slicing_parameters();
@ -2350,13 +2255,8 @@ void GCodeViewer::load_shells(const Print& print, bool initialized)
const float depth = print.wipe_tower_data(extruders_count).depth;
const float brim_width = print.wipe_tower_data(extruders_count).brim_width;
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
!print.is_step_done(psWipeTower), brim_width);
#else
m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
!print.is_step_done(psWipeTower), brim_width, initialized);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
@ -2947,19 +2847,11 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
void GCodeViewer::render_toolpaths()
{
#if !ENABLE_LEGACY_OPENGL_REMOVAL
const std::array<float, 4> light_intensity = { 0.25f, 0.70f, 0.75f, 0.75f };
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
#if !ENABLE_GL_CORE_PROFILE
const double zoom = camera.get_zoom();
#endif // !ENABLE_GL_CORE_PROFILE
#if !ENABLE_LEGACY_OPENGL_REMOVAL
auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) {
shader.set_uniform("light_intensity", light_intensity);
};
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
auto render_as_lines = [
#if ENABLE_GCODE_VIEWER_STATISTICS
this
@ -3031,11 +2923,7 @@ void GCodeViewer::render_toolpaths()
}
if (range.vbo > 0) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
buffer.model.model.set_color(range.color);
#else
buffer.model.model.set_color(-1, range.color);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
buffer.model.model.render_instanced(range.vbo, range.count);
#if ENABLE_GCODE_VIEWER_STATISTICS
++m_statistics.gl_instanced_models_calls_count;
@ -3045,19 +2933,11 @@ void GCodeViewer::render_toolpaths()
}
};
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GCODE_VIEWER_STATISTICS
auto render_as_batched_model = [this](TBuffer& buffer, GLShaderProgram& shader, int position_id, int normal_id) {
#else
auto render_as_batched_model = [](TBuffer& buffer, GLShaderProgram& shader, int position_id, int normal_id) {
#endif // ENABLE_GCODE_VIEWER_STATISTICS
#else
#if ENABLE_GCODE_VIEWER_STATISTICS
auto render_as_batched_model = [this](TBuffer& buffer, GLShaderProgram& shader) {
#else
auto render_as_batched_model = [](TBuffer& buffer, GLShaderProgram& shader) {
#endif // ENABLE_GCODE_VIEWER_STATISTICS
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
struct Range
{
@ -3076,26 +2956,16 @@ void GCodeViewer::render_toolpaths()
glsafe(::glBindVertexArray(i_buffer.vao));
#endif // ENABLE_GL_CORE_PROFILE
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (position_id != -1) {
glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
glsafe(::glEnableVertexAttribArray(position_id));
}
#else
glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const bool has_normals = buffer.vertices.normal_size_floats() > 0;
if (has_normals) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (normal_id != -1) {
glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
glsafe(::glEnableVertexAttribArray(normal_id));
}
#else
glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
@ -3119,17 +2989,10 @@ void GCodeViewer::render_toolpaths()
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (normal_id != -1)
glsafe(::glDisableVertexAttribArray(normal_id));
if (position_id != -1)
glsafe(::glDisableVertexAttribArray(position_id));
#else
if (has_normals)
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
#if ENABLE_GL_CORE_PROFILE
if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0))
@ -3158,11 +3021,9 @@ void GCodeViewer::render_toolpaths()
shader->start_using();
#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
shader->set_uniform("view_normal_matrix", (Matrix3d)Matrix3d::Identity());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) {
shader->set_uniform("emission_factor", 0.25f);
@ -3171,24 +3032,15 @@ void GCodeViewer::render_toolpaths()
}
else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) {
shader->set_uniform("emission_factor", 0.25f);
#if ENABLE_LEGACY_OPENGL_REMOVAL
const int position_id = shader->get_attrib_location("v_position");
const int normal_id = shader->get_attrib_location("v_normal");
render_as_batched_model(buffer, *shader, position_id, normal_id);
#else
render_as_batched_model(buffer, *shader);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
shader->set_uniform("emission_factor", 0.0f);
}
else {
shader->set_uniform("emission_factor", 0.15f);
#if ENABLE_LEGACY_OPENGL_REMOVAL
const int position_id = shader->get_attrib_location("v_position");
const int normal_id = shader->get_attrib_location("v_normal");
#else
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Line)
shader_init_as_lines(*shader);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const int uniform_color = shader->get_uniform_location("uniform_color");
auto it_path = buffer.render_paths.begin();
@ -3205,26 +3057,16 @@ void GCodeViewer::render_toolpaths()
glsafe(::glBindVertexArray(i_buffer.vao));
#endif // ENABLE_GL_CORE_PROFILE
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (position_id != -1) {
glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
glsafe(::glEnableVertexAttribArray(position_id));
}
#else
glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const bool has_normals = buffer.vertices.normal_size_floats() > 0;
if (has_normals) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (normal_id != -1) {
glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
glsafe(::glEnableVertexAttribArray(normal_id));
}
#else
glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
@ -3251,17 +3093,10 @@ void GCodeViewer::render_toolpaths()
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (normal_id != -1)
glsafe(::glDisableVertexAttribArray(normal_id));
if (position_id != -1)
glsafe(::glDisableVertexAttribArray(position_id));
#else
if (has_normals)
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
#if ENABLE_GL_CORE_PROFILE
if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0))
@ -3286,40 +3121,28 @@ void GCodeViewer::render_toolpaths()
shader->start_using();
#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
shader->set_uniform("view_normal_matrix", (Matrix3d)Matrix3d::Identity());
const int position_id = shader->get_attrib_location("v_position");
const int normal_id = shader->get_attrib_location("v_normal");
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_CORE_PROFILE
if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0))
glsafe(::glBindVertexArray(cap.vao));
#endif // ENABLE_GL_CORE_PROFILE
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo));
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (position_id != -1) {
glsafe(::glVertexAttribPointer(position_id, buffer->vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.position_offset_bytes()));
glsafe(::glEnableVertexAttribArray(position_id));
}
#else
glsafe(::glVertexPointer(buffer->vertices.position_size_floats(), GL_FLOAT, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.position_offset_bytes()));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const bool has_normals = buffer->vertices.normal_size_floats() > 0;
if (has_normals) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (normal_id != -1) {
glsafe(::glVertexAttribPointer(normal_id, buffer->vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.normal_offset_bytes()));
glsafe(::glEnableVertexAttribArray(normal_id));
}
#else
glsafe(::glNormalPointer(GL_FLOAT, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.normal_offset_bytes()));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
shader->set_uniform("uniform_color", cap.color);
@ -3332,17 +3155,10 @@ void GCodeViewer::render_toolpaths()
++m_statistics.gl_triangles_calls_count;
#endif // ENABLE_GCODE_VIEWER_STATISTICS
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (normal_id != -1)
glsafe(::glDisableVertexAttribArray(normal_id));
if (position_id != -1)
glsafe(::glDisableVertexAttribArray(position_id));
#else
if (has_normals)
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
#if ENABLE_GL_CORE_PROFILE
@ -3368,25 +3184,11 @@ void GCodeViewer::render_shells()
if (shader == nullptr)
return;
#if !ENABLE_LEGACY_OPENGL_REMOVAL
// when the background processing is enabled, it may happen that the shells data have been loaded
// before opengl has been initialized for the preview canvas.
// when this happens, the volumes' data have not been sent to gpu yet.
for (GLVolume* v : m_shells.volumes.volumes) {
if (!v->indexed_vertex_array.has_VBOs())
v->finalize_geometry(true);
}
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
// glsafe(::glDepthMask(GL_FALSE));
shader->start_using();
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, true, camera.get_view_matrix(), camera.get_projection_matrix());
#else
m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, true, wxGetApp().plater()->get_camera().get_view_matrix());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
// glsafe(::glDepthMask(GL_TRUE));

View File

@ -364,11 +364,7 @@ class GCodeViewer
}
case ERenderPrimitiveType::InstancedModel: { return model.model.is_initialized() && !model.instances.buffer.empty(); }
case ERenderPrimitiveType::BatchedModel: {
#if ENABLE_LEGACY_OPENGL_REMOVAL
return !model.data.vertices.empty() && !model.data.indices.empty() &&
#else
return model.data.vertices_count() > 0 && model.data.indices_count() &&
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
!vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0;
}
default: { return false; }
@ -418,12 +414,7 @@ class GCodeViewer
return;
const float radius = m_fixed_size ? 10.0f : 1.0f;
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_model.init_from(smooth_sphere(32, radius));
#else
m_model.init_from(its_make_sphere(radius, PI / 32.0));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
};
@ -799,11 +790,7 @@ public:
void init();
// extract rendering data from the given parameters
#if ENABLE_LEGACY_OPENGL_REMOVAL
void load(const GCodeProcessorResult& gcode_result, const Print& print);
#else
void load(const GCodeProcessorResult& gcode_result, const Print& print, bool initialized);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// recalculate ranges in dependence of what is visible and sets tool/print colors
void refresh(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors);
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
@ -855,11 +842,7 @@ public:
private:
void load_toolpaths(const GCodeProcessorResult& gcode_result);
#if ENABLE_LEGACY_OPENGL_REMOVAL
void load_shells(const Print& print);
#else
void load_shells(const Print& print, bool initialized);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void render_toolpaths();
void render_shells();
void render_legend(float& legend_height);

File diff suppressed because it is too large Load Diff

View File

@ -16,9 +16,7 @@
#include "libslic3r/GCode/GCodeProcessor.hpp"
#include "GCodeViewer.hpp"
#include "Camera.hpp"
#if ENABLE_RAYCAST_PICKING
#include "SceneRaycaster.hpp"
#endif // ENABLE_RAYCAST_PICKING
#include "GUI_Utils.hpp"
#include "libslic3r/Slicing.hpp"
@ -245,7 +243,7 @@ class GLCanvas3D
int last_object_id{ -1 };
float last_z{ 0.0f };
LayerHeightEditActionType last_action{ LAYER_HEIGHT_EDIT_ACTION_INCREASE };
#if ENABLE_LEGACY_OPENGL_REMOVAL
struct Profile
{
GLModel baseline;
@ -255,7 +253,6 @@ class GLCanvas3D
std::vector<double> old_layer_height_profile;
};
Profile m_profile;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
LayersEditing() = default;
~LayersEditing();
@ -282,9 +279,6 @@ class GLCanvas3D
static float get_cursor_z_relative(const GLCanvas3D& canvas);
static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y);
static Rect get_bar_rect_screen(const GLCanvas3D& canvas);
#if !ENABLE_LEGACY_OPENGL_REMOVAL
static Rect get_bar_rect_viewport(const GLCanvas3D& canvas);
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
static float get_overlay_window_width() { return LayersEditing::s_overlay_window_width; }
float object_max_z() const { return m_object_max_z; }
@ -294,13 +288,8 @@ class GLCanvas3D
private:
bool is_initialized() const;
void generate_layer_height_texture();
#if ENABLE_LEGACY_OPENGL_REMOVAL
void render_active_object_annotations(const GLCanvas3D& canvas);
void render_profile(const GLCanvas3D& canvas);
#else
void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect);
void render_profile(const Rect& bar_rect);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void update_slicing_parameters();
static float thickness_bar_width(const GLCanvas3D &canvas);
@ -347,7 +336,6 @@ class GLCanvas3D
struct SlaCap
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
struct Triangles
{
GLModel object;
@ -356,16 +344,6 @@ class GLCanvas3D
typedef std::map<unsigned int, Triangles> ObjectIdToModelsMap;
double z;
ObjectIdToModelsMap triangles;
#else
struct Triangles
{
Pointf3s object;
Pointf3s supports;
};
typedef std::map<unsigned int, Triangles> ObjectIdToTrianglesMap;
double z;
ObjectIdToTrianglesMap triangles;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
SlaCap() { reset(); }
void reset() { z = DBL_MAX; triangles.clear(); }
@ -422,6 +400,7 @@ class GLCanvas3D
std::chrono::steady_clock::time_point m_start_time;
// Indicator that the mouse is inside an ImGUI dialog, therefore the tooltip should be suppressed.
bool m_in_imgui = false;
float m_cursor_height{ 16.0f };
public:
bool is_empty() const { return m_text.empty(); }
@ -483,9 +462,7 @@ public:
private:
wxGLCanvas* m_canvas;
wxGLContext* m_context;
#if ENABLE_RAYCAST_PICKING
SceneRaycaster m_scene_raycaster;
#endif // ENABLE_RAYCAST_PICKING
Bed3D &m_bed;
#if ENABLE_RETINA_GL
std::unique_ptr<RetinaHelper> m_retina_helper;
@ -642,7 +619,6 @@ private:
}
m_gizmo_highlighter;
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SHOW_CAMERA_TARGET
struct CameraTarget
{
@ -653,7 +629,6 @@ private:
CameraTarget m_camera_target;
#endif // ENABLE_SHOW_CAMERA_TARGET
GLModel m_background;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
public:
explicit GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed);
@ -669,7 +644,6 @@ public:
bool init();
void post_event(wxEvent &&event);
#if ENABLE_RAYCAST_PICKING
std::shared_ptr<SceneRaycasterItem> add_raycaster_for_picking(SceneRaycaster::EType type, int id, const MeshRaycaster& raycaster,
const Transform3d& trafo = Transform3d::Identity(), bool use_back_faces = false) {
return m_scene_raycaster.add_raycaster(type, id, raycaster, trafo, use_back_faces);
@ -688,7 +662,6 @@ public:
void set_raycaster_gizmos_on_top(bool value) {
m_scene_raycaster.set_gizmos_on_top(value);
}
#endif // ENABLE_RAYCAST_PICKING
void set_as_dirty();
void requires_check_outside_state() { m_requires_check_outside_state = true; }
@ -991,13 +964,8 @@ private:
void _picking_pass();
void _rectangular_selection_picking_pass();
void _render_background();
#if ENABLE_LEGACY_OPENGL_REMOVAL
void _render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_axes);
void _render_bed_for_picking(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom);
#else
void _render_bed(bool bottom, bool show_axes);
void _render_bed_for_picking(bool bottom);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void _render_objects(GLVolumeCollection::ERenderType type);
void _render_gcode();
void _render_gcode_cog();
@ -1008,11 +976,7 @@ private:
#endif // ENABLE_RENDER_SELECTION_CENTER
void _check_and_update_toolbar_icon_scale();
void _render_overlays();
#if ENABLE_RAYCAST_PICKING
void _render_volumes_for_picking(const Camera& camera) const;
#else
void _render_volumes_for_picking() const;
#endif // ENABLE_RAYCAST_PICKING
void _render_current_gizmo() const;
void _render_gizmos_overlay();
void _render_main_toolbar();

View File

@ -12,10 +12,8 @@
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/Polygon.hpp"
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "libslic3r/BuildVolume.hpp"
#include "libslic3r/Geometry/ConvexHull.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GLMODEL_STATISTICS
#include <imgui/imgui_internal.h>
@ -24,20 +22,17 @@
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string/predicate.hpp>
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SMOOTH_NORMALS
#include <igl/per_face_normals.h>
#include <igl/per_corner_normals.h>
#include <igl/per_vertex_normals.h>
#endif // ENABLE_SMOOTH_NORMALS
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include <GL/glew.h>
namespace Slic3r {
namespace GUI {
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SMOOTH_NORMALS
static void smooth_normals_corner(const TriangleMesh& mesh, std::vector<stl_normal>& normals)
{
@ -64,9 +59,7 @@ static void smooth_normals_corner(const TriangleMesh& mesh, std::vector<stl_norm
}
}
#endif // ENABLE_SMOOTH_NORMALS
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::Geometry::add_vertex(const Vec2f& position)
{
assert(format.vertex_layout == EVertexLayout::P2);
@ -484,37 +477,13 @@ bool GLModel::Geometry::has_extra(const Format& format)
};
}
#endif // ENABLE_OPENGL_ES
#else
size_t GLModel::Geometry::vertices_count() const
{
size_t ret = 0;
for (const Entity& entity : entities) {
ret += entity.positions.size();
}
return ret;
}
size_t GLModel::Geometry::indices_count() const
{
size_t ret = 0;
for (const Entity& entity : entities) {
ret += entity.indices.size();
}
return ret;
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GLMODEL_STATISTICS
GLModel::Statistics GLModel::s_statistics;
#endif // ENABLE_GLMODEL_STATISTICS
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::init_from(Geometry&& data)
#else
void GLModel::init_from(const Geometry& data)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (is_initialized()) {
// call reset() if you want to reuse this model
assert(false);
@ -538,46 +507,8 @@ void GLModel::init_from(const Geometry& data)
m_bounding_box.merge(Vec3f(position.x(), position.y(), 0.0f).cast<double>());
}
}
#else
if (!m_render_data.empty()) // call reset() if you want to reuse this model
return;
for (const Geometry::Entity& entity : data.entities) {
if (entity.positions.empty() || entity.indices.empty())
continue;
assert(entity.normals.empty() || entity.normals.size() == entity.positions.size());
RenderData rdata;
rdata.type = entity.type;
rdata.color = entity.color;
// vertices/normals data
std::vector<float> vertices(6 * entity.positions.size());
for (size_t i = 0; i < entity.positions.size(); ++i) {
const size_t offset = i * 6;
::memcpy(static_cast<void*>(&vertices[offset]), static_cast<const void*>(entity.positions[i].data()), 3 * sizeof(float));
if (!entity.normals.empty())
::memcpy(static_cast<void*>(&vertices[3 + offset]), static_cast<const void*>(entity.normals[i].data()), 3 * sizeof(float));
}
// indices data
std::vector<unsigned int> indices = entity.indices;
rdata.indices_count = static_cast<unsigned int>(indices.size());
// update bounding box
for (size_t i = 0; i < entity.positions.size(); ++i) {
m_bounding_box.merge(entity.positions[i].cast<double>());
}
send_to_gpu(rdata, vertices, indices);
m_render_data.emplace_back(rdata);
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SMOOTH_NORMALS
void GLModel::init_from(const TriangleMesh& mesh, bool smooth_normals)
{
@ -629,11 +560,7 @@ void GLModel::init_from(const TriangleMesh& mesh)
#endif // ENABLE_SMOOTH_NORMALS
void GLModel::init_from(const indexed_triangle_set& its)
#else
void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bbox)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (is_initialized()) {
// call reset() if you want to reuse this model
assert(false);
@ -667,49 +594,10 @@ void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bb
for (size_t i = 0; i < vertices_count(); ++i) {
m_bounding_box.merge(data.extract_position_3(i).cast<double>());
}
#else
if (!m_render_data.empty()) // call reset() if you want to reuse this model
return;
RenderData data;
data.type = EPrimitiveType::Triangles;
std::vector<float> vertices = std::vector<float>(18 * its.indices.size());
std::vector<unsigned int> indices = std::vector<unsigned int>(3 * its.indices.size());
unsigned int vertices_count = 0;
for (uint32_t i = 0; i < its.indices.size(); ++i) {
stl_triangle_vertex_indices face = its.indices[i];
stl_vertex vertex[3] = { its.vertices[face[0]], its.vertices[face[1]], its.vertices[face[2]] };
stl_vertex n = face_normal_normalized(vertex);
for (size_t j = 0; j < 3; ++ j) {
size_t offset = i * 18 + j * 6;
::memcpy(static_cast<void*>(&vertices[offset]), static_cast<const void*>(vertex[j].data()), 3 * sizeof(float));
::memcpy(static_cast<void*>(&vertices[3 + offset]), static_cast<const void*>(n.data()), 3 * sizeof(float));
}
for (size_t j = 0; j < 3; ++j)
indices[i * 3 + j] = vertices_count + j;
vertices_count += 3;
}
data.indices_count = static_cast<unsigned int>(indices.size());
m_bounding_box = bbox;
send_to_gpu(data, vertices, indices);
m_render_data.emplace_back(data);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::init_from(const indexed_triangle_set& its)
{
init_from(its, bounding_box(its));
}
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::init_from(const Polygons& polygons, float z)
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (is_initialized()) {
// call reset() if you want to reuse this model
assert(false);
@ -749,31 +637,6 @@ void GLModel::init_from(const Polygons& polygons, float z)
for (size_t i = 0; i < vertices_count(); ++i) {
m_bounding_box.merge(data.extract_position_3(i).cast<double>());
}
#else
auto append_polygon = [](const Polygon& polygon, float z, GUI::GLModel::Geometry& data) {
if (!polygon.empty()) {
GUI::GLModel::Geometry::Entity entity;
entity.type = GUI::GLModel::EPrimitiveType::LineLoop;
// contour
entity.positions.reserve(polygon.size() + 1);
entity.indices.reserve(polygon.size() + 1);
unsigned int id = 0;
for (const Point& p : polygon) {
Vec3f position = unscale(p.x(), p.y(), 0.0).cast<float>();
position.z() = z;
entity.positions.emplace_back(position);
entity.indices.emplace_back(id++);
}
data.entities.emplace_back(entity);
}
};
Geometry init_data;
for (const Polygon& polygon : polygons) {
append_polygon(polygon, z, init_data);
}
init_from(init_data);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
bool GLModel::init_from_file(const std::string& filename)
@ -792,37 +655,15 @@ bool GLModel::init_from_file(const std::string& filename)
return false;
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
init_from(model.mesh());
#else
const TriangleMesh& mesh = model.mesh();
init_from(mesh.its, mesh.bounding_box());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_filename = filename;
return true;
}
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::set_color(int entity_id, const ColorRGBA& color)
{
for (size_t i = 0; i < m_render_data.size(); ++i) {
if (entity_id == -1 || static_cast<int>(i) == entity_id)
m_render_data[i].color = color;
}
}
ColorRGBA GLModel::get_color(size_t entity_id) const
{
if (entity_id < 0 || entity_id >= m_render_data.size()) return ColorRGBA{};
return m_render_data[entity_id].color;
}
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::reset()
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
// release gpu memory
if (m_render_data.ibo_id > 0) {
glsafe(::glDeleteBuffers(1, &m_render_data.ibo_id));
@ -849,22 +690,10 @@ void GLModel::reset()
m_render_data.indices_count = 0;
m_render_data.geometry.vertices = std::vector<float>();
m_render_data.geometry.indices = std::vector<unsigned int>();
#else
for (RenderData& data : m_render_data) {
// release gpu memory
if (data.ibo_id > 0)
glsafe(::glDeleteBuffers(1, &data.ibo_id));
if (data.vbo_id > 0)
glsafe(::glDeleteBuffers(1, &data.vbo_id));
}
m_render_data.clear();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_bounding_box = BoundingBoxf3();
m_filename = std::string();
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
static GLenum get_primitive_mode(const GLModel::Geometry::Format& format)
{
switch (format.type)
@ -892,54 +721,10 @@ static GLenum get_index_type(const GLModel::Geometry& data)
}
void GLModel::render()
#else
void GLModel::render() const
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
render(std::make_pair<size_t, size_t>(0, indices_count()));
#else
GLShaderProgram* shader = wxGetApp().get_current_shader();
for (const RenderData& data : m_render_data) {
if (data.vbo_id == 0 || data.ibo_id == 0)
continue;
GLenum mode;
switch (data.type)
{
default:
case EPrimitiveType::Triangles: { mode = GL_TRIANGLES; break; }
case EPrimitiveType::Lines: { mode = GL_LINES; break; }
case EPrimitiveType::LineStrip: { mode = GL_LINE_STRIP; break; }
case EPrimitiveType::LineLoop: { mode = GL_LINE_LOOP; break; }
}
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, data.vbo_id));
glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)0));
glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
if (shader != nullptr)
shader->set_uniform("uniform_color", data.color);
else
glsafe(::glColor4fv(data.color.data()));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo_id));
glsafe(::glDrawElements(mode, static_cast<GLsizei>(data.indices_count), GL_UNSIGNED_INT, (const void*)0));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::render(const std::pair<size_t, size_t>& range)
{
if (m_render_disabled)
@ -1048,19 +833,13 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
++s_statistics.render_calls;
#endif // ENABLE_GLMODEL_STATISTICS
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count)
#else
void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count) const
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (instances_vbo == 0 || instances_count == 0)
return;
GLShaderProgram* shader = wxGetApp().get_current_shader();
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (shader == nullptr || !boost::algorithm::iends_with(shader->get_name(), "_instanced"))
return;
@ -1080,19 +859,6 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
if (!send_to_gpu())
return;
}
#else
assert(shader == nullptr || boost::algorithm::iends_with(shader->get_name(), "_instanced"));
// vertex attributes
GLint position_id = (shader != nullptr) ? shader->get_attrib_location("v_position") : -1;
GLint normal_id = (shader != nullptr) ? shader->get_attrib_location("v_normal") : -1;
assert(position_id != -1 && normal_id != -1);
// instance attributes
GLint offset_id = (shader != nullptr) ? shader->get_attrib_location("i_offset") : -1;
GLint scales_id = (shader != nullptr) ? shader->get_attrib_location("i_scales") : -1;
assert(offset_id != -1 && scales_id != -1);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_CORE_PROFILE
if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0))
@ -1100,7 +866,6 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
#endif // ENABLE_GL_CORE_PROFILE
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, instances_vbo));
#if ENABLE_LEGACY_OPENGL_REMOVAL
const size_t instance_stride = 5 * sizeof(float);
glsafe(::glVertexAttribPointer(offset_id, 3, GL_FLOAT, GL_FALSE, instance_stride, (const void*)0));
glsafe(::glEnableVertexAttribArray(offset_id));
@ -1109,20 +874,7 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
glsafe(::glVertexAttribPointer(scales_id, 2, GL_FLOAT, GL_FALSE, instance_stride, (const void*)(3 * sizeof(float))));
glsafe(::glEnableVertexAttribArray(scales_id));
glsafe(::glVertexAttribDivisor(scales_id, 1));
#else
if (offset_id != -1) {
glsafe(::glVertexAttribPointer(offset_id, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)0));
glsafe(::glEnableVertexAttribArray(offset_id));
glsafe(::glVertexAttribDivisor(offset_id, 1));
}
if (scales_id != -1) {
glsafe(::glVertexAttribPointer(scales_id, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)(3 * sizeof(float))));
glsafe(::glEnableVertexAttribArray(scales_id));
glsafe(::glVertexAttribDivisor(scales_id, 1));
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Geometry& data = m_render_data.geometry;
const GLenum mode = get_primitive_mode(data.format);
@ -1164,51 +916,6 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
glsafe(::glDisableVertexAttribArray(scales_id));
glsafe(::glDisableVertexAttribArray(offset_id));
#else
for (const RenderData& data : m_render_data) {
if (data.vbo_id == 0 || data.ibo_id == 0)
continue;
GLenum mode;
switch (data.type)
{
default:
case EPrimitiveType::Triangles: { mode = GL_TRIANGLES; break; }
case EPrimitiveType::Lines: { mode = GL_LINES; break; }
case EPrimitiveType::LineStrip: { mode = GL_LINE_STRIP; break; }
case EPrimitiveType::LineLoop: { mode = GL_LINE_LOOP; break; }
}
if (shader != nullptr)
shader->set_uniform("uniform_color", data.color);
else
glsafe(::glColor4fv(data.color.data()));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, data.vbo_id));
if (position_id != -1) {
glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid*)0));
glsafe(::glEnableVertexAttribArray(position_id));
}
if (normal_id != -1) {
glsafe(::glVertexAttribPointer(normal_id, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid*)(3 * sizeof(float))));
glsafe(::glEnableVertexAttribArray(normal_id));
}
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo_id));
glsafe(::glDrawElementsInstanced(mode, static_cast<GLsizei>(data.indices_count), GL_UNSIGNED_INT, (const void*)0, instances_count));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
if (normal_id != -1)
glsafe(::glDisableVertexAttribArray(normal_id));
if (position_id != -1)
glsafe(::glDisableVertexAttribArray(position_id));
}
if (scales_id != -1)
glsafe(::glDisableVertexAttribArray(scales_id));
if (offset_id != -1)
glsafe(::glDisableVertexAttribArray(offset_id));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
#if ENABLE_GL_CORE_PROFILE
@ -1221,7 +928,6 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
#endif // ENABLE_GLMODEL_STATISTICS
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
bool GLModel::send_to_gpu()
{
if (m_render_data.vbo_id > 0 || m_render_data.ibo_id > 0) {
@ -1361,27 +1067,6 @@ void GLModel::render_statistics()
}
#endif // ENABLE_GLMODEL_STATISTICS
#else
void GLModel::send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices)
{
assert(data.vbo_id == 0);
assert(data.ibo_id == 0);
// vertex data -> send to gpu
glsafe(::glGenBuffers(1, &data.vbo_id));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, data.vbo_id));
glsafe(::glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
// indices data -> send to gpu
glsafe(::glGenBuffers(1, &data.ibo_id));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo_id));
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
template<typename Fn>
inline bool all_vertices_inside(const GLModel::Geometry& geometry, Fn fn)
{
@ -1435,33 +1120,15 @@ bool contains(const BuildVolume& volume, const GLModel& model, bool ignore_botto
return true;
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
GLModel::Geometry stilized_arrow(unsigned int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height)
{
#if !ENABLE_LEGACY_OPENGL_REMOVAL
auto append_vertex = [](GLModel::Geometry::Entity& entity, const Vec3f& position, const Vec3f& normal) {
entity.positions.emplace_back(position);
entity.normals.emplace_back(normal);
};
auto append_indices = [](GLModel::Geometry::Entity& entity, unsigned int v1, unsigned int v2, unsigned int v3) {
entity.indices.emplace_back(v1);
entity.indices.emplace_back(v2);
entity.indices.emplace_back(v3);
};
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
resolution = std::max<unsigned int>(4, resolution);
GLModel::Geometry data;
#if ENABLE_LEGACY_OPENGL_REMOVAL
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
data.reserve_vertices(6 * resolution + 2);
data.reserve_indices(6 * resolution * 3);
#else
GLModel::Geometry::Entity entity;
entity.type = GLModel::EPrimitiveType::Triangles;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const float angle_step = 2.0f * float(PI) / float(resolution);
std::vector<float> cosines(resolution);
@ -1476,7 +1143,6 @@ GLModel::Geometry stilized_arrow(unsigned int resolution, float tip_radius, floa
const float total_height = tip_height + stem_height;
// tip vertices/normals
#if ENABLE_LEGACY_OPENGL_REMOVAL
data.add_vertex(Vec3f(0.0f, 0.0f, total_height), (Vec3f)Vec3f::UnitZ());
for (unsigned int i = 0; i < resolution; ++i) {
data.add_vertex(Vec3f(tip_radius * sines[i], tip_radius * cosines[i], stem_height), Vec3f(sines[i], cosines[i], 0.0f));
@ -1535,97 +1201,18 @@ GLModel::Geometry stilized_arrow(unsigned int resolution, float tip_radius, floa
const unsigned int v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2;
data.add_triangle(5 * resolution + 1, v3, i + 5 * resolution + 2);
}
#else
append_vertex(entity, { 0.0f, 0.0f, total_height }, Vec3f::UnitZ());
for (unsigned int i = 0; i < resolution; ++i) {
append_vertex(entity, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f });
}
// tip triangles
for (unsigned int i = 0; i < resolution; ++i) {
const int v3 = (i < resolution - 1) ? i + 2 : 1;
append_indices(entity, 0, i + 1, v3);
}
// tip cap outer perimeter vertices
for (unsigned int i = 0; i < resolution; ++i) {
append_vertex(entity, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, -Vec3f::UnitZ());
}
// tip cap inner perimeter vertices
for (unsigned int i = 0; i < resolution; ++i) {
append_vertex(entity, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, -Vec3f::UnitZ());
}
// tip cap triangles
for (unsigned int i = 0; i < resolution; ++i) {
const unsigned int v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1;
const unsigned int v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1;
append_indices(entity, i + resolution + 1, v3, v2);
append_indices(entity, i + resolution + 1, i + 2 * resolution + 1, v3);
}
// stem bottom vertices
for (unsigned int i = 0; i < resolution; ++i) {
append_vertex(entity, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f });
}
// stem top vertices
for (unsigned int i = 0; i < resolution; ++i) {
append_vertex(entity, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, { sines[i], cosines[i], 0.0f });
}
// stem triangles
for (unsigned int i = 0; i < resolution; ++i) {
const int unsigned v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1;
const int unsigned v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1;
append_indices(entity, i + 3 * resolution + 1, v3, v2);
append_indices(entity, i + 3 * resolution + 1, i + 4 * resolution + 1, v3);
}
// stem cap vertices
append_vertex(entity, Vec3f::Zero(), -Vec3f::UnitZ());
for (unsigned int i = 0; i < resolution; ++i) {
append_vertex(entity, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, -Vec3f::UnitZ());
}
// stem cap triangles
for (unsigned int i = 0; i < resolution; ++i) {
const unsigned int v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2;
append_indices(entity, 5 * resolution + 1, v3, i + 5 * resolution + 2);
}
data.entities.emplace_back(entity);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return data;
}
GLModel::Geometry circular_arrow(unsigned int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness)
{
#if !ENABLE_LEGACY_OPENGL_REMOVAL
auto append_vertex = [](GLModel::Geometry::Entity& entity, const Vec3f& position, const Vec3f& normal) {
entity.positions.emplace_back(position);
entity.normals.emplace_back(normal);
};
auto append_indices = [](GLModel::Geometry::Entity& entity, unsigned int v1, unsigned int v2, unsigned int v3) {
entity.indices.emplace_back(v1);
entity.indices.emplace_back(v2);
entity.indices.emplace_back(v3);
};
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
resolution = std::max<unsigned int>(2, resolution);
GLModel::Geometry data;
#if ENABLE_LEGACY_OPENGL_REMOVAL
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
data.reserve_vertices(8 * (resolution + 1) + 30);
data.reserve_indices((8 * resolution + 16) * 3);
#else
GLModel::Geometry::Entity entity;
entity.type = GLModel::EPrimitiveType::Triangles;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const float half_thickness = 0.5f * thickness;
const float half_stem_width = 0.5f * stem_width;
@ -1635,7 +1222,6 @@ GLModel::Geometry circular_arrow(unsigned int resolution, float radius, float ti
const float inner_radius = radius - half_stem_width;
const float step_angle = 0.5f * float(PI) / float(resolution);
#if ENABLE_LEGACY_OPENGL_REMOVAL
// tip
// top face vertices
data.add_vertex(Vec3f(0.0f, outer_radius, half_thickness), (Vec3f)Vec3f::UnitZ());
@ -1779,187 +1365,22 @@ GLModel::Geometry circular_arrow(unsigned int resolution, float radius, float ti
data.add_triangle(ii, ii + 1, ii + resolution + 2);
data.add_triangle(ii, ii + resolution + 2, ii + resolution + 1);
}
#else
// tip
// top face vertices
append_vertex(entity, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitZ());
append_vertex(entity, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitZ());
append_vertex(entity, { -tip_height, radius, half_thickness }, Vec3f::UnitZ());
append_vertex(entity, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitZ());
append_vertex(entity, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitZ());
// top face triangles
append_indices(entity, 0, 1, 2);
append_indices(entity, 0, 2, 4);
append_indices(entity, 4, 2, 3);
// bottom face vertices
append_vertex(entity, { 0.0f, outer_radius, -half_thickness }, -Vec3f::UnitZ());
append_vertex(entity, { 0.0f, radius + half_tip_width, -half_thickness }, -Vec3f::UnitZ());
append_vertex(entity, { -tip_height, radius, -half_thickness }, -Vec3f::UnitZ());
append_vertex(entity, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitZ());
append_vertex(entity, { 0.0f, inner_radius, -half_thickness }, -Vec3f::UnitZ());
// bottom face triangles
append_indices(entity, 5, 7, 6);
append_indices(entity, 5, 9, 7);
append_indices(entity, 9, 8, 7);
// side faces vertices
append_vertex(entity, { 0.0f, outer_radius, -half_thickness }, Vec3f::UnitX());
append_vertex(entity, { 0.0f, radius + half_tip_width, -half_thickness }, Vec3f::UnitX());
append_vertex(entity, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitX());
append_vertex(entity, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitX());
Vec3f normal(-half_tip_width, tip_height, 0.0f);
normal.normalize();
append_vertex(entity, { 0.0f, radius + half_tip_width, -half_thickness }, normal);
append_vertex(entity, { -tip_height, radius, -half_thickness }, normal);
append_vertex(entity, { 0.0f, radius + half_tip_width, half_thickness }, normal);
append_vertex(entity, { -tip_height, radius, half_thickness }, normal);
normal = Vec3f(-half_tip_width, -tip_height, 0.0f);
normal.normalize();
append_vertex(entity, { -tip_height, radius, -half_thickness }, normal);
append_vertex(entity, { 0.0f, radius - half_tip_width, -half_thickness }, normal);
append_vertex(entity, { -tip_height, radius, half_thickness }, normal);
append_vertex(entity, { 0.0f, radius - half_tip_width, half_thickness }, normal);
append_vertex(entity, { 0.0f, radius - half_tip_width, -half_thickness }, Vec3f::UnitX());
append_vertex(entity, { 0.0f, inner_radius, -half_thickness }, Vec3f::UnitX());
append_vertex(entity, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitX());
append_vertex(entity, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitX());
// side face triangles
for (int i = 0; i < 4; ++i) {
const int ii = i * 4;
append_indices(entity, 10 + ii, 11 + ii, 13 + ii);
append_indices(entity, 10 + ii, 13 + ii, 12 + ii);
}
// stem
// top face vertices
for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = static_cast<float>(i) * step_angle;
append_vertex(entity, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ());
}
for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = static_cast<float>(i) * step_angle;
append_vertex(entity, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ());
}
// top face triangles
for (unsigned int i = 0; i < resolution; ++i) {
append_indices(entity, 26 + i, 27 + i, 27 + resolution + i);
append_indices(entity, 27 + i, 28 + resolution + i, 27 + resolution + i);
}
// bottom face vertices
for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = static_cast<float>(i) * step_angle;
append_vertex(entity, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ());
}
for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = static_cast<float>(i) * step_angle;
append_vertex(entity, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ());
}
// bottom face triangles
for (unsigned int i = 0; i < resolution; ++i) {
append_indices(entity, 28 + 2 * resolution + i, 29 + 3 * resolution + i, 29 + 2 * resolution + i);
append_indices(entity, 29 + 2 * resolution + i, 29 + 3 * resolution + i, 30 + 3 * resolution + i);
}
// side faces vertices and triangles
for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = static_cast<float>(i) * step_angle;
const float c = ::cos(angle);
const float s = ::sin(angle);
append_vertex(entity, { inner_radius * s, inner_radius * c, -half_thickness }, { -s, -c, 0.0f });
}
for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = static_cast<float>(i) * step_angle;
const float c = ::cos(angle);
const float s = ::sin(angle);
append_vertex(entity, { inner_radius * s, inner_radius * c, half_thickness }, { -s, -c, 0.0f });
}
unsigned int first_id = 26 + 4 * (resolution + 1);
for (unsigned int i = 0; i < resolution; ++i) {
const unsigned int ii = first_id + i;
append_indices(entity, ii, ii + 1, ii + resolution + 2);
append_indices(entity, ii, ii + resolution + 2, ii + resolution + 1);
}
append_vertex(entity, { inner_radius, 0.0f, -half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { outer_radius, 0.0f, -half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { inner_radius, 0.0f, half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { outer_radius, 0.0f, half_thickness }, -Vec3f::UnitY());
first_id = 26 + 6 * (resolution + 1);
append_indices(entity, first_id, first_id + 1, first_id + 3);
append_indices(entity, first_id, first_id + 3, first_id + 2);
for (int i = int(resolution); i >= 0; --i) {
const float angle = static_cast<float>(i) * step_angle;
const float c = ::cos(angle);
const float s = ::sin(angle);
append_vertex(entity, { outer_radius * s, outer_radius * c, -half_thickness }, { s, c, 0.0f });
}
for (int i = int(resolution); i >= 0; --i) {
const float angle = static_cast<float>(i) * step_angle;
const float c = ::cos(angle);
const float s = ::sin(angle);
append_vertex(entity, { outer_radius * s, outer_radius * c, +half_thickness }, { s, c, 0.0f });
}
first_id = 30 + 6 * (resolution + 1);
for (unsigned int i = 0; i < resolution; ++i) {
const unsigned int ii = first_id + i;
append_indices(entity, ii, ii + 1, ii + resolution + 2);
append_indices(entity, ii, ii + resolution + 2, ii + resolution + 1);
}
data.entities.emplace_back(entity);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return data;
}
GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness)
{
#if !ENABLE_LEGACY_OPENGL_REMOVAL
auto append_vertex = [](GLModel::Geometry::Entity& entity, const Vec3f& position, const Vec3f& normal) {
entity.positions.emplace_back(position);
entity.normals.emplace_back(normal);
};
auto append_indices = [](GLModel::Geometry::Entity& entity, unsigned int v1, unsigned int v2, unsigned int v3) {
entity.indices.emplace_back(v1);
entity.indices.emplace_back(v2);
entity.indices.emplace_back(v3);
};
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
GLModel::Geometry data;
#if ENABLE_LEGACY_OPENGL_REMOVAL
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
data.reserve_vertices(42);
data.reserve_indices(72);
#else
GLModel::Geometry::Entity entity;
entity.type = GLModel::EPrimitiveType::Triangles;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const float half_thickness = 0.5f * thickness;
const float half_stem_width = 0.5f * stem_width;
const float half_tip_width = 0.5f * tip_width;
const float total_height = tip_height + stem_height;
#if ENABLE_LEGACY_OPENGL_REMOVAL
// top face vertices
data.add_vertex(Vec3f(half_stem_width, 0.0f, half_thickness), (Vec3f)Vec3f::UnitZ());
data.add_vertex(Vec3f(half_stem_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ());
@ -2038,88 +1459,6 @@ GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_w
data.add_triangle(14 + ii, 15 + ii, 17 + ii);
data.add_triangle(14 + ii, 17 + ii, 16 + ii);
}
#else
// top face vertices
append_vertex(entity, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ());
append_vertex(entity, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ());
append_vertex(entity, { half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ());
append_vertex(entity, { 0.0, total_height, half_thickness }, Vec3f::UnitZ());
append_vertex(entity, { -half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ());
append_vertex(entity, { -half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ());
append_vertex(entity, { -half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ());
// top face triangles
append_indices(entity, 0, 1, 6);
append_indices(entity, 6, 1, 5);
append_indices(entity, 4, 5, 3);
append_indices(entity, 5, 1, 3);
append_indices(entity, 1, 2, 3);
// bottom face vertices
append_vertex(entity, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ());
append_vertex(entity, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
append_vertex(entity, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
append_vertex(entity, { 0.0, total_height, -half_thickness }, -Vec3f::UnitZ());
append_vertex(entity, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
append_vertex(entity, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
append_vertex(entity, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ());
// bottom face triangles
append_indices(entity, 7, 13, 8);
append_indices(entity, 13, 12, 8);
append_indices(entity, 12, 11, 10);
append_indices(entity, 8, 12, 10);
append_indices(entity, 9, 8, 10);
// side faces vertices
append_vertex(entity, { half_stem_width, 0.0, -half_thickness }, Vec3f::UnitX());
append_vertex(entity, { half_stem_width, stem_height, -half_thickness }, Vec3f::UnitX());
append_vertex(entity, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitX());
append_vertex(entity, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitX());
append_vertex(entity, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY());
Vec3f normal(tip_height, half_tip_width, 0.0f);
normal.normalize();
append_vertex(entity, { half_tip_width, stem_height, -half_thickness }, normal);
append_vertex(entity, { 0.0, total_height, -half_thickness }, normal);
append_vertex(entity, { half_tip_width, stem_height, half_thickness }, normal);
append_vertex(entity, { 0.0, total_height, half_thickness }, normal);
normal = Vec3f(-tip_height, half_tip_width, 0.0f);
normal.normalize();
append_vertex(entity, { 0.0, total_height, -half_thickness }, normal);
append_vertex(entity, { -half_tip_width, stem_height, -half_thickness }, normal);
append_vertex(entity, { 0.0, total_height, half_thickness }, normal);
append_vertex(entity, { -half_tip_width, stem_height, half_thickness }, normal);
append_vertex(entity, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { -half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitX());
append_vertex(entity, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitX());
append_vertex(entity, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitX());
append_vertex(entity, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitX());
append_vertex(entity, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY());
append_vertex(entity, { half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY());
// side face triangles
for (int i = 0; i < 7; ++i) {
const int ii = i * 4;
append_indices(entity, 14 + ii, 15 + ii, 17 + ii);
append_indices(entity, 14 + ii, 17 + ii, 16 + ii);
}
data.entities.emplace_back(entity);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return data;
}
@ -2129,18 +1468,12 @@ GLModel::Geometry diamond(unsigned int resolution)
resolution = std::max<unsigned int>(4, resolution);
GLModel::Geometry data;
#if ENABLE_LEGACY_OPENGL_REMOVAL
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
data.reserve_vertices(resolution + 2);
data.reserve_indices((2 * (resolution + 1)) * 3);
#else
GLModel::Geometry::Entity entity;
entity.type = GLModel::EPrimitiveType::Triangles;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const float step = 2.0f * float(PI) / float(resolution);
#if ENABLE_LEGACY_OPENGL_REMOVAL
// vertices
for (unsigned int i = 0; i < resolution; ++i) {
const float ii = float(i) * step;
@ -2164,48 +1497,10 @@ GLModel::Geometry diamond(unsigned int resolution)
data.add_triangle(i + 0, resolution + 1, i + 1);
}
data.add_triangle(resolution - 1, resolution + 1, 0);
#else
// positions
for (unsigned int i = 0; i < resolution; ++i) {
const float ii = float(i) * step;
entity.positions.emplace_back(0.5f * ::cos(ii), 0.5f * ::sin(ii), 0.0f);
}
entity.positions.emplace_back(0.0f, 0.0f, 0.5f);
entity.positions.emplace_back(0.0f, 0.0f, -0.5f);
// normals
for (const Vec3f& v : entity.positions) {
entity.normals.emplace_back(v.normalized());
}
// triangles
// top
for (unsigned int i = 0; i < resolution; ++i) {
entity.indices.push_back(i + 0);
entity.indices.push_back(i + 1);
entity.indices.push_back(resolution);
}
entity.indices.push_back(resolution - 1);
entity.indices.push_back(0);
entity.indices.push_back(resolution);
// bottom
for (unsigned int i = 0; i < resolution; ++i) {
entity.indices.push_back(i + 0);
entity.indices.push_back(resolution + 1);
entity.indices.push_back(i + 1);
}
entity.indices.push_back(resolution - 1);
entity.indices.push_back(resolution + 1);
entity.indices.push_back(0);
data.entities.emplace_back(entity);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return data;
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel::Geometry smooth_sphere(unsigned int resolution, float radius)
{
resolution = std::max<unsigned int>(4, resolution);
@ -2390,7 +1685,6 @@ GLModel::Geometry smooth_torus(unsigned int primary_resolution, unsigned int sec
return data;
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
} // namespace GUI
} // namespace Slic3r

View File

@ -15,37 +15,15 @@ namespace Slic3r {
class TriangleMesh;
class Polygon;
using Polygons = std::vector<Polygon>;
#if ENABLE_LEGACY_OPENGL_REMOVAL
class BuildVolume;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
namespace GUI {
class GLModel
{
public:
#if !ENABLE_LEGACY_OPENGL_REMOVAL
enum class EPrimitiveType : unsigned char
{
Triangles,
Lines,
LineStrip,
LineLoop
};
struct RenderData
{
EPrimitiveType type;
unsigned int vbo_id{ 0 };
unsigned int ibo_id{ 0 };
size_t indices_count{ 0 };
ColorRGBA color;
};
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
struct Geometry
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
enum class EPrimitiveType : unsigned char
{
Points,
@ -175,28 +153,8 @@ namespace GUI {
#if ENABLE_OPENGL_ES
static bool has_extra(const Format& format);
#endif // ENABLE_OPENGL_ES
#else
struct Entity
{
EPrimitiveType type;
std::vector<Vec3f> positions;
std::vector<Vec3f> normals;
std::vector<unsigned int> indices;
ColorRGBA color;
};
std::vector<Entity> entities;
size_t vertices_count() const;
size_t vertices_size_floats() const { return vertices_count() * 6; }
size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); }
size_t indices_count() const;
size_t indices_size_bytes() const { return indices_count() * sizeof(unsigned int); }
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
#if ENABLE_LEGACY_OPENGL_REMOVAL
struct RenderData
{
Geometry geometry;
@ -208,10 +166,8 @@ namespace GUI {
size_t vertices_count{ 0 };
size_t indices_count{ 0 };
};
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
private:
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GLMODEL_STATISTICS
struct Statistics
{
@ -245,9 +201,6 @@ namespace GUI {
// enable_render()
// to keep the data on cpu side until needed.
bool m_render_disabled{ false };
#else
std::vector<RenderData> m_render_data;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
BoundingBoxf3 m_bounding_box;
std::string m_filename;
@ -255,7 +208,6 @@ namespace GUI {
GLModel() = default;
virtual ~GLModel() { reset(); }
#if ENABLE_LEGACY_OPENGL_REMOVAL
size_t vertices_count() const { return m_render_data.vertices_count > 0 ?
m_render_data.vertices_count : m_render_data.geometry.vertices_count(); }
size_t indices_count() const { return m_render_data.indices_count > 0 ?
@ -274,42 +226,24 @@ namespace GUI {
#else
void init_from(const TriangleMesh& mesh);
#endif // ENABLE_SMOOTH_NORMALS
#else
void init_from(const Geometry& data);
void init_from(const indexed_triangle_set& its, const BoundingBoxf3& bbox);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void init_from(const indexed_triangle_set& its);
void init_from(const Polygons& polygons, float z);
bool init_from_file(const std::string& filename);
#if ENABLE_LEGACY_OPENGL_REMOVAL
void set_color(const ColorRGBA& color) { m_render_data.geometry.color = color; }
const ColorRGBA& get_color() const { return m_render_data.geometry.color; }
#else
// if entity_id == -1 set the color of all entities
void set_color(int entity_id, const ColorRGBA& color);
ColorRGBA get_color(size_t entity_id = 0U) const;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void reset();
#if ENABLE_LEGACY_OPENGL_REMOVAL
void render();
void render(const std::pair<size_t, size_t>& range);
void render_instanced(unsigned int instances_vbo, unsigned int instances_count);
bool is_initialized() const { return vertices_count() > 0 && indices_count() > 0; }
bool is_empty() const { return m_render_data.geometry.is_empty(); }
#else
void render() const;
void render_instanced(unsigned int instances_vbo, unsigned int instances_count) const;
bool is_initialized() const { return !m_render_data.empty(); }
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; }
const std::string& get_filename() const { return m_filename; }
#if ENABLE_LEGACY_OPENGL_REMOVAL
bool is_render_disabled() const { return m_render_disabled; }
void enable_render() { m_render_disabled = false; }
void disable_render() { m_render_disabled = true; }
@ -338,19 +272,12 @@ namespace GUI {
s_statistics.render_instanced_calls = 0;
}
#endif // ENABLE_GLMODEL_STATISTICS
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
private:
#if ENABLE_LEGACY_OPENGL_REMOVAL
bool send_to_gpu();
#else
void send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
#if ENABLE_LEGACY_OPENGL_REMOVAL
bool contains(const BuildVolume& volume, const GLModel& model, bool ignore_bottom = true);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution
// the origin of the arrow is in the center of the stem cap
@ -375,7 +302,6 @@ namespace GUI {
// the diamond is contained into a box with size [1, 1, 1]
GLModel::Geometry diamond(unsigned int resolution);
#if ENABLE_LEGACY_OPENGL_REMOVAL
// create a sphere with smooth normals
// the origin of the sphere is in its center
GLModel::Geometry smooth_sphere(unsigned int resolution, float radius);
@ -387,7 +313,6 @@ namespace GUI {
// the axis of the torus is the Z axis
// the origin of the torus is in its center
GLModel::Geometry smooth_torus(unsigned int primary_resolution, unsigned int secondary_resolution, float radius, float thickness);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
} // namespace GUI
} // namespace Slic3r

View File

@ -30,21 +30,10 @@ namespace GUI {
m_end_corner = mouse_position;
}
#if ENABLE_RAYCAST_PICKING
std::vector<unsigned int> GLSelectionRectangle::contains(const std::vector<Vec3d>& points) const
#else
std::vector<unsigned int> GLSelectionRectangle::stop_dragging(const GLCanvas3D& canvas, const std::vector<Vec3d>& points)
#endif // ENABLE_RAYCAST_PICKING
{
std::vector<unsigned int> out;
#if !ENABLE_RAYCAST_PICKING
if (!is_dragging())
return out;
m_state = EState::Off;
#endif // !ENABLE_RAYCAST_PICKING
// bounding box created from the rectangle corners - will take care of order of the corners
const BoundingBox rectangle(Points{ Point(m_start_corner.cast<coord_t>()), Point(m_end_corner.cast<coord_t>()) });
@ -71,7 +60,6 @@ namespace GUI {
return;
const Size cnv_size = canvas.get_canvas_size();
#if ENABLE_LEGACY_OPENGL_REMOVAL
const float cnv_width = (float)cnv_size.get_width();
const float cnv_height = (float)cnv_size.get_height();
if (cnv_width == 0.0f || cnv_height == 0.0f)
@ -83,49 +71,15 @@ namespace GUI {
const float right = 2.0f * (get_right() * cnv_inv_width - 0.5f);
const float top = -2.0f * (get_top() * cnv_inv_height - 0.5f);
const float bottom = -2.0f * (get_bottom() * cnv_inv_height - 0.5f);
#else
const Camera& camera = wxGetApp().plater()->get_camera();
const float inv_zoom = (float)camera.get_inv_zoom();
const float cnv_half_width = 0.5f * (float)cnv_size.get_width();
const float cnv_half_height = 0.5f * (float)cnv_size.get_height();
if (cnv_half_width == 0.0f || cnv_half_height == 0.0f)
return;
const Vec2d start(m_start_corner.x() - cnv_half_width, cnv_half_height - m_start_corner.y());
const Vec2d end(m_end_corner.x() - cnv_half_width, cnv_half_height - m_end_corner.y());
const float left = (float)std::min(start.x(), end.x()) * inv_zoom;
const float top = (float)std::max(start.y(), end.y()) * inv_zoom;
const float right = (float)std::max(start.x(), end.x()) * inv_zoom;
const float bottom = (float)std::min(start.y(), end.y()) * inv_zoom;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_CORE_PROFILE
const bool core_profile = OpenGLManager::get_gl_info().is_core_profile();
if (!core_profile)
#endif // ENABLE_GL_CORE_PROFILE
glsafe(::glLineWidth(1.5f));
#if !ENABLE_LEGACY_OPENGL_REMOVAL
float color[3];
color[0] = (m_state == EState::Select) ? 0.3f : 1.0f;
color[1] = (m_state == EState::Select) ? 1.0f : 0.3f;
color[2] = 0.3f;
glsafe(::glColor3fv(color));
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glDisable(GL_DEPTH_TEST));
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPushMatrix());
glsafe(::glLoadIdentity());
// ensure that the rectangle is renderered inside the frustrum
glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.5)));
// ensure that the overlay fits the frustrum near z plane
const double gui_scale = camera.get_gui_scale();
glsafe(::glScaled(gui_scale, gui_scale, 1.0));
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#if !ENABLE_OPENGL_ES
#if ENABLE_GL_CORE_PROFILE
if (!core_profile) {
@ -138,7 +92,6 @@ namespace GUI {
#endif // ENABLE_GL_CORE_PROFILE
#endif // !ENABLE_OPENGL_ES
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_OPENGL_ES
GLShaderProgram* shader = wxGetApp().get_shader("dashed_lines");
#elif ENABLE_GL_CORE_PROFILE
@ -221,14 +174,6 @@ namespace GUI {
m_rectangle.render();
shader->stop_using();
}
#else
::glBegin(GL_LINE_LOOP);
::glVertex2f((GLfloat)left, (GLfloat)bottom);
::glVertex2f((GLfloat)right, (GLfloat)bottom);
::glVertex2f((GLfloat)right, (GLfloat)top);
::glVertex2f((GLfloat)left, (GLfloat)top);
glsafe(::glEnd());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if !ENABLE_OPENGL_ES
#if ENABLE_GL_CORE_PROFILE
@ -236,10 +181,6 @@ namespace GUI {
#endif // ENABLE_GL_CORE_PROFILE
glsafe(::glPopAttrib());
#endif // !ENABLE_OPENGL_ES
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
} // namespace GUI

View File

@ -2,9 +2,7 @@
#define slic3r_GLSelectionRectangle_hpp_
#include "libslic3r/Point.hpp"
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "GLModel.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
namespace Slic3r {
namespace GUI {
@ -26,15 +24,9 @@ public:
// To be called on mouse move.
void dragging(const Vec2d& mouse_position);
#if ENABLE_RAYCAST_PICKING
// Given a vector of points in world coordinates, the function returns indices of those
// that are in the rectangle.
std::vector<unsigned int> contains(const std::vector<Vec3d>& points) const;
#else
// Given a vector of points in world coordinates, the function returns indices of those
// that are in the rectangle. It then disables the rectangle.
std::vector<unsigned int> stop_dragging(const GLCanvas3D& canvas, const std::vector<Vec3d>& points);
#endif // ENABLE_RAYCAST_PICKING
// Disables the rectangle.
void stop_dragging();
@ -57,11 +49,9 @@ private:
EState m_state{ EState::Off };
Vec2d m_start_corner{ Vec2d::Zero() };
Vec2d m_end_corner{ Vec2d::Zero() };
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_rectangle;
Vec2d m_old_start_corner{ Vec2d::Zero() };
Vec2d m_old_end_corner{ Vec2d::Zero() };
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};

View File

@ -36,7 +36,6 @@ std::pair<bool, std::string> GLShadersManager::init()
bool valid = true;
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_OPENGL_ES
const std::string prefix = "ES/";
// used to render wireframed triangles
@ -62,73 +61,36 @@ std::pair<bool, std::string> GLShadersManager::init()
// used to render thick and/or dashed lines
valid &= append_shader("dashed_thick_lines", { prefix + "dashed_thick_lines.vs", prefix + "dashed_thick_lines.fs", prefix + "dashed_thick_lines.gs" });
#endif // ENABLE_OPENGL_ES
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// used to render toolpaths center of gravity
#if ENABLE_LEGACY_OPENGL_REMOVAL
valid &= append_shader("toolpaths_cog", { prefix + "toolpaths_cog.vs", prefix + "toolpaths_cog.fs" });
#else
valid &= append_shader("toolpaths_cog", { "toolpaths_cog.vs", "toolpaths_cog.fs" });
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview
valid &= append_shader("gouraud_light", { prefix + "gouraud_light.vs", prefix + "gouraud_light.fs" });
// used to render printbed
valid &= append_shader("printbed", { prefix + "printbed.vs", prefix + "printbed.fs" });
#else
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview
valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" });
// used to render printbed
valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" });
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// used to render options in gcode preview
if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
valid &= append_shader("gouraud_light_instanced", { prefix + "gouraud_light_instanced.vs", prefix + "gouraud_light_instanced.fs" });
#else
valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" });
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
// used to render objects in 3d editor
valid &= append_shader("gouraud", { prefix + "gouraud.vs", prefix + "gouraud.fs" }
#else
// used to render extrusion and travel paths as lines in gcode preview
valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" });
// used to render objects in 3d editor
valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_ENVIRONMENT_MAP
, { "ENABLE_ENVIRONMENT_MAP"sv }
#endif // ENABLE_ENVIRONMENT_MAP
);
#if ENABLE_LEGACY_OPENGL_REMOVAL
// used to render variable layers heights in 3d editor
valid &= append_shader("variable_layer_height", { prefix + "variable_layer_height.vs", prefix + "variable_layer_height.fs" });
// used to render highlight contour around selected triangles inside the multi-material gizmo
valid &= append_shader("mm_contour", { prefix + "mm_contour.vs", prefix + "mm_contour.fs" });
#else
// used to render variable layers heights in 3d editor
valid &= append_shader("variable_layer_height", { "variable_layer_height.vs", "variable_layer_height.fs" });
// used to render highlight contour around selected triangles inside the multi-material gizmo
valid &= append_shader("mm_contour", { "mm_contour.vs", "mm_contour.fs" });
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Used to render painted triangles inside the multi-material gizmo. Triangle normals are computed inside fragment shader.
// For Apple's on Arm CPU computed triangle normals inside fragment shader using dFdx and dFdy has the opposite direction.
// Because of this, objects had darker colors inside the multi-material gizmo.
// Based on https://stackoverflow.com/a/66206648, the similar behavior was also spotted on some other devices with Arm CPU.
// Since macOS 12 (Monterey), this issue with the opposite direction on Apple's Arm CPU seems to be fixed, and computed
// triangle normals inside fragment shader have the right direction.
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12)
valid &= append_shader("mm_gouraud", { prefix + "mm_gouraud.vs", prefix + "mm_gouraud.fs" }, { "FLIP_TRIANGLE_NORMALS"sv });
else
valid &= append_shader("mm_gouraud", { prefix + "mm_gouraud.vs", prefix + "mm_gouraud.fs" });
#else
if (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12)
valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}, {"FLIP_TRIANGLE_NORMALS"sv});
else
valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"});
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return { valid, error };
}

View File

@ -3,10 +3,8 @@
#include "3DScene.hpp"
#include "OpenGLManager.hpp"
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "GUI_App.hpp"
#include "GLModel.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include "BitmapCache.hpp"
#include <GL/glew.h>
@ -342,7 +340,6 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right,
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id));
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel::Geometry init_data;
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2 };
init_data.reserve_vertices(4);
@ -364,21 +361,11 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right,
GLShaderProgram* shader = wxGetApp().get_shader("flat_texture");
if (shader != nullptr) {
shader->start_using();
#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->set_uniform("view_model_matrix", Transform3d::Identity());
shader->set_uniform("projection_matrix", Transform3d::Identity());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
model.render();
shader->stop_using();
}
#else
::glBegin(GL_QUADS);
::glTexCoord2f(uvs.left_bottom.u, uvs.left_bottom.v); ::glVertex2f(left, bottom);
::glTexCoord2f(uvs.right_bottom.u, uvs.right_bottom.v); ::glVertex2f(right, bottom);
::glTexCoord2f(uvs.right_top.u, uvs.right_top.v); ::glVertex2f(right, top);
::glTexCoord2f(uvs.left_top.u, uvs.left_top.v); ::glVertex2f(left, top);
glsafe(::glEnd());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));

View File

@ -85,11 +85,7 @@ bool GLToolbarItem::update_enabled_state()
return ret;
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLToolbarItem::render(const GLCanvas3D& parent, unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const
#else
void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
auto uvs = [this](unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) -> GLTexture::Quad_UVs {
assert(tex_width != 0 && tex_height != 0);
@ -118,7 +114,6 @@ void GLToolbarItem::render(unsigned int tex_id, float left, float right, float b
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, uvs(tex_width, tex_height, icon_size));
if (is_pressed()) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Size cnv_size = parent.get_canvas_size();
const float cnv_w = (float)cnv_size.get_width();
const float cnv_h = (float)cnv_size.get_height();
@ -131,12 +126,6 @@ void GLToolbarItem::render(unsigned int tex_id, float left, float right, float b
m_data.left.render_callback(out_left, out_right, out_bottom, out_top);
else if (m_last_action_type == Right && m_data.right.can_render())
m_data.right.render_callback(out_left, out_right, out_bottom, out_top);
#else
if (m_last_action_type == Left && m_data.left.can_render())
m_data.left.render_callback(left, right, bottom, top);
else if (m_last_action_type == Right && m_data.right.can_render())
m_data.right.render_callback(left, right, bottom, top);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
@ -202,7 +191,6 @@ bool GLToolbar::init(const BackgroundTexture::Metadata& background_texture)
return res;
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
bool GLToolbar::init_arrow(const std::string& filename)
{
if (m_arrow_texture.get_id() != 0)
@ -211,24 +199,6 @@ bool GLToolbar::init_arrow(const std::string& filename)
const std::string path = resources_dir() + "/icons/";
return (!filename.empty()) ? m_arrow_texture.load_from_svg_file(path + filename, false, false, false, 512) : false;
}
#else
bool GLToolbar::init_arrow(const BackgroundTexture::Metadata& arrow_texture)
{
if (m_arrow_texture.texture.get_id() != 0)
return true;
std::string path = resources_dir() + "/icons/";
bool res = false;
if (!arrow_texture.filename.empty())
res = m_arrow_texture.texture.load_from_svg_file(path + arrow_texture.filename, false, false, false, 1000);
if (res)
m_arrow_texture.metadata = arrow_texture;
return res;
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
GLToolbar::Layout::EType GLToolbar::get_layout_type() const
{
@ -693,7 +663,6 @@ void GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent)
}
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent)
{
const Size cnv_size = parent.get_canvas_size();
@ -891,224 +860,6 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D&
}
}
}
#else
void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent)
{
// NB: mouse_pos is already scaled appropriately
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
float factor = m_layout.scale * inv_zoom;
Size cnv_size = parent.get_canvas_size();
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
float scaled_icons_size = m_layout.icons_size * factor;
float scaled_separator_size = m_layout.separator_size * factor;
float scaled_gap_size = m_layout.gap_size * factor;
float scaled_border = m_layout.border * factor;
float separator_stride = scaled_separator_size + scaled_gap_size;
float icon_stride = scaled_icons_size + scaled_gap_size;
float left = m_layout.left + scaled_border;
float top = m_layout.top - scaled_border;
for (GLToolbarItem* item : m_items)
{
if (!item->is_visible())
continue;
if (item->is_separator())
left += separator_stride;
else
{
float right = left + scaled_icons_size;
float bottom = top - scaled_icons_size;
GLToolbarItem::EState state = item->get_state();
bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top);
switch (state)
{
case GLToolbarItem::Normal:
{
if (inside)
{
item->set_state(GLToolbarItem::Hover);
parent.set_as_dirty();
}
break;
}
case GLToolbarItem::Hover:
{
if (!inside)
{
item->set_state(GLToolbarItem::Normal);
parent.set_as_dirty();
}
break;
}
case GLToolbarItem::Pressed:
{
if (inside)
{
item->set_state(GLToolbarItem::HoverPressed);
parent.set_as_dirty();
}
break;
}
case GLToolbarItem::HoverPressed:
{
if (!inside)
{
item->set_state(GLToolbarItem::Pressed);
parent.set_as_dirty();
}
break;
}
case GLToolbarItem::Disabled:
{
if (inside)
{
item->set_state(GLToolbarItem::HoverDisabled);
parent.set_as_dirty();
}
break;
}
case GLToolbarItem::HoverDisabled:
{
if (!inside)
{
item->set_state(GLToolbarItem::Disabled);
parent.set_as_dirty();
}
break;
}
default:
{
break;
}
}
left += icon_stride;
}
}
}
void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent)
{
// NB: mouse_pos is already scaled appropriately
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
float factor = m_layout.scale * inv_zoom;
Size cnv_size = parent.get_canvas_size();
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
float scaled_icons_size = m_layout.icons_size * factor;
float scaled_separator_size = m_layout.separator_size * factor;
float scaled_gap_size = m_layout.gap_size * factor;
float scaled_border = m_layout.border * factor;
float separator_stride = scaled_separator_size + scaled_gap_size;
float icon_stride = scaled_icons_size + scaled_gap_size;
float left = m_layout.left + scaled_border;
float top = m_layout.top - scaled_border;
for (GLToolbarItem* item : m_items)
{
if (!item->is_visible())
continue;
if (item->is_separator())
top -= separator_stride;
else
{
float right = left + scaled_icons_size;
float bottom = top - scaled_icons_size;
GLToolbarItem::EState state = item->get_state();
bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top);
switch (state)
{
case GLToolbarItem::Normal:
{
if (inside)
{
item->set_state(GLToolbarItem::Hover);
parent.set_as_dirty();
}
break;
}
case GLToolbarItem::Hover:
{
if (!inside)
{
item->set_state(GLToolbarItem::Normal);
parent.set_as_dirty();
}
break;
}
case GLToolbarItem::Pressed:
{
if (inside)
{
item->set_state(GLToolbarItem::HoverPressed);
parent.set_as_dirty();
}
break;
}
case GLToolbarItem::HoverPressed:
{
if (!inside)
{
item->set_state(GLToolbarItem::Pressed);
parent.set_as_dirty();
}
break;
}
case GLToolbarItem::Disabled:
{
if (inside)
{
item->set_state(GLToolbarItem::HoverDisabled);
parent.set_as_dirty();
}
break;
}
case GLToolbarItem::HoverDisabled:
{
if (!inside)
{
item->set_state(GLToolbarItem::Disabled);
parent.set_as_dirty();
}
break;
}
default:
{
break;
}
}
top -= icon_stride;
}
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
GLToolbarItem* GLToolbar::get_item(const std::string& item_name)
{
@ -1135,7 +886,6 @@ int GLToolbar::contains_mouse(const Vec2d& mouse_pos, const GLCanvas3D& parent)
}
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
{
const Size cnv_size = parent.get_canvas_size();
@ -1283,154 +1033,7 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D&
return -1;
}
#else
int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
{
// NB: mouse_pos is already scaled appropriately
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
float factor = m_layout.scale * inv_zoom;
Size cnv_size = parent.get_canvas_size();
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
float scaled_icons_size = m_layout.icons_size * factor;
float scaled_separator_size = m_layout.separator_size * factor;
float scaled_gap_size = m_layout.gap_size * factor;
float scaled_border = m_layout.border * factor;
float left = m_layout.left + scaled_border;
float top = m_layout.top - scaled_border;
for (size_t id=0; id<m_items.size(); ++id)
{
GLToolbarItem* item = m_items[id];
if (!item->is_visible())
continue;
if (item->is_separator())
{
float right = left + scaled_separator_size;
float bottom = top - scaled_icons_size;
// mouse inside the separator
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
return id;
left = right;
right += scaled_gap_size;
if (id < m_items.size() - 1)
{
// mouse inside the gap
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
return -2;
}
left = right;
}
else
{
float right = left + scaled_icons_size;
float bottom = top - scaled_icons_size;
// mouse inside the icon
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
return id;
left = right;
right += scaled_gap_size;
if (id < m_items.size() - 1)
{
// mouse inside the gap
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
return -2;
}
left = right;
}
}
return -1;
}
int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
{
// NB: mouse_pos is already scaled appropriately
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
float factor = m_layout.scale * inv_zoom;
Size cnv_size = parent.get_canvas_size();
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
float scaled_icons_size = m_layout.icons_size * factor;
float scaled_separator_size = m_layout.separator_size * factor;
float scaled_gap_size = m_layout.gap_size * factor;
float scaled_border = m_layout.border * factor;
float left = m_layout.left + scaled_border;
float top = m_layout.top - scaled_border;
for (size_t id=0; id<m_items.size(); ++id)
{
GLToolbarItem* item = m_items[id];
if (!item->is_visible())
continue;
if (item->is_separator())
{
float right = left + scaled_icons_size;
float bottom = top - scaled_separator_size;
// mouse inside the separator
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
return id;
top = bottom;
bottom -= scaled_gap_size;
if (id < m_items.size() - 1)
{
// mouse inside the gap
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
return -2;
}
top = bottom;
}
else
{
float right = left + scaled_icons_size;
float bottom = top - scaled_icons_size;
// mouse inside the icon
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
return id;
top = bottom;
bottom -= scaled_gap_size;
if (id < m_items.size() - 1)
{
// mouse inside the gap
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
return -2;
}
top = bottom;
}
}
return -1;
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLToolbar::render_background(float left, float top, float right, float bottom, float border_w, float border_h) const
{
const unsigned int tex_id = m_background_texture.texture.get_id();
@ -1507,86 +1110,7 @@ void GLToolbar::render_background(float left, float top, float right, float bott
GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } });
}
}
#else
void GLToolbar::render_background(float left, float top, float right, float bottom, float border) const
{
unsigned int tex_id = m_background_texture.texture.get_id();
float tex_width = (float)m_background_texture.texture.get_width();
float tex_height = (float)m_background_texture.texture.get_height();
if (tex_id != 0 && tex_width > 0 && tex_height > 0) {
float inv_tex_width = (tex_width != 0.0f) ? 1.0f / tex_width : 0.0f;
float inv_tex_height = (tex_height != 0.0f) ? 1.0f / tex_height : 0.0f;
float internal_left = left + border;
float internal_right = right - border;
float internal_top = top - border;
float internal_bottom = bottom + border;
float left_uv = 0.0f;
float right_uv = 1.0f;
float top_uv = 1.0f;
float bottom_uv = 0.0f;
float internal_left_uv = (float)m_background_texture.metadata.left * inv_tex_width;
float internal_right_uv = 1.0f - (float)m_background_texture.metadata.right * inv_tex_width;
float internal_top_uv = 1.0f - (float)m_background_texture.metadata.top * inv_tex_height;
float internal_bottom_uv = (float)m_background_texture.metadata.bottom * inv_tex_height;
// top-left corner
if ((m_layout.horizontal_orientation == Layout::HO_Left) || (m_layout.vertical_orientation == Layout::VO_Top))
GLTexture::render_sub_texture(tex_id, left, internal_left, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
else
GLTexture::render_sub_texture(tex_id, left, internal_left, internal_top, top, { { left_uv, internal_top_uv }, { internal_left_uv, internal_top_uv }, { internal_left_uv, top_uv }, { left_uv, top_uv } });
// top edge
if (m_layout.vertical_orientation == Layout::VO_Top)
GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
else
GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_top, top, { { internal_left_uv, internal_top_uv }, { internal_right_uv, internal_top_uv }, { internal_right_uv, top_uv }, { internal_left_uv, top_uv } });
// top-right corner
if ((m_layout.horizontal_orientation == Layout::HO_Right) || (m_layout.vertical_orientation == Layout::VO_Top))
GLTexture::render_sub_texture(tex_id, internal_right, right, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
else
GLTexture::render_sub_texture(tex_id, internal_right, right, internal_top, top, { { internal_right_uv, internal_top_uv }, { right_uv, internal_top_uv }, { right_uv, top_uv }, { internal_right_uv, top_uv } });
// center-left edge
if (m_layout.horizontal_orientation == Layout::HO_Left)
GLTexture::render_sub_texture(tex_id, left, internal_left, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
else
GLTexture::render_sub_texture(tex_id, left, internal_left, internal_bottom, internal_top, { { left_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv }, { internal_left_uv, internal_top_uv }, { left_uv, internal_top_uv } });
// center
GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
// center-right edge
if (m_layout.horizontal_orientation == Layout::HO_Right)
GLTexture::render_sub_texture(tex_id, internal_right, right, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
else
GLTexture::render_sub_texture(tex_id, internal_right, right, internal_bottom, internal_top, { { internal_right_uv, internal_bottom_uv }, { right_uv, internal_bottom_uv }, { right_uv, internal_top_uv }, { internal_right_uv, internal_top_uv } });
// bottom-left corner
if ((m_layout.horizontal_orientation == Layout::HO_Left) || (m_layout.vertical_orientation == Layout::VO_Bottom))
GLTexture::render_sub_texture(tex_id, left, internal_left, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
else
GLTexture::render_sub_texture(tex_id, left, internal_left, bottom, internal_bottom, { { left_uv, bottom_uv }, { internal_left_uv, bottom_uv }, { internal_left_uv, internal_bottom_uv }, { left_uv, internal_bottom_uv } });
// bottom edge
if (m_layout.vertical_orientation == Layout::VO_Bottom)
GLTexture::render_sub_texture(tex_id, internal_left, internal_right, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
else
GLTexture::render_sub_texture(tex_id, internal_left, internal_right, bottom, internal_bottom, { { internal_left_uv, bottom_uv }, { internal_right_uv, bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv } });
// bottom-right corner
if ((m_layout.horizontal_orientation == Layout::HO_Right) || (m_layout.vertical_orientation == Layout::VO_Bottom))
GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
else
GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } });
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighted_item)
{
// arrow texture not initialized
@ -1655,75 +1179,7 @@ void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighte
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, { { left_uv, top_uv }, { right_uv, top_uv }, { right_uv, bottom_uv }, { left_uv, bottom_uv } });
}
}
#else
void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighted_item)
{
// arrow texture not initialized
if (m_arrow_texture.texture.get_id() == 0)
return;
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
float factor = inv_zoom * m_layout.scale;
float scaled_icons_size = m_layout.icons_size * factor;
float scaled_separator_size = m_layout.separator_size * factor;
float scaled_gap_size = m_layout.gap_size * factor;
float border = m_layout.border * factor;
float separator_stride = scaled_separator_size + scaled_gap_size;
float icon_stride = scaled_icons_size + scaled_gap_size;
float left = m_layout.left;
float top = m_layout.top - icon_stride;
bool found = false;
for (const GLToolbarItem* item : m_items) {
if (!item->is_visible())
continue;
if (item->is_separator())
left += separator_stride;
else {
if (item->get_name() == highlighted_item->get_name()) {
found = true;
break;
}
left += icon_stride;
}
}
if (!found)
return;
left += border;
top -= separator_stride;
float right = left + scaled_icons_size;
unsigned int tex_id = m_arrow_texture.texture.get_id();
// arrow width and height
float arr_tex_width = (float)m_arrow_texture.texture.get_width();
float arr_tex_height = (float)m_arrow_texture.texture.get_height();
if ((tex_id != 0) && (arr_tex_width > 0) && (arr_tex_height > 0)) {
float inv_tex_width = (arr_tex_width != 0.0f) ? 1.0f / arr_tex_width : 0.0f;
float inv_tex_height = (arr_tex_height != 0.0f) ? 1.0f / arr_tex_height : 0.0f;
float internal_left = left + border - scaled_icons_size * 1.5f; // add scaled_icons_size for huge arrow
float internal_right = right - border + scaled_icons_size * 1.5f;
float internal_top = top - border;
// bottom is not moving and should be calculated from arrow texture sides ratio
float arrow_sides_ratio = (float)m_arrow_texture.texture.get_height() / (float)m_arrow_texture.texture.get_width();
float internal_bottom = internal_top - (internal_right - internal_left) * arrow_sides_ratio ;
float internal_left_uv = (float)m_arrow_texture.metadata.left * inv_tex_width;
float internal_right_uv = 1.0f - (float)m_arrow_texture.metadata.right * inv_tex_width;
float internal_top_uv = 1.0f - (float)m_arrow_texture.metadata.top * inv_tex_height;
float internal_bottom_uv = (float)m_arrow_texture.metadata.bottom * inv_tex_height;
GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_bottom, internal_top, { { internal_left_uv, internal_top_uv }, { internal_right_uv, internal_top_uv }, { internal_right_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv } });
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLToolbar::render_horizontal(const GLCanvas3D& parent)
{
const Size cnv_size = parent.get_canvas_size();
@ -1833,101 +1289,6 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent)
}
}
}
#else
void GLToolbar::render_horizontal(const GLCanvas3D& parent)
{
unsigned int tex_id = m_icons_texture.get_id();
int tex_width = m_icons_texture.get_width();
int tex_height = m_icons_texture.get_height();
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
float factor = inv_zoom * m_layout.scale;
float scaled_icons_size = m_layout.icons_size * factor;
float scaled_separator_size = m_layout.separator_size * factor;
float scaled_gap_size = m_layout.gap_size * factor;
float scaled_border = m_layout.border * factor;
float scaled_width = get_width() * inv_zoom;
float scaled_height = get_height() * inv_zoom;
float separator_stride = scaled_separator_size + scaled_gap_size;
float icon_stride = scaled_icons_size + scaled_gap_size;
float left = m_layout.left;
float top = m_layout.top;
float right = left + scaled_width;
float bottom = top - scaled_height;
render_background(left, top, right, bottom, scaled_border);
left += scaled_border;
top -= scaled_border;
if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0))
return;
// renders icons
for (const GLToolbarItem* item : m_items)
{
if (!item->is_visible())
continue;
if (item->is_separator())
left += separator_stride;
else
{
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale));
left += icon_stride;
}
}
}
void GLToolbar::render_vertical(const GLCanvas3D& parent)
{
unsigned int tex_id = m_icons_texture.get_id();
int tex_width = m_icons_texture.get_width();
int tex_height = m_icons_texture.get_height();
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
float factor = inv_zoom * m_layout.scale;
float scaled_icons_size = m_layout.icons_size * factor;
float scaled_separator_size = m_layout.separator_size * factor;
float scaled_gap_size = m_layout.gap_size * factor;
float scaled_border = m_layout.border * factor;
float scaled_width = get_width() * inv_zoom;
float scaled_height = get_height() * inv_zoom;
float separator_stride = scaled_separator_size + scaled_gap_size;
float icon_stride = scaled_icons_size + scaled_gap_size;
float left = m_layout.left;
float top = m_layout.top;
float right = left + scaled_width;
float bottom = top - scaled_height;
render_background(left, top, right, bottom, scaled_border);
left += scaled_border;
top -= scaled_border;
if (tex_id == 0 || tex_width <= 0 || tex_height <= 0)
return;
// renders icons
for (const GLToolbarItem* item : m_items) {
if (!item->is_visible())
continue;
if (item->is_separator())
top -= separator_stride;
else {
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale));
top -= icon_stride;
}
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
bool GLToolbar::generate_icons_texture()
{

View File

@ -153,11 +153,7 @@ public:
// returns true if the state changes
bool update_enabled_state();
#if ENABLE_LEGACY_OPENGL_REMOVAL
void render(const GLCanvas3D& parent, unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const;
#else
void render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
private:
void set_visible(bool visible) { m_data.visible = visible; }
@ -251,11 +247,7 @@ private:
GLTexture m_icons_texture;
bool m_icons_texture_dirty;
BackgroundTexture m_background_texture;
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLTexture m_arrow_texture;
#else
BackgroundTexture m_arrow_texture;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
Layout m_layout;
ItemsList m_items;
@ -282,11 +274,7 @@ public:
bool init(const BackgroundTexture::Metadata& background_texture);
#if ENABLE_LEGACY_OPENGL_REMOVAL
bool init_arrow(const std::string& filename);
#else
bool init_arrow(const BackgroundTexture::Metadata& arrow_texture);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
Layout::EType get_layout_type() const;
void set_layout_type(Layout::EType type);
@ -357,11 +345,7 @@ private:
int contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const;
int contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const;
#if ENABLE_LEGACY_OPENGL_REMOVAL
void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const;
#else
void render_background(float left, float top, float right, float bottom, float border) const;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void render_horizontal(const GLCanvas3D& parent);
void render_vertical(const GLCanvas3D& parent);

View File

@ -692,7 +692,6 @@ void Preview::update_moves_slider()
if (view.endpoints.last < view.endpoints.first)
return;
#if ENABLE_PROCESS_G2_G3_LINES
assert(view.endpoints.first <= view.current.first && view.current.first <= view.endpoints.last);
assert(view.endpoints.first <= view.current.last && view.current.last <= view.endpoints.last);
@ -721,22 +720,6 @@ void Preview::update_moves_slider()
m_moves_slider->SetSliderAlternateValues(alternate_values);
m_moves_slider->SetMaxValue(int(values.size()) - 1);
m_moves_slider->SetSelectionSpan(values.front() - 1 - view.endpoints.first, values.back() - 1 - view.endpoints.first);
#else
std::vector<double> values(view.endpoints.last - view.endpoints.first + 1);
std::vector<double> alternate_values(view.endpoints.last - view.endpoints.first + 1);
unsigned int count = 0;
for (unsigned int i = view.endpoints.first; i <= view.endpoints.last; ++i) {
values[count] = static_cast<double>(i + 1);
if (view.gcode_ids[i] > 0)
alternate_values[count] = static_cast<double>(view.gcode_ids[i]);
++count;
}
m_moves_slider->SetSliderValues(values);
m_moves_slider->SetSliderAlternateValues(alternate_values);
m_moves_slider->SetMaxValue(view.endpoints.last - view.endpoints.first);
m_moves_slider->SetSelectionSpan(view.current.first - view.endpoints.first, view.current.last - view.endpoints.first);
#endif // ENABLE_PROCESS_G2_G3_LINES
}
void Preview::enable_moves_slider(bool enable)

View File

@ -289,12 +289,7 @@ static void generate_thumbnail_from_model(const std::string& filename)
GLVolumeCollection volumes;
volumes.volumes.push_back(new GLVolume());
GLVolume* volume = volumes.volumes.back();
#if ENABLE_LEGACY_OPENGL_REMOVAL
volume->model.init_from(model.mesh());
#else
volume->indexed_vertex_array.load_mesh(model.mesh());
volume->indexed_vertex_array.finalize_geometry(true);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
volume->set_instance_transformation(model.objects[0]->instances[0]->get_transformation());
volume->set_volume_transformation(model.objects[0]->volumes[0]->get_transformation());

View File

@ -5,9 +5,7 @@
#include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "slic3r/GUI/Plater.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// TODO: Display tooltips quicker on Linux
@ -18,29 +16,16 @@ const float GLGizmoBase::Grabber::SizeFactor = 0.05f;
const float GLGizmoBase::Grabber::MinHalfSize = 1.5f;
const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f;
#if ENABLE_RAYCAST_PICKING
PickingModel GLGizmoBase::Grabber::s_cube;
PickingModel GLGizmoBase::Grabber::s_cone;
#else
GLModel GLGizmoBase::Grabber::s_cube;
GLModel GLGizmoBase::Grabber::s_cone;
#endif // ENABLE_RAYCAST_PICKING
GLGizmoBase::Grabber::~Grabber()
{
#if ENABLE_RAYCAST_PICKING
if (s_cube.model.is_initialized())
s_cube.model.reset();
if (s_cone.model.is_initialized())
s_cone.model.reset();
#else
if (s_cube.is_initialized())
s_cube.reset();
if (s_cone.is_initialized())
s_cone.reset();
#endif // ENABLE_RAYCAST_PICKING
}
float GLGizmoBase::Grabber::get_half_size(float size) const
@ -53,7 +38,6 @@ float GLGizmoBase::Grabber::get_dragging_half_size(float size) const
return get_half_size(size) * DraggingScaleFactor;
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoBase::Grabber::register_raycasters_for_picking(int id)
{
picking_id = id;
@ -66,95 +50,44 @@ void GLGizmoBase::Grabber::unregister_raycasters_for_picking()
picking_id = -1;
raycasters = { nullptr };
}
#endif // ENABLE_RAYCAST_PICKING
#if ENABLE_RAYCAST_PICKING
void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color)
#else
void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, bool picking)
#endif // ENABLE_RAYCAST_PICKING
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLShaderProgram* shader = wxGetApp().get_current_shader();
if (shader == nullptr)
return;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
if (!s_cube.model.is_initialized()) {
#else
if (!s_cube.is_initialized()) {
#endif // ENABLE_RAYCAST_PICKING
// This cannot be done in constructor, OpenGL is not yet
// initialized at that point (on Linux at least).
indexed_triangle_set its = its_make_cube(1.0, 1.0, 1.0);
its_translate(its, -0.5f * Vec3f::Ones());
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
s_cube.model.init_from(its);
s_cube.mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
#else
s_cube.init_from(its);
#endif // ENABLE_RAYCAST_PICKING
#else
s_cube.init_from(its, BoundingBoxf3{ { -0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 } });
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_RAYCAST_PICKING
if (!s_cone.model.is_initialized()) {
indexed_triangle_set its = its_make_cone(0.375, 1.5, double(PI) / 18.0);
s_cone.model.init_from(its);
s_cone.mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
}
#else
if (!s_cone.is_initialized())
s_cone.init_from(its_make_cone(0.375, 1.5, double(PI) / 18.0));
#endif // ENABLE_RAYCAST_PICKING
const float half_size = dragging ? get_dragging_half_size(size) : get_half_size(size);
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
s_cube.model.set_color(render_color);
s_cone.model.set_color(render_color);
#else
s_cube.set_color(render_color);
s_cone.set_color(render_color);
#endif // ENABLE_RAYCAST_PICKING
const Camera& camera = wxGetApp().plater()->get_camera();
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
#if ENABLE_RAYCAST_PICKING
const Transform3d& view_matrix = camera.get_view_matrix();
const Matrix3d view_matrix_no_offset = view_matrix.matrix().block(0, 0, 3, 3);
std::vector<Transform3d> elements_matrices(GRABBER_ELEMENTS_MAX_COUNT, Transform3d::Identity());
elements_matrices[0] = matrix * Geometry::translation_transform(center) * Geometry::rotation_transform(angles) * Geometry::scale_transform(2.0 * half_size);
Transform3d view_model_matrix = view_matrix * elements_matrices[0];
#else
const Transform3d& view_matrix = camera.get_view_matrix();
const Transform3d model_matrix = matrix * Geometry::translation_transform(center) * Geometry::rotation_transform(angles) * Geometry::scale_transform(2.0 * half_size);
const Transform3d view_model_matrix = view_matrix * model_matrix;
#endif // ENABLE_RAYCAST_PICKING
shader->set_uniform("view_model_matrix", view_model_matrix);
#if ENABLE_RAYCAST_PICKING
Matrix3d view_normal_matrix = view_matrix_no_offset * elements_matrices[0].matrix().block(0, 0, 3, 3).inverse().transpose();
#else
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
#endif // ENABLE_RAYCAST_PICKING
shader->set_uniform("view_normal_matrix", view_normal_matrix);
#else
s_cube.set_color(-1, render_color);
s_cone.set_color(-1, render_color);
glsafe(::glPushMatrix());
glsafe(::glTranslated(center.x(), center.y(), center.z()));
glsafe(::glRotated(Geometry::rad2deg(angles.z()), 0.0, 0.0, 1.0));
glsafe(::glRotated(Geometry::rad2deg(angles.y()), 0.0, 1.0, 0.0));
glsafe(::glRotated(Geometry::rad2deg(angles.x()), 1.0, 0.0, 0.0));
glsafe(::glScaled(2.0 * half_size, 2.0 * half_size, 2.0 * half_size));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
s_cube.model.render();
auto render_extension = [&view_matrix, &view_matrix_no_offset, shader](const Transform3d& matrix) {
@ -164,113 +97,32 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, boo
shader->set_uniform("view_normal_matrix", view_normal_matrix);
s_cone.model.render();
};
#else
s_cube.render();
#endif // ENABLE_RAYCAST_PICKING
#if ENABLE_LEGACY_OPENGL_REMOVAL
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosX)) != 0) {
#if ENABLE_RAYCAST_PICKING
elements_matrices[1] = elements_matrices[0] * Geometry::translation_transform(Vec3d::UnitX()) * Geometry::rotation_transform({ 0.0, 0.5 * double(PI), 0.0 });
render_extension(elements_matrices[1]);
#else
shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::translation_transform(Vec3d::UnitX()) * Geometry::rotation_transform({ 0.0, 0.5 * double(PI), 0.0 }));
s_cone.render();
#endif // ENABLE_RAYCAST_PICKING
}
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegX)) != 0) {
#if ENABLE_RAYCAST_PICKING
elements_matrices[2] = elements_matrices[0] * Geometry::translation_transform(-Vec3d::UnitX()) * Geometry::rotation_transform({ 0.0, -0.5 * double(PI), 0.0 });
render_extension(elements_matrices[2]);
#else
shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::translation_transform(-Vec3d::UnitX()) * Geometry::rotation_transform({ 0.0, -0.5 * double(PI), 0.0 }));
s_cone.render();
#endif // ENABLE_RAYCAST_PICKING
}
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosY)) != 0) {
#if ENABLE_RAYCAST_PICKING
elements_matrices[3] = elements_matrices[0] * Geometry::translation_transform(Vec3d::UnitY()) * Geometry::rotation_transform({ -0.5 * double(PI), 0.0, 0.0 });
render_extension(elements_matrices[3]);
#else
shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::translation_transform(Vec3d::UnitY()) * Geometry::rotation_transform({ -0.5 * double(PI), 0.0, 0.0 }));
s_cone.render();
#endif // ENABLE_RAYCAST_PICKING
}
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegY)) != 0) {
#if ENABLE_RAYCAST_PICKING
elements_matrices[4] = elements_matrices[0] * Geometry::translation_transform(-Vec3d::UnitY()) * Geometry::rotation_transform({ 0.5 * double(PI), 0.0, 0.0 });
render_extension(elements_matrices[4]);
#else
shader->set_uniform("view_model_matrix", view_model_matrix* Geometry::translation_transform(-Vec3d::UnitY())* Geometry::rotation_transform({ 0.5 * double(PI), 0.0, 0.0 }));
s_cone.render();
#endif // ENABLE_RAYCAST_PICKING
}
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosZ)) != 0) {
#if ENABLE_RAYCAST_PICKING
elements_matrices[5] = elements_matrices[0] * Geometry::translation_transform(Vec3d::UnitZ());
render_extension(elements_matrices[5]);
#else
shader->set_uniform("view_model_matrix", view_model_matrix* Geometry::translation_transform(Vec3d::UnitZ()));
s_cone.render();
#endif // ENABLE_RAYCAST_PICKING
}
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegZ)) != 0) {
#if ENABLE_RAYCAST_PICKING
elements_matrices[6] = elements_matrices[0] * Geometry::translation_transform(-Vec3d::UnitZ()) * Geometry::rotation_transform({ double(PI), 0.0, 0.0 });
render_extension(elements_matrices[6]);
#else
shader->set_uniform("view_model_matrix", view_model_matrix* Geometry::translation_transform(-Vec3d::UnitZ())* Geometry::rotation_transform({ double(PI), 0.0, 0.0 }));
s_cone.render();
#endif // ENABLE_RAYCAST_PICKING
}
#else
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosX)) != 0) {
glsafe(::glPushMatrix());
glsafe(::glTranslated(1.0, 0.0, 0.0));
glsafe(::glRotated(0.5 * Geometry::rad2deg(double(PI)), 0.0, 1.0, 0.0));
s_cone.render();
glsafe(::glPopMatrix());
}
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegX)) != 0) {
glsafe(::glPushMatrix());
glsafe(::glTranslated(-1.0, 0.0, 0.0));
glsafe(::glRotated(-0.5 * Geometry::rad2deg(double(PI)), 0.0, 1.0, 0.0));
s_cone.render();
glsafe(::glPopMatrix());
}
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosY)) != 0) {
glsafe(::glPushMatrix());
glsafe(::glTranslated(0.0, 1.0, 0.0));
glsafe(::glRotated(-0.5 * Geometry::rad2deg(double(PI)), 1.0, 0.0, 0.0));
s_cone.render();
glsafe(::glPopMatrix());
}
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegY)) != 0) {
glsafe(::glPushMatrix());
glsafe(::glTranslated(0.0, -1.0, 0.0));
glsafe(::glRotated(0.5 * Geometry::rad2deg(double(PI)), 1.0, 0.0, 0.0));
s_cone.render();
glsafe(::glPopMatrix());
}
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosZ)) != 0) {
glsafe(::glPushMatrix());
glsafe(::glTranslated(0.0, 0.0, 1.0));
s_cone.render();
glsafe(::glPopMatrix());
}
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegZ)) != 0) {
glsafe(::glPushMatrix());
glsafe(::glTranslated(0.0, 0.0, -1.0));
glsafe(::glRotated(Geometry::rad2deg(double(PI)), 1.0, 0.0, 0.0));
s_cone.render();
glsafe(::glPopMatrix());
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
if (raycasters[0] == nullptr) {
GLCanvas3D& canvas = *wxGetApp().plater()->canvas3D();
raycasters[0] = canvas.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, picking_id, *s_cube.mesh_raycaster, elements_matrices[0]);
@ -293,7 +145,6 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, boo
raycasters[i]->set_transform(elements_matrices[i]);
}
}
#endif // ENABLE_RAYCAST_PICKING
}
GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
@ -327,7 +178,6 @@ bool GLGizmoBase::update_items_state()
return res;
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoBase::register_grabbers_for_picking()
{
for (size_t i = 0; i < m_grabbers.size(); ++i) {
@ -341,16 +191,6 @@ void GLGizmoBase::unregister_grabbers_for_picking()
m_grabbers[i].unregister_raycasters_for_picking();
}
}
#else
ColorRGBA GLGizmoBase::picking_color_component(unsigned int id) const
{
id = BASE_ID - id;
if (m_group_id > -1)
id -= m_group_id;
return picking_decode(id);
}
#endif // ENABLE_RAYCAST_PICKING
void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const
{
@ -371,29 +211,6 @@ void GLGizmoBase::render_grabbers(float size) const
shader->stop_using();
}
#if !ENABLE_RAYCAST_PICKING
void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLShaderProgram* shader = wxGetApp().get_shader("flat");
if (shader != nullptr) {
shader->start_using();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0);
for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i) {
if (m_grabbers[i].enabled) {
m_grabbers[i].color = picking_color_component(i);
m_grabbers[i].render_for_picking(mean_size);
}
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#endif // !ENABLE_RAYCAST_PICKING
// help function to process grabbers
// call start_dragging, stop_dragging, on_dragging
bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {

View File

@ -6,10 +6,8 @@
#include "slic3r/GUI/I18N.hpp"
#include "slic3r/GUI/GLModel.hpp"
#if ENABLE_RAYCAST_PICKING
#include "slic3r/GUI/MeshUtils.hpp"
#include "slic3r/GUI/SceneRaycaster.hpp"
#endif // ENABLE_RAYCAST_PICKING
#include <cereal/archives/binary.hpp>
@ -68,49 +66,29 @@ protected:
bool dragging{ false };
Vec3d center{ Vec3d::Zero() };
Vec3d angles{ Vec3d::Zero() };
#if ENABLE_LEGACY_OPENGL_REMOVAL
Transform3d matrix{ Transform3d::Identity() };
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
ColorRGBA color{ ColorRGBA::WHITE() };
EGrabberExtension extensions{ EGrabberExtension::None };
#if ENABLE_RAYCAST_PICKING
// the picking id shared by all the elements
int picking_id{ -1 };
std::array<std::shared_ptr<SceneRaycasterItem>, GRABBER_ELEMENTS_MAX_COUNT> raycasters = { nullptr };
#endif // ENABLE_RAYCAST_PICKING
Grabber() = default;
~Grabber();
#if ENABLE_RAYCAST_PICKING
void render(bool hover, float size) { render(size, hover ? complementary(color) : color); }
#else
void render(bool hover, float size) { render(size, hover ? complementary(color) : color, false); }
void render_for_picking(float size) { render(size, color, true); }
#endif // ENABLE_RAYCAST_PICKING
float get_half_size(float size) const;
float get_dragging_half_size(float size) const;
#if ENABLE_RAYCAST_PICKING
void register_raycasters_for_picking(int id);
void unregister_raycasters_for_picking();
#endif // ENABLE_RAYCAST_PICKING
private:
#if ENABLE_RAYCAST_PICKING
void render(float size, const ColorRGBA& render_color);
#else
void render(float size, const ColorRGBA& render_color, bool picking);
#endif // ENABLE_RAYCAST_PICKING
#if ENABLE_RAYCAST_PICKING
static PickingModel s_cube;
static PickingModel s_cone;
#else
static GLModel s_cube;
static GLModel s_cone;
#endif // ENABLE_RAYCAST_PICKING
};
public:
@ -186,9 +164,6 @@ public:
bool update_items_state();
void render() { on_render(); }
#if !ENABLE_RAYCAST_PICKING
void render_for_picking() { on_render_for_picking(); }
#endif // !ENABLE_RAYCAST_PICKING
void render_input_window(float x, float y, float bottom_limit);
/// <summary>
@ -210,10 +185,8 @@ public:
/// <returns>Return True when use the information and don't want to propagate it otherwise False.</returns>
virtual bool on_mouse(const wxMouseEvent &mouse_event) { return false; }
#if ENABLE_RAYCAST_PICKING
void register_raycasters_for_picking() { register_grabbers_for_picking(); on_register_raycasters_for_picking(); }
void unregister_raycasters_for_picking() { unregister_grabbers_for_picking(); on_unregister_raycasters_for_picking(); }
#endif // ENABLE_RAYCAST_PICKING
virtual bool is_in_editing_mode() const { return false; }
virtual bool is_selection_rectangle_dragging() const { return false; }
@ -237,27 +210,15 @@ protected:
virtual void on_dragging(const UpdateData& data) {}
virtual void on_render() = 0;
#if !ENABLE_RAYCAST_PICKING
virtual void on_render_for_picking() = 0;
#endif // !ENABLE_RAYCAST_PICKING
virtual void on_render_input_window(float x, float y, float bottom_limit) {}
#if ENABLE_RAYCAST_PICKING
void register_grabbers_for_picking();
void unregister_grabbers_for_picking();
virtual void on_register_raycasters_for_picking() {}
virtual void on_unregister_raycasters_for_picking() {}
#else
// Returns the picking color for the given id, based on the BASE_ID constant
// No check is made for clashing with other picking color (i.e. GLVolumes)
ColorRGBA picking_color_component(unsigned int id) const;
#endif // ENABLE_RAYCAST_PICKING
void render_grabbers(const BoundingBoxf3& box) const;
void render_grabbers(float size) const;
#if !ENABLE_RAYCAST_PICKING
void render_grabbers_for_picking(const BoundingBoxf3& box) const;
#endif // !ENABLE_RAYCAST_PICKING
std::string format(float value, unsigned int decimals) const;

View File

@ -1144,11 +1144,11 @@ void GLGizmoCut3D::dragging_grabber_xy(const GLGizmoBase::UpdateData &data)
void GLGizmoCut3D::dragging_connector(const GLGizmoBase::UpdateData &data)
{
CutConnectors& connectors = m_c->selection_info()->model_object()->cut_connectors;
std::pair<Vec3d, Vec3d> pos_and_normal;
Vec3d pos;
Vec3d pos_world;
if (unproject_on_cut_plane(data.mouse_pos.cast<double>(), pos_and_normal, pos_world)) {
connectors[m_hover_id - m_connectors_group_id].pos = pos_and_normal.first;
if (unproject_on_cut_plane(data.mouse_pos.cast<double>(), pos, pos_world)) {
connectors[m_hover_id - m_connectors_group_id].pos = pos;
update_raycasters_for_picking_transform();
}
}
@ -2006,44 +2006,41 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
// Unprojects the mouse position on the mesh and saves hit point and normal of the facet into pos_and_normal
// Return false if no intersection was found, true otherwise.
bool GLGizmoCut3D::unproject_on_cut_plane(const Vec2d& mouse_position, std::pair<Vec3d, Vec3d>& pos_and_normal, Vec3d& pos_world)
bool GLGizmoCut3D::unproject_on_cut_plane(const Vec2d& mouse_position, Vec3d& pos, Vec3d& pos_world)
{
const float sla_shift = m_c->selection_info()->get_sla_shift();
const ModelObject* mo = m_c->selection_info()->model_object();
const ModelInstance* mi = mo->instances[m_c->selection_info()->get_active_instance()];
const Transform3d instance_trafo = sla_shift > 0.f ?
translation_transform(sla_shift * Vec3d::UnitZ()) * mi->get_transformation().get_matrix() : mi->get_transformation().get_matrix();
const Camera& camera = wxGetApp().plater()->get_camera();
int mesh_id = -1;
for (const ModelVolume* mv : mo->volumes) {
++mesh_id;
if (!mv->is_model_part())
continue;
Vec3f normal;
Vec3f hit;
bool clipping_plane_was_hit = false;
// Calculate intersection with the clipping plane.
const ClippingPlane* cp = m_c->object_clipper()->get_clipping_plane(true);
Vec3d point;
Vec3d direction;
Vec3d hit;
MeshRaycaster::line_from_mouse_pos(mouse_position, Transform3d::Identity(), camera, point, direction);
Vec3d normal = -cp->get_normal().cast<double>();
double den = normal.dot(direction);
if (den != 0.) {
double t = (-cp->get_offset() - normal.dot(point))/den;
hit = (point + t * direction);
} else
return false;
// const Transform3d volume_trafo = get_volume_transformation(mv);
const Transform3d volume_trafo = mv->get_transformation().get_matrix();
if (! m_c->object_clipper()->is_projection_inside_cut(hit))
return false;
m_c->raycaster()->raycasters()[mesh_id]->unproject_on_mesh(mouse_position, instance_trafo * volume_trafo,
camera, hit, normal, m_c->object_clipper()->get_clipping_plane(true),
nullptr, &clipping_plane_was_hit);
if (clipping_plane_was_hit) {
// recalculate hit to object's local position
Vec3d hit_d = hit.cast<double>();
Vec3d hit_d = hit;
hit_d -= mi->get_offset();
hit_d[Z] -= sla_shift;
// Return both the point and the facet normal.
pos_and_normal = std::make_pair(hit_d, normal.cast<double>());
pos_world = hit.cast<double>();
pos = hit_d;
pos_world = hit;
return true;
}
}
return false;
}
void GLGizmoCut3D::clear_selection()
@ -2139,17 +2136,13 @@ bool GLGizmoCut3D::add_connector(CutConnectors& connectors, const Vec2d& mouse_p
if (!m_connectors_editing)
return false;
std::pair<Vec3d, Vec3d> pos_and_normal;
Vec3d pos;
Vec3d pos_world;
if (unproject_on_cut_plane(mouse_position.cast<double>(), pos_and_normal, pos_world)) {
// check if pos is out of enabled clipping plane
if (m_c->object_clipper() && !m_c->object_clipper()->is_projection_inside_cut(pos_world))
return true;
if (unproject_on_cut_plane(mouse_position.cast<double>(), pos, pos_world)) {
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Add connector"), UndoRedo::SnapshotType::GizmoAction);
unselect_all_connectors();
connectors.emplace_back(pos_and_normal.first, m_rotation_m,
connectors.emplace_back(pos, m_rotation_m,
m_connector_size * 0.5f, m_connector_depth_ratio,
m_connector_size_tolerance, m_connector_depth_ratio_tolerance,
CutConnectorAttributes( CutConnectorType(m_connector_type),
@ -2247,9 +2240,9 @@ bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_posi
if (!m_connectors_editing) {
if (0 && action == SLAGizmoEventType::LeftDown) {
// disable / enable current contour
std::pair<Vec3d, Vec3d> pos_and_normal;
Vec3d pos;
Vec3d pos_world;
if (unproject_on_cut_plane(mouse_position.cast<double>(), pos_and_normal, pos_world)) {
if (unproject_on_cut_plane(mouse_position.cast<double>(), pos, pos_world)) {
// Following would inform the clipper about the mouse click, so it can
// toggle the respective contour as disabled.
m_c->object_clipper()->pass_mouse_click(pos_world);

View File

@ -155,7 +155,7 @@ public:
GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
std::string get_tooltip() const override;
bool unproject_on_cut_plane(const Vec2d& mouse_pos, std::pair<Vec3d, Vec3d>& pos_and_normal, Vec3d& pos_world);
bool unproject_on_cut_plane(const Vec2d& mouse_pos, Vec3d& pos, Vec3d& pos_world);
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
bool is_in_editing_mode() const override { return m_connectors_editing; }

View File

@ -535,28 +535,16 @@ void GLGizmoEmboss::on_render() {
if (m_temp_transformation.has_value()) {
// draw text volume on temporary position
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLVolume& gl_volume = *selection.get_volume(*selection.get_volume_idxs().begin());
#else
const GLVolume& gl_volume = *selection.get_volume(*selection.get_volume_idxs().begin());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#else
glsafe(::glPushMatrix());
glsafe(::glMultMatrixd(m_temp_transformation->data()));
GLShaderProgram *shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
shader->start_using();
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d matrix = camera.get_view_matrix() * (*m_temp_transformation);
shader->set_uniform("view_model_matrix", matrix);
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
shader->set_uniform("view_normal_matrix", (Matrix3d) (matrix).matrix().block(0, 0, 3, 3).inverse().transpose());
shader->set_uniform("emission_factor", 0.0f);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// dragging object must be selected so draw it with correct color
//auto color = gl_volume.color;
@ -569,25 +557,15 @@ void GLGizmoEmboss::on_render() {
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
}
#if !ENABLE_LEGACY_OPENGL_REMOVAL
shader->set_uniform("uniform_color", color);
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glEnable(GL_DEPTH_TEST));
#if ENABLE_LEGACY_OPENGL_REMOVAL
gl_volume.model.set_color(color);
gl_volume.model.render();
#else
gl_volume.indexed_vertex_array.render();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glDisable(GL_DEPTH_TEST));
if (is_transparent) glsafe(::glDisable(GL_BLEND));
shader->stop_using();
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
bool is_surface_dragging = m_temp_transformation.has_value();
@ -600,18 +578,12 @@ void GLGizmoEmboss::on_render() {
}
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoEmboss::on_register_raycasters_for_picking(){
m_rotate_gizmo.register_raycasters_for_picking();
}
void GLGizmoEmboss::on_unregister_raycasters_for_picking(){
m_rotate_gizmo.unregister_raycasters_for_picking();
}
#else // !ENABLE_RAYCAST_PICKING
void GLGizmoEmboss::on_render_for_picking() {
m_rotate_gizmo.render_for_picking();
}
#endif // ENABLE_RAYCAST_PICKING
#ifdef SHOW_FINE_POSITION
// draw suggested position of window

View File

@ -56,12 +56,8 @@ protected:
bool on_init() override;
std::string on_get_name() const override;
void on_render() override;
#if ENABLE_RAYCAST_PICKING
virtual void on_register_raycasters_for_picking() override;
virtual void on_unregister_raycasters_for_picking() override;
#else // !ENABLE_RAYCAST_PICKING
void on_render_for_picking() override;
#endif // ENABLE_RAYCAST_PICKING
void on_render_input_window(float x, float y, float bottom_limit) override;
bool on_is_activable() const override { return true; }
bool on_is_selectable() const override { return false; }

View File

@ -1,10 +1,8 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoFlatten.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp"
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/Plater.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
@ -100,13 +98,11 @@ void GLGizmoFlatten::on_render()
{
const Selection& selection = m_parent.get_selection();
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLShaderProgram* shader = wxGetApp().get_shader("flat");
if (shader == nullptr)
return;
shader->start_using();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
@ -115,50 +111,27 @@ void GLGizmoFlatten::on_render()
if (selection.is_single_full_instance()) {
const Transform3d& inst_matrix = selection.get_first_volume()->get_instance_transformation().get_matrix();
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d model_matrix = Geometry::translation_transform(selection.get_first_volume()->get_sla_shift_z() * Vec3d::UnitZ()) * inst_matrix;
const Transform3d view_model_matrix = camera.get_view_matrix() * model_matrix;
shader->set_uniform("view_model_matrix", view_model_matrix);
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
#else
glsafe(::glPushMatrix());
glsafe(::glTranslatef(0.f, 0.f, selection.get_first_volume()->get_sla_shift_z()));
glsafe(::glMultMatrixd(inst_matrix.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (this->is_plane_update_necessary())
update_planes();
for (int i = 0; i < (int)m_planes.size(); ++i) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
m_planes_casters[i]->set_transform(model_matrix);
m_planes[i].vbo.model.set_color(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR : DEFAULT_PLANE_COLOR);
m_planes[i].vbo.model.render();
#else
m_planes[i].vbo.set_color(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR : DEFAULT_PLANE_COLOR);
m_planes[i].vbo.render();
#endif // ENABLE_RAYCAST_PICKING
#else
glsafe(::glColor4fv(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR.data() : DEFAULT_PLANE_COLOR.data()));
if (m_planes[i].vbo.has_VBOs())
m_planes[i].vbo.render();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
glsafe(::glEnable(GL_CULL_FACE));
glsafe(::glDisable(GL_BLEND));
#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoFlatten::on_register_raycasters_for_picking()
{
// the gizmo grabbers are rendered on top of the scene, so the raytraced picker should take it into account
@ -183,66 +156,12 @@ void GLGizmoFlatten::on_unregister_raycasters_for_picking()
m_parent.set_raycaster_gizmos_on_top(false);
m_planes_casters.clear();
}
#else
void GLGizmoFlatten::on_render_for_picking()
{
const Selection& selection = m_parent.get_selection();
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLShaderProgram* shader = wxGetApp().get_shader("flat");
if (shader == nullptr)
return;
shader->start_using();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glDisable(GL_DEPTH_TEST));
glsafe(::glDisable(GL_BLEND));
if (selection.is_single_full_instance() && !wxGetKeyState(WXK_CONTROL)) {
const Transform3d& m = selection.get_first_volume()->get_instance_transformation().get_matrix();
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d view_model_matrix = camera.get_view_matrix() *
Geometry::translation_transform(selection.get_first_volume()->get_sla_shift_z() * Vec3d::UnitZ()) * m;
shader->set_uniform("view_model_matrix", view_model_matrix);
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
#else
glsafe(::glPushMatrix());
glsafe(::glTranslatef(0.f, 0.f, selection.get_first_volume()->get_sla_shift_z()));
glsafe(::glMultMatrixd(m.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (this->is_plane_update_necessary())
update_planes();
for (int i = 0; i < (int)m_planes.size(); ++i) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_planes[i].vbo.set_color(picking_color_component(i));
#else
glsafe(::glColor4fv(picking_color_component(i).data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_planes[i].vbo.render();
}
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
glsafe(::glEnable(GL_CULL_FACE));
#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#endif // ENABLE_RAYCAST_PICKING
void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object)
{
if (model_object != m_old_model_object) {
m_planes.clear();
#if ENABLE_RAYCAST_PICKING
on_unregister_raycasters_for_picking();
#endif // ENABLE_RAYCAST_PICKING
}
}
@ -259,9 +178,7 @@ void GLGizmoFlatten::update_planes()
}
ch = ch.convex_hull_3d();
m_planes.clear();
#if ENABLE_RAYCAST_PICKING
on_unregister_raycasters_for_picking();
#endif // ENABLE_RAYCAST_PICKING
#if ENABLE_WORLD_COORDINATE
const Transform3d inst_matrix = mo->instances.front()->get_matrix_no_offset();
#else
@ -457,8 +374,6 @@ void GLGizmoFlatten::update_planes()
// And finally create respective VBOs. The polygon is convex with
// the vertices in order, so triangulation is trivial.
for (auto& plane : m_planes) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
indexed_triangle_set its;
its.vertices.reserve(plane.vertices.size());
its.indices.reserve(plane.vertices.size() / 3);
@ -470,38 +385,15 @@ void GLGizmoFlatten::update_planes()
}
plane.vbo.model.init_from(its);
plane.vbo.mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
#else
GLModel::Geometry init_data;
init_data.format = { GLModel::Geometry::EPrimitiveType::TriangleFan, GLModel::Geometry::EVertexLayout::P3N3 };
init_data.reserve_vertices(plane.vertices.size());
init_data.reserve_indices(plane.vertices.size());
// vertices + indices
for (size_t i = 0; i < plane.vertices.size(); ++i) {
init_data.add_vertex((Vec3f)plane.vertices[i].cast<float>(), (Vec3f)plane.normal.cast<float>());
init_data.add_index((unsigned int)i);
}
plane.vbo.init_from(std::move(init_data));
#endif // ENABLE_RAYCAST_PICKING
#else
plane.vbo.reserve(plane.vertices.size());
for (const auto& vert : plane.vertices)
plane.vbo.push_geometry(vert, plane.normal);
for (size_t i=1; i<plane.vertices.size()-1; ++i)
plane.vbo.push_triangle(0, i, i+1); // triangle fan
plane.vbo.finalize_geometry(true);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// FIXME: vertices should really be local, they need not
// persist now when we use VBOs
plane.vertices.clear();
plane.vertices.shrink_to_fit();
}
#if ENABLE_RAYCAST_PICKING
on_register_raycasters_for_picking();
#endif // ENABLE_RAYCAST_PICKING
}
bool GLGizmoFlatten::is_plane_update_necessary() const
{
const ModelObject* mo = m_c->selection_info()->model_object();

View File

@ -2,14 +2,8 @@
#define slic3r_GLGizmoFlatten_hpp_
#include "GLGizmoBase.hpp"
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "slic3r/GUI/GLModel.hpp"
#if ENABLE_RAYCAST_PICKING
#include "slic3r/GUI/MeshUtils.hpp"
#endif // ENABLE_RAYCAST_PICKING
#else
#include "slic3r/GUI/3DScene.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
namespace Slic3r {
@ -29,20 +23,10 @@ private:
struct PlaneData {
std::vector<Vec3d> vertices; // should be in fact local in update_planes()
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
PickingModel vbo;
#else
GLModel vbo;
#endif // ENABLE_RAYCAST_PICKING
#else
GLIndexedVertexArray vbo;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
Vec3d normal;
float area;
#if ENABLE_RAYCAST_PICKING
int picking_id{ -1 };
#endif // ENABLE_RAYCAST_PICKING
};
// This holds information to decide whether recalculation is necessary:
@ -52,9 +36,7 @@ private:
Vec3d m_first_instance_mirror;
std::vector<PlaneData> m_planes;
#if ENABLE_RAYCAST_PICKING
std::vector<std::shared_ptr<SceneRaycasterItem>> m_planes_casters;
#endif // ENABLE_RAYCAST_PICKING
bool m_mouse_left_down = false; // for detection left_up of this gizmo
const ModelObject* m_old_model_object = nullptr;
@ -79,12 +61,8 @@ protected:
std::string on_get_name() const override;
bool on_is_activable() const override;
void on_render() override;
#if ENABLE_RAYCAST_PICKING
virtual void on_register_raycasters_for_picking() override;
virtual void on_unregister_raycasters_for_picking() override;
#else
void on_render_for_picking() override;
#endif // ENABLE_RAYCAST_PICKING
void on_set_state() override;
CommonGizmosDataID on_get_requirements() const override;
};

View File

@ -55,12 +55,10 @@ void GLGizmoHollow::data_changed()
}
if (m_c->hollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh())
m_holes_in_drilled_mesh = mo->sla_drain_holes;
#if ENABLE_RAYCAST_PICKING
if (m_raycasters.empty())
on_register_raycasters_for_picking();
else
update_raycasters_for_picking_transform();
#endif // ENABLE_RAYCAST_PICKING
}
}
@ -68,11 +66,6 @@ void GLGizmoHollow::data_changed()
void GLGizmoHollow::on_render()
{
#if !ENABLE_RAYCAST_PICKING
if (!m_cylinder.is_initialized())
m_cylinder.init_from(its_make_cylinder(1.0, 1.0));
#endif // !ENABLE_RAYCAST_PICKING
const Selection& selection = m_parent.get_selection();
const CommonGizmosDataObjects::SelectionInfo* sel_info = m_c->selection_info();
@ -88,11 +81,7 @@ void GLGizmoHollow::on_render()
glsafe(::glEnable(GL_DEPTH_TEST));
if (selection.is_from_single_instance())
#if ENABLE_RAYCAST_PICKING
render_points(selection);
#else
render_points(selection, false);
#endif // ENABLE_RAYCAST_PICKING
m_selection_rectangle.render(m_parent);
m_c->object_clipper()->render_cut();
@ -101,7 +90,6 @@ void GLGizmoHollow::on_render()
glsafe(::glDisable(GL_BLEND));
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoHollow::on_register_raycasters_for_picking()
{
assert(m_raycasters.empty());
@ -126,43 +114,19 @@ void GLGizmoHollow::on_unregister_raycasters_for_picking()
m_raycasters.clear();
set_sla_auxiliary_volumes_picking_state(true);
}
#else
void GLGizmoHollow::on_render_for_picking()
{
const Selection& selection = m_parent.get_selection();
glsafe(::glEnable(GL_DEPTH_TEST));
render_points(selection, true);
}
#endif // ENABLE_RAYCAST_PICKING
#if ENABLE_RAYCAST_PICKING
void GLGizmoHollow::render_points(const Selection& selection)
#else
void GLGizmoHollow::render_points(const Selection& selection, bool picking)
#endif // ENABLE_RAYCAST_PICKING
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#else
GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat") : wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_RAYCAST_PICKING
if (shader == nullptr)
return;
shader->start_using();
ScopeGuard guard([shader]() { shader->stop_using(); });
#else
GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_shader("gouraud_light");
if (shader)
shader->start_using();
ScopeGuard guard([shader]() { if (shader) shader->stop_using(); });
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const GLVolume* vol = selection.get_first_volume();
const Transform3d trafo = vol->world_matrix();
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WORLD_COORDINATE
const Transform3d instance_scaling_matrix_inverse = vol->get_instance_transformation().get_scaling_factor_matrix().inverse();
#else
@ -171,14 +135,6 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
#else
const Transform3d& instance_scaling_matrix_inverse = trafo.get_matrix(true, true, false, true).inverse();
const Transform3d& instance_matrix = trafo.get_matrix();
glsafe(::glPushMatrix());
glsafe(::glTranslated(0.0, 0.0, m_c->selection_info()->get_sla_shift()));
glsafe(::glMultMatrixd(instance_matrix.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
ColorRGBA render_color;
const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
@ -188,22 +144,12 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
const sla::DrainHole& drain_hole = drain_holes[i];
const bool point_selected = m_selected[i];
#if ENABLE_RAYCAST_PICKING
const bool clipped = is_mesh_point_clipped(drain_hole.pos.cast<double>());
m_raycasters[i]->set_active(!clipped);
if (clipped)
continue;
#else
if (is_mesh_point_clipped(drain_hole.pos.cast<double>()))
continue;
#endif // ENABLE_RAYCAST_PICKING
// First decide about the color of the point.
#if !ENABLE_RAYCAST_PICKING
if (picking)
render_color = picking_color_component(i);
else {
#endif // !ENABLE_RAYCAST_PICKING
if (size_t(m_hover_id) == i)
render_color = ColorRGBA::CYAN();
else if (m_c->hollowed_mesh() &&
@ -213,25 +159,10 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
}
else
render_color = point_selected ? ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f) : ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f);
#if !ENABLE_RAYCAST_PICKING
}
#endif // !ENABLE_RAYCAST_PICKING
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
m_cylinder.model.set_color(render_color);
#else
m_cylinder.set_color(render_color);
#endif // ENABLE_RAYCAST_PICKING
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
const Transform3d hole_matrix = Geometry::translation_transform(drain_hole.pos.cast<double>()) * instance_scaling_matrix_inverse;
#else
const_cast<GLModel*>(&m_cylinder)->set_color(-1, render_color);
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
glsafe(::glPushMatrix());
glsafe(::glTranslatef(drain_hole.pos.x(), drain_hole.pos.y(), drain_hole.pos.z()));
glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (vol->is_left_handed())
glsafe(::glFrontFace(GL_CW));
@ -240,34 +171,16 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
Eigen::Quaterniond q;
q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * (-drain_hole.normal).cast<double>());
const Eigen::AngleAxisd aa(q);
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Transform3d model_matrix = trafo * hole_matrix * Transform3d(aa.toRotationMatrix()) *
Geometry::translation_transform(-drain_hole.height * Vec3d::UnitZ()) * Geometry::scale_transform(Vec3d(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength));
shader->set_uniform("view_model_matrix", view_matrix * model_matrix);
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);
#else
glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis().x(), aa.axis().y(), aa.axis().z()));
glsafe(::glTranslated(0., 0., -drain_hole.height));
glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
m_cylinder.model.render();
#else
m_cylinder.render();
#endif // ENABLE_RAYCAST_PICKING
if (vol->is_left_handed())
glsafe(::glFrontFace(GL_CCW));
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
bool GLGizmoHollow::is_mesh_point_clipped(const Vec3d& point) const
@ -382,10 +295,8 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
assert(m_selected.size() == mo->sla_drain_holes.size());
m_parent.set_as_dirty();
m_wait_for_up_event = true;
#if ENABLE_RAYCAST_PICKING
on_unregister_raycasters_for_picking();
on_register_raycasters_for_picking();
#endif // ENABLE_RAYCAST_PICKING
}
else
return false;
@ -410,12 +321,8 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
// Now ask the rectangle which of the points are inside.
std::vector<Vec3f> points_inside;
#if ENABLE_RAYCAST_PICKING
std::vector<unsigned int> points_idxs = m_selection_rectangle.contains(points);
m_selection_rectangle.stop_dragging();
#else
std::vector<unsigned int> points_idxs = m_selection_rectangle.stop_dragging(m_parent, points);
#endif // ENABLE_RAYCAST_PICKING
for (size_t idx : points_idxs)
points_inside.push_back(points[idx].cast<float>());
@ -509,10 +416,8 @@ void GLGizmoHollow::delete_selected_points()
}
}
#if ENABLE_RAYCAST_PICKING
on_unregister_raycasters_for_picking();
on_register_raycasters_for_picking();
#endif // ENABLE_RAYCAST_PICKING
select_point(NoPoints);
}
@ -588,7 +493,6 @@ void GLGizmoHollow::hollow_mesh(bool postpone_error_messages)
});
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoHollow::set_sla_auxiliary_volumes_picking_state(bool state)
{
std::vector<std::shared_ptr<SceneRaycasterItem>>* raycasters = m_parent.get_raycasters_for_picking(SceneRaycaster::EType::Volume);
@ -630,7 +534,6 @@ void GLGizmoHollow::update_raycasters_for_picking_transform()
}
}
}
#endif // ENABLE_RAYCAST_PICKING
std::vector<std::pair<const ConfigOption*, const ConfigOptionDef*>>
GLGizmoHollow::get_config_options(const std::vector<std::string>& keys) const
@ -900,6 +803,9 @@ RENDER_AGAIN:
bool show_sups = m_c->instances_hider()->are_supports_shown();
if (m_imgui->checkbox(m_desc["show_supports"], show_sups)) {
m_c->instances_hider()->show_supports(show_sups);
if (show_sups)
// ensure supports and pad are disabled from picking even when they are visible
set_sla_auxiliary_volumes_picking_state(false);
force_refresh = true;
}
@ -1095,7 +1001,6 @@ void GLGizmoHollow::on_set_hover_id()
m_hover_id = -1;
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoHollow::init_cylinder_model()
{
if (!m_cylinder.model.is_initialized()) {
@ -1104,7 +1009,6 @@ void GLGizmoHollow::init_cylinder_model()
m_cylinder.mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
}
}
#endif // ENABLE_RAYCAST_PICKING

View File

@ -46,33 +46,19 @@ public:
protected:
bool on_init() override;
void on_render() override;
#if ENABLE_RAYCAST_PICKING
virtual void on_register_raycasters_for_picking() override;
virtual void on_unregister_raycasters_for_picking() override;
#else
void on_render_for_picking() override;
#endif // ENABLE_RAYCAST_PICKING
private:
#if ENABLE_RAYCAST_PICKING
void render_points(const Selection& selection);
#else
void render_points(const Selection& selection, bool picking = false);
#endif // ENABLE_RAYCAST_PICKING
void hollow_mesh(bool postpone_error_messages = false);
#if ENABLE_RAYCAST_PICKING
void set_sla_auxiliary_volumes_picking_state(bool state);
void update_raycasters_for_picking_transform();
#endif // ENABLE_RAYCAST_PICKING
ObjectID m_old_mo_id = -1;
#if ENABLE_RAYCAST_PICKING
PickingModel m_cylinder;
std::vector<std::shared_ptr<SceneRaycasterItem>> m_raycasters;
#else
GLModel m_cylinder;
#endif // ENABLE_RAYCAST_PICKING
float m_new_hole_radius = 2.f; // Size of a new hole.
float m_new_hole_height = 6.f;
@ -128,9 +114,7 @@ protected:
void on_load(cereal::BinaryInputArchive& ar) override;
void on_save(cereal::BinaryOutputArchive& ar) const override;
#if ENABLE_RAYCAST_PICKING
void init_cylinder_model();
#endif // ENABLE_RAYCAST_PICKING
};

File diff suppressed because it is too large Load Diff

View File

@ -4,12 +4,12 @@
#include "GLGizmoBase.hpp"
#include "slic3r/GUI/GLModel.hpp"
#include "slic3r/GUI/GUI_Utils.hpp"
#include "slic3r/GUI/MeshUtils.hpp"
#include "libslic3r/Measure.hpp"
#include "libslic3r/Model.hpp"
namespace Slic3r {
class ModelVolume;
enum class ModelVolumeType : int;
namespace Measure { class Measuring; }
@ -24,20 +24,19 @@ class GLGizmoMeasure : public GLGizmoBase
enum class EMode : unsigned char
{
FeatureSelection,
PointSelection,
CenterSelection
PointSelection
};
struct SelectedFeatures
{
struct Item
{
std::string source;
bool is_center{ false };
std::optional<Measure::SurfaceFeature> source;
std::optional<Measure::SurfaceFeature> feature;
bool operator == (const Item& other) const {
if (this->source != other.source) return false;
return this->feature == other.feature;
return this->is_center == other.is_center && this->source == other.source && this->feature == other.feature;
}
bool operator != (const Item& other) const {
@ -45,7 +44,8 @@ class GLGizmoMeasure : public GLGizmoBase
}
void reset() {
source.clear();
is_center = false;
source.reset();
feature.reset();
}
};
@ -68,6 +68,21 @@ class GLGizmoMeasure : public GLGizmoBase
}
};
struct VolumeCacheItem
{
const ModelObject* object{ nullptr };
const ModelInstance* instance{ nullptr };
const ModelVolume* volume{ nullptr };
Transform3d world_trafo;
bool operator == (const VolumeCacheItem& other) const {
return this->object == other.object && this->instance == other.instance && this->volume == other.volume &&
this->world_trafo.isApprox(other.world_trafo);
}
};
std::vector<VolumeCacheItem> m_volumes_cache;
EMode m_mode{ EMode::FeatureSelection };
Measure::MeasurementResult m_measurement_result;
@ -85,10 +100,14 @@ class GLGizmoMeasure : public GLGizmoBase
};
Dimensioning m_dimensioning;
Transform3d m_volume_matrix{ Transform3d::Identity() };
// Uses a standalone raycaster and not the shared one because of the
// difference in how the mesh is updated
std::unique_ptr<MeshRaycaster> m_raycaster;
std::vector<GLModel> m_plane_models_cache;
std::map<int, std::shared_ptr<SceneRaycasterItem>> m_raycasters;
std::vector<std::shared_ptr<SceneRaycasterItem>> m_selection_raycasters;
// used to keep the raycasters for point/center spheres
std::vector<std::shared_ptr<SceneRaycasterItem>> m_selected_sphere_raycasters;
std::optional<Measure::SurfaceFeature> m_curr_feature;
std::optional<Vec3d> m_curr_point_on_feature_position;
struct SceneRaycasterState
@ -100,21 +119,14 @@ class GLGizmoMeasure : public GLGizmoBase
std::vector<SceneRaycasterState> m_scene_raycasters;
// These hold information to decide whether recalculation is necessary:
std::vector<Transform3d> m_volumes_matrices;
std::vector<ModelVolumeType> m_volumes_types;
Vec3d m_first_instance_scale{ Vec3d::Ones() };
Vec3d m_first_instance_mirror{ Vec3d::Ones() };
float m_last_inv_zoom{ 0.0f };
std::optional<Measure::SurfaceFeature> m_last_circle;
int m_last_plane_idx{ -1 };
bool m_mouse_left_down{ false }; // for detection left_up of this gizmo
const ModelObject* m_old_model_object{ nullptr };
const ModelVolume* m_old_model_volume{ nullptr };
Vec2d m_mouse_pos{ Vec2d::Zero() };
KeyAutoRepeatFilter m_ctrl_kar_filter;
KeyAutoRepeatFilter m_shift_kar_filter;
SelectedFeatures m_selected_features;
@ -147,17 +159,24 @@ public:
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
bool wants_enter_leave_snapshots() const override { return true; }
std::string get_gizmo_entering_text() const override { return _u8L("Entering Measure gizmo"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Measure gizmo"); }
std::string get_action_snapshot_name() override { return _u8L("Measure gizmo editing"); }
protected:
bool on_init() override;
std::string on_get_name() const override;
bool on_is_activable() const override;
void on_render() override;
void on_set_state() override;
CommonGizmosDataID on_get_requirements() const override;
virtual void on_render_input_window(float x, float y, float bottom_limit) override;
virtual void on_register_raycasters_for_picking() override;
virtual void on_unregister_raycasters_for_picking() override;
void remove_selected_sphere_raycaster(int id);
void update_measurement_result();
};
} // namespace GUI

View File

@ -193,26 +193,16 @@ void GLGizmoMmuSegmentation::render_triangles(const Selection &selection) const
if (is_left_handed)
glsafe(::glFrontFace(GL_CW));
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
shader->set_uniform("view_model_matrix", view_matrix * trafo_matrix);
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * trafo_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
shader->set_uniform("view_normal_matrix", view_normal_matrix);
#else
glsafe(::glPushMatrix());
glsafe(::glMultMatrixd(trafo_matrix.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
shader->set_uniform("volume_world_matrix", trafo_matrix);
shader->set_uniform("volume_mirrored", is_left_handed);
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix);
#else
m_triangle_selectors[mesh_id]->render(m_imgui);
glsafe(::glPopMatrix());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (is_left_handed)
glsafe(::glFrontFace(GL_CCW));
@ -582,11 +572,7 @@ ColorRGBA GLGizmoMmuSegmentation::get_cursor_sphere_right_button_color() const
return color;
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void TriangleSelectorMmGui::render(ImGuiWrapper* imgui, const Transform3d& matrix)
#else
void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (m_update_render_data)
update_render_data();
@ -595,14 +581,12 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
if (!shader)
return;
assert(shader->get_name() == "mm_gouraud");
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
shader->set_uniform("view_model_matrix", view_matrix * matrix);
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
shader->set_uniform("view_normal_matrix", view_normal_matrix);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx) {
if (m_gizmo_scene.has_VBOs(color_idx)) {
@ -615,21 +599,7 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
}
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
render_paint_contour(matrix);
#else
if (m_paint_contour.has_VBO()) {
ScopeGuard guard_mm_gouraud([shader]() { shader->start_using(); });
shader->stop_using();
auto *contour_shader = wxGetApp().get_shader("mm_contour");
contour_shader->start_using();
contour_shader->set_uniform("offset", OpenGLManager::get_gl_info().is_mesa() ? 0.0005 : 0.00001);
m_paint_contour.render();
contour_shader->stop_using();
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_update_render_data = false;
}
@ -662,29 +632,7 @@ void TriangleSelectorMmGui::update_render_data()
m_gizmo_scene.triangle_indices_sizes[color_idx] = m_gizmo_scene.triangle_indices[color_idx].size();
m_gizmo_scene.finalize_triangle_indices();
#if ENABLE_LEGACY_OPENGL_REMOVAL
update_paint_contour();
#else
m_paint_contour.release_geometry();
std::vector<Vec2i> contour_edges = this->get_seed_fill_contour();
m_paint_contour.contour_vertices.reserve(contour_edges.size() * 6);
for (const Vec2i &edge : contour_edges) {
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(0)].v.x());
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(0)].v.y());
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(0)].v.z());
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(1)].v.x());
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(1)].v.y());
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(1)].v.z());
}
m_paint_contour.contour_indices.assign(m_paint_contour.contour_vertices.size() / 3, 0);
std::iota(m_paint_contour.contour_indices.begin(), m_paint_contour.contour_indices.end(), 0);
m_paint_contour.contour_indices_size = m_paint_contour.contour_indices.size();
m_paint_contour.finalize_geometry();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
wxString GLGizmoMmuSegmentation::handle_snapshot_action_name(bool shift_down, GLGizmoPainterBase::Button button_down) const
@ -729,11 +677,9 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const
assert(this->vertices_VBO_id != 0);
assert(this->triangle_indices_VBO_ids[triangle_indices_idx] != 0);
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLShaderProgram* shader = wxGetApp().get_current_shader();
if (shader == nullptr)
return;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_CORE_PROFILE
if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0))
@ -741,7 +687,6 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const
// the following binding is needed to set the vertex attributes
#endif // ENABLE_GL_CORE_PROFILE
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id));
#if ENABLE_LEGACY_OPENGL_REMOVAL
const GLint position_id = shader->get_attrib_location("v_position");
if (position_id != -1) {
glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (GLvoid*)0));
@ -751,24 +696,13 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const
// Render using the Vertex Buffer Objects.
if (this->triangle_indices_VBO_ids[triangle_indices_idx] != 0 &&
this->triangle_indices_sizes[triangle_indices_idx] > 0) {
#else
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), (const void*)(0 * sizeof(float))));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
// Render using the Vertex Buffer Objects.
if (this->triangle_indices_sizes[triangle_indices_idx] > 0) {
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_ids[triangle_indices_idx]));
glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_sizes[triangle_indices_idx]), GL_UNSIGNED_INT, nullptr));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (position_id != -1)
glsafe(::glDisableVertexAttribArray(position_id));
#else
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
#if ENABLE_GL_CORE_PROFILE

View File

@ -69,13 +69,7 @@ public:
: TriangleSelectorGUI(mesh), m_colors(colors), m_default_volume_color(default_volume_color), m_gizmo_scene(2 * (colors.size() + 1)) {}
~TriangleSelectorMmGui() override = default;
#if ENABLE_LEGACY_OPENGL_REMOVAL
void render(ImGuiWrapper* imgui, const Transform3d& matrix) override;
#else
// Render current selection. Transformation matrices are supposed
// to be already set.
void render(ImGuiWrapper* imgui) override;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
private:
void update_render_data();

View File

@ -5,9 +5,7 @@
#if ENABLE_WORLD_COORDINATE
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
#endif // ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "slic3r/GUI/Plater.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include "libslic3r/Model.hpp"
#include <GL/glew.h>
@ -151,18 +149,11 @@ void GLGizmoMove3D::on_render()
glsafe(::glEnable(GL_DEPTH_TEST));
#if ENABLE_WORLD_COORDINATE
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPushMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
calc_selection_box_and_center();
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Transform3d base_matrix = local_transform(m_parent.get_selection());
for (int i = 0; i < 3; ++i) {
m_grabbers[i].matrix = base_matrix;
}
#else
transform_to_local(m_parent.get_selection());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const Vec3d zero = Vec3d::Zero();
const Vec3d half_box_size = 0.5 * m_bounding_box.size();
@ -201,7 +192,6 @@ void GLGizmoMove3D::on_render()
#endif // ENABLE_GL_CORE_PROFILE
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WORLD_COORDINATE
auto render_grabber_connection = [this, &zero](unsigned int id) {
#else
@ -240,10 +230,8 @@ void GLGizmoMove3D::on_render()
m_grabber_connections[id].model.render();
}
};
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (m_hover_id == -1) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_CORE_PROFILE
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
#else
@ -264,31 +252,14 @@ void GLGizmoMove3D::on_render()
shader->set_uniform("width", 0.25f);
shader->set_uniform("gap_size", 0.0f);
#endif // ENABLE_GL_CORE_PROFILE
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// draw axes
for (unsigned int i = 0; i < 3; ++i) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
render_grabber_connection(i);
#else
if (m_grabbers[i].enabled) {
glsafe(::glColor4fv(AXES_COLOR[i].data()));
::glBegin(GL_LINES);
#if ENABLE_WORLD_COORDINATE
::glVertex3dv(zero.data());
#else
::glVertex3dv(center.data());
#endif // ENABLE_WORLD_COORDINATE
::glVertex3dv(m_grabbers[i].center.data());
glsafe(::glEnd());
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// draw grabbers
#if ENABLE_WORLD_COORDINATE
@ -299,7 +270,6 @@ void GLGizmoMove3D::on_render()
}
else {
// draw axis
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_CORE_PROFILE
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
#else
@ -327,19 +297,6 @@ void GLGizmoMove3D::on_render()
}
shader = wxGetApp().get_shader("gouraud_light");
#else
glsafe(::glColor4fv(AXES_COLOR[m_hover_id].data()));
::glBegin(GL_LINES);
#if ENABLE_WORLD_COORDINATE
::glVertex3dv(zero.data());
#else
::glVertex3dv(center.data());
#endif // ENABLE_WORLD_COORDINATE
::glVertex3dv(m_grabbers[m_hover_id].center.data());
glsafe(::glEnd());
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@ -354,15 +311,8 @@ void GLGizmoMove3D::on_render()
shader->stop_using();
}
}
#if ENABLE_WORLD_COORDINATE
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#endif // ENABLE_WORLD_COORDINATE
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoMove3D::on_register_raycasters_for_picking()
{
// the gizmo grabbers are rendered on top of the scene, so the raytraced picker should take it into account
@ -373,32 +323,6 @@ void GLGizmoMove3D::on_unregister_raycasters_for_picking()
{
m_parent.set_raycaster_gizmos_on_top(false);
}
#else
void GLGizmoMove3D::on_render_for_picking()
{
glsafe(::glDisable(GL_DEPTH_TEST));
#if ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Transform3d base_matrix = local_transform(m_parent.get_selection());
for (int i = 0; i < 3; ++i) {
m_grabbers[i].matrix = base_matrix;
}
#else
glsafe(::glPushMatrix());
transform_to_local(m_parent.get_selection());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
render_grabbers_for_picking(m_bounding_box);
#if ENABLE_LEGACY_OPENGL_REMOVAL
#else
glsafe(::glPopMatrix());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#else
const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box();
render_grabbers_for_picking(box);
#endif // ENABLE_WORLD_COORDINATE
}
#endif // ENABLE_RAYCAST_PICKING
double GLGizmoMove3D::calc_projection(const UpdateData& data) const
{
@ -427,7 +351,6 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const
}
#if ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
Transform3d GLGizmoMove3D::local_transform(const Selection& selection) const
{
Transform3d ret = Geometry::translation_transform(m_center);
@ -440,20 +363,6 @@ Transform3d GLGizmoMove3D::local_transform(const Selection& selection) const
}
return ret;
}
#else
void GLGizmoMove3D::transform_to_local(const Selection& selection) const
{
glsafe(::glTranslated(m_center.x(), m_center.y(), m_center.z()));
if (!wxGetApp().obj_manipul()->is_world_coordinates()) {
const GLVolume& v = *selection.get_first_volume();
Transform3d orient_matrix = v.get_instance_transformation().get_matrix(true, false, true, true);
if (selection.is_single_volume_or_modifier() && wxGetApp().obj_manipul()->is_local_coordinates())
orient_matrix = orient_matrix * v.get_volume_transformation().get_matrix(true, false, true, true);
glsafe(::glMultMatrixd(orient_matrix.data()));
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoMove3D::calc_selection_box_and_center()
{

View File

@ -25,14 +25,12 @@ class GLGizmoMove3D : public GLGizmoBase
Vec3d m_starting_box_center{ Vec3d::Zero() };
Vec3d m_starting_box_bottom_center{ Vec3d::Zero() };
#if ENABLE_LEGACY_OPENGL_REMOVAL
struct GrabberConnection
{
GLModel model;
Vec3d old_center{ Vec3d::Zero() };
};
std::array<GrabberConnection, 3> m_grabber_connections;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
public:
GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
@ -62,21 +60,13 @@ protected:
void on_stop_dragging() override;
void on_dragging(const UpdateData& data) override;
void on_render() override;
#if ENABLE_RAYCAST_PICKING
virtual void on_register_raycasters_for_picking() override;
virtual void on_unregister_raycasters_for_picking() override;
#else
void on_render_for_picking() override;
#endif // ENABLE_RAYCAST_PICKING
private:
double calc_projection(const UpdateData& data) const;
#if ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
Transform3d local_transform(const Selection& selection) const;
#else
void transform_to_local(const Selection& selection) const;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void calc_selection_box_and_center();
#endif // ENABLE_WORLD_COORDINATE
};

View File

@ -19,11 +19,7 @@
namespace Slic3r::GUI {
#if ENABLE_LEGACY_OPENGL_REMOVAL
std::shared_ptr<GLModel> GLGizmoPainterBase::s_sphere = nullptr;
#else
std::shared_ptr<GLIndexedVertexArray> GLGizmoPainterBase::s_sphere = nullptr;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoBase(parent, icon_filename, sprite_id)
@ -32,13 +28,8 @@ GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& ic
GLGizmoPainterBase::~GLGizmoPainterBase()
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (s_sphere != nullptr)
s_sphere.reset();
#else
if (s_sphere != nullptr && s_sphere->has_VBOs())
s_sphere->release_geometry();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void GLGizmoPainterBase::data_changed()
@ -106,17 +97,12 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const
if (is_left_handed)
glsafe(::glFrontFace(GL_CW));
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
shader->set_uniform("view_model_matrix", view_matrix * trafo_matrix);
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * trafo_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
shader->set_uniform("view_normal_matrix", view_normal_matrix);
#else
glsafe(::glPushMatrix());
glsafe(::glMultMatrixd(trafo_matrix.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// For printers with multiple extruders, it is necessary to pass trafo_matrix
// to the shader input variable print_box.volume_world_matrix before
@ -124,13 +110,7 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const
// wrong transformation matrix is used for "Clipping of view".
shader->set_uniform("volume_world_matrix", trafo_matrix);
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix);
#else
m_triangle_selectors[mesh_id]->render(m_imgui);
glsafe(::glPopMatrix());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (is_left_handed)
glsafe(::glFrontFace(GL_CCW));
}
@ -165,14 +145,7 @@ void GLGizmoPainterBase::render_cursor()
void GLGizmoPainterBase::render_cursor_circle()
{
#if !ENABLE_LEGACY_OPENGL_REMOVAL
const Camera &camera = wxGetApp().plater()->get_camera();
const float zoom = float(camera.get_zoom());
const float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
const Size cnv_size = m_parent.get_canvas_size();
#if ENABLE_LEGACY_OPENGL_REMOVAL
const float cnv_width = float(cnv_size.get_width());
const float cnv_height = float(cnv_size.get_height());
if (cnv_width == 0.0f || cnv_height == 0.0f)
@ -188,43 +161,19 @@ void GLGizmoPainterBase::render_cursor_circle()
#else
const float radius = m_cursor_radius * float(wxGetApp().plater()->get_camera().get_zoom());
#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES
#else
const float cnv_half_width = 0.5f * float(cnv_size.get_width());
const float cnv_half_height = 0.5f * float(cnv_size.get_height());
if (cnv_half_width == 0.0f || cnv_half_height == 0.0f)
return;
const Vec2d mouse_pos(m_parent.get_local_mouse_position().x(), m_parent.get_local_mouse_position().y());
Vec2d center(mouse_pos.x() - cnv_half_width, cnv_half_height - mouse_pos.y());
center = center * inv_zoom;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_CORE_PROFILE
if (!OpenGLManager::get_gl_info().is_core_profile())
#endif // ENABLE_GL_CORE_PROFILE
glsafe(::glLineWidth(1.5f));
#if !ENABLE_LEGACY_OPENGL_REMOVAL
static const std::array<float, 3> color = { 0.f, 1.f, 0.3f };
glsafe(::glColor3fv(color.data()));
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glDisable(GL_DEPTH_TEST));
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPushMatrix());
glsafe(::glLoadIdentity());
// ensure that the circle is renderered inside the frustrum
glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.5)));
// ensure that the overlay fits the frustrum near z plane
const double gui_scale = camera.get_gui_scale();
glsafe(::glScaled(gui_scale, gui_scale, 1.0));
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#if !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES
glsafe(::glPushAttrib(GL_ENABLE_BIT));
glsafe(::glLineStipple(4, 0xAAAA));
glsafe(::glEnable(GL_LINE_STIPPLE));
#endif // !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES
if (!m_circle.is_initialized() || std::abs(m_old_cursor_radius - radius) > EPSILON) {
m_old_cursor_radius = radius;
@ -299,19 +248,10 @@ void GLGizmoPainterBase::render_cursor_circle()
m_circle.render();
shader->stop_using();
}
#else
::glBegin(GL_LINE_LOOP);
for (double angle=0; angle<2*M_PI; angle+=M_PI/20.)
::glVertex2f(GLfloat(center.x()+m_cursor_radius*cos(angle)), GLfloat(center.y()+m_cursor_radius*sin(angle)));
glsafe(::glEnd());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES
glsafe(::glPopAttrib());
#endif // !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glEnable(GL_DEPTH_TEST));
}
@ -319,21 +259,13 @@ void GLGizmoPainterBase::render_cursor_circle()
void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
{
if (s_sphere == nullptr) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
s_sphere = std::make_shared<GLModel>();
s_sphere->init_from(its_make_sphere(1.0, double(PI) / 12.0));
#else
s_sphere = std::make_shared<GLIndexedVertexArray>();
s_sphere->load_its_flat_shading(its_make_sphere(1.0, double(PI) / 12.0));
s_sphere->finalize_geometry(true);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLShaderProgram* shader = wxGetApp().get_shader("flat");
if (shader == nullptr)
return;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WORLD_COORDINATE
const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_scaling_factor_matrix().inverse();
@ -342,15 +274,6 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
#endif // ENABLE_WORLD_COORDINATE
const bool is_left_handed = Geometry::Transformation(trafo).is_left_handed();
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPushMatrix());
glsafe(::glMultMatrixd(trafo.data()));
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
glsafe(::glTranslatef(m_rr.hit.x(), m_rr.hit.y(), m_rr.hit.z()));
glsafe(::glMultMatrixd(complete_scaling_matrix_inverse.data()));
glsafe(::glScaled(m_cursor_radius, m_cursor_radius, m_cursor_radius));
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
if (is_left_handed)
glsafe(::glFrontFace(GL_CW));
@ -359,7 +282,7 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
render_color = this->get_cursor_sphere_left_button_color();
else if (m_button_down == Button::Right)
render_color = this->get_cursor_sphere_right_button_color();
#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->start_using();
const Camera& camera = wxGetApp().plater()->get_camera();
@ -372,23 +295,12 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
assert(s_sphere != nullptr);
s_sphere->set_color(render_color);
#else
glsafe(::glColor4fv(render_color.data()));
assert(s_sphere != nullptr);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
s_sphere->render();
#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (is_left_handed)
glsafe(::glFrontFace(GL_CCW));
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
@ -967,11 +879,7 @@ ColorRGBA TriangleSelectorGUI::get_seed_fill_color(const ColorRGBA& base_color)
return saturate(base_color, 0.75f);
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void TriangleSelectorGUI::render(ImGuiWrapper* imgui, const Transform3d& matrix)
#else
void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
static const ColorRGBA enforcers_color = { 0.47f, 0.47f, 1.0f, 1.0f };
static const ColorRGBA blockers_color = { 1.0f, 0.44f, 0.44f, 1.0f };
@ -989,18 +897,10 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
for (auto iva : {std::make_pair(&m_iva_enforcers, enforcers_color),
std::make_pair(&m_iva_blockers, blockers_color)}) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
iva.first->set_color(iva.second);
iva.first->render();
#else
if (iva.first->has_VBOs()) {
shader->set_uniform("uniform_color", iva.second);
iva.first->render();
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
for (auto& iva : m_iva_seed_fills) {
size_t color_idx = &iva - &m_iva_seed_fills.front();
const ColorRGBA& color = TriangleSelectorGUI::get_seed_fill_color(color_idx == 1 ? enforcers_color :
@ -1009,32 +909,8 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
iva.set_color(color);
iva.render();
}
#else
for (auto& iva : m_iva_seed_fills)
if (iva.has_VBOs()) {
size_t color_idx = &iva - &m_iva_seed_fills.front();
const ColorRGBA& color = TriangleSelectorGUI::get_seed_fill_color(color_idx == 1 ? enforcers_color :
color_idx == 2 ? blockers_color :
GLVolume::NEUTRAL_COLOR);
shader->set_uniform("uniform_color", color);
iva.render();
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
render_paint_contour(matrix);
#else
if (m_paint_contour.has_VBO()) {
ScopeGuard guard_gouraud([shader]() { shader->start_using(); });
shader->stop_using();
auto *contour_shader = wxGetApp().get_shader("mm_contour");
contour_shader->start_using();
contour_shader->set_uniform("offset", OpenGLManager::get_gl_info().is_mesa() ? 0.0005 : 0.00001);
m_paint_contour.render();
contour_shader->stop_using();
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
if (imgui)
@ -1050,7 +926,6 @@ void TriangleSelectorGUI::update_render_data()
int blc_cnt = 0;
std::vector<int> seed_fill_cnt(m_iva_seed_fills.size(), 0);
#if ENABLE_LEGACY_OPENGL_REMOVAL
for (auto* iva : { &m_iva_enforcers, &m_iva_blockers }) {
iva->reset();
}
@ -1066,13 +941,6 @@ void TriangleSelectorGUI::update_render_data()
std::array<GLModel::Geometry, 3> iva_seed_fills_data;
for (auto& data : iva_seed_fills_data)
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
#else
for (auto *iva : {&m_iva_enforcers, &m_iva_blockers})
iva->release_geometry();
for (auto &iva : m_iva_seed_fills)
iva.release_geometry();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// small value used to offset triangles along their normal to avoid z-fighting
static const float offset = 0.001f;
@ -1082,15 +950,9 @@ void TriangleSelectorGUI::update_render_data()
continue;
int tr_state = int(tr.get_state());
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel::Geometry &iva = tr.is_selected_by_seed_fill() ? iva_seed_fills_data[tr_state] :
tr.get_state() == EnforcerBlockerType::ENFORCER ? iva_enforcers_data :
iva_blockers_data;
#else
GLIndexedVertexArray &iva = tr.is_selected_by_seed_fill() ? m_iva_seed_fills[tr_state] :
tr.get_state() == EnforcerBlockerType::ENFORCER ? m_iva_enforcers :
m_iva_blockers;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
int &cnt = tr.is_selected_by_seed_fill() ? seed_fill_cnt[tr_state] :
tr.get_state() == EnforcerBlockerType::ENFORCER ? enf_cnt :
blc_cnt;
@ -1102,21 +964,13 @@ void TriangleSelectorGUI::update_render_data()
const Vec3f n = (v1 - v0).cross(v2 - v1).normalized();
// small value used to offset triangles along their normal to avoid z-fighting
const Vec3f offset_n = offset * n;
#if ENABLE_LEGACY_OPENGL_REMOVAL
iva.add_vertex(v0 + offset_n, n);
iva.add_vertex(v1 + offset_n, n);
iva.add_vertex(v2 + offset_n, n);
iva.add_triangle((unsigned int)cnt, (unsigned int)cnt + 1, (unsigned int)cnt + 2);
#else
iva.push_geometry(v0 + offset_n, n);
iva.push_geometry(v1 + offset_n, n);
iva.push_geometry(v2 + offset_n, n);
iva.push_triangle(cnt, cnt + 1, cnt + 2);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
cnt += 3;
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (!iva_enforcers_data.is_empty())
m_iva_enforcers.init_from(std::move(iva_enforcers_data));
if (!iva_blockers_data.is_empty())
@ -1127,94 +981,8 @@ void TriangleSelectorGUI::update_render_data()
}
update_paint_contour();
#else
for (auto *iva : {&m_iva_enforcers, &m_iva_blockers})
iva->finalize_geometry(true);
for (auto &iva : m_iva_seed_fills)
iva.finalize_geometry(true);
m_paint_contour.release_geometry();
std::vector<Vec2i> contour_edges = this->get_seed_fill_contour();
m_paint_contour.contour_vertices.reserve(contour_edges.size() * 6);
for (const Vec2i &edge : contour_edges) {
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(0)].v.x());
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(0)].v.y());
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(0)].v.z());
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(1)].v.x());
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(1)].v.y());
m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(1)].v.z());
}
m_paint_contour.contour_indices.assign(m_paint_contour.contour_vertices.size() / 3, 0);
std::iota(m_paint_contour.contour_indices.begin(), m_paint_contour.contour_indices.end(), 0);
m_paint_contour.contour_indices_size = m_paint_contour.contour_indices.size();
m_paint_contour.finalize_geometry();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void GLPaintContour::render() const
{
assert(m_contour_VBO_id != 0);
assert(m_contour_EBO_id != 0);
glsafe(::glLineWidth(4.0f));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_contour_VBO_id));
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), nullptr));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
if (this->contour_indices_size > 0) {
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_contour_EBO_id));
glsafe(::glDrawElements(GL_LINES, GLsizei(this->contour_indices_size), GL_UNSIGNED_INT, nullptr));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
void GLPaintContour::finalize_geometry()
{
assert(m_contour_VBO_id == 0);
assert(m_contour_EBO_id == 0);
if (!this->contour_vertices.empty()) {
glsafe(::glGenBuffers(1, &m_contour_VBO_id));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_contour_VBO_id));
glsafe(::glBufferData(GL_ARRAY_BUFFER, this->contour_vertices.size() * sizeof(float), this->contour_vertices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
this->contour_vertices.clear();
}
if (!this->contour_indices.empty()) {
glsafe(::glGenBuffers(1, &m_contour_EBO_id));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_contour_EBO_id));
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->contour_indices.size() * sizeof(unsigned int), this->contour_indices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
this->contour_indices.clear();
}
}
void GLPaintContour::release_geometry()
{
if (m_contour_VBO_id) {
glsafe(::glDeleteBuffers(1, &m_contour_VBO_id));
m_contour_VBO_id = 0;
}
if (m_contour_EBO_id) {
glsafe(::glDeleteBuffers(1, &m_contour_EBO_id));
m_contour_EBO_id = 0;
}
this->clear();
}
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
{
@ -1250,91 +1018,48 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
INVALID
};
#if ENABLE_LEGACY_OPENGL_REMOVAL
for (auto& va : m_varrays)
va.reset();
#else
for (auto& va : m_varrays)
va.release_geometry();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
std::array<int, 3> cnts;
::glScalef(1.01f, 1.01f, 1.01f);
#if ENABLE_LEGACY_OPENGL_REMOVAL
std::array<GLModel::Geometry, 3> varrays_data;
for (auto& data : varrays_data)
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
for (int tr_id=0; tr_id<int(m_triangles.size()); ++tr_id) {
const Triangle& tr = m_triangles[tr_id];
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel::Geometry* va = nullptr;
#else
GLIndexedVertexArray* va = nullptr;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
int* cnt = nullptr;
if (tr_id < m_orig_size_indices) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
va = &varrays_data[ORIGINAL];
#else
va = &m_varrays[ORIGINAL];
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
cnt = &cnts[ORIGINAL];
}
else if (tr.valid()) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
va = &varrays_data[SPLIT];
#else
va = &m_varrays[SPLIT];
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
cnt = &cnts[SPLIT];
}
else {
if (! m_show_invalid)
continue;
#if ENABLE_LEGACY_OPENGL_REMOVAL
va = &varrays_data[INVALID];
#else
va = &m_varrays[INVALID];
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
cnt = &cnts[INVALID];
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
for (int i = 0; i < 3; ++i) {
va->add_vertex(m_vertices[tr.verts_idxs[i]].v, Vec3f(0.0f, 0.0f, 1.0f));
}
va->add_uint_triangle((unsigned int)*cnt, (unsigned int)*cnt + 1, (unsigned int)*cnt + 2);
#else
for (int i = 0; i < 3; ++i)
va->push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]),
double(m_vertices[tr.verts_idxs[i]].v[1]),
double(m_vertices[tr.verts_idxs[i]].v[2]),
0., 0., 1.);
va->push_triangle(*cnt,
*cnt + 1,
*cnt + 2);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
*cnt += 3;
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
for (int i = 0; i < 3; ++i) {
if (!varrays_data[i].is_empty())
m_varrays[i].init_from(std::move(varrays_data[i]));
}
#else
// for (auto* iva : { &m_iva_enforcers, &m_iva_blockers })
// iva->finalize_geometry(true);
//
// for (auto& iva : m_iva_seed_fills)
// iva.finalize_geometry(true);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLShaderProgram* curr_shader = wxGetApp().get_current_shader();
if (curr_shader != nullptr)
curr_shader->stop_using();
@ -1346,11 +1071,9 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
const Camera& camera = wxGetApp().plater()->get_camera();
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
::glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
for (vtype i : {ORIGINAL, SPLIT, INVALID}) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel& va = m_varrays[i];
switch (i) {
case ORIGINAL: va.set_color({ 0.0f, 0.0f, 1.0f, 1.0f }); break;
@ -1358,32 +1081,17 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
case INVALID: va.set_color({ 1.0f, 1.0f, 0.0f, 1.0f }); break;
}
va.render();
#else
GLIndexedVertexArray& va = m_varrays[i];
va.finalize_geometry(true);
if (va.has_VBOs()) {
switch (i) {
case ORIGINAL : ::glColor3f(0.f, 0.f, 1.f); break;
case SPLIT : ::glColor3f(1.f, 0.f, 0.f); break;
case INVALID : ::glColor3f(1.f, 1.f, 0.f); break;
}
va.render();
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
::glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
}
if (curr_shader != nullptr)
curr_shader->start_using();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
#if ENABLE_LEGACY_OPENGL_REMOVAL
void TriangleSelectorGUI::update_paint_contour()
{
m_paint_contour.reset();
@ -1430,6 +1138,5 @@ void TriangleSelectorGUI::render_paint_contour(const Transform3d& matrix)
if (curr_shader != nullptr)
curr_shader->start_using();
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
} // namespace Slic3r::GUI

View File

@ -3,11 +3,7 @@
#include "GLGizmoBase.hpp"
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "slic3r/GUI/GLModel.hpp"
#else
#include "slic3r/GUI/3DScene.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include "libslic3r/ObjectID.hpp"
#include "libslic3r/TriangleSelector.hpp"
@ -33,59 +29,14 @@ enum class PainterGizmoType {
MMU_SEGMENTATION
};
#if !ENABLE_LEGACY_OPENGL_REMOVAL
class GLPaintContour
{
public:
GLPaintContour() = default;
void render() const;
inline bool has_VBO() const { return m_contour_EBO_id != 0; }
// Release the geometry data, release OpenGL VBOs.
void release_geometry();
// Finalize the initialization of the contour geometry and the indices, upload both to OpenGL VBO objects
// and possibly releasing it if it has been loaded into the VBOs.
void finalize_geometry();
void clear()
{
this->contour_vertices.clear();
this->contour_indices.clear();
this->contour_indices_size = 0;
}
std::vector<float> contour_vertices;
std::vector<int> contour_indices;
// When the triangle indices are loaded into the graphics card as Vertex Buffer Objects,
// the above mentioned std::vectors are cleared and the following variables keep their original length.
size_t contour_indices_size{0};
// IDs of the Vertex Array Objects, into which the geometry has been loaded.
// Zero if the VBOs are not sent to GPU yet.
GLuint m_contour_VBO_id{0};
GLuint m_contour_EBO_id{0};
};
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
class TriangleSelectorGUI : public TriangleSelector {
public:
explicit TriangleSelectorGUI(const TriangleMesh& mesh)
: TriangleSelector(mesh) {}
virtual ~TriangleSelectorGUI() = default;
#if ENABLE_LEGACY_OPENGL_REMOVAL
virtual void render(ImGuiWrapper* imgui, const Transform3d& matrix);
void render(const Transform3d& matrix) { this->render(nullptr, matrix); }
#else
// Render current selection. Transformation matrices are supposed
// to be already set.
virtual void render(ImGuiWrapper *imgui);
void render() { this->render(nullptr); }
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void request_update_render_data() { m_update_render_data = true; }
@ -103,29 +54,18 @@ protected:
private:
void update_render_data();
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_iva_enforcers;
GLModel m_iva_blockers;
std::array<GLModel, 3> m_iva_seed_fills;
#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
std::array<GLModel, 3> m_varrays;
#endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
#else
GLIndexedVertexArray m_iva_enforcers;
GLIndexedVertexArray m_iva_blockers;
std::array<GLIndexedVertexArray, 3> m_iva_seed_fills;
std::array<GLIndexedVertexArray, 3> m_varrays;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
protected:
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_paint_contour;
void update_paint_contour();
void render_paint_contour(const Transform3d& matrix);
#else
GLPaintContour m_paint_contour;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
@ -138,9 +78,6 @@ private:
ObjectID m_old_mo_id;
size_t m_old_volumes_size = 0;
void on_render() override {}
#if !ENABLE_RAYCAST_PICKING
void on_render_for_picking() override {}
#endif // !ENABLE_RAYCAST_PICKING
public:
GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
@ -211,13 +148,11 @@ protected:
bool m_paint_on_overhangs_only = false;
float m_highlight_by_angle_threshold_deg = 0.f;
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_circle;
#if !ENABLE_GL_CORE_PROFILE
Vec2d m_old_center{ Vec2d::Zero() };
#endif // !ENABLE_GL_CORE_PROFILE
float m_old_cursor_radius{ 0.0f };
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
static constexpr float SmartFillAngleMin = 0.0f;
static constexpr float SmartFillAngleMax = 90.f;
@ -251,11 +186,7 @@ private:
const Camera& camera,
const std::vector<Transform3d>& trafo_matrices) const;
#if ENABLE_LEGACY_OPENGL_REMOVAL
static std::shared_ptr<GLModel> s_sphere;
#else
static std::shared_ptr<GLIndexedVertexArray> s_sphere;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
bool m_internal_stack_active = false;
bool m_schedule_update = false;

View File

@ -179,18 +179,13 @@ void GLGizmoRotate::on_render()
glsafe(::glEnable(GL_DEPTH_TEST));
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_grabbers.front().matrix = local_transform(selection);
#else
glsafe(::glPushMatrix());
transform_to_local(selection);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_CORE_PROFILE
if (!OpenGLManager::get_gl_info().is_core_profile())
#endif // ENABLE_GL_CORE_PROFILE
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_CORE_PROFILE
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
#else
@ -228,61 +223,14 @@ void GLGizmoRotate::on_render()
render_grabber_connection(color, radius_changed);
shader->stop_using();
}
#else
glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color.data() : m_highlight_color.data()));
render_circle();
if (m_hover_id != -1) {
render_scale();
render_snap_radii();
render_reference_radius();
}
glsafe(::glColor4fv(m_highlight_color.data()));
if (m_hover_id != -1)
render_angle();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WORLD_COORDINATE
render_grabber(m_bounding_box);
#else
render_grabber(box);
#endif // ENABLE_WORLD_COORDINATE
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
#if !ENABLE_RAYCAST_PICKING
void GLGizmoRotate::on_render_for_picking()
{
const Selection& selection = m_parent.get_selection();
glsafe(::glDisable(GL_DEPTH_TEST));
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_grabbers.front().matrix = local_transform(selection);
#else
glsafe(::glPushMatrix());
transform_to_local(selection);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WORLD_COORDINATE
render_grabbers_for_picking(m_bounding_box);
#else
const BoundingBoxf3& box = selection.get_bounding_box();
render_grabbers_for_picking(box);
#endif // ENABLE_WORLD_COORDINATE
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
#endif // !ENABLE_RAYCAST_PICKING
#if ENABLE_WORLD_COORDINATE
void GLGizmoRotate::init_data_from_selection(const Selection& selection)
{
@ -363,13 +311,8 @@ void GLGizmoRotate3D::load_rotoptimize_state()
}
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_circle(const ColorRGBA& color, bool radius_changed)
#else
void GLGizmoRotate::render_circle() const
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (!m_circle.is_initialized() || radius_changed) {
m_circle.reset();
@ -390,29 +333,13 @@ void GLGizmoRotate::render_circle() const
m_circle.set_color(color);
m_circle.render();
#else
::glBegin(GL_LINE_LOOP);
for (unsigned int i = 0; i < ScaleStepsCount; ++i) {
const float angle = float(i) * ScaleStepRad;
const float x = ::cos(angle) * m_radius;
const float y = ::sin(angle) * m_radius;
const float z = 0.0f;
::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
}
glsafe(::glEnd());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_scale(const ColorRGBA& color, bool radius_changed)
#else
void GLGizmoRotate::render_scale() const
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
const float out_radius_long = m_snap_fine_out_radius;
const float out_radius_short = m_radius * (1.0f + 0.5f * ScaleLongTooth);
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (!m_scale.is_initialized() || radius_changed) {
m_scale.reset();
@ -444,36 +371,14 @@ void GLGizmoRotate::render_scale() const
m_scale.set_color(color);
m_scale.render();
#else
::glBegin(GL_LINES);
for (unsigned int i = 0; i < ScaleStepsCount; ++i) {
const float angle = (float)i * ScaleStepRad;
const float cosa = ::cos(angle);
const float sina = ::sin(angle);
const float in_x = cosa * m_radius;
const float in_y = sina * m_radius;
const float in_z = 0.0f;
const float out_x = (i % ScaleLongEvery == 0) ? cosa * out_radius_long : cosa * out_radius_short;
const float out_y = (i % ScaleLongEvery == 0) ? sina * out_radius_long : sina * out_radius_short;
const float out_z = 0.0f;
::glVertex3f((GLfloat)in_x, (GLfloat)in_y, (GLfloat)in_z);
::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z);
}
glsafe(::glEnd());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_snap_radii(const ColorRGBA& color, bool radius_changed)
#else
void GLGizmoRotate::render_snap_radii() const
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
const float step = 2.0f * float(PI) / float(SnapRegionsCount);
const float in_radius = m_radius / 3.0f;
const float out_radius = 2.0f * in_radius;
#if ENABLE_LEGACY_OPENGL_REMOVAL
if (!m_snap_radii.is_initialized() || radius_changed) {
m_snap_radii.reset();
@ -505,26 +410,8 @@ void GLGizmoRotate::render_snap_radii() const
m_snap_radii.set_color(color);
m_snap_radii.render();
#else
::glBegin(GL_LINES);
for (unsigned int i = 0; i < SnapRegionsCount; ++i) {
const float angle = (float)i * step;
const float cosa = ::cos(angle);
const float sina = ::sin(angle);
const float in_x = cosa * in_radius;
const float in_y = sina * in_radius;
const float in_z = 0.0f;
const float out_x = cosa * out_radius;
const float out_y = sina * out_radius;
const float out_z = 0.0f;
::glVertex3f((GLfloat)in_x, (GLfloat)in_y, (GLfloat)in_z);
::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z);
}
glsafe(::glEnd());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_reference_radius(const ColorRGBA& color, bool radius_changed)
{
if (!m_reference_radius.is_initialized() || radius_changed) {
@ -548,26 +435,12 @@ void GLGizmoRotate::render_reference_radius(const ColorRGBA& color, bool radius_
m_reference_radius.set_color(color);
m_reference_radius.render();
}
#else
void GLGizmoRotate::render_reference_radius() const
{
::glBegin(GL_LINES);
::glVertex3f(0.0f, 0.0f, 0.0f);
::glVertex3f((GLfloat)(m_radius * (1.0f + GrabberOffset)), 0.0f, 0.0f);
glsafe(::glEnd());
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_angle_arc(const ColorRGBA& color, bool radius_changed)
#else
void GLGizmoRotate::render_angle() const
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
const float step_angle = float(m_angle) / float(AngleResolution);
const float ex_radius = m_radius * (1.0f + GrabberOffset);
#if ENABLE_LEGACY_OPENGL_REMOVAL
const bool angle_changed = std::abs(m_old_angle - m_angle) > EPSILON;
m_old_angle = m_angle;
@ -592,20 +465,8 @@ void GLGizmoRotate::render_angle() const
m_angle_arc.set_color(color);
m_angle_arc.render();
#else
::glBegin(GL_LINE_STRIP);
for (unsigned int i = 0; i <= AngleResolution; ++i) {
const float angle = float(i) * step_angle;
const float x = ::cos(angle) * ex_radius;
const float y = ::sin(angle) * ex_radius;
const float z = 0.0f;
::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
}
glsafe(::glEnd());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radius_changed)
{
if (!m_grabber_connection.model.is_initialized() || radius_changed || !m_grabber_connection.old_center.isApprox(m_grabbers.front().center)) {
@ -630,28 +491,13 @@ void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radiu
m_grabber_connection.model.set_color(color);
m_grabber_connection.model.render();
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_grabber(const BoundingBoxf3& box)
{
#if !ENABLE_LEGACY_OPENGL_REMOVAL
const double grabber_radius = double(m_radius) * (1.0 + double(GrabberOffset));
m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0);
m_grabbers[0].angles.z() = m_angle;
glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color.data() : m_highlight_color.data()));
::glBegin(GL_LINES);
::glVertex3f(0.0f, 0.0f, 0.0f);
::glVertex3dv(m_grabbers[0].center.data());
glsafe(::glEnd());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
m_grabbers.front().color = m_highlight_color;
render_grabbers(box);
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
Transform3d GLGizmoRotate::local_transform(const Selection& selection) const
{
Transform3d ret;
@ -693,43 +539,6 @@ Transform3d GLGizmoRotate::local_transform(const Selection& selection) const
return Geometry::assemble_transform(m_center) * ret;
#endif // ENABLE_WORLD_COORDINATE
}
#else
void GLGizmoRotate::transform_to_local(const Selection& selection) const
{
glsafe(::glTranslated(m_center.x(), m_center.y(), m_center.z()));
#if ENABLE_WORLD_COORDINATE
glsafe(::glMultMatrixd(m_orient_matrix.data()));
#else
if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes()) {
const Transform3d orient_matrix = selection.get_first_volume()->get_instance_transformation().get_matrix(true, false, true, true);
glsafe(::glMultMatrixd(orient_matrix.data()));
}
#endif // ENABLE_WORLD_COORDINATE
switch (m_axis)
{
case X:
{
glsafe(::glRotatef(90.0f, 0.0f, 1.0f, 0.0f));
glsafe(::glRotatef(-90.0f, 0.0f, 0.0f, 1.0f));
break;
}
case Y:
{
glsafe(::glRotatef(-90.0f, 0.0f, 0.0f, 1.0f));
glsafe(::glRotatef(-90.0f, 0.0f, 1.0f, 0.0f));
break;
}
default:
case Z:
{
// no rotation
break;
}
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WORLD_COORDINATE
Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray) const
@ -906,7 +715,6 @@ void GLGizmoRotate3D::on_render()
m_gizmos[Z].render();
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoRotate3D::on_register_raycasters_for_picking()
{
// the gizmo grabbers are rendered on top of the scene, so the raytraced picker should take it into account
@ -923,7 +731,6 @@ void GLGizmoRotate3D::on_unregister_raycasters_for_picking()
}
m_parent.set_raycaster_gizmos_on_top(false);
}
#endif // ENABLE_RAYCAST_PICKING
GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper * imgui,
State & state,

View File

@ -40,7 +40,6 @@ private:
Transform3d m_orient_matrix{ Transform3d::Identity() };
#endif // ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_circle;
GLModel m_scale;
GLModel m_snap_radii;
@ -55,7 +54,6 @@ private:
float m_old_radius{ 0.0f };
float m_old_hover_radius{ 0.0f };
float m_old_angle{ 0.0f };
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// emboss need to draw rotation gizmo in local coordinate systems
bool m_using_local_coordinate{false};
@ -98,32 +96,17 @@ protected:
void on_start_dragging() override;
void on_dragging(const UpdateData &data) override;
void on_render() override;
#if !ENABLE_RAYCAST_PICKING
void on_render_for_picking() override;
#endif // !ENABLE_RAYCAST_PICKING
private:
#if ENABLE_LEGACY_OPENGL_REMOVAL
void render_circle(const ColorRGBA& color, bool radius_changed);
void render_scale(const ColorRGBA& color, bool radius_changed);
void render_snap_radii(const ColorRGBA& color, bool radius_changed);
void render_reference_radius(const ColorRGBA& color, bool radius_changed);
void render_angle_arc(const ColorRGBA& color, bool radius_changed);
void render_grabber_connection(const ColorRGBA& color, bool radius_changed);
#else
void render_circle() const;
void render_scale() const;
void render_snap_radii() const;
void render_reference_radius() const;
void render_angle() const;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void render_grabber(const BoundingBoxf3& box);
#if ENABLE_LEGACY_OPENGL_REMOVAL
Transform3d local_transform(const Selection& selection) const;
#else
void transform_to_local(const Selection& selection) const;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate
#if ENABLE_WORLD_COORDINATE
@ -189,16 +172,8 @@ protected:
void on_dragging(const UpdateData &data) override;
void on_render() override;
#if ENABLE_RAYCAST_PICKING
virtual void on_register_raycasters_for_picking() override;
virtual void on_unregister_raycasters_for_picking() override;
#else
void on_render_for_picking() override {
for (GLGizmoRotate& g : m_gizmos) {
g.render_for_picking();
}
}
#endif // ENABLE_RAYCAST_PICKING
void on_render_input_window(float x, float y, float bottom_limit) override;

View File

@ -5,9 +5,7 @@
#if ENABLE_WORLD_COORDINATE
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
#endif // ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "slic3r/GUI/Plater.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include "libslic3r/Model.hpp"
#include <GL/glew.h>
@ -29,7 +27,6 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filen
, m_drag_color(DEFAULT_DRAG_COLOR)
, m_highlight_color(DEFAULT_HIGHLIGHT_COLOR)
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_grabber_connections[0].grabber_indices = { 0, 1 };
m_grabber_connections[1].grabber_indices = { 2, 3 };
m_grabber_connections[2].grabber_indices = { 4, 5 };
@ -37,7 +34,6 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filen
m_grabber_connections[4].grabber_indices = { 7, 8 };
m_grabber_connections[5].grabber_indices = { 8, 9 };
m_grabber_connections[6].grabber_indices = { 9, 6 };
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
std::string GLGizmoScale3D::get_tooltip() const
@ -380,15 +376,10 @@ void GLGizmoScale3D::on_render()
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
#if ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Transform3d base_matrix = local_transform(selection);
for (int i = 0; i < 10; ++i) {
m_grabbers[i].matrix = base_matrix;
}
#else
glsafe(::glPushMatrix());
transform_to_local(selection);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const float grabber_mean_size = (float)((m_bounding_box.size().x() + m_bounding_box.size().y() + m_bounding_box.size().z()) / 3.0);
#else
@ -397,7 +388,6 @@ void GLGizmoScale3D::on_render()
#endif // ENABLE_WORLD_COORDINATE
if (m_hover_id == -1) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
// draw connections
#if ENABLE_GL_CORE_PROFILE
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
@ -431,32 +421,11 @@ void GLGizmoScale3D::on_render()
render_grabbers_connection(9, 6, m_base_color);
shader->stop_using();
}
#else
// draw connections
if (m_grabbers[0].enabled && m_grabbers[1].enabled) {
glsafe(::glColor4fv(m_grabbers[0].color.data()));
render_grabbers_connection(0, 1);
}
if (m_grabbers[2].enabled && m_grabbers[3].enabled) {
glsafe(::glColor4fv(m_grabbers[2].color.data()));
render_grabbers_connection(2, 3);
}
if (m_grabbers[4].enabled && m_grabbers[5].enabled) {
glsafe(::glColor4fv(m_grabbers[4].color.data()));
render_grabbers_connection(4, 5);
}
glsafe(::glColor4fv(m_base_color.data()));
render_grabbers_connection(6, 7);
render_grabbers_connection(7, 8);
render_grabbers_connection(8, 9);
render_grabbers_connection(9, 6);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// draw grabbers
render_grabbers(grabber_mean_size);
}
else if ((m_hover_id == 0 || m_hover_id == 1) && m_grabbers[0].enabled && m_grabbers[1].enabled) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
// draw connections
#if ENABLE_GL_CORE_PROFILE
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
@ -484,14 +453,6 @@ void GLGizmoScale3D::on_render()
// draw grabbers
shader = wxGetApp().get_shader("gouraud_light");
#else
// draw connection
glsafe(::glColor4fv(AXES_COLOR[0].data()));
render_grabbers_connection(0, 1);
// draw grabbers
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@ -501,7 +462,6 @@ void GLGizmoScale3D::on_render()
}
}
else if ((m_hover_id == 2 || m_hover_id == 3) && m_grabbers[2].enabled && m_grabbers[3].enabled) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
// draw connections
#if ENABLE_GL_CORE_PROFILE
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
@ -529,14 +489,6 @@ void GLGizmoScale3D::on_render()
// draw grabbers
shader = wxGetApp().get_shader("gouraud_light");
#else
// draw connection
glsafe(::glColor4fv(AXES_COLOR[1].data()));
render_grabbers_connection(2, 3);
// draw grabbers
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@ -546,7 +498,6 @@ void GLGizmoScale3D::on_render()
}
}
else if ((m_hover_id == 4 || m_hover_id == 5) && m_grabbers[4].enabled && m_grabbers[5].enabled) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
// draw connections
#if ENABLE_GL_CORE_PROFILE
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
@ -574,14 +525,6 @@ void GLGizmoScale3D::on_render()
// draw grabbers
shader = wxGetApp().get_shader("gouraud_light");
#else
// draw connection
glsafe(::glColor4fv(AXES_COLOR[2].data()));
render_grabbers_connection(4, 5);
// draw grabbers
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@ -591,7 +534,6 @@ void GLGizmoScale3D::on_render()
}
}
else if (m_hover_id >= 6) {
#if ENABLE_LEGACY_OPENGL_REMOVAL
// draw connections
#if ENABLE_GL_CORE_PROFILE
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
@ -622,17 +564,6 @@ void GLGizmoScale3D::on_render()
// draw grabbers
shader = wxGetApp().get_shader("gouraud_light");
#else
// draw connection
glsafe(::glColor4fv(m_drag_color.data()));
render_grabbers_connection(6, 7);
render_grabbers_connection(7, 8);
render_grabbers_connection(8, 9);
render_grabbers_connection(9, 6);
// draw grabbers
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@ -642,15 +573,8 @@ void GLGizmoScale3D::on_render()
shader->stop_using();
}
}
#if ENABLE_WORLD_COORDINATE
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#endif // ENABLE_WORLD_COORDINATE
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoScale3D::on_register_raycasters_for_picking()
{
// the gizmo grabbers are rendered on top of the scene, so the raytraced picker should take it into account
@ -661,31 +585,7 @@ void GLGizmoScale3D::on_unregister_raycasters_for_picking()
{
m_parent.set_raycaster_gizmos_on_top(false);
}
#else
void GLGizmoScale3D::on_render_for_picking()
{
glsafe(::glDisable(GL_DEPTH_TEST));
#if ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Transform3d base_matrix = local_transform(m_parent.get_selection());
for (int i = 0; i < 10; ++i) {
m_grabbers[i].matrix = base_matrix;
}
#else
glsafe(::glPushMatrix());
transform_to_local(m_parent.get_selection());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
render_grabbers_for_picking(m_bounding_box);
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#else
render_grabbers_for_picking(m_parent.get_selection().get_bounding_box());
#endif // ENABLE_WORLD_COORDINATE
}
#endif // !ENABLE_RAYCAST_PICKING
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int id_2, const ColorRGBA& color)
{
auto grabber_connection = [this](unsigned int id_1, unsigned int id_2) {
@ -725,18 +625,6 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int
m_grabber_connections[id].model.set_color(color);
m_grabber_connections[id].model.render();
}
#else
void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int id_2) const
{
unsigned int grabbers_count = (unsigned int)m_grabbers.size();
if (id_1 < grabbers_count && id_2 < grabbers_count) {
::glBegin(GL_LINES);
::glVertex3dv(m_grabbers[id_1].center.data());
::glVertex3dv(m_grabbers[id_2].center.data());
glsafe(::glEnd());
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WORLD_COORDINATE
void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
@ -908,7 +796,6 @@ double GLGizmoScale3D::calc_ratio(const UpdateData& data) const
}
#if ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
Transform3d GLGizmoScale3D::local_transform(const Selection& selection) const
{
Transform3d ret = Geometry::translation_transform(m_center);
@ -921,19 +808,6 @@ Transform3d GLGizmoScale3D::local_transform(const Selection& selection) const
}
return ret;
}
#else
void GLGizmoScale3D::transform_to_local(const Selection& selection) const
{
glsafe(::glTranslated(m_center.x(), m_center.y(), m_center.z()));
if (!wxGetApp().obj_manipul()->is_world_coordinates()) {
Transform3d orient_matrix = selection.get_first_volume()->get_instance_transformation().get_matrix(true, false, true, true);
if (selection.is_single_volume_or_modifier() && wxGetApp().obj_manipul()->is_local_coordinates())
orient_matrix = orient_matrix * selection.get_first_volume()->get_volume_transformation().get_matrix(true, false, true, true);
glsafe(::glMultMatrixd(orient_matrix.data()));
}
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#endif // ENABLE_WORLD_COORDINATE
} // namespace GUI

View File

@ -48,7 +48,6 @@ class GLGizmoScale3D : public GLGizmoBase
double m_snap_step{ 0.05 };
StartingData m_starting;
#if ENABLE_LEGACY_OPENGL_REMOVAL
struct GrabberConnection
{
GLModel model;
@ -57,7 +56,6 @@ class GLGizmoScale3D : public GLGizmoBase
Vec3d old_v2{ Vec3d::Zero() };
};
std::array<GrabberConnection, 7> m_grabber_connections;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
ColorRGBA m_base_color;
ColorRGBA m_drag_color;
@ -94,30 +92,18 @@ protected:
virtual void on_stop_dragging() override;
virtual void on_dragging(const UpdateData& data) override;
virtual void on_render() override;
#if ENABLE_RAYCAST_PICKING
virtual void on_register_raycasters_for_picking() override;
virtual void on_unregister_raycasters_for_picking() override;
#else
virtual void on_render_for_picking() override;
#endif // ENABLE_RAYCAST_PICKING
private:
#if ENABLE_LEGACY_OPENGL_REMOVAL
void render_grabbers_connection(unsigned int id_1, unsigned int id_2, const ColorRGBA& color);
#else
void render_grabbers_connection(unsigned int id_1, unsigned int id_2) const;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void do_scale_along_axis(Axis axis, const UpdateData& data);
void do_scale_uniform(const UpdateData& data);
double calc_ratio(const UpdateData& data) const;
#if ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
Transform3d local_transform(const Selection& selection) const;
#else
void transform_to_local(const Selection& selection) const;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#endif // ENABLE_WORLD_COORDINATE
};

View File

@ -650,25 +650,13 @@ void GLGizmoSimplify::init_model()
}
assert(volume != nullptr);
#if ENABLE_LEGACY_OPENGL_REMOVAL
// set actual triangle count
m_triangle_count += volume->mesh().its.indices.size();
#else
const indexed_triangle_set &its = volume->mesh().its;
// set actual triangle count
m_triangle_count += its.indices.size();
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
assert(m_glmodels.find(id) == m_glmodels.end());
GLModel &glmodel = m_glmodels[id]; // create new glmodel
#if ENABLE_LEGACY_OPENGL_REMOVAL
glmodel.init_from(volume->mesh());
glmodel.set_color(selected_volume->color);
#else
glmodel.init_from(its);
glmodel.set_color(-1,selected_volume->color);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_parent.toggle_model_objects_visibility(false, info->model_object(),
info->get_active_instance(),
@ -720,11 +708,7 @@ void GLGizmoSimplify::update_model(const State::Data &data)
#else
glmodel.init_from(its);
#endif // ENABLE_OPENGL_ES
#if ENABLE_LEGACY_OPENGL_REMOVAL
glmodel.set_color(color);
#else
glmodel.set_color(-1, color);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_triangle_count += its.indices.size();
}
@ -759,10 +743,6 @@ void GLGizmoSimplify::on_render()
GLModel &glmodel = it->second;
const Transform3d trafo_matrix = selected_volume->world_matrix();
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPushMatrix());
glsafe(::glMultMatrixd(trafo_matrix.data()));
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
auto* gouraud_shader = wxGetApp().get_shader("gouraud_light");
#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES
bool depth_test_enabled = ::glIsEnabled(GL_DEPTH_TEST);
@ -771,7 +751,6 @@ void GLGizmoSimplify::on_render()
#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES
glsafe(::glEnable(GL_DEPTH_TEST));
gouraud_shader->start_using();
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
const Transform3d view_model_matrix = view_matrix * trafo_matrix;
@ -779,7 +758,6 @@ void GLGizmoSimplify::on_render()
gouraud_shader->set_uniform("projection_matrix", camera.get_projection_matrix());
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * trafo_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
gouraud_shader->set_uniform("view_normal_matrix", view_normal_matrix);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glmodel.render();
gouraud_shader->stop_using();
@ -791,12 +769,10 @@ void GLGizmoSimplify::on_render()
#endif // ENABLE_OPENGL_ES
contour_shader->start_using();
contour_shader->set_uniform("offset", OpenGLManager::get_gl_info().is_mesa() ? 0.0005 : 0.00001);
#if ENABLE_LEGACY_OPENGL_REMOVAL
contour_shader->set_uniform("view_model_matrix", view_model_matrix);
contour_shader->set_uniform("projection_matrix", camera.get_projection_matrix());
const ColorRGBA color = glmodel.get_color();
glmodel.set_color(ColorRGBA::WHITE());
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_CORE_PROFILE
if (!OpenGLManager::get_gl_info().is_core_profile())
#endif // ENABLE_GL_CORE_PROFILE
@ -808,9 +784,7 @@ void GLGizmoSimplify::on_render()
#if !ENABLE_OPENGL_ES
glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL));
#endif // !ENABLE_OPENGL_ES
#if ENABLE_LEGACY_OPENGL_REMOVAL
glmodel.set_color(color);
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
contour_shader->stop_using();
}
#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES
@ -819,9 +793,6 @@ void GLGizmoSimplify::on_render()
#else
glsafe(::glPopAttrib());
#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
}

View File

@ -38,9 +38,6 @@ protected:
// must implement
virtual bool on_init() override { return true;};
virtual void on_render() override;
#if !ENABLE_RAYCAST_PICKING
virtual void on_render_for_picking() override{};
#endif // !ENABLE_RAYCAST_PICKING
CommonGizmosDataID on_get_requirements() const override;

View File

@ -22,10 +22,8 @@
#include "libslic3r/PresetBundle.hpp"
#include "libslic3r/SLAPrint.hpp"
#if ENABLE_RAYCAST_PICKING
static const double CONE_RADIUS = 0.25;
static const double CONE_HEIGHT = 0.75;
#endif // ENABLE_RAYCAST_PICKING
namespace Slic3r {
namespace GUI {
@ -51,12 +49,6 @@ bool GLGizmoSlaSupports::on_init()
m_desc["clipping_of_view"] = _L("Clipping of view")+ ": ";
m_desc["reset_direction"] = _L("Reset direction");
#if !ENABLE_RAYCAST_PICKING
m_cone.init_from(its_make_cone(1., 1., 2 * PI / 24));
m_cylinder.init_from(its_make_cylinder(1., 1., 2 * PI / 24.));
m_sphere.init_from(its_make_sphere(1., (2 * M_PI) / 24.));
#endif // !ENABLE_RAYCAST_PICKING
return true;
}
@ -79,12 +71,10 @@ void GLGizmoSlaSupports::data_changed()
if (mo->sla_points_status == sla::PointsStatus::Generating)
get_data_from_backend();
#if ENABLE_RAYCAST_PICKING
if (m_raycasters.empty())
on_register_raycasters_for_picking();
else
update_raycasters_for_picking_transform();
#endif // ENABLE_RAYCAST_PICKING
}
}
@ -92,7 +82,6 @@ void GLGizmoSlaSupports::data_changed()
void GLGizmoSlaSupports::on_render()
{
#if ENABLE_RAYCAST_PICKING
if (!m_sphere.model.is_initialized()) {
indexed_triangle_set its = its_make_sphere(1.0, double(PI) / 12.0);
m_sphere.model.init_from(its);
@ -103,12 +92,6 @@ void GLGizmoSlaSupports::on_render()
m_cone.model.init_from(its);
m_cone.mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
}
#else
if (!m_cone.is_initialized())
m_cone.init_from(its_make_cone(1.0, 1.0, double(PI) / 12.0));
if (!m_sphere.is_initialized())
m_sphere.init_from(its_make_sphere(1.0, double(PI) / 12.0));
#endif // ENABLE_RAYCAST_PICKING
if (!m_cylinder.is_initialized())
m_cylinder.init_from(its_make_cylinder(1.0, 1.0, double(PI) / 12.0));
@ -127,11 +110,7 @@ void GLGizmoSlaSupports::on_render()
glsafe(::glEnable(GL_DEPTH_TEST));
if (selection.is_from_single_instance())
#if ENABLE_RAYCAST_PICKING
render_points(selection);
#else
render_points(selection, false);
#endif // ENABLE_RAYCAST_PICKING
m_selection_rectangle.render(m_parent);
m_c->object_clipper()->render_cut();
@ -140,7 +119,6 @@ void GLGizmoSlaSupports::on_render()
glsafe(::glDisable(GL_BLEND));
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoSlaSupports::on_register_raycasters_for_picking()
{
assert(m_raycasters.empty());
@ -161,20 +139,8 @@ void GLGizmoSlaSupports::on_unregister_raycasters_for_picking()
m_raycasters.clear();
set_sla_auxiliary_volumes_picking_state(true);
}
#else
void GLGizmoSlaSupports::on_render_for_picking()
{
const Selection& selection = m_parent.get_selection();
//glsafe(::glEnable(GL_DEPTH_TEST));
render_points(selection, true);
}
#endif // ENABLE_RAYCAST_PICKING
#if ENABLE_RAYCAST_PICKING
void GLGizmoSlaSupports::render_points(const Selection& selection)
#else
void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
#endif // ENABLE_RAYCAST_PICKING
{
const size_t cache_size = m_editing_mode ? m_editing_cache.size() : m_normal_cache.size();
@ -185,26 +151,12 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
if (! has_points && ! has_holes)
return;
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#else
GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light");
#endif // ENABLE_RAYCAST_PICKING
if (shader == nullptr)
return;
shader->start_using();
ScopeGuard guard([shader]() { shader->stop_using(); });
#else
GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_shader("gouraud_light");
if (shader != nullptr)
shader->start_using();
ScopeGuard guard([shader]() {
if (shader != nullptr)
shader->stop_using();
});
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const GLVolume* vol = selection.get_first_volume();
const Geometry::Transformation transformation(vol->world_matrix());
@ -213,24 +165,15 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
#else
const Transform3d& instance_scaling_matrix_inverse = transformation.get_matrix(true, true, false, true).inverse();
#endif // ENABLE_WORLD_COORDINATE
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
#else
const Transform3d& instance_matrix = transformation.get_matrix();
const float z_shift = m_c->selection_info()->get_sla_shift();
glsafe(::glPushMatrix());
glsafe(::glTranslated(0.0, 0.0, z_shift));
glsafe(::glMultMatrixd(instance_matrix.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
ColorRGBA render_color;
for (size_t i = 0; i < cache_size; ++i) {
const sla::SupportPoint& support_point = m_editing_mode ? m_editing_cache[i].support_point : m_normal_cache[i];
const bool point_selected = m_editing_mode ? m_editing_cache[i].selected : false;
#if ENABLE_RAYCAST_PICKING
const bool clipped = is_mesh_point_clipped(support_point.pos.cast<double>());
if (!m_raycasters.empty()) {
m_raycasters[i].first->set_active(!clipped);
@ -238,17 +181,8 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
}
if (clipped)
continue;
#else
if (is_mesh_point_clipped(support_point.pos.cast<double>()))
continue;
#endif // ENABLE_RAYCAST_PICKING
// First decide about the color of the point.
#if !ENABLE_RAYCAST_PICKING
if (picking)
render_color = picking_color_component(i);
else {
#endif // !ENABLE_RAYCAST_PICKING
if (size_t(m_hover_id) == i && m_editing_mode) // ignore hover state unless editing mode is active
render_color = { 0.f, 1.f, 1.f, 1.f };
else { // neigher hover nor picking
@ -265,36 +199,13 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
else
render_color = { 0.5f, 0.5f, 0.5f, 1.f };
}
#if !ENABLE_RAYCAST_PICKING
}
#endif // !ENABLE_RAYCAST_PICKING
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
m_cone.model.set_color(render_color);
m_sphere.model.set_color(render_color);
#else
m_cone.set_color(render_color);
m_sphere.set_color(render_color);
#endif // ENABLE_RAYCAST_PICKING
#if !ENABLE_RAYCAST_PICKING
if (!picking)
#endif // !ENABLE_RAYCAST_PICKING
#else
m_cone.set_color(-1, render_color);
m_sphere.set_color(-1, render_color);
if (shader && !picking)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
shader->set_uniform("emission_factor", 0.5f);
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Transform3d support_matrix = Geometry::translation_transform(support_point.pos.cast<double>()) * instance_scaling_matrix_inverse;
#else
glsafe(::glPushMatrix());
glsafe(::glTranslatef(support_point.pos.x(), support_point.pos.y(), support_point.pos.z()));
glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (vol->is_left_handed())
glsafe(::glFrontFace(GL_CW));
@ -309,93 +220,37 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
Eigen::Quaterniond q;
q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast<double>());
const Eigen::AngleAxisd aa(q);
#if !ENABLE_RAYCAST_PICKING
const double cone_radius = 0.25; // mm
const double cone_height = 0.75;
#endif // !ENABLE_RAYCAST_PICKING
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Transform3d model_matrix = vol->world_matrix() * support_matrix * Transform3d(aa.toRotationMatrix()) *
#if ENABLE_RAYCAST_PICKING
Geometry::translation_transform((CONE_HEIGHT + support_point.head_front_radius * RenderPointScale) * Vec3d::UnitZ()) *
Geometry::rotation_transform({ double(PI), 0.0, 0.0 }) * Geometry::scale_transform({ CONE_RADIUS, CONE_RADIUS, CONE_HEIGHT });
#else
Geometry::translation_transform((cone_height + support_point.head_front_radius * RenderPointScale) * Vec3d::UnitZ()) *
Geometry::rotation_transform({ double(PI), 0.0, 0.0 }), * Geometry::scale_transform({ cone_radius, cone_radius, cone_height });
#endif // ENABLE_RAYCAST_PICKING
shader->set_uniform("view_model_matrix", view_matrix * model_matrix);
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);
#else
glsafe(::glPushMatrix());
glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis().x(), aa.axis().y(), aa.axis().z()));
glsafe(::glTranslatef(0.f, 0.f, cone_height + support_point.head_front_radius * RenderPointScale));
glsafe(::glRotated(180., 1., 0., 0.));
glsafe(::glScaled(cone_radius, cone_radius, cone_height));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
m_cone.model.render();
#else
m_cone.render();
#endif // ENABLE_RAYCAST_PICKING
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
const double radius = (double)support_point.head_front_radius * RenderPointScale;
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Transform3d model_matrix = vol->world_matrix() * support_matrix * Geometry::scale_transform(radius);
shader->set_uniform("view_model_matrix", view_matrix * model_matrix);
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);
#else
glsafe(::glPushMatrix());
glsafe(::glScaled(radius, radius, radius));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_RAYCAST_PICKING
m_sphere.model.render();
#else
m_sphere.render();
#endif // ENABLE_RAYCAST_PICKING
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
if (vol->is_left_handed())
glsafe(::glFrontFace(GL_CCW));
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
// Now render the drain holes:
#if ENABLE_RAYCAST_PICKING
if (has_holes) {
#else
if (has_holes && ! picking) {
#endif // ENABLE_RAYCAST_PICKING
render_color = { 0.7f, 0.7f, 0.7f, 0.7f };
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_cylinder.set_color(render_color);
#else
m_cylinder.set_color(-1, render_color);
if (shader != nullptr)
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
shader->set_uniform("emission_factor", 0.5f);
for (const sla::DrainHole& drain_hole : m_c->selection_info()->model_object()->sla_drain_holes) {
if (is_mesh_point_clipped(drain_hole.pos.cast<double>()))
continue;
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Transform3d hole_matrix = Geometry::translation_transform(drain_hole.pos.cast<double>()) * instance_scaling_matrix_inverse;
#else
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
glsafe(::glPushMatrix());
glsafe(::glTranslatef(drain_hole.pos.x(), drain_hole.pos.y(), drain_hole.pos.z()));
glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (vol->is_left_handed())
glsafe(::glFrontFace(GL_CW));
@ -404,30 +259,17 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
Eigen::Quaterniond q;
q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * (-drain_hole.normal).cast<double>());
const Eigen::AngleAxisd aa(q);
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Transform3d model_matrix = vol->world_matrix() * hole_matrix * Transform3d(aa.toRotationMatrix()) *
Geometry::translation_transform(-drain_hole.height * Vec3d::UnitZ()) * Geometry::scale_transform(Vec3d(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength));
shader->set_uniform("view_model_matrix", view_matrix * model_matrix);
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);
#else
glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis().x(), aa.axis().y(), aa.axis().z()));
glsafe(::glTranslated(0., 0., -drain_hole.height));
glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_cylinder.render();
if (vol->is_left_handed())
glsafe(::glFrontFace(GL_CCW));
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
}
#if !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopMatrix());
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
@ -544,10 +386,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
m_editing_cache.emplace_back(sla::SupportPoint(pos_and_normal.first, m_new_point_head_diameter/2.f, false), false, pos_and_normal.second);
m_parent.set_as_dirty();
m_wait_for_up_event = true;
#if ENABLE_RAYCAST_PICKING
on_unregister_raycasters_for_picking();
on_register_raycasters_for_picking();
#endif // ENABLE_RAYCAST_PICKING
}
else
return false;
@ -572,12 +412,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
// Now ask the rectangle which of the points are inside.
std::vector<Vec3f> points_inside;
#if ENABLE_RAYCAST_PICKING
std::vector<unsigned int> points_idxs = m_selection_rectangle.contains(points);
m_selection_rectangle.stop_dragging();
#else
std::vector<unsigned int> points_idxs = m_selection_rectangle.stop_dragging(m_parent, points);
#endif // ENABLE_RAYCAST_PICKING
for (size_t idx : points_idxs)
points_inside.push_back(points[idx].cast<float>());
@ -707,10 +543,8 @@ void GLGizmoSlaSupports::delete_selected_points(bool force)
}
}
#if ENABLE_RAYCAST_PICKING
on_unregister_raycasters_for_picking();
on_register_raycasters_for_picking();
#endif // ENABLE_RAYCAST_PICKING
select_point(NoPoints);
}
@ -1390,9 +1224,7 @@ void GLGizmoSlaSupports::switch_to_editing_mode()
for (const sla::SupportPoint& sp : m_normal_cache)
m_editing_cache.emplace_back(sp);
select_point(NoPoints);
#if ENABLE_RAYCAST_PICKING
on_register_raycasters_for_picking();
#endif // ENABLE_RAYCAST_PICKING
m_c->instances_hider()->show_supports(false);
m_parent.set_as_dirty();
@ -1406,9 +1238,7 @@ void GLGizmoSlaSupports::disable_editing_mode()
wxGetApp().plater()->leave_gizmos_stack();
m_c->instances_hider()->show_supports(true);
m_parent.set_as_dirty();
#if ENABLE_RAYCAST_PICKING
on_unregister_raycasters_for_picking();
#endif // ENABLE_RAYCAST_PICKING
}
wxGetApp().plater()->get_notification_manager()->close_notification_of_type(NotificationType::QuitSLAManualMode);
}
@ -1427,7 +1257,6 @@ bool GLGizmoSlaSupports::unsaved_changes() const
return false;
}
#if ENABLE_RAYCAST_PICKING
void GLGizmoSlaSupports::set_sla_auxiliary_volumes_picking_state(bool state)
{
std::vector<std::shared_ptr<SceneRaycasterItem>>* raycasters = m_parent.get_raycasters_for_picking(SceneRaycaster::EType::Volume);
@ -1473,7 +1302,6 @@ void GLGizmoSlaSupports::update_raycasters_for_picking_transform()
}
}
}
#endif // ENABLE_RAYCAST_PICKING
SlaGizmoHelpDialog::SlaGizmoHelpDialog()
: wxDialog(nullptr, wxID_ANY, _L("SLA gizmo keyboard shortcuts"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)

View File

@ -81,23 +81,13 @@ public:
private:
bool on_init() override;
void on_render() override;
#if ENABLE_RAYCAST_PICKING
virtual void on_register_raycasters_for_picking() override;
virtual void on_unregister_raycasters_for_picking() override;
#else
void on_render_for_picking() override;
#endif // ENABLE_RAYCAST_PICKING
#if ENABLE_RAYCAST_PICKING
void render_points(const Selection& selection);
#else
void render_points(const Selection& selection, bool picking = false);
#endif // ENABLE_RAYCAST_PICKING
bool unsaved_changes() const;
#if ENABLE_RAYCAST_PICKING
void set_sla_auxiliary_volumes_picking_state(bool state);
void update_raycasters_for_picking_transform();
#endif // ENABLE_RAYCAST_PICKING
bool m_lock_unique_islands = false;
bool m_editing_mode = false; // Is editing mode active?
@ -110,14 +100,9 @@ private:
std::vector<sla::SupportPoint> m_normal_cache; // to restore after discarding changes or undo/redo
ObjectID m_old_mo_id;
#if ENABLE_RAYCAST_PICKING
PickingModel m_sphere;
PickingModel m_cone;
std::vector<std::pair<std::shared_ptr<SceneRaycasterItem>, std::shared_ptr<SceneRaycasterItem>>> m_raycasters;
#else
GLModel m_cone;
GLModel m_sphere;
#endif // ENABLE_RAYCAST_PICKING
GLModel m_cylinder;
// This map holds all translated description texts, so they can be easily referenced during layout calculations

Some files were not shown because too many files have changed in this diff Show More