mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-24 07:03:59 -06:00
Tech ENABLE_LEGACY_OPENGL_REMOVAL - porting remaining changes
(cherry picked from commit prusa3d/PrusaSlicer@2f572d3cf0 )
This commit is contained in:
parent
9f4713eee8
commit
71fd4084c2
68 changed files with 2145 additions and 1837 deletions
12
resources/shaders/background_attr.vs
Normal file
12
resources/shaders/background_attr.vs
Normal file
|
@ -0,0 +1,12 @@
|
|||
#version 110
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec2 v_tex_coord;
|
||||
|
||||
varying vec2 tex_coord;
|
||||
|
||||
void main()
|
||||
{
|
||||
tex_coord = v_tex_coord;
|
||||
gl_Position = vec4(v_position, 1.0);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#version 110
|
||||
|
||||
uniform vec4 uniform_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = uniform_color;
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#version 110
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ftransform();
|
||||
}
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
attribute vec3 v_position;
|
||||
|
||||
uniform mat4 projection_view_model_matrix;
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection_view_model_matrix * vec4(v_position, 1.0);
|
||||
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
|
||||
}
|
||||
|
|
15
resources/shaders/flat_texture_attr.vs
Normal file
15
resources/shaders/flat_texture_attr.vs
Normal file
|
@ -0,0 +1,15 @@
|
|||
#version 110
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec2 v_tex_coord;
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
varying vec2 tex_coord;
|
||||
|
||||
void main()
|
||||
{
|
||||
tex_coord = v_tex_coord;
|
||||
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
|
||||
}
|
|
@ -48,7 +48,6 @@ varying vec2 intensity;
|
|||
|
||||
uniform PrintVolumeDetection print_volume;
|
||||
|
||||
varying vec4 model_pos;
|
||||
varying vec4 world_pos;
|
||||
varying float world_normal_z;
|
||||
varying vec3 eye_normal;
|
||||
|
|
|
@ -38,7 +38,6 @@ varying vec2 intensity;
|
|||
|
||||
varying vec3 clipping_planes_dots;
|
||||
|
||||
varying vec4 model_pos;
|
||||
varying vec4 world_pos;
|
||||
varying float world_normal_z;
|
||||
varying vec3 eye_normal;
|
||||
|
@ -60,7 +59,6 @@ void main()
|
|||
NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
|
||||
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
|
||||
|
||||
model_pos = gl_Vertex;
|
||||
// Point in homogenous coordinates.
|
||||
world_pos = volume_world_matrix * gl_Vertex;
|
||||
|
||||
|
|
77
resources/shaders/gouraud_attr.vs
Normal file
77
resources/shaders/gouraud_attr.vs
Normal file
|
@ -0,0 +1,77 @@
|
|||
#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;
|
||||
};
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec3 v_normal;
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat3 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(normal_matrix * 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 position = view_model_matrix * vec4(v_position, 1.0);
|
||||
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), 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 * vec4(v_position, 1.0);
|
||||
|
||||
// z component of normal vector in world coordinate used for slope shading
|
||||
world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0;
|
||||
|
||||
gl_Position = projection_matrix * position;
|
||||
// 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);
|
||||
}
|
45
resources/shaders/gouraud_light_attr.vs
Normal file
45
resources/shaders/gouraud_light_attr.vs
Normal file
|
@ -0,0 +1,45 @@
|
|||
#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
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec3 v_normal;
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat3 normal_matrix;
|
||||
|
||||
// x = tainted, y = specular;
|
||||
varying vec2 intensity;
|
||||
|
||||
void main()
|
||||
{
|
||||
// First transform the normal into camera space and normalize the result.
|
||||
vec3 normal = normalize(normal_matrix * 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(normal, LIGHT_TOP_DIR), 0.0);
|
||||
|
||||
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
|
||||
vec4 position = view_model_matrix * vec4(v_position, 1.0);
|
||||
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), 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 = projection_matrix * position;
|
||||
}
|
50
resources/shaders/gouraud_light_instanced_attr.vs
Normal file
50
resources/shaders/gouraud_light_instanced_attr.vs
Normal file
|
@ -0,0 +1,50 @@
|
|||
#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;
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat3 normal_matrix;
|
||||
|
||||
// x = tainted, y = specular;
|
||||
varying vec2 intensity;
|
||||
|
||||
void main()
|
||||
{
|
||||
// First transform the normal into camera space and normalize the result.
|
||||
vec3 eye_normal = normalize(normal_matrix * 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);
|
||||
vec4 eye_position = view_model_matrix * world_position;
|
||||
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position.xyz), 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 = projection_matrix * eye_position;
|
||||
}
|
13
resources/shaders/mm_contour_attr.fs
Normal file
13
resources/shaders/mm_contour_attr.fs
Normal file
|
@ -0,0 +1,13 @@
|
|||
#version 110
|
||||
|
||||
const float EPSILON = 0.0001;
|
||||
|
||||
uniform vec4 uniform_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = uniform_color;
|
||||
// Values inside depth buffer for fragments of the contour of a selected area are offset
|
||||
// by small epsilon to solve z-fighting between painted triangles and contour lines.
|
||||
gl_FragDepth = gl_FragCoord.z - EPSILON;
|
||||
}
|
11
resources/shaders/mm_contour_attr.vs
Normal file
11
resources/shaders/mm_contour_attr.vs
Normal file
|
@ -0,0 +1,11 @@
|
|||
#version 110
|
||||
|
||||
attribute vec3 v_position;
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
|
||||
}
|
90
resources/shaders/mm_gouraud_attr.fs
Normal file
90
resources/shaders/mm_gouraud_attr.fs
Normal file
|
@ -0,0 +1,90 @@
|
|||
#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;
|
||||
//BBS: add grey and orange
|
||||
//const vec3 GREY = vec3(0.9, 0.9, 0.9);
|
||||
const vec3 ORANGE = vec3(0.8, 0.4, 0.0);
|
||||
const vec3 LightRed = vec3(0.78, 0.0, 0.0);
|
||||
const vec3 LightBlue = vec3(0.73, 1.0, 1.0);
|
||||
uniform vec4 uniform_color;
|
||||
|
||||
uniform bool volume_mirrored;
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat3 normal_matrix;
|
||||
|
||||
varying vec3 clipping_planes_dots;
|
||||
varying vec4 model_pos;
|
||||
varying vec4 world_pos;
|
||||
|
||||
struct SlopeDetection
|
||||
{
|
||||
bool actived;
|
||||
float normal_z;
|
||||
mat3 volume_world_normal_matrix;
|
||||
};
|
||||
uniform SlopeDetection slope;
|
||||
|
||||
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;
|
||||
|
||||
vec3 transformed_normal = normalize(slope.volume_world_normal_matrix * triangle_normal);
|
||||
|
||||
if (slope.actived) {
|
||||
if(world_pos.z<0.1&&world_pos.z>-0.1)
|
||||
{
|
||||
color = LightBlue;
|
||||
alpha = 1.0;
|
||||
}
|
||||
else if( transformed_normal.z < slope.normal_z - EPSILON)
|
||||
{
|
||||
color = color * 0.5 + LightRed * 0.5;
|
||||
alpha = 1.0;
|
||||
}
|
||||
}
|
||||
// First transform the normal into camera space and normalize the result.
|
||||
vec3 eye_normal = normalize(normal_matrix * 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);
|
||||
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
|
||||
vec3 position = (view_model_matrix * 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);
|
||||
}
|
35
resources/shaders/mm_gouraud_attr.vs
Normal file
35
resources/shaders/mm_gouraud_attr.vs
Normal file
|
@ -0,0 +1,35 @@
|
|||
#version 110
|
||||
|
||||
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
attribute vec3 v_position;
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
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;
|
||||
varying vec4 world_pos;
|
||||
struct SlopeDetection
|
||||
{
|
||||
bool actived;
|
||||
float normal_z;
|
||||
mat3 volume_world_normal_matrix;
|
||||
};
|
||||
uniform SlopeDetection slope;
|
||||
void main()
|
||||
{
|
||||
model_pos = vec4(v_position, 1.0);
|
||||
// Point in homogenous coordinates.
|
||||
world_pos = volume_world_matrix * model_pos;
|
||||
|
||||
gl_Position = projection_matrix * view_model_matrix * model_pos;
|
||||
// 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);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#version 110
|
||||
|
||||
uniform vec4 uniform_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = uniform_color;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#version 110
|
||||
|
||||
uniform bool use_fixed_screen_size;
|
||||
uniform float zoom;
|
||||
uniform float point_size;
|
||||
uniform float near_plane_height;
|
||||
|
||||
float fixed_screen_size()
|
||||
{
|
||||
return point_size;
|
||||
}
|
||||
|
||||
float fixed_world_size()
|
||||
{
|
||||
return (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ftransform();
|
||||
gl_PointSize = use_fixed_screen_size ? fixed_screen_size() : fixed_world_size();
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// version 120 is needed for gl_PointCoord
|
||||
#version 120
|
||||
|
||||
uniform vec4 uniform_color;
|
||||
uniform float percent_outline_radius;
|
||||
uniform float percent_center_radius;
|
||||
|
||||
vec4 calc_color(float radius, vec4 color)
|
||||
{
|
||||
return ((radius < percent_center_radius) || (radius > 1.0 - percent_outline_radius)) ?
|
||||
vec4(0.5 * color.rgb, color.a) : color;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 pos = (gl_PointCoord - 0.5) * 2.0;
|
||||
float radius = length(pos);
|
||||
if (radius > 1.0)
|
||||
discard;
|
||||
|
||||
gl_FragColor = calc_color(radius, uniform_color);
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#version 120
|
||||
|
||||
uniform bool use_fixed_screen_size;
|
||||
uniform float zoom;
|
||||
uniform float point_size;
|
||||
uniform float near_plane_height;
|
||||
|
||||
float fixed_screen_size()
|
||||
{
|
||||
return point_size;
|
||||
}
|
||||
|
||||
float fixed_world_size()
|
||||
{
|
||||
return (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ftransform();
|
||||
gl_PointSize = use_fixed_screen_size ? fixed_screen_size() : fixed_world_size();
|
||||
}
|
|
@ -7,15 +7,15 @@ uniform sampler2D texture;
|
|||
uniform bool transparent_background;
|
||||
uniform bool svg_source;
|
||||
|
||||
varying vec2 tex_coords;
|
||||
varying vec2 tex_coord;
|
||||
|
||||
vec4 svg_color()
|
||||
{
|
||||
// takes foreground from texture
|
||||
vec4 fore_color = texture2D(texture, tex_coords);
|
||||
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_coords.xy) - vec2(0.5)))));
|
||||
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);
|
||||
|
@ -24,7 +24,7 @@ vec4 svg_color()
|
|||
vec4 non_svg_color()
|
||||
{
|
||||
// takes foreground from texture
|
||||
vec4 color = texture2D(texture, tex_coords);
|
||||
vec4 color = texture2D(texture, tex_coord);
|
||||
return vec4(color.rgb, transparent_background ? color.a * 0.25 : color.a);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#version 110
|
||||
|
||||
varying vec2 tex_coords;
|
||||
varying vec2 tex_coord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ftransform();
|
||||
tex_coords = gl_MultiTexCoord0.xy;
|
||||
tex_coord = gl_MultiTexCoord0.xy;
|
||||
}
|
||||
|
|
15
resources/shaders/printbed_attr.vs
Normal file
15
resources/shaders/printbed_attr.vs
Normal file
|
@ -0,0 +1,15 @@
|
|||
#version 110
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec2 v_tex_coord;
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
varying vec2 tex_coord;
|
||||
|
||||
void main()
|
||||
{
|
||||
tex_coord = v_tex_coord;
|
||||
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
|
||||
}
|
51
resources/shaders/thumbnail_attr.vs
Normal file
51
resources/shaders/thumbnail_attr.vs
Normal file
|
@ -0,0 +1,51 @@
|
|||
#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
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec3 v_normal;
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat3 normal_matrix;
|
||||
|
||||
uniform mat4 volume_world_matrix;
|
||||
|
||||
// x = tainted, y = specular;
|
||||
varying vec2 intensity;
|
||||
varying vec4 world_pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
// First transform the normal into camera space and normalize the result.
|
||||
vec3 normal = normalize(normal_matrix * 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(normal, LIGHT_TOP_DIR), 0.0);
|
||||
|
||||
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
|
||||
vec4 position = view_model_matrix * vec4(v_position, 1.0);
|
||||
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), 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;
|
||||
|
||||
// Point in homogenous coordinates.
|
||||
world_pos = volume_world_matrix * gl_Vertex;
|
||||
|
||||
gl_Position = projection_matrix * position;
|
||||
}
|
60
resources/shaders/variable_layer_height_attr.vs
Normal file
60
resources/shaders/variable_layer_height_attr.vs
Normal file
|
@ -0,0 +1,60 @@
|
|||
#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
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec3 v_normal;
|
||||
attribute vec2 v_tex_coord;
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 volume_world_matrix;
|
||||
uniform float object_max_z;
|
||||
|
||||
// x = tainted, y = specular;
|
||||
varying vec2 intensity;
|
||||
|
||||
varying float object_z;
|
||||
|
||||
void main()
|
||||
{
|
||||
// =====================================================
|
||||
// NOTE:
|
||||
// when object_max_z > 0.0 we are rendering the overlay
|
||||
// when object_max_z == 0.0 we are rendering the volumes
|
||||
// =====================================================
|
||||
|
||||
// First transform the normal into camera space and normalize the result.
|
||||
vec3 normal = (object_max_z > 0.0) ? vec3(0.0, 0.0, 1.0) : normalize(normal_matrix * 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(normal, LIGHT_TOP_DIR), 0.0);
|
||||
|
||||
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
|
||||
vec4 position = view_model_matrix * vec4(v_position, 1.0);
|
||||
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), 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.
|
||||
object_z = (object_max_z > 0.0) ? object_max_z * v_tex_coord.y : (volume_world_matrix * vec4(v_position, 1.0)).z;
|
||||
|
||||
gl_Position = projection_matrix * position;
|
||||
}
|
|
@ -2370,7 +2370,7 @@ int CLI::run(int argc, char **argv)
|
|||
}
|
||||
|
||||
ThumbnailsParams thumbnail_params;
|
||||
GLShaderProgram* shader = opengl_mgr.get_shader("thumbnail");
|
||||
GLShaderProgram* shader = opengl_mgr.get_shader("thumbnail_attr");
|
||||
if (!shader) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("can not get shader for rendering thumbnail");
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ bool init_model_from_poly(GLModel &model, const ExPolygon &poly, float z)
|
|||
return false;
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3T2, GLModel::Geometry::index_type(triangles.size()) };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3T2 };
|
||||
init_data.reserve_vertices(triangles.size());
|
||||
init_data.reserve_indices(triangles.size() / 3);
|
||||
|
||||
|
@ -71,12 +71,8 @@ bool init_model_from_poly(GLModel &model, const ExPolygon &poly, float z)
|
|||
const Vec3f p = {v.x(), v.y(), z};
|
||||
init_data.add_vertex(p, (Vec2f)(v - min).cwiseProduct(inv_size).eval());
|
||||
++vertices_counter;
|
||||
if (vertices_counter % 3 == 0) {
|
||||
if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
||||
init_data.add_ushort_triangle((unsigned short)vertices_counter - 3, (unsigned short)vertices_counter - 2, (unsigned short)vertices_counter - 1);
|
||||
else
|
||||
init_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
|
||||
}
|
||||
if (vertices_counter % 3 == 0)
|
||||
init_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
|
||||
}
|
||||
|
||||
model.init_from(std::move(init_data));
|
||||
|
@ -210,17 +206,19 @@ void Bed3D::load_render_colors()
|
|||
|
||||
void Bed3D::Axes::render()
|
||||
{
|
||||
auto render_axis = [this](const Transform3f& transform) {
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glMultMatrixf(transform.data()));
|
||||
auto render_axis = [this](GLShaderProgram* shader, const Transform3d& transform) {
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d matrix = camera.get_view_matrix() * transform;
|
||||
shader->set_uniform("view_model_matrix", matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_arrow.render();
|
||||
glsafe(::glPopMatrix());
|
||||
};
|
||||
|
||||
if (!m_arrow.is_initialized())
|
||||
m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length));
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -231,15 +229,15 @@ void Bed3D::Axes::render()
|
|||
|
||||
// x axis
|
||||
m_arrow.set_color(AXIS_X_COLOR);
|
||||
render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }).cast<float>());
|
||||
render_axis(shader, Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }));
|
||||
|
||||
// y axis
|
||||
m_arrow.set_color(AXIS_Y_COLOR);
|
||||
render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }).cast<float>());
|
||||
render_axis(shader, Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }));
|
||||
|
||||
// z axis
|
||||
m_arrow.set_color(AXIS_Z_COLOR);
|
||||
render_axis(Geometry::assemble_transform(m_origin).cast<float>());
|
||||
render_axis(shader, Geometry::assemble_transform(m_origin));
|
||||
|
||||
shader->stop_using();
|
||||
|
||||
|
@ -362,17 +360,17 @@ void Bed3D::on_change_color_mode(bool is_dark)
|
|||
m_is_dark = is_dark;
|
||||
}
|
||||
|
||||
void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes)
|
||||
void Bed3D::render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes)
|
||||
{
|
||||
render_internal(canvas, bottom, scale_factor, show_axes);
|
||||
render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, show_axes);
|
||||
}
|
||||
|
||||
/*void Bed3D::render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor)
|
||||
/*void Bed3D::render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor)
|
||||
{
|
||||
render_internal(canvas, bottom, scale_factor, false, false, true);
|
||||
render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, false, false, true);
|
||||
}*/
|
||||
|
||||
void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
||||
void Bed3D::render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor,
|
||||
bool show_axes)
|
||||
{
|
||||
m_scale_factor = scale_factor;
|
||||
|
@ -386,9 +384,9 @@ void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
|||
|
||||
switch (m_type)
|
||||
{
|
||||
case Type::System: { render_system(canvas, bottom); break; }
|
||||
case Type::System: { render_system(canvas, view_matrix, projection_matrix, bottom); break; }
|
||||
default:
|
||||
case Type::Custom: { render_custom(canvas, bottom); break; }
|
||||
case Type::Custom: { render_custom(canvas, view_matrix, projection_matrix, bottom); break; }
|
||||
}
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
@ -464,10 +462,10 @@ void Bed3D::render_axes()
|
|||
m_axes.render();
|
||||
}
|
||||
|
||||
void Bed3D::render_system(GLCanvas3D& canvas, bool bottom)
|
||||
void Bed3D::render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom)
|
||||
{
|
||||
if (!bottom)
|
||||
render_model();
|
||||
render_model(view_matrix, projection_matrix);
|
||||
|
||||
/*if (show_texture)
|
||||
render_texture(bottom, canvas);*/
|
||||
|
@ -538,9 +536,12 @@ void Bed3D::render_system(GLCanvas3D& canvas, bool bottom)
|
|||
}
|
||||
|
||||
if (m_triangles.get_vertices_count() > 0) {
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("printbed");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("printbed_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
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());
|
||||
shader->set_uniform("transparent_background", bottom);
|
||||
shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg"));
|
||||
|
||||
|
@ -658,7 +659,7 @@ void Bed3D::update_bed_triangles()
|
|||
const_cast<BoundingBoxf3&>(m_extended_bounding_box) = calc_extended_bounding_box();
|
||||
}
|
||||
|
||||
void Bed3D::render_model()
|
||||
void Bed3D::render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix)
|
||||
{
|
||||
if (m_model_filename.empty())
|
||||
return;
|
||||
|
@ -670,20 +671,21 @@ void Bed3D::render_model()
|
|||
}
|
||||
|
||||
if (!m_model.get_filename().empty()) {
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.0f);
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z()));
|
||||
const Transform3d matrix = view_matrix * Geometry::assemble_transform(m_model_offset);
|
||||
shader->set_uniform("view_model_matrix", matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_model.render();
|
||||
glsafe(::glPopMatrix());
|
||||
shader->stop_using();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom)
|
||||
void Bed3D::render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom)
|
||||
{
|
||||
if (m_model_filename.empty()) {
|
||||
render_default(bottom);
|
||||
|
@ -691,7 +693,7 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom)
|
|||
}
|
||||
|
||||
if (!bottom)
|
||||
render_model();
|
||||
render_model(view_matrix, projection_matrix);
|
||||
|
||||
/*if (show_texture)
|
||||
render_texture(bottom, canvas);*/
|
||||
|
@ -708,8 +710,9 @@ void Bed3D::render_default(bool bottom)
|
|||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
const Transform3d matrix = wxGetApp().plater()->get_camera().get_projection_view_matrix();
|
||||
shader->set_uniform("projection_view_model_matrix", matrix);
|
||||
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());
|
||||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
glsafe(::glEnable(GL_BLEND));
|
||||
|
|
|
@ -146,8 +146,8 @@ public:
|
|||
bool contains(const Point& point) const;
|
||||
Point point_projection(const Point& point) const;
|
||||
|
||||
void render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes);
|
||||
//void render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor);
|
||||
void render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes);
|
||||
//void render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor);
|
||||
|
||||
void on_change_color_mode(bool is_dark);
|
||||
|
||||
|
@ -159,13 +159,13 @@ private:
|
|||
//BBS: with offset
|
||||
void update_bed_triangles();
|
||||
static std::tuple<Type, std::string, std::string> detect_type(const Pointfs& shape);
|
||||
void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
||||
void render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor,
|
||||
bool show_axes);
|
||||
void render_axes();
|
||||
void render_system(GLCanvas3D& canvas, bool bottom);
|
||||
void render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom);
|
||||
//void render_texture(bool bottom, GLCanvas3D& canvas);
|
||||
void render_model();
|
||||
void render_custom(GLCanvas3D& canvas, bool bottom);
|
||||
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);
|
||||
void render_default(bool bottom);
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "GUI_Colors.hpp"
|
||||
#include "Plater.hpp"
|
||||
#include "BitmapCache.hpp"
|
||||
#include "Camera.hpp"
|
||||
|
||||
#include "libslic3r/BuildVolume.hpp"
|
||||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
|
@ -96,10 +97,14 @@ void GLVolume::SinkingContours::render()
|
|||
{
|
||||
update();
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(m_shift.x(), m_shift.y(), m_shift.z()));
|
||||
GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
const GUI::Camera& camera = GUI::wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * Geometry::assemble_transform(m_shift));
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
m_model.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
void GLVolume::SinkingContours::update()
|
||||
|
@ -117,7 +122,7 @@ void GLVolume::SinkingContours::update()
|
|||
|
||||
m_model.reset();
|
||||
GUI::GLModel::Geometry init_data;
|
||||
init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Triangles, GUI::GLModel::Geometry::EVertexLayout::P3, GUI::GLModel::Geometry::EIndexType::UINT };
|
||||
init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Triangles, GUI::GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.color = ColorRGBA::WHITE();
|
||||
unsigned int vertices_counter = 0;
|
||||
MeshSlicingParams slicing_params;
|
||||
|
@ -131,7 +136,7 @@ void GLVolume::SinkingContours::update()
|
|||
init_data.add_vertex((Vec3f)(v.cast<float>() + 0.015f * Vec3f::UnitZ())); // add a small positive z to avoid z-fighting
|
||||
++vertices_counter;
|
||||
if (vertices_counter % 3 == 0)
|
||||
init_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
|
||||
init_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
|
||||
}
|
||||
}
|
||||
m_model.init_from(std::move(init_data));
|
||||
|
@ -398,10 +403,17 @@ void GLVolume::render(bool with_outline)
|
|||
if (!is_active)
|
||||
return;
|
||||
|
||||
GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
if (this->is_left_handed())
|
||||
glFrontFace(GL_CW);
|
||||
glsafe(::glCullFace(GL_BACK));
|
||||
glsafe(::glPushMatrix());
|
||||
if (with_outline) {
|
||||
// Error: not supported!
|
||||
throw Slic3r::InvalidArgument("Render GLVolume with outline is not supported");
|
||||
}
|
||||
|
||||
// BBS: add logic for mmu segmentation rendering
|
||||
auto render_body = [&]() {
|
||||
|
@ -446,7 +458,6 @@ void GLVolume::render(bool with_outline)
|
|||
for (int index = 0; index < colors.size(); index++)
|
||||
colors[index].a(render_color.a());
|
||||
}
|
||||
glsafe(::glMultMatrixd(world_matrix().data()));
|
||||
for (int idx = 0; idx < mmuseg_models.size(); idx++) {
|
||||
GUI::GLModel &m = mmuseg_models[idx];
|
||||
if (m.is_empty())
|
||||
|
@ -489,7 +500,6 @@ void GLVolume::render(bool with_outline)
|
|||
}
|
||||
}
|
||||
else {
|
||||
glsafe(::glMultMatrixd(world_matrix().data()));
|
||||
if (tverts_range == std::make_pair<size_t, size_t>(0, -1))
|
||||
model.render();
|
||||
else
|
||||
|
@ -498,7 +508,6 @@ void GLVolume::render(bool with_outline)
|
|||
};
|
||||
|
||||
//BBS: add logic of outline rendering
|
||||
GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
|
||||
//BOOST_LOG_TRIVIAL(info) << boost::format(": %1%, with_outline %2%, shader %3%.")%__LINE__ %with_outline %shader;
|
||||
if (with_outline && shader != nullptr)
|
||||
{
|
||||
|
@ -629,7 +638,6 @@ void GLVolume::render(bool with_outline)
|
|||
render_body();
|
||||
//BOOST_LOG_TRIVIAL(info) << boost::format(": %1%, normal render.")%__LINE__;
|
||||
}
|
||||
glsafe(::glPopMatrix());
|
||||
if (this->is_left_handed())
|
||||
glFrontFace(GL_CCW);
|
||||
}
|
||||
|
@ -640,7 +648,6 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj
|
|||
if (this->is_left_handed())
|
||||
glFrontFace(GL_CW);
|
||||
glsafe(::glCullFace(GL_BACK));
|
||||
glsafe(::glPushMatrix());
|
||||
|
||||
bool color_volume = false;
|
||||
ModelObject* model_object = nullptr;
|
||||
|
@ -704,16 +711,12 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj
|
|||
else
|
||||
m.render(this->tverts_range);
|
||||
}
|
||||
}
|
||||
else {
|
||||
glsafe(::glMultMatrixd(world_matrix().data()));
|
||||
} else {
|
||||
if (tverts_range == std::make_pair<size_t, size_t>(0, -1))
|
||||
model.render();
|
||||
else
|
||||
model.render(this->tverts_range);
|
||||
}
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
if (this->is_left_handed())
|
||||
glFrontFace(GL_CCW);
|
||||
}
|
||||
|
@ -997,8 +1000,8 @@ int GLVolumeCollection::get_selection_support_threshold_angle(bool &enable_suppo
|
|||
}
|
||||
|
||||
//BBS: add outline drawing logic
|
||||
void GLVolumeCollection::render(
|
||||
GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d &view_matrix, std::function<bool(const GLVolume &)> filter_func, bool with_outline) const
|
||||
void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix,
|
||||
std::function<bool(const GLVolume&)> filter_func, bool with_outline) const
|
||||
{
|
||||
GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func);
|
||||
if (to_render.empty())
|
||||
|
@ -1008,8 +1011,9 @@ void GLVolumeCollection::render(
|
|||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat_attr");
|
||||
GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat_attr");
|
||||
assert(boost::algorithm::iends_with(shader->get_name(), "_attr"));
|
||||
|
||||
if (type == ERenderType::Transparent) {
|
||||
glsafe(::glEnable(GL_BLEND));
|
||||
|
@ -1049,9 +1053,6 @@ void GLVolumeCollection::render(
|
|||
}
|
||||
shader->start_using();
|
||||
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
|
||||
if (!volume.first->model.is_initialized())
|
||||
shader->set_uniform("uniform_color", volume.first->render_color);
|
||||
shader->set_uniform("z_range", m_z_range, 2);
|
||||
|
@ -1096,6 +1097,10 @@ void GLVolumeCollection::render(
|
|||
glcheck();
|
||||
|
||||
volume.first->model.set_color(volume.first->render_color);
|
||||
const Transform3d matrix = view_matrix * volume.first->world_matrix();
|
||||
shader->set_uniform("view_model_matrix", matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
//BBS: add outline related logic
|
||||
volume.first->render(with_outline && volume.first->selected);
|
||||
|
||||
|
@ -1106,9 +1111,6 @@ void GLVolumeCollection::render(
|
|||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
}
|
||||
|
||||
if (m_show_sinking_contours) {
|
||||
|
@ -1462,8 +1464,8 @@ static void thick_lines_to_geometry(
|
|||
|
||||
if (!is_first && bottom_z_different) {
|
||||
// Found a change of the layer thickness -> Add a cap at the end of the previous segment.
|
||||
geometry.add_uint_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
|
||||
geometry.add_uint_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
|
||||
geometry.add_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
|
||||
geometry.add_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
|
||||
}
|
||||
|
||||
// Share top / bottom vertices if possible.
|
||||
|
@ -1513,13 +1515,13 @@ static void thick_lines_to_geometry(
|
|||
geometry.add_vertex(Vec3f(a2.x(), a2.y(), middle_z), Vec3f(-xy_right_normal.x(), -xy_right_normal.y(), 0.0f));
|
||||
if (cross2(v_prev, v) > 0.0) {
|
||||
// Right turn. Fill in the right turn wedge.
|
||||
geometry.add_uint_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]);
|
||||
geometry.add_uint_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]);
|
||||
geometry.add_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]);
|
||||
geometry.add_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]);
|
||||
}
|
||||
else {
|
||||
// Left turn. Fill in the left turn wedge.
|
||||
geometry.add_uint_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]);
|
||||
geometry.add_uint_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]);
|
||||
geometry.add_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]);
|
||||
geometry.add_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1541,11 +1543,11 @@ static void thick_lines_to_geometry(
|
|||
// Replace the left / right vertex indices to point to the start of the loop.
|
||||
const size_t indices_count = geometry.indices_count();
|
||||
for (size_t u = indices_count - 24; u < indices_count; ++u) {
|
||||
const unsigned int id = geometry.extract_uint_index(u);
|
||||
const unsigned int id = geometry.extract_index(u);
|
||||
if (id == (unsigned int)idx_prev[Left])
|
||||
geometry.set_uint_index(u, (unsigned int)idx_initial[Left]);
|
||||
geometry.set_index(u, (unsigned int)idx_initial[Left]);
|
||||
else if (id == (unsigned int)idx_prev[Right])
|
||||
geometry.set_uint_index(u, (unsigned int)idx_initial[Right]);
|
||||
geometry.set_index(u, (unsigned int)idx_initial[Right]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1582,36 +1584,36 @@ static void thick_lines_to_geometry(
|
|||
|
||||
if (bottom_z_different && (closed || (!is_first && !is_last))) {
|
||||
// Found a change of the layer thickness -> Add a cap at the beginning of this segment.
|
||||
geometry.add_uint_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
|
||||
geometry.add_uint_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
|
||||
geometry.add_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
|
||||
geometry.add_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
|
||||
}
|
||||
|
||||
if (!closed) {
|
||||
// Terminate open paths with caps.
|
||||
if (is_first) {
|
||||
geometry.add_uint_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
|
||||
geometry.add_uint_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
|
||||
geometry.add_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
|
||||
geometry.add_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
|
||||
}
|
||||
// We don't use 'else' because both cases are true if we have only one line.
|
||||
if (is_last) {
|
||||
geometry.add_uint_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
|
||||
geometry.add_uint_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
|
||||
geometry.add_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
|
||||
geometry.add_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
|
||||
}
|
||||
}
|
||||
|
||||
// Add quads for a straight hollow tube-like segment.
|
||||
// bottom-right face
|
||||
geometry.add_uint_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]);
|
||||
geometry.add_uint_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]);
|
||||
geometry.add_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]);
|
||||
geometry.add_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]);
|
||||
// top-right face
|
||||
geometry.add_uint_triangle(idx_a[Right], idx_b[Right], idx_b[Top]);
|
||||
geometry.add_uint_triangle(idx_a[Right], idx_b[Top], idx_a[Top]);
|
||||
geometry.add_triangle(idx_a[Right], idx_b[Right], idx_b[Top]);
|
||||
geometry.add_triangle(idx_a[Right], idx_b[Top], idx_a[Top]);
|
||||
// top-left face
|
||||
geometry.add_uint_triangle(idx_a[Top], idx_b[Top], idx_b[Left]);
|
||||
geometry.add_uint_triangle(idx_a[Top], idx_b[Left], idx_a[Left]);
|
||||
geometry.add_triangle(idx_a[Top], idx_b[Top], idx_b[Left]);
|
||||
geometry.add_triangle(idx_a[Top], idx_b[Left], idx_a[Left]);
|
||||
// bottom-left face
|
||||
geometry.add_uint_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]);
|
||||
geometry.add_uint_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]);
|
||||
geometry.add_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]);
|
||||
geometry.add_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1751,13 +1753,13 @@ static void thick_lines_to_geometry(
|
|||
|
||||
if (is_right_turn) {
|
||||
// Right turn. Fill in the right turn wedge.
|
||||
geometry.add_uint_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]);
|
||||
geometry.add_uint_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]);
|
||||
geometry.add_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]);
|
||||
geometry.add_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]);
|
||||
}
|
||||
else {
|
||||
// Left turn. Fill in the left turn wedge.
|
||||
geometry.add_uint_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]);
|
||||
geometry.add_uint_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]);
|
||||
geometry.add_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]);
|
||||
geometry.add_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1776,11 +1778,11 @@ static void thick_lines_to_geometry(
|
|||
// Replace the left / right vertex indices to point to the start of the loop.
|
||||
const size_t indices_count = geometry.indices_count();
|
||||
for (size_t u = indices_count - 24; u < indices_count; ++u) {
|
||||
const unsigned int id = geometry.extract_uint_index(u);
|
||||
const unsigned int id = geometry.extract_index(u);
|
||||
if (id == (unsigned int)idx_prev[Left])
|
||||
geometry.set_uint_index(u, (unsigned int)idx_initial[Left]);
|
||||
geometry.set_index(u, (unsigned int)idx_initial[Left]);
|
||||
else if (id == (unsigned int)idx_prev[Right])
|
||||
geometry.set_uint_index(u, (unsigned int)idx_initial[Right]);
|
||||
geometry.set_index(u, (unsigned int)idx_initial[Right]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1819,30 +1821,30 @@ static void thick_lines_to_geometry(
|
|||
if (!closed) {
|
||||
// Terminate open paths with caps.
|
||||
if (i == 0) {
|
||||
geometry.add_uint_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
|
||||
geometry.add_uint_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
|
||||
geometry.add_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
|
||||
geometry.add_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
|
||||
}
|
||||
|
||||
// We don't use 'else' because both cases are true if we have only one line.
|
||||
if (i + 1 == lines.size()) {
|
||||
geometry.add_uint_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
|
||||
geometry.add_uint_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
|
||||
geometry.add_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
|
||||
geometry.add_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
|
||||
}
|
||||
}
|
||||
|
||||
// Add quads for a straight hollow tube-like segment.
|
||||
// bottom-right face
|
||||
geometry.add_uint_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]);
|
||||
geometry.add_uint_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]);
|
||||
geometry.add_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]);
|
||||
geometry.add_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]);
|
||||
// top-right face
|
||||
geometry.add_uint_triangle(idx_a[Right], idx_b[Right], idx_b[Top]);
|
||||
geometry.add_uint_triangle(idx_a[Right], idx_b[Top], idx_a[Top]);
|
||||
geometry.add_triangle(idx_a[Right], idx_b[Right], idx_b[Top]);
|
||||
geometry.add_triangle(idx_a[Right], idx_b[Top], idx_a[Top]);
|
||||
// top-left face
|
||||
geometry.add_uint_triangle(idx_a[Top], idx_b[Top], idx_b[Left]);
|
||||
geometry.add_uint_triangle(idx_a[Top], idx_b[Left], idx_a[Left]);
|
||||
geometry.add_triangle(idx_a[Top], idx_b[Top], idx_b[Left]);
|
||||
geometry.add_triangle(idx_a[Top], idx_b[Left], idx_a[Left]);
|
||||
// bottom-left face
|
||||
geometry.add_uint_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]);
|
||||
geometry.add_uint_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]);
|
||||
geometry.add_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]);
|
||||
geometry.add_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -446,11 +446,8 @@ public:
|
|||
int get_selection_support_threshold_angle(bool&) const;
|
||||
// Render the volumes by OpenGL.
|
||||
//BBS: add outline drawing logic
|
||||
void render(ERenderType type,
|
||||
bool disable_cullface,
|
||||
const Transform3d & view_matrix,
|
||||
std::function<bool(const GLVolume &)> filter_func = std::function<bool(const GLVolume &)>(),
|
||||
bool with_outline = true) const;
|
||||
void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix,
|
||||
std::function<bool(const GLVolume &)> filter_func = std::function<bool(const GLVolume &)>(), bool with_outline = true) const;
|
||||
|
||||
// Clear the geometry
|
||||
void clear() { for (auto *v : volumes) delete v; volumes.clear(); }
|
||||
|
|
|
@ -92,7 +92,6 @@ public:
|
|||
const std::array<int, 4>& get_viewport() const { return m_viewport; }
|
||||
const Transform3d& get_view_matrix() const { return m_view_matrix; }
|
||||
const Transform3d& get_projection_matrix() const { return m_projection_matrix; }
|
||||
Transform3d get_projection_view_matrix() const { return m_projection_matrix * m_view_matrix; }
|
||||
|
||||
//BBS
|
||||
const Eigen::Quaterniond& get_view_rotation() const {return m_view_rotation; }
|
||||
|
|
|
@ -307,7 +307,7 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
|
|||
if (!m_visible)
|
||||
return;
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -317,13 +317,14 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
|
|||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.0f);
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glMultMatrixf(m_world_transform.data()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d matrix = camera.get_view_matrix() * m_world_transform.cast<double>();
|
||||
shader->set_uniform("view_model_matrix", matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
|
||||
m_model.render();
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
shader->stop_using();
|
||||
|
||||
glsafe(::glDisable(GL_BLEND));
|
||||
|
@ -787,7 +788,7 @@ void GCodeViewer::init(ConfigOptionMode mode, PresetBundle* preset_bundle)
|
|||
case EMoveType::Seam: {
|
||||
// if (wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) {
|
||||
// buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::InstancedModel;
|
||||
// buffer.shader = "gouraud_light_instanced";
|
||||
// buffer.shader = "gouraud_light_instanced_attr";
|
||||
// buffer.model.model.init_from(diamond(16));
|
||||
// buffer.model.color = option_color(type);
|
||||
// buffer.model.instances.format = InstanceVBuffer::EFormat::InstancedModel;
|
||||
|
@ -798,7 +799,7 @@ void GCodeViewer::init(ConfigOptionMode mode, PresetBundle* preset_bundle)
|
|||
|
||||
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::BatchedModel;
|
||||
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
|
||||
buffer.shader = "gouraud_light";
|
||||
buffer.shader = "gouraud_light_attr";
|
||||
|
||||
buffer.model.data = diamond(16);
|
||||
buffer.model.color = option_color(type);
|
||||
|
@ -810,13 +811,13 @@ void GCodeViewer::init(ConfigOptionMode mode, PresetBundle* preset_bundle)
|
|||
case EMoveType::Extrude: {
|
||||
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle;
|
||||
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
|
||||
buffer.shader = "gouraud_light";
|
||||
buffer.shader = "gouraud_light_attr";
|
||||
break;
|
||||
}
|
||||
case EMoveType::Travel: {
|
||||
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line;
|
||||
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
|
||||
buffer.shader = "toolpaths_lines";
|
||||
buffer.vertices.format = VBuffer::EFormat::Position;
|
||||
buffer.shader = "flat_attr";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1324,7 +1325,7 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
|
|||
// Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
|
||||
assert(!path.sizes.empty());
|
||||
assert(!path.offsets.empty());
|
||||
glsafe(::glUniform4fv(uniform_color, 1, static_cast<const GLfloat*>(path.color.data())));
|
||||
shader.set_uniform(uniform_color, path.color);
|
||||
glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
++m_statistics.gl_multi_triangles_calls_count;
|
||||
|
@ -1359,7 +1360,7 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
|
|||
#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) {
|
||||
auto render_as_batched_model = [](TBuffer& buffer, GLShaderProgram& shader, int position_id, int normal_id) {
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
||||
struct Range
|
||||
|
@ -1375,12 +1376,16 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
|
|||
const IBuffer& i_buffer = buffer.indices[j];
|
||||
buffer_range.last = buffer_range.first + i_buffer.count / indices_per_instance;
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
|
||||
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));
|
||||
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));
|
||||
}
|
||||
bool has_normals = buffer.vertices.normal_size_floats() > 0;
|
||||
if (has_normals) {
|
||||
glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
|
||||
|
@ -1404,10 +1409,10 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
|
|||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
|
||||
if (has_normals)
|
||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
if (normal_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(normal_id));
|
||||
if (position_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(position_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
|
||||
buffer_range.first = buffer_range.last;
|
||||
|
@ -1423,10 +1428,15 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
|
|||
if (!buffer.visible || !buffer.has_data())
|
||||
continue;
|
||||
|
||||
GLShaderProgram* shader = opengl_manager.get_shader("cali");
|
||||
GLShaderProgram* shader = opengl_manager.get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
int position_id = shader->get_attrib_location("v_position");
|
||||
int normal_id = shader->get_attrib_location("v_normal");
|
||||
|
||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) {
|
||||
//shader->set_uniform("emission_factor", 0.25f);
|
||||
render_as_instanced_model(buffer, *shader);
|
||||
|
@ -1434,7 +1444,7 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
|
|||
}
|
||||
else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
//shader->set_uniform("emission_factor", 0.25f);
|
||||
render_as_batched_model(buffer, *shader);
|
||||
render_as_batched_model(buffer, *shader, position_id, normal_id);
|
||||
//shader->set_uniform("emission_factor", 0.0f);
|
||||
}
|
||||
else {
|
||||
|
@ -1452,12 +1462,16 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
|
|||
continue;
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
|
||||
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));
|
||||
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));
|
||||
}
|
||||
bool has_normals = false;// buffer.vertices.normal_size_floats() > 0;
|
||||
if (has_normals) {
|
||||
glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
|
||||
|
@ -1474,10 +1488,11 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
|
|||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
|
||||
if (has_normals)
|
||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
if (normal_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(normal_id));
|
||||
if (position_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(position_id));
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
}
|
||||
}
|
||||
|
@ -2032,15 +2047,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const
|
|||
|
||||
// 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) {
|
||||
auto add_vertex = [&vertices](const Vec3f& position, const Vec3f& normal) {
|
||||
auto add_vertex = [&vertices](const Vec3f& position) {
|
||||
// add position
|
||||
vertices.push_back(position.x());
|
||||
vertices.push_back(position.y());
|
||||
vertices.push_back(position.z());
|
||||
// add normal
|
||||
vertices.push_back(normal.x());
|
||||
vertices.push_back(normal.y());
|
||||
vertices.push_back(normal.z());
|
||||
};
|
||||
// x component of the normal to the current segment (the normal is parallel to the XY plane)
|
||||
//BBS: Has modified a lot for this function to support arc move
|
||||
|
@ -2048,13 +2059,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const
|
|||
for (size_t i = 0; i < loop_num + 1; i++) {
|
||||
const Vec3f &previous = (i == 0? prev.position : curr.interpolation_points[i-1]);
|
||||
const Vec3f ¤t = (i == loop_num? curr.position : curr.interpolation_points[i]);
|
||||
const Vec3f dir = (current - previous).normalized();
|
||||
Vec3f normal(dir.y(), -dir.x(), 0.0);
|
||||
normal.normalize();
|
||||
// add previous vertex
|
||||
add_vertex(previous, normal);
|
||||
add_vertex(previous);
|
||||
// add current vertex
|
||||
add_vertex(current, normal);
|
||||
add_vertex(current);
|
||||
}
|
||||
};
|
||||
//BBS: modify a lot to support arc travel
|
||||
|
@ -2325,7 +2333,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const
|
|||
auto add_indices_as_model_batch = [](const GLModel::Geometry& data, IndexBuffer& indices, IBufferType base_index) {
|
||||
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_ushort_index(i) + base_index));
|
||||
indices.push_back(static_cast<IBufferType>(data.extract_index(i) + base_index));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3765,15 +3773,14 @@ m_no_render_path = false;
|
|||
void GCodeViewer::render_toolpaths()
|
||||
{
|
||||
#if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
|
||||
float point_size = 20.0f;
|
||||
const float point_size = 20.0f;
|
||||
#else
|
||||
float point_size = 0.8f;
|
||||
const float point_size = 0.8f;
|
||||
#endif // ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
|
||||
std::array<float, 4> light_intensity = { 0.25f, 0.70f, 0.75f, 0.75f };
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
double zoom = camera.get_zoom();
|
||||
const double zoom = camera.get_zoom();
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
float near_plane_height = camera.get_type() == Camera::EType::Perspective ? static_cast<float>(viewport[3]) / (2.0f * static_cast<float>(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) :
|
||||
const float near_plane_height = camera.get_type() == Camera::EType::Perspective ? static_cast<float>(viewport[3]) / (2.0f * static_cast<float>(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) :
|
||||
static_cast<float>(viewport[3]) * 0.0005;
|
||||
|
||||
auto shader_init_as_points = [zoom, point_size, near_plane_height](GLShaderProgram& shader) {
|
||||
|
@ -3793,7 +3800,7 @@ void GCodeViewer::render_toolpaths()
|
|||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
this
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
](std::vector<RenderPath>::reverse_iterator it_path, std::vector<RenderPath>::reverse_iterator it_end, GLShaderProgram& shader, int uniform_color) {
|
||||
](std::vector<RenderPath>::iterator it_path, std::vector<RenderPath>::iterator it_end, GLShaderProgram& shader, int uniform_color) {
|
||||
glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
||||
glsafe(::glEnable(GL_POINT_SPRITE));
|
||||
|
||||
|
@ -3802,7 +3809,7 @@ void GCodeViewer::render_toolpaths()
|
|||
// Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
|
||||
assert(! path.sizes.empty());
|
||||
assert(! path.offsets.empty());
|
||||
glsafe(::glUniform4fv(uniform_color, 1, static_cast<const GLfloat*>(path.color.data())));
|
||||
shader.set_uniform(uniform_color, path.color);
|
||||
glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
++m_statistics.gl_multi_points_calls_count;
|
||||
|
@ -3813,20 +3820,17 @@ void GCodeViewer::render_toolpaths()
|
|||
glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
||||
};
|
||||
|
||||
auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) {
|
||||
shader.set_uniform("light_intensity", light_intensity);
|
||||
};
|
||||
auto render_as_lines = [
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
this
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
](std::vector<RenderPath>::reverse_iterator it_path, std::vector<RenderPath>::reverse_iterator it_end, GLShaderProgram& shader, int uniform_color) {
|
||||
](std::vector<RenderPath>::iterator it_path, std::vector<RenderPath>::iterator it_end, GLShaderProgram& shader, int uniform_color) {
|
||||
for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) {
|
||||
const RenderPath& path = *it;
|
||||
// Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
|
||||
assert(! path.sizes.empty());
|
||||
assert(! path.offsets.empty());
|
||||
glsafe(::glUniform4fv(uniform_color, 1, static_cast<const GLfloat*>(path.color.data())));
|
||||
shader.set_uniform(uniform_color, path.color);
|
||||
glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
++m_statistics.gl_multi_lines_calls_count;
|
||||
|
@ -3838,13 +3842,13 @@ void GCodeViewer::render_toolpaths()
|
|||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
this
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
](std::vector<RenderPath>::reverse_iterator it_path, std::vector<RenderPath>::reverse_iterator it_end, GLShaderProgram& shader, int uniform_color) {
|
||||
](std::vector<RenderPath>::iterator it_path, std::vector<RenderPath>::iterator it_end, GLShaderProgram& shader, int uniform_color) {
|
||||
for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) {
|
||||
const RenderPath& path = *it;
|
||||
// Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
|
||||
assert(! path.sizes.empty());
|
||||
assert(! path.offsets.empty());
|
||||
glsafe(::glUniform4fv(uniform_color, 1, static_cast<const GLfloat*>(path.color.data())));
|
||||
shader.set_uniform(uniform_color, path.color);
|
||||
glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
++m_statistics.gl_multi_triangles_calls_count;
|
||||
|
@ -3877,9 +3881,9 @@ void GCodeViewer::render_toolpaths()
|
|||
};
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
auto render_as_batched_model = [this](TBuffer& buffer, GLShaderProgram& shader) {
|
||||
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) {
|
||||
auto render_as_batched_model = [](TBuffer& buffer, GLShaderProgram& shader, int position_id, int normal_id) {
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
||||
struct Range
|
||||
|
@ -3889,30 +3893,34 @@ void GCodeViewer::render_toolpaths()
|
|||
bool intersects(const Range& other) const { return (other.last < first || other.first > last) ? false : true; }
|
||||
};
|
||||
Range buffer_range = { 0, 0 };
|
||||
size_t indices_per_instance = buffer.model.data.indices_count();
|
||||
const size_t indices_per_instance = buffer.model.data.indices_count();
|
||||
|
||||
for (size_t j = 0; j < buffer.indices.size(); ++j) {
|
||||
const IBuffer& i_buffer = buffer.indices[j];
|
||||
buffer_range.last = buffer_range.first + i_buffer.count / indices_per_instance;
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
|
||||
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));
|
||||
bool has_normals = buffer.vertices.normal_size_floats() > 0;
|
||||
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));
|
||||
}
|
||||
const bool has_normals = buffer.vertices.normal_size_floats() > 0;
|
||||
if (has_normals) {
|
||||
glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
|
||||
|
||||
for (auto& range : buffer.model.instances.render_ranges.ranges) {
|
||||
Range range_range = { range.offset, range.offset + range.count };
|
||||
const Range range_range = { range.offset, range.offset + range.count };
|
||||
if (range_range.intersects(buffer_range)) {
|
||||
shader.set_uniform("uniform_color", range.color);
|
||||
unsigned int offset = (range_range.first > buffer_range.first) ? range_range.first - buffer_range.first : 0;
|
||||
size_t offset_bytes = static_cast<size_t>(offset) * indices_per_instance * sizeof(IBufferType);
|
||||
Range render_range = { std::max(range_range.first, buffer_range.first), std::min(range_range.last, buffer_range.last) };
|
||||
size_t count = static_cast<size_t>(render_range.last - render_range.first) * indices_per_instance;
|
||||
const unsigned int offset = (range_range.first > buffer_range.first) ? range_range.first - buffer_range.first : 0;
|
||||
const size_t offset_bytes = static_cast<size_t>(offset) * indices_per_instance * sizeof(IBufferType);
|
||||
const Range render_range = { std::max(range_range.first, buffer_range.first), std::min(range_range.last, buffer_range.last) };
|
||||
const size_t count = static_cast<size_t>(render_range.last - render_range.first) * indices_per_instance;
|
||||
if (count > 0) {
|
||||
glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)count, GL_UNSIGNED_SHORT, (const void*)offset_bytes));
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
@ -3924,10 +3932,10 @@ void GCodeViewer::render_toolpaths()
|
|||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
|
||||
if (has_normals)
|
||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
if (normal_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(normal_id));
|
||||
if (position_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(position_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
|
||||
buffer_range.first = buffer_range.last;
|
||||
|
@ -3938,9 +3946,8 @@ void GCodeViewer::render_toolpaths()
|
|||
return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0));
|
||||
};
|
||||
|
||||
unsigned char begin_id = buffer_id(EMoveType::Retract);
|
||||
unsigned char end_id = buffer_id(EMoveType::Count);
|
||||
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":begin_id %1%, end_id %2% ")%(int)begin_id %(int)end_id;
|
||||
const unsigned char begin_id = buffer_id(EMoveType::Retract);
|
||||
const unsigned char end_id = buffer_id(EMoveType::Count);
|
||||
|
||||
for (unsigned char i = begin_id; i < end_id; ++i) {
|
||||
TBuffer& buffer = m_buffers[i];
|
||||
|
@ -3948,9 +3955,21 @@ void GCodeViewer::render_toolpaths()
|
|||
continue;
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str());
|
||||
if (shader != nullptr) {
|
||||
if (shader == nullptr)
|
||||
continue;
|
||||
|
||||
shader->start_using();
|
||||
|
||||
int position_id = -1;
|
||||
int normal_id = -1;
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
shader->set_uniform("view_model_matrix", view_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
|
||||
position_id = shader->get_attrib_location("v_position");
|
||||
normal_id = shader->get_attrib_location("v_normal");
|
||||
|
||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) {
|
||||
shader->set_uniform("emission_factor", 0.25f);
|
||||
render_as_instanced_model(buffer, *shader);
|
||||
|
@ -3958,35 +3977,34 @@ void GCodeViewer::render_toolpaths()
|
|||
}
|
||||
else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
shader->set_uniform("emission_factor", 0.25f);
|
||||
render_as_batched_model(buffer, *shader);
|
||||
render_as_batched_model(buffer, *shader, position_id, normal_id);
|
||||
shader->set_uniform("emission_factor", 0.0f);
|
||||
}
|
||||
else {
|
||||
switch (buffer.render_primitive_type) {
|
||||
case TBuffer::ERenderPrimitiveType::Point: shader_init_as_points(*shader); break;
|
||||
case TBuffer::ERenderPrimitiveType::Line: shader_init_as_lines(*shader); break;
|
||||
default: break;
|
||||
}
|
||||
int uniform_color = shader->get_uniform_location("uniform_color");
|
||||
auto it_path = buffer.render_paths.rbegin();
|
||||
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":buffer indices size %1%, render_path size %2% ")%buffer.indices.size() %buffer.render_paths.size();
|
||||
unsigned int indices_count = static_cast<unsigned int>(buffer.indices.size());
|
||||
for (unsigned int index = 0; index < indices_count; ++index) {
|
||||
unsigned int ibuffer_id = indices_count - index - 1;
|
||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Point)
|
||||
shader_init_as_points(*shader);
|
||||
const int uniform_color = shader->get_uniform_location("uniform_color");
|
||||
|
||||
auto it_path = buffer.render_paths.begin();
|
||||
for (unsigned int ibuffer_id = 0; ibuffer_id < static_cast<unsigned int>(buffer.indices.size()); ++ibuffer_id) {
|
||||
const IBuffer& i_buffer = buffer.indices[ibuffer_id];
|
||||
// Skip all paths with ibuffer_id < ibuffer_id.
|
||||
for (; it_path != buffer.render_paths.rend() && it_path->ibuffer_id > ibuffer_id; ++ it_path) ;
|
||||
if (it_path == buffer.render_paths.rend() || it_path->ibuffer_id < ibuffer_id)
|
||||
for (; it_path != buffer.render_paths.end() && it_path->ibuffer_id < ibuffer_id; ++it_path);
|
||||
if (it_path == buffer.render_paths.end() || it_path->ibuffer_id > ibuffer_id)
|
||||
// Not found. This shall not happen.
|
||||
continue;
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
|
||||
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));
|
||||
bool has_normals = buffer.vertices.normal_size_floats() > 0;
|
||||
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));
|
||||
}
|
||||
const bool has_normals = buffer.vertices.normal_size_floats() > 0;
|
||||
if (has_normals) {
|
||||
glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
|
||||
|
@ -3995,16 +4013,16 @@ void GCodeViewer::render_toolpaths()
|
|||
switch (buffer.render_primitive_type)
|
||||
{
|
||||
case TBuffer::ERenderPrimitiveType::Point: {
|
||||
render_as_points(it_path, buffer.render_paths.rend(), *shader, uniform_color);
|
||||
render_as_points(it_path, buffer.render_paths.end(), *shader, uniform_color);
|
||||
break;
|
||||
}
|
||||
case TBuffer::ERenderPrimitiveType::Line: {
|
||||
glsafe(::glLineWidth(static_cast<GLfloat>(line_width(zoom))));
|
||||
render_as_lines(it_path, buffer.render_paths.rend(), *shader, uniform_color);
|
||||
render_as_lines(it_path, buffer.render_paths.end(), *shader, uniform_color);
|
||||
break;
|
||||
}
|
||||
case TBuffer::ERenderPrimitiveType::Triangle: {
|
||||
render_as_triangles(it_path, buffer.render_paths.rend(), *shader, uniform_color);
|
||||
render_as_triangles(it_path, buffer.render_paths.end(), *shader, uniform_color);
|
||||
break;
|
||||
}
|
||||
default: { break; }
|
||||
|
@ -4012,17 +4030,16 @@ void GCodeViewer::render_toolpaths()
|
|||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
|
||||
if (has_normals)
|
||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
if (normal_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(normal_id));
|
||||
if (position_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(position_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
}
|
||||
}
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
auto render_sequential_range_cap = [this]
|
||||
|
@ -4030,17 +4047,35 @@ void GCodeViewer::render_toolpaths()
|
|||
auto render_sequential_range_cap = []
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
(const SequentialRangeCap& cap) {
|
||||
GLShaderProgram* shader = wxGetApp().get_shader(cap.buffer->shader.c_str());
|
||||
if (shader != nullptr) {
|
||||
const TBuffer* buffer = cap.buffer;
|
||||
GLShaderProgram* shader = wxGetApp().get_shader(buffer->shader.c_str());
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
shader->start_using();
|
||||
|
||||
int position_id = -1;
|
||||
int normal_id = -1;
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
shader->set_uniform("view_model_matrix", view_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
|
||||
position_id = shader->get_attrib_location("v_position");
|
||||
normal_id = shader->get_attrib_location("v_normal");
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo));
|
||||
glsafe(::glVertexPointer(cap.buffer->vertices.position_size_floats(), GL_FLOAT, cap.buffer->vertices.vertex_size_bytes(), (const void*)cap.buffer->vertices.position_offset_bytes()));
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
bool has_normals = cap.buffer->vertices.normal_size_floats() > 0;
|
||||
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));
|
||||
}
|
||||
const bool has_normals = buffer->vertices.normal_size_floats() > 0;
|
||||
if (has_normals) {
|
||||
glsafe(::glNormalPointer(GL_FLOAT, cap.buffer->vertices.vertex_size_bytes(), (const void*)cap.buffer->vertices.normal_offset_bytes()));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
shader->set_uniform("uniform_color", cap.color);
|
||||
|
@ -4053,14 +4088,14 @@ void GCodeViewer::render_toolpaths()
|
|||
++m_statistics.gl_triangles_calls_count;
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
||||
if (has_normals)
|
||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
if (normal_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(normal_id));
|
||||
if (position_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(position_id));
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i < 2; ++i) {
|
||||
|
@ -4076,7 +4111,7 @@ void GCodeViewer::render_shells()
|
|||
//if (!m_shells.visible || m_shells.volumes.empty())
|
||||
return;
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -4084,8 +4119,9 @@ void GCodeViewer::render_shells()
|
|||
// glsafe(::glDepthMask(GL_FALSE));
|
||||
|
||||
shader->start_using();
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
//BBS: reopen cul faces
|
||||
m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix());
|
||||
m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, false, camera.get_view_matrix(), camera.get_projection_matrix());
|
||||
shader->stop_using();
|
||||
|
||||
// glsafe(::glDepthMask(GL_TRUE));
|
||||
|
|
|
@ -14,22 +14,16 @@
|
|||
#include "libslic3r/Technologies.hpp"
|
||||
#include "libslic3r/Tesselate.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "slic3r/GUI/3DBed.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#include "slic3r/GUI/BackgroundSlicingProcess.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
#include "slic3r/GUI/GLShader.hpp"
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/Tab.hpp"
|
||||
#include "slic3r/GUI/GUI_Preview.hpp"
|
||||
#include "slic3r/GUI/OpenGLManager.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/MainFrame.hpp"
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp"
|
||||
#include "slic3r/GUI/BitmapCache.hpp"
|
||||
#include "slic3r/Utils/MacDarkMode.hpp"
|
||||
|
||||
#include "3DBed.hpp"
|
||||
#include "3DScene.hpp"
|
||||
#include "BackgroundSlicingProcess.hpp"
|
||||
#include "GLShader.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "Tab.hpp"
|
||||
#include "GUI_Preview.hpp"
|
||||
#include "OpenGLManager.hpp"
|
||||
#include "Plater.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#include "GUI_Colors.hpp"
|
||||
|
@ -38,6 +32,9 @@
|
|||
#include "NotificationManager.hpp"
|
||||
#include "format.hpp"
|
||||
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp"
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
|
||||
#include <slic3r/GUI/GUI_Utils.hpp>
|
||||
|
||||
#if ENABLE_RETINA_GL
|
||||
|
@ -166,7 +163,7 @@ void GLCanvas3D::LayersEditing::select_object(const Model& model, int object_id)
|
|||
|
||||
bool GLCanvas3D::LayersEditing::is_allowed() const
|
||||
{
|
||||
return wxGetApp().get_shader("variable_layer_height") != nullptr && m_z_texture_id > 0;
|
||||
return wxGetApp().get_shader("variable_layer_height_attr") != nullptr && m_z_texture_id > 0;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::LayersEditing::is_enabled() const
|
||||
|
@ -220,9 +217,8 @@ void GLCanvas3D::LayersEditing::render_variable_layer_height_dialog(const GLCanv
|
|||
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
const Size& cnv_size = canvas.get_canvas_size();
|
||||
float zoom = (float)wxGetApp().plater()->get_camera().get_zoom();
|
||||
float left_pos = canvas.m_main_toolbar.get_item("layersediting")->render_left_pos;
|
||||
const float x = 0.5 * cnv_size.get_width() + left_pos * zoom;
|
||||
const float x = (1 + left_pos) * cnv_size.get_width() / 2;
|
||||
imgui.set_next_window_pos(x, canvas.m_main_toolbar.get_height(), ImGuiCond_Always, 0.0f, 0.0f);
|
||||
|
||||
imgui.push_toolbar_style(canvas.get_scale());
|
||||
|
@ -322,12 +318,8 @@ void GLCanvas3D::LayersEditing::render_variable_layer_height_dialog(const GLCanv
|
|||
void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas)
|
||||
{
|
||||
render_variable_layer_height_dialog(canvas);
|
||||
const Rect& bar_rect = get_bar_rect_viewport(canvas);
|
||||
m_profile.dirty = m_profile.old_bar_rect != bar_rect;
|
||||
render_active_object_annotations(canvas, bar_rect);
|
||||
render_profile(bar_rect);
|
||||
m_profile.old_bar_rect = bar_rect;
|
||||
m_profile.dirty = false;
|
||||
render_active_object_annotations(canvas);
|
||||
render_profile(canvas);
|
||||
}
|
||||
|
||||
float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
|
||||
|
@ -361,18 +353,9 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas)
|
|||
return { w - thickness_bar_width(canvas), 0.0f, w, h };
|
||||
}
|
||||
|
||||
Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
|
||||
{
|
||||
const Size& cnv_size = canvas.get_canvas_size();
|
||||
float half_w = 0.5f * (float)cnv_size.get_width();
|
||||
float half_h = 0.5f * (float)cnv_size.get_height();
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
return { (half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom };
|
||||
}
|
||||
|
||||
bool GLCanvas3D::LayersEditing::is_initialized() const
|
||||
{
|
||||
return wxGetApp().get_shader("variable_layer_height") != nullptr;
|
||||
return wxGetApp().get_shader("variable_layer_height_attr") != nullptr;
|
||||
}
|
||||
|
||||
std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) const
|
||||
|
@ -401,12 +384,20 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con
|
|||
return ret;
|
||||
}
|
||||
|
||||
void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect)
|
||||
void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas)
|
||||
{
|
||||
if (!m_enabled)
|
||||
return;
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height");
|
||||
const Size cnv_size = canvas.get_canvas_size();
|
||||
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)
|
||||
return;
|
||||
|
||||
const float cnv_inv_width = 1.0f / cnv_width;
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -417,32 +408,36 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3
|
|||
shader->set_uniform("z_cursor", m_object_max_z * this->get_cursor_z_relative(canvas));
|
||||
shader->set_uniform("z_cursor_band_width", band_width);
|
||||
shader->set_uniform("object_max_z", m_object_max_z);
|
||||
shader->set_uniform("view_model_matrix", Transform3d::Identity());
|
||||
shader->set_uniform("projection_matrix", Transform3d::Identity());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)Eigen::Matrix3d::Identity());
|
||||
|
||||
glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id));
|
||||
|
||||
// Render the color bar
|
||||
if (!m_profile.background.is_initialized() || m_profile.dirty) {
|
||||
if (!m_profile.background.is_initialized() || m_profile.old_canvas_width != cnv_width) {
|
||||
m_profile.old_canvas_width = cnv_width;
|
||||
m_profile.background.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2 };
|
||||
init_data.reserve_vertices(4);
|
||||
init_data.reserve_indices(6);
|
||||
|
||||
// vertices
|
||||
const float l = bar_rect.get_left();
|
||||
const float r = bar_rect.get_right();
|
||||
const float t = bar_rect.get_top();
|
||||
const float b = bar_rect.get_bottom();
|
||||
const float l = 1.0f - 2.0f * THICKNESS_BAR_WIDTH * cnv_inv_width;
|
||||
const float r = 1.0f;
|
||||
const float t = 1.0f;
|
||||
const float b = -1.0f;
|
||||
init_data.add_vertex(Vec2f(l, b), Vec2f(0.0f, 0.0f));
|
||||
init_data.add_vertex(Vec2f(r, b), Vec2f(1.0f, 0.0f));
|
||||
init_data.add_vertex(Vec2f(r, t), Vec2f(1.0f, 1.0f));
|
||||
init_data.add_vertex(Vec2f(l, t), Vec2f(0.0f, 1.0f));
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_triangle(0, 1, 2);
|
||||
init_data.add_ushort_triangle(2, 3, 0);
|
||||
init_data.add_triangle(0, 1, 2);
|
||||
init_data.add_triangle(2, 3, 0);
|
||||
|
||||
m_profile.background.init_from(std::move(init_data));
|
||||
}
|
||||
|
@ -454,73 +449,82 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3
|
|||
shader->stop_using();
|
||||
}
|
||||
|
||||
void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect)
|
||||
void GLCanvas3D::LayersEditing::render_profile(const GLCanvas3D& canvas)
|
||||
{
|
||||
if (!m_enabled)
|
||||
return;
|
||||
|
||||
//FIXME show some kind of legend.
|
||||
|
||||
if (!m_slicing_parameters)
|
||||
return;
|
||||
|
||||
const Size cnv_size = canvas.get_canvas_size();
|
||||
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)
|
||||
return;
|
||||
|
||||
// Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region.
|
||||
const float scale_x = bar_rect.get_width() / float(1.12 * m_slicing_parameters->max_layer_height);
|
||||
const float scale_y = bar_rect.get_height() / m_object_max_z;
|
||||
const float scale_x = THICKNESS_BAR_WIDTH / float(1.12 * m_slicing_parameters->max_layer_height);
|
||||
const float scale_y = cnv_height / m_object_max_z;
|
||||
|
||||
const float cnv_inv_width = 1.0f / cnv_width;
|
||||
const float cnv_inv_height = 1.0f / cnv_height;
|
||||
|
||||
// Baseline
|
||||
if (!m_profile.baseline.is_initialized() || m_profile.dirty) {
|
||||
if (!m_profile.baseline.is_initialized() || m_profile.old_layer_height_profile != m_layer_height_profile) {
|
||||
m_profile.baseline.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P2};
|
||||
init_data.color = ColorRGBA::BLACK();
|
||||
init_data.reserve_vertices(2);
|
||||
init_data.reserve_indices(2);
|
||||
|
||||
// vertices
|
||||
const float x = bar_rect.get_left() + float(m_slicing_parameters->layer_height) * scale_x;
|
||||
init_data.add_vertex(Vec2f(x, bar_rect.get_bottom()));
|
||||
init_data.add_vertex(Vec2f(x, bar_rect.get_top()));
|
||||
const float axis_x = 2.0f * ((cnv_width - THICKNESS_BAR_WIDTH + float(m_slicing_parameters->layer_height) * scale_x) * cnv_inv_width - 0.5f);
|
||||
init_data.add_vertex(Vec2f(axis_x, -1.0f));
|
||||
init_data.add_vertex(Vec2f(axis_x, 1.0f));
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_line(0, 1);
|
||||
init_data.add_line(0, 1);
|
||||
|
||||
m_profile.baseline.init_from(std::move(init_data));
|
||||
}
|
||||
|
||||
if (!m_profile.profile.is_initialized() || m_profile.dirty || m_profile.old_layer_height_profile != m_layer_height_profile) {
|
||||
if (!m_profile.profile.is_initialized() || m_profile.old_layer_height_profile != m_layer_height_profile) {
|
||||
m_profile.old_layer_height_profile = m_layer_height_profile;
|
||||
m_profile.profile.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::index_type(m_layer_height_profile.size() / 2) };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P2 };
|
||||
init_data.color = ColorRGBA::BLUE();
|
||||
init_data.reserve_vertices(m_layer_height_profile.size() / 2);
|
||||
init_data.reserve_indices(m_layer_height_profile.size() / 2);
|
||||
|
||||
// vertices + indices
|
||||
for (unsigned int i = 0; i < (unsigned int)m_layer_height_profile.size(); i += 2) {
|
||||
init_data.add_vertex(Vec2f(bar_rect.get_left() + float(m_layer_height_profile[i + 1]) * scale_x,
|
||||
bar_rect.get_bottom() + float(m_layer_height_profile[i]) * scale_y));
|
||||
if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
||||
init_data.add_ushort_index((unsigned short)i / 2);
|
||||
else
|
||||
init_data.add_uint_index(i / 2);
|
||||
init_data.add_vertex(Vec2f(2.0f * ((cnv_width - THICKNESS_BAR_WIDTH + float(m_layer_height_profile[i + 1]) * scale_x) * cnv_inv_width - 0.5f),
|
||||
2.0f * (float(m_layer_height_profile[i]) * scale_y * cnv_inv_height - 0.5)));
|
||||
init_data.add_index(i / 2);
|
||||
}
|
||||
|
||||
m_profile.profile.init_from(std::move(init_data));
|
||||
}
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
shader->set_uniform("view_model_matrix", Transform3d::Identity());
|
||||
shader->set_uniform("projection_matrix", Transform3d::Identity());
|
||||
m_profile.baseline.render();
|
||||
m_profile.profile.render();
|
||||
shader->stop_using();
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D & canvas, const GLVolumeCollection & volumes)//render volume and layer height texture (has mapping relation with each other)
|
||||
void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection& volumes)
|
||||
{
|
||||
assert(this->is_allowed());
|
||||
assert(this->last_object_id != -1);
|
||||
|
@ -530,7 +534,7 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D & canvas, const
|
|||
if (current_shader != nullptr)
|
||||
current_shader->stop_using();
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -544,6 +548,9 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D & canvas, const
|
|||
shader->set_uniform("z_cursor", float(m_object_max_z) * float(this->get_cursor_z_relative(canvas)));
|
||||
shader->set_uniform("z_cursor_band_width", float(this->band_width));
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
// Initialize the layer height texture mapping.
|
||||
const GLsizei w = (GLsizei)m_layers_texture.width;
|
||||
const GLsizei h = (GLsizei)m_layers_texture.height;
|
||||
|
@ -562,6 +569,9 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D & canvas, const
|
|||
|
||||
shader->set_uniform("volume_world_matrix", glvolume->world_matrix());
|
||||
shader->set_uniform("object_max_z", 0.0f);
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() * glvolume->world_matrix();
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
|
||||
glvolume->render();
|
||||
}
|
||||
|
@ -883,7 +893,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
|
|||
if (!polygons.empty()) {
|
||||
if (m_render_fill) {
|
||||
GLModel::Geometry fill_data;
|
||||
fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::UINT };
|
||||
fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 };
|
||||
fill_data.color = { 0.8f, 0.8f, 1.0f, 0.5f };
|
||||
|
||||
// vertices + indices
|
||||
|
@ -897,7 +907,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
|
|||
fill_data.add_vertex((Vec3f)(v.cast<float>() + 0.0125f * Vec3f::UnitZ())); // add a small positive z to avoid z-fighting
|
||||
++vertices_counter;
|
||||
if (vertices_counter % 3 == 0)
|
||||
fill_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
|
||||
fill_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -910,7 +920,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
|
|||
//BBS: add the height limit compute logic
|
||||
if (!height_polygons.empty()) {
|
||||
GLModel::Geometry height_fill_data;
|
||||
height_fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::UINT };
|
||||
height_fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 };
|
||||
height_fill_data.color = {0.8f, 0.8f, 1.0f, 0.5f};
|
||||
|
||||
// vertices + indices
|
||||
|
@ -923,7 +933,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
|
|||
height_fill_data.add_vertex(point);
|
||||
++vertices_counter;
|
||||
if (vertices_counter % 3 == 0)
|
||||
height_fill_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
|
||||
height_fill_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -936,12 +946,16 @@ void GLCanvas3D::SequentialPrintClearance::render()
|
|||
const ColorRGBA FILL_COLOR = { 0.7f, 0.7f, 1.0f, 0.5f };
|
||||
const ColorRGBA NO_FILL_COLOR = { 0.75f, 0.75f, 0.75f, 0.75f };
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
shader->start_using();
|
||||
|
||||
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());
|
||||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
glsafe(::glDisable(GL_CULL_FACE));
|
||||
glsafe(::glEnable(GL_BLEND));
|
||||
|
@ -1839,9 +1853,9 @@ void GLCanvas3D::render(bool only_init)
|
|||
_render_sla_slices();
|
||||
_render_selection();
|
||||
if (!no_partplate)
|
||||
_render_bed(!camera.is_looking_downward(), show_axes);
|
||||
_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes);
|
||||
if (!no_partplate) //BBS: add outline logic
|
||||
_render_platelist(!camera.is_looking_downward(), only_current, only_body, hover_id, true);
|
||||
_render_platelist(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), only_current, only_body, hover_id, true);
|
||||
_render_objects(GLVolumeCollection::ERenderType::Transparent, !m_gizmos.is_running());
|
||||
}
|
||||
/* preview render */
|
||||
|
@ -1849,8 +1863,8 @@ void GLCanvas3D::render(bool only_init)
|
|||
_render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running());
|
||||
_render_sla_slices();
|
||||
_render_selection();
|
||||
_render_bed(!camera.is_looking_downward(), show_axes);
|
||||
_render_platelist(!camera.is_looking_downward(), only_current, true, hover_id);
|
||||
_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes);
|
||||
_render_platelist(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), only_current, true, hover_id);
|
||||
// BBS: GUI refactor: add canvas size as parameters
|
||||
_render_gcode(cnv_size.get_width(), cnv_size.get_height());
|
||||
}
|
||||
|
@ -1858,7 +1872,7 @@ void GLCanvas3D::render(bool only_init)
|
|||
else if (m_canvas_type == ECanvasType::CanvasAssembleView) {
|
||||
//BBS: add outline logic
|
||||
_render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running());
|
||||
//_render_bed(!camera.is_looking_downward(), show_axes);
|
||||
//_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes);
|
||||
_render_plane();
|
||||
//BBS: add outline logic insteadof selection under assemble view
|
||||
//_render_selection();
|
||||
|
@ -1992,7 +2006,7 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w,
|
|||
void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
|
||||
const GLVolumeCollection& volumes, Camera::EType camera_type, bool use_top_view, bool for_picking)
|
||||
{
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("thumbnail");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("thumbnail_attr");
|
||||
ModelObjectPtrs& model_objects = GUI::wxGetApp().model().objects;
|
||||
std::vector<ColorRGBA> colors = ::get_extruders_colors();
|
||||
switch (OpenGLManager::get_framebuffers_type())
|
||||
|
@ -5180,7 +5194,7 @@ bool GLCanvas3D::_render_orient_menu(float left, float right, float bottom, floa
|
|||
//original use center as {0.0}, and top is (canvas_h/2), bottom is (-canvas_h/2), also plus inv_camera
|
||||
//now change to left_up as {0,0}, and top is 0, bottom is canvas_h
|
||||
#if BBS_TOOLBAR_ON_TOP
|
||||
const float x = left * float(wxGetApp().plater()->get_camera().get_zoom()) + 0.5f * canvas_w;
|
||||
const float x = (1 + left) * canvas_w / 2;
|
||||
ImGuiWrapper::push_toolbar_style(get_scale());
|
||||
imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
|
||||
#else
|
||||
|
@ -5265,9 +5279,8 @@ bool GLCanvas3D::_render_arrange_menu(float left, float right, float bottom, flo
|
|||
//original use center as {0.0}, and top is (canvas_h/2), bottom is (-canvas_h/2), also plus inv_camera
|
||||
//now change to left_up as {0,0}, and top is 0, bottom is canvas_h
|
||||
#if BBS_TOOLBAR_ON_TOP
|
||||
float zoom = (float)wxGetApp().plater()->get_camera().get_zoom();
|
||||
float left_pos = m_main_toolbar.get_item("arrange")->render_left_pos;
|
||||
const float x = 0.5 * canvas_w + left_pos * zoom;
|
||||
const float x = (1 + left_pos) * canvas_w / 2;
|
||||
imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.0f, 0.0f);
|
||||
|
||||
#else
|
||||
|
@ -5536,19 +5549,15 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
|
|||
}
|
||||
else {
|
||||
camera.zoom_to_box(volumes_box);
|
||||
const Vec3d& target = camera.get_target();
|
||||
double distance = camera.get_distance();
|
||||
camera.select_view("iso");
|
||||
camera.apply_view_matrix();
|
||||
|
||||
camera.apply_projection(plate_build_volume);
|
||||
}
|
||||
|
||||
camera.apply_view_matrix();
|
||||
|
||||
const Transform3d &view_matrix = camera.get_view_matrix();
|
||||
|
||||
camera.apply_projection(plate_build_volume);
|
||||
|
||||
//GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||
//GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
|
||||
if (!for_picking && (shader == nullptr)) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("render_thumbnail with no picking: shader is null, return directly");
|
||||
return;
|
||||
|
@ -5561,6 +5570,8 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
|
|||
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
const Transform3d &projection_matrix = camera.get_projection_matrix();
|
||||
|
||||
if (for_picking) {
|
||||
//if (OpenGLManager::can_multisample())
|
||||
// This flag is often ignored by NVIDIA drivers if rendering into a screen buffer.
|
||||
|
@ -5573,9 +5584,6 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
|
|||
// do not cull backfaces to show broken geometry, if any
|
||||
glsafe(::glDisable(GL_CULL_FACE));
|
||||
|
||||
//glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
//glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
|
||||
for (GLVolume* vol : visible_volumes) {
|
||||
// Object picking mode. Render the object with a color encoding the object index.
|
||||
// we reserve color = (0,0,0) for occluders (as the printbed)
|
||||
|
@ -5587,15 +5595,19 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
|
|||
unsigned int g = (id & (0x000000FF << 8)) >> 8;
|
||||
unsigned int b = (id & (0x000000FF << 16)) >> 16;
|
||||
unsigned int a = 0xFF;
|
||||
glsafe(::glColor4f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255));
|
||||
vol->model.set_color({(GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255});
|
||||
/*curr_color[0] = (GLfloat)r * INV_255;
|
||||
curr_color[1] = (GLfloat)g * INV_255;
|
||||
curr_color[2] = (GLfloat)b * INV_255;
|
||||
curr_color[3] = (GLfloat)a * INV_255;
|
||||
shader->set_uniform("uniform_color", curr_color);*/
|
||||
|
||||
bool is_active = vol->is_active;
|
||||
const bool is_active = vol->is_active;
|
||||
vol->is_active = true;
|
||||
const Transform3d matrix = view_matrix * vol->world_matrix();
|
||||
shader->set_uniform("view_model_matrix", matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d) matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
vol->simple_render(nullptr, model_objects, extruder_colors);
|
||||
vol->is_active = is_active;
|
||||
}
|
||||
|
@ -5627,8 +5639,12 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
|
|||
shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? orange : gray);
|
||||
}*/
|
||||
// the volume may have been deactivated by an active gizmo
|
||||
bool is_active = vol->is_active;
|
||||
const bool is_active = vol->is_active;
|
||||
vol->is_active = true;
|
||||
const Transform3d matrix = view_matrix * vol->world_matrix();
|
||||
shader->set_uniform("view_model_matrix", matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d) matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
vol->simple_render(shader, model_objects, extruder_colors);
|
||||
vol->is_active = is_active;
|
||||
}
|
||||
|
@ -6404,7 +6420,8 @@ void GLCanvas3D::_picking_pass()
|
|||
|
||||
//BBS: only render plate in view 3D
|
||||
if (m_canvas_type == ECanvasType::CanvasView3D) {
|
||||
_render_plates_for_picking();
|
||||
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||
_render_plates_for_picking(camera.get_view_matrix(), camera.get_projection_matrix());
|
||||
}
|
||||
|
||||
m_camera_clipping_plane = m_gizmos.get_clipping_plane();
|
||||
|
@ -6574,12 +6591,6 @@ void GLCanvas3D::_render_background()
|
|||
}
|
||||
}
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glLoadIdentity());
|
||||
glsafe(::glMatrixMode(GL_PROJECTION));
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glLoadIdentity());
|
||||
|
||||
// Draws a bottom to top gradient over the complete screen.
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
|
@ -6591,7 +6602,7 @@ void GLCanvas3D::_render_background()
|
|||
m_background.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2 };
|
||||
init_data.reserve_vertices(4);
|
||||
init_data.reserve_indices(6);
|
||||
|
||||
|
@ -6602,30 +6613,25 @@ void GLCanvas3D::_render_background()
|
|||
init_data.add_vertex(Vec2f(-1.0f, 1.0f), Vec2f(0.0f, 1.0f));
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_triangle(0, 1, 2);
|
||||
init_data.add_ushort_triangle(2, 3, 0);
|
||||
init_data.add_triangle(0, 1, 2);
|
||||
init_data.add_triangle(2, 3, 0);
|
||||
|
||||
m_background.init_from(std::move(init_data));
|
||||
}
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("background");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("background_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
shader->set_uniform("top_color", use_error_color ? ERROR_BG_LIGHT_COLOR : DEFAULT_BG_LIGHT_COLOR);
|
||||
shader->set_uniform("bottom_color", bottom_color);
|
||||
|
||||
m_background.render();
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
glsafe(::glMatrixMode(GL_MODELVIEW));
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_bed(bool bottom, bool show_axes)
|
||||
void GLCanvas3D::_render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_axes)
|
||||
{
|
||||
float scale_factor = 1.0;
|
||||
#if ENABLE_RETINA_GL
|
||||
|
@ -6643,27 +6649,27 @@ void GLCanvas3D::_render_bed(bool bottom, bool show_axes)
|
|||
//bool show_texture = true;
|
||||
//BBS set axes mode
|
||||
m_bed.set_axes_mode(m_main_toolbar.is_enabled());
|
||||
m_bed.render(*this, bottom, scale_factor, show_axes);
|
||||
m_bed.render(*this, view_matrix, projection_matrix, bottom, scale_factor, show_axes);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_bed_for_picking(bool bottom)
|
||||
void GLCanvas3D::_render_bed_for_picking(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom)
|
||||
{
|
||||
float scale_factor = 1.0;
|
||||
#if ENABLE_RETINA_GL
|
||||
scale_factor = m_retina_helper->get_scale_factor();
|
||||
#endif // ENABLE_RETINA_GL
|
||||
|
||||
//m_bed.render_for_picking(*this, bottom, scale_factor);
|
||||
//m_bed.render_for_picking(*this, view_matrix, projection_matrix, bottom, scale_factor);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_platelist(bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali) const
|
||||
void GLCanvas3D::_render_platelist(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali)
|
||||
{
|
||||
wxGetApp().plater()->get_partplate_list().render(bottom, only_current, only_body, hover_id, render_cali);
|
||||
wxGetApp().plater()->get_partplate_list().render(view_matrix, projection_matrix, bottom, only_current, only_body, hover_id, render_cali);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_plates_for_picking() const
|
||||
void GLCanvas3D::_render_plates_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix)
|
||||
{
|
||||
wxGetApp().plater()->get_partplate_list().render_for_picking_pass();
|
||||
wxGetApp().plater()->get_partplate_list().render_for_picking_pass(view_matrix, projection_matrix);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_plane() const
|
||||
|
@ -6736,7 +6742,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
else
|
||||
m_volumes.set_show_sinking_contours(!m_gizmos.is_hiding_instances());
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_attr");
|
||||
ECanvasType canvas_type = this->m_canvas_type;
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
@ -6751,7 +6757,8 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
{
|
||||
if (m_picking_enabled && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
|
||||
int object_id = m_layers_editing.last_object_id;
|
||||
m_volumes.render(type, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) {
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix(), [object_id](const GLVolume& volume) {
|
||||
// Which volume to paint without the layer height profile shader?
|
||||
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
|
||||
});
|
||||
|
@ -6766,7 +6773,8 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
}*/
|
||||
//BBS:add assemble view related logic
|
||||
// do not cull backfaces to show broken geometry, if any
|
||||
m_volumes.render(type, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this, canvas_type](const GLVolume& volume) {
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
m_volumes.render(type, m_picking_enabled, camera.get_view_matrix(), camera.get_projection_matrix(), [this, canvas_type](const GLVolume& volume) {
|
||||
if (canvas_type == ECanvasType::CanvasAssembleView) {
|
||||
return !volume.is_modifier && !volume.is_wipe_tower;
|
||||
}
|
||||
|
@ -6798,8 +6806,9 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
else
|
||||
shader->set_uniform("show_wireframe", false);
|
||||
}*/
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
//BBS:add assemble view related logic
|
||||
m_volumes.render(type, false, wxGetApp().plater()->get_camera().get_view_matrix(), [this, canvas_type](const GLVolume& volume) {
|
||||
m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix(), [this, canvas_type](const GLVolume& volume) {
|
||||
if (canvas_type == ECanvasType::CanvasAssembleView) {
|
||||
return !volume.is_modifier;
|
||||
}
|
||||
|
@ -7171,16 +7180,13 @@ void GLCanvas3D::_render_style_editor()
|
|||
|
||||
void GLCanvas3D::_render_volumes_for_picking() const
|
||||
{
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
// do not cull backfaces to show broken geometry, if any
|
||||
glsafe(::glDisable(GL_CULL_FACE));
|
||||
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
|
||||
const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix();
|
||||
for (size_t type = 0; type < 2; ++ type) {
|
||||
GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::ERenderType::Opaque : GLVolumeCollection::ERenderType::Transparent, view_matrix);
|
||||
|
@ -7194,14 +7200,14 @@ void GLCanvas3D::_render_volumes_for_picking() const
|
|||
//const unsigned int id = 1 + volume.second.first;
|
||||
volume.first->model.set_color(picking_decode(id));
|
||||
shader->start_using();
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * volume.first->world_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
volume.first->render();
|
||||
shader->stop_using();
|
||||
}
|
||||
}
|
||||
|
||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
|
||||
glsafe(::glEnable(GL_CULL_FACE));
|
||||
}
|
||||
|
||||
|
@ -7241,33 +7247,20 @@ void GLCanvas3D::_render_main_toolbar()
|
|||
if (!m_main_toolbar.is_enabled())
|
||||
return;
|
||||
|
||||
Size cnv_size = get_canvas_size();
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
const Size cnv_size = get_canvas_size();
|
||||
const float top = 0.5f * (float)cnv_size.get_height();
|
||||
|
||||
#if BBS_TOOLBAR_ON_TOP
|
||||
GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
|
||||
float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
||||
float gizmo_width = m_gizmos.get_scaled_total_width();
|
||||
float assemble_width = m_assemble_view_toolbar.get_width();
|
||||
float separator_width = m_separator_toolbar.get_width();
|
||||
float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
|
||||
float left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + separator_width + gizmo_width + assemble_width - collapse_toolbar_width)) * inv_zoom;
|
||||
#else
|
||||
float gizmo_height = m_gizmos.get_scaled_total_height();
|
||||
float space_height = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale();
|
||||
float main_toolbar_height = (float)m_main_toolbar.get_height();
|
||||
float assemble_height = m_assemble_view_toolbar.get_height();
|
||||
float top = 0.5f * (main_toolbar_height + gizmo_height + assemble_height) * inv_zoom;
|
||||
float left = (0.5f * (float)cnv_size.get_width() - m_main_toolbar.get_width()) * inv_zoom;
|
||||
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": top %1%, main_toolbar_height %2%, space_height %3% gizmo_height %4%") % top % main_toolbar_height % space_height % gizmo_height;
|
||||
#endif
|
||||
const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
||||
const float gizmo_width = m_gizmos.get_scaled_total_width();
|
||||
const float assemble_width = m_assemble_view_toolbar.get_width();
|
||||
const float separator_width = m_separator_toolbar.get_width();
|
||||
const float left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + separator_width + gizmo_width + assemble_width - collapse_toolbar_width));
|
||||
m_main_toolbar.set_position(top, left);
|
||||
m_main_toolbar.render(*this);
|
||||
if (m_toolbar_highlighter.m_render_arrow)
|
||||
{
|
||||
m_main_toolbar.render_arrow(*this, m_toolbar_highlighter.m_toolbar_item);
|
||||
}
|
||||
}
|
||||
|
||||
//BBS: GUI refactor: GLToolbar adjust
|
||||
//when rendering, {0, 0} is at the center, {-0.5, 0.5} at the left-up
|
||||
|
@ -7591,28 +7584,16 @@ void GLCanvas3D::_render_assemble_view_toolbar() const
|
|||
if (!m_assemble_view_toolbar.is_enabled())
|
||||
return;
|
||||
|
||||
Size cnv_size = get_canvas_size();
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
|
||||
#if BBS_TOOLBAR_ON_TOP
|
||||
const Size cnv_size = get_canvas_size();
|
||||
GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
|
||||
float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
||||
float gizmo_width = m_gizmos.get_scaled_total_width();
|
||||
float assemble_width = m_assemble_view_toolbar.get_width();
|
||||
float separator_width = m_separator_toolbar.get_width();
|
||||
float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
|
||||
float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width - separator_width - collapse_toolbar_width)) * inv_zoom;
|
||||
float left = main_toolbar_left + (m_main_toolbar.get_width() + gizmo_width) * inv_zoom;
|
||||
//float left = 0.5f * (m_main_toolbar.get_width() + gizmo_width - m_assemble_view_toolbar.get_width() + collapse_toolbar_width) * inv_zoom;
|
||||
#else
|
||||
float gizmo_height = m_gizmos.get_scaled_total_height();
|
||||
//float space_height = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale();
|
||||
float main_toolbar_height = (float)m_main_toolbar.get_height();
|
||||
float assemble_height = (float)m_assemble_view_toolbar.get_height();
|
||||
float top = 0.5f * (assemble_height - main_toolbar_height - gizmo_height) * inv_zoom;
|
||||
float left = (0.5f * (float)cnv_size.get_width() - m_assemble_view_toolbar.get_width()) * inv_zoom;
|
||||
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": top %1%, main_toolbar_height %2%, space_height %3% gizmo_height %4%") % top % main_toolbar_height % space_height % gizmo_height;
|
||||
#endif
|
||||
const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
||||
const float gizmo_width = m_gizmos.get_scaled_total_width();
|
||||
const float assemble_width = m_assemble_view_toolbar.get_width();
|
||||
const float separator_width = m_separator_toolbar.get_width();
|
||||
const float top = 0.5f * (float)cnv_size.get_height();
|
||||
const float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width + separator_width - collapse_toolbar_width));
|
||||
const float left = main_toolbar_left + (m_main_toolbar.get_width() + gizmo_width + separator_width);
|
||||
|
||||
m_assemble_view_toolbar.set_position(top, left);
|
||||
m_assemble_view_toolbar.render(*this);
|
||||
}
|
||||
|
@ -7677,17 +7658,15 @@ void GLCanvas3D::_render_separator_toolbar_right() const
|
|||
if (!m_separator_toolbar.is_enabled())
|
||||
return;
|
||||
|
||||
Size cnv_size = get_canvas_size();
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
|
||||
const Size cnv_size = get_canvas_size();
|
||||
GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
|
||||
float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
||||
float gizmo_width = m_gizmos.get_scaled_total_width();
|
||||
float assemble_width = m_assemble_view_toolbar.get_width();
|
||||
float separator_width = m_separator_toolbar.get_width();
|
||||
float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
|
||||
float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width - collapse_toolbar_width)) * inv_zoom;
|
||||
float left = main_toolbar_left + (m_main_toolbar.get_width() + gizmo_width) * inv_zoom;
|
||||
const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
||||
const float gizmo_width = m_gizmos.get_scaled_total_width();
|
||||
const float assemble_width = m_assemble_view_toolbar.get_width();
|
||||
const float separator_width = m_separator_toolbar.get_width();
|
||||
const float top = 0.5f * (float)cnv_size.get_height();
|
||||
const float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width + separator_width - collapse_toolbar_width));
|
||||
const float left = main_toolbar_left + (m_main_toolbar.get_width() + gizmo_width + separator_width / 2);
|
||||
|
||||
m_separator_toolbar.set_position(top, left);
|
||||
m_separator_toolbar.render(*this,GLToolbarItem::SeparatorLine);
|
||||
|
@ -7698,17 +7677,15 @@ void GLCanvas3D::_render_separator_toolbar_left() const
|
|||
if (!m_separator_toolbar.is_enabled())
|
||||
return;
|
||||
|
||||
Size cnv_size = get_canvas_size();
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
|
||||
const Size cnv_size = get_canvas_size();
|
||||
GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
|
||||
float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
||||
float gizmo_width = m_gizmos.get_scaled_total_width();
|
||||
float assemble_width = m_assemble_view_toolbar.get_width();
|
||||
float separator_width = m_separator_toolbar.get_width();
|
||||
float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
|
||||
float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width + separator_width - collapse_toolbar_width)) * inv_zoom;
|
||||
float left = main_toolbar_left + (m_main_toolbar.get_width()) * inv_zoom;
|
||||
const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
||||
const float gizmo_width = m_gizmos.get_scaled_total_width();
|
||||
const float assemble_width = m_assemble_view_toolbar.get_width();
|
||||
const float separator_width = m_separator_toolbar.get_width();
|
||||
const float top = 0.5f * (float)cnv_size.get_height();
|
||||
const float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width + separator_width - collapse_toolbar_width));
|
||||
const float left = main_toolbar_left + (m_main_toolbar.get_width());
|
||||
|
||||
m_separator_toolbar.set_position(top, left);
|
||||
m_separator_toolbar.render(*this,GLToolbarItem::SeparatorLine);
|
||||
|
@ -7718,12 +7695,10 @@ void GLCanvas3D::_render_collapse_toolbar() const
|
|||
{
|
||||
GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
|
||||
|
||||
Size cnv_size = get_canvas_size();
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
|
||||
float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
|
||||
//float left = (0.5f * (float)cnv_size.get_width() - (float)collapse_toolbar.get_width() - band) * inv_zoom;
|
||||
float left = -0.5f * (float)cnv_size.get_width() * inv_zoom;
|
||||
const Size cnv_size = get_canvas_size();
|
||||
const float top = 0.5f * (float)cnv_size.get_height();
|
||||
//const float left = (0.5f * (float)cnv_size.get_width() - (float)collapse_toolbar.get_width() - band);
|
||||
const float left = -0.5f * (float)cnv_size.get_width();
|
||||
|
||||
collapse_toolbar.set_position(top, left);
|
||||
collapse_toolbar.render(*this);
|
||||
|
@ -8002,52 +7977,51 @@ void GLCanvas3D::_render_assemble_info() const
|
|||
#if ENABLE_SHOW_CAMERA_TARGET
|
||||
void GLCanvas3D::_render_camera_target()
|
||||
{
|
||||
static const double half_length = 5.0;
|
||||
static const float half_length = 5.0f;
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
glsafe(::glLineWidth(2.0f));
|
||||
const Vec3d& target = wxGetApp().plater()->get_camera().get_target();
|
||||
bool target_changed = !m_camera_target.target.isApprox(target);
|
||||
m_camera_target.target = target;
|
||||
const Vec3f& target = wxGetApp().plater()->get_camera().get_target().cast<float>();
|
||||
bool target_changed = !m_camera_target.target.isApprox(target.cast<double>());
|
||||
m_camera_target.target = target.cast<double>();
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (!m_camera_target.axis[i].is_initialized() || target_changed) {
|
||||
m_camera_target.axis[i].reset();
|
||||
|
||||
GLModel::InitializationData init_data;
|
||||
GLModel::InitializationData::Entity entity;
|
||||
entity.type = GLModel::PrimitiveType::Lines;
|
||||
entity.positions.reserve(2);
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.color = (i == X) ? ColorRGBA::X() : ((i == Y) ? ColorRGBA::Y() : ColorRGBA::Z());
|
||||
init_data.reserve_vertices(2);
|
||||
init_data.reserve_indices(2);
|
||||
|
||||
// vertices
|
||||
if (i == X) {
|
||||
entity.positions.emplace_back(target.x() - half_length, target.y(), target.z());
|
||||
entity.positions.emplace_back(target.x() + half_length, target.y(), target.z());
|
||||
init_data.add_vertex(Vec3f(target.x() - half_length, target.y(), target.z()));
|
||||
init_data.add_vertex(Vec3f(target.x() + half_length, target.y(), target.z()));
|
||||
}
|
||||
else if (i == Y) {
|
||||
entity.positions.emplace_back(target.x(), target.y() - half_length, target.z());
|
||||
entity.positions.emplace_back(target.x(), target.y() + half_length, target.z());
|
||||
init_data.add_vertex(Vec3f(target.x(), target.y() - half_length, target.z()));
|
||||
init_data.add_vertex(Vec3f(target.x(), target.y() + half_length, target.z()));
|
||||
}
|
||||
else {
|
||||
entity.positions.emplace_back(target.x(), target.y(), target.z() - half_length);
|
||||
entity.positions.emplace_back(target.x(), target.y(), target.z() + half_length);
|
||||
}
|
||||
entity.normals.reserve(2);
|
||||
for (size_t j = 0; j < 2; ++j) {
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
init_data.add_vertex(Vec3f(target.x(), target.y(), target.z() - half_length));
|
||||
init_data.add_vertex(Vec3f(target.x(), target.y(), target.z() + half_length));
|
||||
}
|
||||
|
||||
entity.indices.reserve(2);
|
||||
entity.indices.emplace_back(0);
|
||||
entity.indices.emplace_back(1);
|
||||
// indices
|
||||
init_data.add_line(0, 1);
|
||||
|
||||
init_data.entities.emplace_back(entity);
|
||||
m_camera_target.axis[i].init_from(init_data);
|
||||
m_camera_target.axis[i].set_color(-1, (i == X) ? ColorRGBA::X() : (i == Y) ? ColorRGBA::Y() : ColorRGBA::Z());
|
||||
m_camera_target.axis[i].init_from(std::move(init_data));
|
||||
}
|
||||
}
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
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());
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
m_camera_target.axis[i].render();
|
||||
}
|
||||
|
@ -8100,7 +8074,7 @@ void GLCanvas3D::_render_sla_slices()
|
|||
|
||||
auto init_model = [](GLModel& model, const Pointf3s& triangles, const ColorRGBA& color) {
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(triangles.size()) };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(triangles.size());
|
||||
init_data.reserve_indices(triangles.size() / 3);
|
||||
init_data.color = color;
|
||||
|
@ -8110,10 +8084,7 @@ void GLCanvas3D::_render_sla_slices()
|
|||
init_data.add_vertex((Vec3f)v.cast<float>());
|
||||
++vertices_count;
|
||||
if (vertices_count % 3 == 0) {
|
||||
if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
||||
init_data.add_ushort_triangle((unsigned short)vertices_count - 3, (unsigned short)vertices_count - 2, (unsigned short)vertices_count - 1);
|
||||
else
|
||||
init_data.add_uint_triangle(vertices_count - 3, vertices_count - 2, vertices_count - 1);
|
||||
init_data.add_triangle(vertices_count - 3, vertices_count - 2, vertices_count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8164,24 +8135,25 @@ void GLCanvas3D::_render_sla_slices()
|
|||
}
|
||||
}
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
for (const SLAPrintObject::Instance& inst : obj->instances()) {
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(unscale<double>(inst.shift.x()), unscale<double>(inst.shift.y()), 0.0));
|
||||
glsafe(::glRotatef(Geometry::rad2deg(inst.rotation), 0.0f, 0.0f, 1.0f));
|
||||
if (obj->is_left_handed())
|
||||
// The polygons are mirrored by X.
|
||||
glsafe(::glScalef(-1.0f, 1.0f, 1.0f));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() *
|
||||
Geometry::assemble_transform(Vec3d(unscale<double>(inst.shift.x()), unscale<double>(inst.shift.y()), 0.0),
|
||||
inst.rotation * Vec3d::UnitZ(), Vec3d::Ones(),
|
||||
obj->is_left_handed() ? Vec3d(-1.0f, 1.0f, 1.0f) : Vec3d::Ones());
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
bottom_obj_triangles.render();
|
||||
top_obj_triangles.render();
|
||||
bottom_sup_triangles.render();
|
||||
top_sup_triangles.render();
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
shader->stop_using();
|
||||
|
@ -8371,7 +8343,7 @@ void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume)
|
|||
|
||||
GLVolume* volume = m_volumes.new_toolpath_volume(color);
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
for (size_t i = 0; i < skirt_height; ++ i) {
|
||||
volume->print_zs.emplace_back(print_zs[i]);
|
||||
volume->offsets.emplace_back(init_data.indices_count());
|
||||
|
@ -8594,7 +8566,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
|||
|
||||
assert(vols.size() == geometries.size());
|
||||
for (GLModel::Geometry& g : geometries) {
|
||||
g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
|
||||
g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
}
|
||||
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
|
||||
const Layer *layer = ctxt.layers[idx_layer];
|
||||
|
@ -8793,7 +8765,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con
|
|||
|
||||
assert(vols.size() == geometries.size());
|
||||
for (GLModel::Geometry& g : geometries) {
|
||||
g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
|
||||
g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
}
|
||||
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) {
|
||||
const std::vector<WipeTower::ToolChangeResult> &layer = ctxt.tool_change(idx_layer);
|
||||
|
|
|
@ -261,9 +261,8 @@ class GLCanvas3D
|
|||
GLModel baseline;
|
||||
GLModel profile;
|
||||
GLModel background;
|
||||
Rect old_bar_rect;
|
||||
float old_canvas_width{ 0.0f };
|
||||
std::vector<double> old_layer_height_profile;
|
||||
bool dirty{ false };
|
||||
};
|
||||
Profile m_profile;
|
||||
|
||||
|
@ -294,7 +293,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);
|
||||
static Rect get_bar_rect_viewport(const GLCanvas3D& canvas);
|
||||
static float get_overlay_window_width() { return LayersEditing::s_overlay_window_width; }
|
||||
|
||||
float object_max_z() const { return m_object_max_z; }
|
||||
|
@ -304,8 +302,8 @@ class GLCanvas3D
|
|||
private:
|
||||
bool is_initialized() const;
|
||||
void generate_layer_height_texture();
|
||||
void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect);
|
||||
void render_profile(const Rect& bar_rect);
|
||||
void render_active_object_annotations(const GLCanvas3D& canvas);
|
||||
void render_profile(const GLCanvas3D& canvas);
|
||||
void update_slicing_parameters();
|
||||
|
||||
static float thickness_bar_width(const GLCanvas3D& canvas);
|
||||
|
@ -1117,11 +1115,11 @@ private:
|
|||
void _picking_pass();
|
||||
void _rectangular_selection_picking_pass();
|
||||
void _render_background();
|
||||
void _render_bed(bool bottom, bool show_axes);
|
||||
void _render_bed_for_picking(bool bottom);
|
||||
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);
|
||||
//BBS: add part plate related logic
|
||||
void _render_platelist(bool bottom, bool only_current, bool only_body = false, int hover_id = -1, bool render_cali = false) const;
|
||||
void _render_plates_for_picking() const;
|
||||
void _render_platelist(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body = false, int hover_id = -1, bool render_cali = false);
|
||||
void _render_plates_for_picking(const Transform3d& view_matrix, const Transform3d& projection_matrix);
|
||||
//BBS: add outline drawing logic
|
||||
void _render_objects(GLVolumeCollection::ERenderType type, bool with_outline = true);
|
||||
//BBS: GUI refactor: add canvas size as parameters
|
||||
|
|
|
@ -52,16 +52,6 @@ static void smooth_normals_corner(const TriangleMesh& mesh, std::vector<stl_norm
|
|||
}
|
||||
#endif // ENABLE_SMOOTH_NORMALS
|
||||
|
||||
void GLModel::Geometry::reserve_vertices(size_t vertices_count)
|
||||
{
|
||||
vertices.reserve(vertices_count * vertex_stride_floats(format));
|
||||
}
|
||||
|
||||
void GLModel::Geometry::reserve_indices(size_t indices_count)
|
||||
{
|
||||
indices.reserve(indices_count * index_stride_bytes(format));
|
||||
}
|
||||
|
||||
void GLModel::Geometry::add_vertex(const Vec2f& position)
|
||||
{
|
||||
assert(format.vertex_layout == EVertexLayout::P2);
|
||||
|
@ -107,70 +97,22 @@ void GLModel::Geometry::add_vertex(const Vec3f& position, const Vec3f& normal)
|
|||
vertices.emplace_back(normal.z());
|
||||
}
|
||||
|
||||
void GLModel::Geometry::add_ushort_index(unsigned short id)
|
||||
void GLModel::Geometry::add_index(unsigned int id)
|
||||
{
|
||||
if (format.index_type != EIndexType::USHORT) {
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
indices.resize(indices.size() + sizeof(unsigned short));
|
||||
::memcpy(indices.data() + indices.size() - sizeof(unsigned short), &id, sizeof(unsigned short));
|
||||
indices.emplace_back(id);
|
||||
}
|
||||
|
||||
void GLModel::Geometry::add_uint_index(unsigned int id)
|
||||
void GLModel::Geometry::add_line(unsigned int id1, unsigned int id2)
|
||||
{
|
||||
if (format.index_type != EIndexType::UINT) {
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
indices.resize(indices.size() + sizeof(unsigned int));
|
||||
::memcpy(indices.data() + indices.size() - sizeof(unsigned int), &id, sizeof(unsigned int));
|
||||
indices.emplace_back(id1);
|
||||
indices.emplace_back(id2);
|
||||
}
|
||||
|
||||
void GLModel::Geometry::add_ushort_line(unsigned short id1, unsigned short id2)
|
||||
void GLModel::Geometry::add_triangle(unsigned int id1, unsigned int id2, unsigned int id3)
|
||||
{
|
||||
if (format.index_type != EIndexType::USHORT) {
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
indices.resize(indices.size() + 2 * sizeof(unsigned short));
|
||||
::memcpy(indices.data() + indices.size() - 2 * sizeof(unsigned short), &id1, sizeof(unsigned short));
|
||||
::memcpy(indices.data() + indices.size() - sizeof(unsigned short), &id2, sizeof(unsigned short));
|
||||
}
|
||||
|
||||
void GLModel::Geometry::add_uint_line(unsigned int id1, unsigned int id2)
|
||||
{
|
||||
if (format.index_type != EIndexType::UINT) {
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
indices.resize(indices.size() + 2 * sizeof(unsigned int));
|
||||
::memcpy(indices.data() + indices.size() - 2 * sizeof(unsigned int), &id1, sizeof(unsigned int));
|
||||
::memcpy(indices.data() + indices.size() - sizeof(unsigned int), &id2, sizeof(unsigned int));
|
||||
}
|
||||
|
||||
void GLModel::Geometry::add_ushort_triangle(unsigned short id1, unsigned short id2, unsigned short id3)
|
||||
{
|
||||
if (format.index_type != EIndexType::USHORT) {
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
indices.resize(indices.size() + 3 * sizeof(unsigned short));
|
||||
::memcpy(indices.data() + indices.size() - 3 * sizeof(unsigned short), &id1, sizeof(unsigned short));
|
||||
::memcpy(indices.data() + indices.size() - 2 * sizeof(unsigned short), &id2, sizeof(unsigned short));
|
||||
::memcpy(indices.data() + indices.size() - sizeof(unsigned short), &id3, sizeof(unsigned short));
|
||||
}
|
||||
|
||||
void GLModel::Geometry::add_uint_triangle(unsigned int id1, unsigned int id2, unsigned int id3)
|
||||
{
|
||||
if (format.index_type != EIndexType::UINT) {
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
indices.resize(indices.size() + 3 * sizeof(unsigned int));
|
||||
::memcpy(indices.data() + indices.size() - 3 * sizeof(unsigned int), &id1, sizeof(unsigned int));
|
||||
::memcpy(indices.data() + indices.size() - 2 * sizeof(unsigned int), &id2, sizeof(unsigned int));
|
||||
::memcpy(indices.data() + indices.size() - sizeof(unsigned int), &id3, sizeof(unsigned int));
|
||||
indices.emplace_back(id1);
|
||||
indices.emplace_back(id2);
|
||||
indices.emplace_back(id3);
|
||||
}
|
||||
|
||||
Vec2f GLModel::Geometry::extract_position_2(size_t id) const
|
||||
|
@ -256,60 +198,29 @@ void GLModel::Geometry::set_vertex(size_t id, const Vec3f& position, const Vec3f
|
|||
}
|
||||
}
|
||||
|
||||
void GLModel::Geometry::set_ushort_index(size_t id, unsigned short index)
|
||||
void GLModel::Geometry::set_index(size_t id, unsigned int index)
|
||||
{
|
||||
assert(id < indices_count());
|
||||
if (id < indices_count())
|
||||
::memcpy(indices.data() + id * sizeof(unsigned short), &index, sizeof(unsigned short));
|
||||
indices[id] = index;
|
||||
}
|
||||
|
||||
void GLModel::Geometry::set_uint_index(size_t id, unsigned int index)
|
||||
unsigned int GLModel::Geometry::extract_index(size_t id) const
|
||||
{
|
||||
assert(id < indices_count());
|
||||
if (id < indices_count())
|
||||
::memcpy(indices.data() + id * sizeof(unsigned int), &index, sizeof(unsigned int));
|
||||
}
|
||||
|
||||
unsigned int GLModel::Geometry::extract_uint_index(size_t id) const
|
||||
{
|
||||
if (format.index_type != EIndexType::UINT) {
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (indices_count() <= id) {
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int ret = (unsigned int)-1;
|
||||
::memcpy(&ret, indices.data() + id * index_stride_bytes(format), sizeof(unsigned int));
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned short GLModel::Geometry::extract_ushort_index(size_t id) const
|
||||
{
|
||||
if (format.index_type != EIndexType::USHORT) {
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (indices_count() <= id) {
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned short ret = (unsigned short)-1;
|
||||
::memcpy(&ret, indices.data() + id * index_stride_bytes(format), sizeof(unsigned short));
|
||||
return ret;
|
||||
return indices[id];
|
||||
}
|
||||
|
||||
void GLModel::Geometry::remove_vertex(size_t id)
|
||||
{
|
||||
assert(id < vertices_count());
|
||||
if (id < vertices_count()) {
|
||||
size_t stride = vertex_stride_floats(format);
|
||||
std::vector<float>::iterator it = vertices.begin() + id * stride;
|
||||
const size_t stride = vertex_stride_floats(format);
|
||||
std::vector<float>::const_iterator it = vertices.begin() + id * stride;
|
||||
vertices.erase(it, it + stride);
|
||||
}
|
||||
}
|
||||
|
@ -391,21 +302,17 @@ size_t GLModel::Geometry::tex_coord_offset_floats(const Format& format)
|
|||
};
|
||||
}
|
||||
|
||||
size_t GLModel::Geometry::index_stride_bytes(const Format& format)
|
||||
size_t GLModel::Geometry::index_stride_bytes(const Geometry& data)
|
||||
{
|
||||
switch (format.index_type)
|
||||
switch (data.index_type)
|
||||
{
|
||||
case EIndexType::UINT: { return sizeof(unsigned int); }
|
||||
case EIndexType::USHORT: { return sizeof(unsigned short); }
|
||||
case EIndexType::UBYTE: { return sizeof(unsigned char); }
|
||||
default: { assert(false); return 0; }
|
||||
};
|
||||
}
|
||||
|
||||
GLModel::Geometry::EIndexType GLModel::Geometry::index_type(size_t vertices_count)
|
||||
{
|
||||
return (vertices_count < 65536) ? EIndexType::USHORT : EIndexType::UINT;
|
||||
}
|
||||
|
||||
bool GLModel::Geometry::has_position(const Format& format)
|
||||
{
|
||||
switch (format.vertex_layout)
|
||||
|
@ -491,7 +398,7 @@ void GLModel::init_from(const indexed_triangle_set& its)
|
|||
}
|
||||
|
||||
Geometry& data = m_render_data.geometry;
|
||||
data.format = { Geometry::EPrimitiveType::Triangles, Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(3 * its.indices.size()) };
|
||||
data.format = { Geometry::EPrimitiveType::Triangles, Geometry::EVertexLayout::P3N3 };
|
||||
data.reserve_vertices(3 * its.indices.size());
|
||||
data.reserve_indices(3 * its.indices.size());
|
||||
|
||||
|
@ -505,10 +412,7 @@ void GLModel::init_from(const indexed_triangle_set& its)
|
|||
data.add_vertex(vertex[j], n);
|
||||
}
|
||||
vertices_counter += 3;
|
||||
if (data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
||||
data.add_ushort_triangle((unsigned short)vertices_counter - 3, (unsigned short)vertices_counter - 2, (unsigned short)vertices_counter - 1);
|
||||
else
|
||||
data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
|
||||
data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
|
||||
}
|
||||
|
||||
// update bounding box
|
||||
|
@ -531,7 +435,7 @@ void GLModel::init_from(const Polygons& polygons, float z)
|
|||
}
|
||||
|
||||
Geometry& data = m_render_data.geometry;
|
||||
data.format = { Geometry::EPrimitiveType::Lines, Geometry::EVertexLayout::P3, Geometry::EIndexType::UINT };
|
||||
data.format = { Geometry::EPrimitiveType::Lines, Geometry::EVertexLayout::P3 };
|
||||
|
||||
size_t segments_count = 0;
|
||||
for (const Polygon& polygon : polygons) {
|
||||
|
@ -550,7 +454,7 @@ void GLModel::init_from(const Polygons& polygons, float z)
|
|||
data.add_vertex(Vec3f(unscale<float>(p0.x()), unscale<float>(p0.y()), z));
|
||||
data.add_vertex(Vec3f(unscale<float>(p1.x()), unscale<float>(p1.y()), z));
|
||||
vertices_counter += 2;
|
||||
data.add_uint_line(vertices_counter - 2, vertices_counter - 1);
|
||||
data.add_line(vertices_counter - 2, vertices_counter - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,7 +502,7 @@ void GLModel::reset()
|
|||
m_render_data.vertices_count = 0;
|
||||
m_render_data.indices_count = 0;
|
||||
m_render_data.geometry.vertices = std::vector<float>();
|
||||
m_render_data.geometry.indices = std::vector<unsigned char>();
|
||||
m_render_data.geometry.indices = std::vector<unsigned int>();
|
||||
m_bounding_box = BoundingBoxf3();
|
||||
m_filename = std::string();
|
||||
}
|
||||
|
@ -618,13 +522,14 @@ static GLenum get_primitive_mode(const GLModel::Geometry::Format& format)
|
|||
}
|
||||
}
|
||||
|
||||
static GLenum get_index_type(const GLModel::Geometry::Format& format)
|
||||
static GLenum get_index_type(const GLModel::Geometry& data)
|
||||
{
|
||||
switch (format.index_type)
|
||||
switch (data.index_type)
|
||||
{
|
||||
default:
|
||||
case GLModel::Geometry::EIndexType::UINT: { return GL_UNSIGNED_INT; }
|
||||
case GLModel::Geometry::EIndexType::USHORT: { return GL_UNSIGNED_SHORT; }
|
||||
case GLModel::Geometry::EIndexType::UBYTE: { return GL_UNSIGNED_BYTE; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -642,7 +547,6 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
|
|||
return;
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_current_shader();
|
||||
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -655,7 +559,7 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
|
|||
const Geometry& data = m_render_data.geometry;
|
||||
|
||||
const GLenum mode = get_primitive_mode(data.format);
|
||||
const GLenum index_type = get_index_type(data.format);
|
||||
const GLenum index_type = get_index_type(data);
|
||||
|
||||
const size_t vertex_stride_bytes = Geometry::vertex_stride_bytes(data.format);
|
||||
const bool position = Geometry::has_position(data.format);
|
||||
|
@ -664,74 +568,44 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
|
|||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id));
|
||||
|
||||
bool use_attributes = boost::algorithm::iends_with(shader->get_name(), "_attr");
|
||||
|
||||
int position_id = -1;
|
||||
int normal_id = -1;
|
||||
int tex_coord_id = -1;
|
||||
|
||||
if (position) {
|
||||
if (use_attributes) {
|
||||
position_id = shader->get_attrib_location("v_position");
|
||||
if (position_id != -1) {
|
||||
glsafe(::glVertexAttribPointer(position_id, Geometry::position_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::position_offset_bytes(data.format)));
|
||||
glsafe(::glEnableVertexAttribArray(position_id));
|
||||
}
|
||||
}
|
||||
else {
|
||||
glsafe(::glVertexPointer(Geometry::position_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::position_offset_bytes(data.format)));
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
}
|
||||
}
|
||||
if (normal) {
|
||||
if (use_attributes) {
|
||||
normal_id = shader->get_attrib_location("v_normal");
|
||||
if (normal_id != -1) {
|
||||
glsafe(::glVertexAttribPointer(normal_id, Geometry::normal_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::normal_offset_bytes(data.format)));
|
||||
glsafe(::glEnableVertexAttribArray(normal_id));
|
||||
}
|
||||
}
|
||||
else {
|
||||
glsafe(::glNormalPointer(GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::normal_offset_bytes(data.format)));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
}
|
||||
}
|
||||
if (tex_coord) {
|
||||
if (use_attributes) {
|
||||
tex_coord_id = shader->get_attrib_location("v_tex_coord");
|
||||
if (tex_coord_id != -1) {
|
||||
glsafe(::glVertexAttribPointer(tex_coord_id, Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::tex_coord_offset_bytes(data.format)));
|
||||
glsafe(::glEnableVertexAttribArray(tex_coord_id));
|
||||
}
|
||||
}
|
||||
else {
|
||||
glsafe(::glTexCoordPointer(Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::tex_coord_offset_bytes(data.format)));
|
||||
glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
}
|
||||
}
|
||||
|
||||
shader->set_uniform("uniform_color", data.color);
|
||||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id));
|
||||
glsafe(::glDrawElements(mode, range.second - range.first, index_type, (const void*)(range.first * Geometry::index_stride_bytes(data.format))));
|
||||
glsafe(::glDrawElements(mode, range.second - range.first, index_type, (const void*)(range.first * Geometry::index_stride_bytes(data))));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
|
||||
if (use_attributes) {
|
||||
if (tex_coord_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(tex_coord_id));
|
||||
if (normal_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(normal_id));
|
||||
if (position_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(position_id));
|
||||
}
|
||||
else {
|
||||
if (tex_coord)
|
||||
glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
if (normal)
|
||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
if (position)
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
}
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
}
|
||||
|
@ -742,18 +616,18 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
|
|||
return;
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_current_shader();
|
||||
if (shader == nullptr || !boost::algorithm::iends_with(shader->get_name(), "_instanced"))
|
||||
if (shader == nullptr || !boost::algorithm::iends_with(shader->get_name(), "_instanced_attr"))
|
||||
return;
|
||||
|
||||
// vertex attributes
|
||||
GLint position_id = shader->get_attrib_location("v_position");
|
||||
GLint normal_id = shader->get_attrib_location("v_normal");
|
||||
const GLint position_id = shader->get_attrib_location("v_position");
|
||||
const GLint normal_id = shader->get_attrib_location("v_normal");
|
||||
if (position_id == -1 || normal_id == -1)
|
||||
return;
|
||||
|
||||
// instance attributes
|
||||
GLint offset_id = shader->get_attrib_location("i_offset");
|
||||
GLint scales_id = shader->get_attrib_location("i_scales");
|
||||
const GLint offset_id = shader->get_attrib_location("i_offset");
|
||||
const GLint scales_id = shader->get_attrib_location("i_scales");
|
||||
if (offset_id == -1 || scales_id == -1)
|
||||
return;
|
||||
|
||||
|
@ -773,8 +647,8 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
|
|||
|
||||
const Geometry& data = m_render_data.geometry;
|
||||
|
||||
GLenum mode = get_primitive_mode(data.format);
|
||||
GLenum index_type = get_index_type(data.format);
|
||||
const GLenum mode = get_primitive_mode(data.format);
|
||||
const GLenum index_type = get_index_type(data);
|
||||
|
||||
shader->set_uniform("uniform_color", data.color);
|
||||
|
||||
|
@ -833,26 +707,36 @@ bool GLModel::send_to_gpu()
|
|||
// indices
|
||||
glsafe(::glGenBuffers(1, &m_render_data.ibo_id));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id));
|
||||
if (m_render_data.vertices_count <= 256) {
|
||||
// convert indices to unsigned char to save gpu memory
|
||||
std::vector<unsigned char> reduced_indices(data.indices.size());
|
||||
for (size_t i = 0; i < data.indices.size(); ++i) {
|
||||
reduced_indices[i] = (unsigned char)data.indices[i];
|
||||
}
|
||||
data.index_type = Geometry::EIndexType::UBYTE;
|
||||
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, reduced_indices.size() * sizeof(unsigned char), reduced_indices.data(), GL_STATIC_DRAW));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
}
|
||||
else if (m_render_data.vertices_count <= 65536) {
|
||||
// convert indices to unsigned short to save gpu memory
|
||||
std::vector<unsigned short> reduced_indices(data.indices.size());
|
||||
for (size_t i = 0; i < data.indices.size(); ++i) {
|
||||
reduced_indices[i] = (unsigned short)data.indices[i];
|
||||
}
|
||||
data.index_type = Geometry::EIndexType::USHORT;
|
||||
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, reduced_indices.size() * sizeof(unsigned short), reduced_indices.data(), GL_STATIC_DRAW));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
}
|
||||
else {
|
||||
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.indices_size_bytes(), data.indices.data(), GL_STATIC_DRAW));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
}
|
||||
m_render_data.indices_count = indices_count();
|
||||
data.indices = std::vector<unsigned char>();
|
||||
data.indices = std::vector<unsigned int>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void append_vertex(GLModel::Geometry& data, const Vec3f& position, const Vec3f& normal)
|
||||
{
|
||||
data.add_vertex(position, normal);
|
||||
}
|
||||
|
||||
static void append_triangle(GLModel::Geometry& data, unsigned short v1, unsigned short v2, unsigned short v3)
|
||||
{
|
||||
data.add_ushort_index(v1);
|
||||
data.add_ushort_index(v2);
|
||||
data.add_ushort_index(v3);
|
||||
}
|
||||
|
||||
template<typename Fn>
|
||||
inline bool all_vertices_inside(const GLModel::Geometry& geometry, Fn fn)
|
||||
{
|
||||
|
@ -907,13 +791,12 @@ bool contains(const BuildVolume& volume, const GLModel& model, bool ignore_botto
|
|||
}
|
||||
}
|
||||
|
||||
GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, float tip_height, float stem_radius, float stem_height)
|
||||
GLModel::Geometry stilized_arrow(unsigned int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height)
|
||||
{
|
||||
resolution = std::max<unsigned short>(4, resolution);
|
||||
resolution = std::min<unsigned short>(10922, resolution); // ensure no unsigned short overflow of indices
|
||||
resolution = std::max<unsigned int>(4, resolution);
|
||||
|
||||
GLModel::Geometry data;
|
||||
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT };
|
||||
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
data.reserve_vertices(6 * resolution + 2);
|
||||
data.reserve_indices(6 * resolution * 3);
|
||||
|
||||
|
@ -921,7 +804,7 @@ GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, fl
|
|||
std::vector<float> cosines(resolution);
|
||||
std::vector<float> sines(resolution);
|
||||
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
const float angle = angle_step * float(i);
|
||||
cosines[i] = ::cos(angle);
|
||||
sines[i] = -::sin(angle);
|
||||
|
@ -930,75 +813,74 @@ GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, fl
|
|||
const float total_height = tip_height + stem_height;
|
||||
|
||||
// tip vertices/normals
|
||||
append_vertex(data, { 0.0f, 0.0f, total_height }, Vec3f::UnitZ());
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f });
|
||||
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));
|
||||
}
|
||||
|
||||
// tip triangles
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
const unsigned short v3 = (i < resolution - 1) ? i + 2 : 1;
|
||||
append_triangle(data, 0, i + 1, v3);
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
const unsigned int v3 = (i < resolution - 1) ? i + 2 : 1;
|
||||
data.add_triangle(0, i + 1, v3);
|
||||
}
|
||||
|
||||
// tip cap outer perimeter vertices
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, -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)(-Vec3f::UnitZ()));
|
||||
}
|
||||
|
||||
// tip cap inner perimeter vertices
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, -Vec3f::UnitZ());
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], stem_height), (Vec3f)(-Vec3f::UnitZ()));
|
||||
}
|
||||
|
||||
// tip cap triangles
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
const unsigned short v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1;
|
||||
const unsigned short v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1;
|
||||
append_triangle(data, i + resolution + 1, v3, v2);
|
||||
append_triangle(data, i + resolution + 1, i + 2 * resolution + 1, v3);
|
||||
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;
|
||||
data.add_triangle(i + resolution + 1, v3, v2);
|
||||
data.add_triangle(i + resolution + 1, i + 2 * resolution + 1, v3);
|
||||
}
|
||||
|
||||
// stem bottom vertices
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f });
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], stem_height), Vec3f(sines[i], cosines[i], 0.0f));
|
||||
}
|
||||
|
||||
// stem top vertices
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, { sines[i], cosines[i], 0.0f });
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], 0.0f), Vec3f(sines[i], cosines[i], 0.0f));
|
||||
}
|
||||
|
||||
// stem triangles
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
const unsigned short v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1;
|
||||
const unsigned short v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1;
|
||||
append_triangle(data, i + 3 * resolution + 1, v3, v2);
|
||||
append_triangle(data, i + 3 * resolution + 1, i + 4 * resolution + 1, v3);
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
const unsigned int v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1;
|
||||
const unsigned int v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1;
|
||||
data.add_triangle(i + 3 * resolution + 1, v3, v2);
|
||||
data.add_triangle(i + 3 * resolution + 1, i + 4 * resolution + 1, v3);
|
||||
}
|
||||
|
||||
// stem cap vertices
|
||||
append_vertex(data, Vec3f::Zero(), -Vec3f::UnitZ());
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, -Vec3f::UnitZ());
|
||||
data.add_vertex((Vec3f)Vec3f::Zero(), (Vec3f)(-Vec3f::UnitZ()));
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], 0.0f), (Vec3f)(-Vec3f::UnitZ()));
|
||||
}
|
||||
|
||||
// stem cap triangles
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
const unsigned short v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2;
|
||||
append_triangle(data, 5 * resolution + 1, v3, i + 5 * resolution + 2);
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
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);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness)
|
||||
GLModel::Geometry circular_arrow(unsigned int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness)
|
||||
{
|
||||
resolution = std::max<unsigned short>(2, resolution);
|
||||
resolution = std::min<unsigned short>(8188, resolution); // ensure no unsigned short overflow of indices
|
||||
resolution = std::max<unsigned int>(2, resolution);
|
||||
|
||||
GLModel::Geometry data;
|
||||
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT };
|
||||
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
data.reserve_vertices(8 * (resolution + 1) + 30);
|
||||
data.reserve_indices((8 * resolution + 16) * 3);
|
||||
|
||||
|
@ -1012,146 +894,146 @@ GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float
|
|||
|
||||
// tip
|
||||
// top face vertices
|
||||
append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitZ());
|
||||
append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitZ());
|
||||
append_vertex(data, { -tip_height, radius, half_thickness }, Vec3f::UnitZ());
|
||||
append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitZ());
|
||||
append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(0.0f, outer_radius, half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(0.0f, radius + half_tip_width, half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(-tip_height, radius, half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(0.0f, radius - half_tip_width, half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(0.0f, inner_radius, half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
|
||||
// top face triangles
|
||||
append_triangle(data, 0, 1, 2);
|
||||
append_triangle(data, 0, 2, 4);
|
||||
append_triangle(data, 4, 2, 3);
|
||||
data.add_triangle(0, 1, 2);
|
||||
data.add_triangle(0, 2, 4);
|
||||
data.add_triangle(4, 2, 3);
|
||||
|
||||
// bottom face vertices
|
||||
append_vertex(data, { 0.0f, outer_radius, -half_thickness }, -Vec3f::UnitZ());
|
||||
append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, -Vec3f::UnitZ());
|
||||
append_vertex(data, { -tip_height, radius, -half_thickness }, -Vec3f::UnitZ());
|
||||
append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitZ());
|
||||
append_vertex(data, { 0.0f, inner_radius, -half_thickness }, -Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(0.0f, outer_radius, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
data.add_vertex(Vec3f(0.0f, radius + half_tip_width, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
data.add_vertex(Vec3f(-tip_height, radius, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
data.add_vertex(Vec3f(0.0f, radius - half_tip_width, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
data.add_vertex(Vec3f(0.0f, inner_radius, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
|
||||
// bottom face triangles
|
||||
append_triangle(data, 5, 7, 6);
|
||||
append_triangle(data, 5, 9, 7);
|
||||
append_triangle(data, 9, 8, 7);
|
||||
data.add_triangle(5, 7, 6);
|
||||
data.add_triangle(5, 9, 7);
|
||||
data.add_triangle(9, 8, 7);
|
||||
|
||||
// side faces vertices
|
||||
append_vertex(data, { 0.0f, outer_radius, -half_thickness }, Vec3f::UnitX());
|
||||
append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, Vec3f::UnitX());
|
||||
append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitX());
|
||||
append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(0.0f, outer_radius, -half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(0.0f, radius + half_tip_width, -half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(0.0f, outer_radius, half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(0.0f, radius + half_tip_width, half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
|
||||
Vec3f normal(-half_tip_width, tip_height, 0.0f);
|
||||
normal.normalize();
|
||||
append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, normal);
|
||||
append_vertex(data, { -tip_height, radius, -half_thickness }, normal);
|
||||
append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, normal);
|
||||
append_vertex(data, { -tip_height, radius, half_thickness }, normal);
|
||||
data.add_vertex(Vec3f(0.0f, radius + half_tip_width, -half_thickness), normal);
|
||||
data.add_vertex(Vec3f(-tip_height, radius, -half_thickness), normal);
|
||||
data.add_vertex(Vec3f(0.0f, radius + half_tip_width, half_thickness), normal);
|
||||
data.add_vertex(Vec3f(-tip_height, radius, half_thickness), normal);
|
||||
|
||||
normal = { -half_tip_width, -tip_height, 0.0f };
|
||||
normal.normalize();
|
||||
append_vertex(data, { -tip_height, radius, -half_thickness }, normal);
|
||||
append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, normal);
|
||||
append_vertex(data, { -tip_height, radius, half_thickness }, normal);
|
||||
append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, normal);
|
||||
data.add_vertex(Vec3f(-tip_height, radius, -half_thickness), normal);
|
||||
data.add_vertex(Vec3f(0.0f, radius - half_tip_width, -half_thickness), normal);
|
||||
data.add_vertex(Vec3f(-tip_height, radius, half_thickness), normal);
|
||||
data.add_vertex(Vec3f(0.0f, radius - half_tip_width, half_thickness), normal);
|
||||
|
||||
append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, Vec3f::UnitX());
|
||||
append_vertex(data, { 0.0f, inner_radius, -half_thickness }, Vec3f::UnitX());
|
||||
append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitX());
|
||||
append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(0.0f, radius - half_tip_width, -half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(0.0f, inner_radius, -half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(0.0f, radius - half_tip_width, half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(0.0f, inner_radius, half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
|
||||
// side face triangles
|
||||
for (unsigned short i = 0; i < 4; ++i) {
|
||||
const unsigned short ii = i * 4;
|
||||
append_triangle(data, 10 + ii, 11 + ii, 13 + ii);
|
||||
append_triangle(data, 10 + ii, 13 + ii, 12 + ii);
|
||||
for (unsigned int i = 0; i < 4; ++i) {
|
||||
const unsigned int ii = i * 4;
|
||||
data.add_triangle(10 + ii, 11 + ii, 13 + ii);
|
||||
data.add_triangle(10 + ii, 13 + ii, 12 + ii);
|
||||
}
|
||||
|
||||
// stem
|
||||
// top face vertices
|
||||
for (unsigned short i = 0; i <= resolution; ++i) {
|
||||
for (unsigned int i = 0; i <= resolution; ++i) {
|
||||
const float angle = float(i) * step_angle;
|
||||
append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
}
|
||||
|
||||
for (unsigned short i = 0; i <= resolution; ++i) {
|
||||
for (unsigned int i = 0; i <= resolution; ++i) {
|
||||
const float angle = float(i) * step_angle;
|
||||
append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
}
|
||||
|
||||
// top face triangles
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
append_triangle(data, 26 + i, 27 + i, 27 + resolution + i);
|
||||
append_triangle(data, 27 + i, 28 + resolution + i, 27 + resolution + i);
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
data.add_triangle(26 + i, 27 + i, 27 + resolution + i);
|
||||
data.add_triangle(27 + i, 28 + resolution + i, 27 + resolution + i);
|
||||
}
|
||||
|
||||
// bottom face vertices
|
||||
for (unsigned short i = 0; i <= resolution; ++i) {
|
||||
for (unsigned int i = 0; i <= resolution; ++i) {
|
||||
const float angle = float(i) * step_angle;
|
||||
append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
}
|
||||
|
||||
for (unsigned short i = 0; i <= resolution; ++i) {
|
||||
for (unsigned int i = 0; i <= resolution; ++i) {
|
||||
const float angle = float(i) * step_angle;
|
||||
append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
}
|
||||
|
||||
// bottom face triangles
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
append_triangle(data, 28 + 2 * resolution + i, 29 + 3 * resolution + i, 29 + 2 * resolution + i);
|
||||
append_triangle(data, 29 + 2 * resolution + i, 29 + 3 * resolution + i, 30 + 3 * resolution + i);
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
data.add_triangle(28 + 2 * resolution + i, 29 + 3 * resolution + i, 29 + 2 * resolution + i);
|
||||
data.add_triangle(29 + 2 * resolution + i, 29 + 3 * resolution + i, 30 + 3 * resolution + i);
|
||||
}
|
||||
|
||||
// side faces vertices and triangles
|
||||
for (unsigned short i = 0; i <= resolution; ++i) {
|
||||
for (unsigned int i = 0; i <= resolution; ++i) {
|
||||
const float angle = float(i) * step_angle;
|
||||
const float c = ::cos(angle);
|
||||
const float s = ::sin(angle);
|
||||
append_vertex(data, { inner_radius * s, inner_radius * c, -half_thickness }, { -s, -c, 0.0f });
|
||||
data.add_vertex(Vec3f(inner_radius * s, inner_radius * c, -half_thickness), Vec3f(-s, -c, 0.0f));
|
||||
}
|
||||
|
||||
for (unsigned short i = 0; i <= resolution; ++i) {
|
||||
for (unsigned int i = 0; i <= resolution; ++i) {
|
||||
const float angle = float(i) * step_angle;
|
||||
const float c = ::cos(angle);
|
||||
const float s = ::sin(angle);
|
||||
append_vertex(data, { inner_radius * s, inner_radius * c, half_thickness }, { -s, -c, 0.0f });
|
||||
data.add_vertex(Vec3f(inner_radius * s, inner_radius * c, half_thickness), Vec3f(-s, -c, 0.0f));
|
||||
}
|
||||
|
||||
unsigned short first_id = 26 + 4 * (resolution + 1);
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
const unsigned short ii = first_id + i;
|
||||
append_triangle(data, ii, ii + 1, ii + resolution + 2);
|
||||
append_triangle(data, ii, ii + resolution + 2, ii + resolution + 1);
|
||||
unsigned int first_id = 26 + 4 * (resolution + 1);
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
const unsigned int ii = first_id + i;
|
||||
data.add_triangle(ii, ii + 1, ii + resolution + 2);
|
||||
data.add_triangle(ii, ii + resolution + 2, ii + resolution + 1);
|
||||
}
|
||||
|
||||
append_vertex(data, { inner_radius, 0.0f, -half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { outer_radius, 0.0f, -half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { inner_radius, 0.0f, half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { outer_radius, 0.0f, half_thickness }, -Vec3f::UnitY());
|
||||
data.add_vertex(Vec3f(inner_radius, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(outer_radius, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(inner_radius, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(outer_radius, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
|
||||
first_id = 26 + 6 * (resolution + 1);
|
||||
append_triangle(data, first_id, first_id + 1, first_id + 3);
|
||||
append_triangle(data, first_id, first_id + 3, first_id + 2);
|
||||
data.add_triangle(first_id, first_id + 1, first_id + 3);
|
||||
data.add_triangle(first_id, first_id + 3, first_id + 2);
|
||||
|
||||
for (short i = resolution; i >= 0; --i) {
|
||||
for (int i = resolution; i >= 0; --i) {
|
||||
const float angle = float(i) * step_angle;
|
||||
const float c = ::cos(angle);
|
||||
const float s = ::sin(angle);
|
||||
append_vertex(data, { outer_radius * s, outer_radius * c, -half_thickness }, { s, c, 0.0f });
|
||||
data.add_vertex(Vec3f(outer_radius * s, outer_radius * c, -half_thickness), Vec3f(s, c, 0.0f));
|
||||
}
|
||||
|
||||
for (short i = resolution; i >= 0; --i) {
|
||||
for (int i = resolution; i >= 0; --i) {
|
||||
const float angle = float(i) * step_angle;
|
||||
const float c = ::cos(angle);
|
||||
const float s = ::sin(angle);
|
||||
append_vertex(data, { outer_radius * s, outer_radius * c, +half_thickness }, { s, c, 0.0f });
|
||||
data.add_vertex(Vec3f(outer_radius * s, outer_radius * c, +half_thickness), Vec3f(s, c, 0.0f));
|
||||
}
|
||||
|
||||
first_id = 30 + 6 * (resolution + 1);
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
const unsigned short ii = first_id + i;
|
||||
append_triangle(data, ii, ii + 1, ii + resolution + 2);
|
||||
append_triangle(data, ii, ii + resolution + 2, ii + resolution + 1);
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
const unsigned int ii = first_id + i;
|
||||
data.add_triangle(ii, ii + 1, ii + resolution + 2);
|
||||
data.add_triangle(ii, ii + resolution + 2, ii + resolution + 1);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
@ -1160,7 +1042,7 @@ GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float
|
|||
GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness)
|
||||
{
|
||||
GLModel::Geometry data;
|
||||
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT };
|
||||
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
data.reserve_vertices(42);
|
||||
data.reserve_indices(72);
|
||||
|
||||
|
@ -1170,122 +1052,121 @@ GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_w
|
|||
const float total_height = tip_height + stem_height;
|
||||
|
||||
// top face vertices
|
||||
append_vertex(data, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ());
|
||||
append_vertex(data, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ());
|
||||
append_vertex(data, { half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ());
|
||||
append_vertex(data, { 0.0, total_height, half_thickness }, Vec3f::UnitZ());
|
||||
append_vertex(data, { -half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ());
|
||||
append_vertex(data, { -half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ());
|
||||
append_vertex(data, { -half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ());
|
||||
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());
|
||||
data.add_vertex(Vec3f(half_tip_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(0.0f, total_height, half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(-half_tip_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(-half_stem_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
data.add_vertex(Vec3f(-half_stem_width, 0.0f, half_thickness), (Vec3f)Vec3f::UnitZ());
|
||||
|
||||
// top face triangles
|
||||
append_triangle(data, 0, 1, 6);
|
||||
append_triangle(data, 6, 1, 5);
|
||||
append_triangle(data, 4, 5, 3);
|
||||
append_triangle(data, 5, 1, 3);
|
||||
append_triangle(data, 1, 2, 3);
|
||||
data.add_triangle(0, 1, 6);
|
||||
data.add_triangle(6, 1, 5);
|
||||
data.add_triangle(4, 5, 3);
|
||||
data.add_triangle(5, 1, 3);
|
||||
data.add_triangle(1, 2, 3);
|
||||
|
||||
// bottom face vertices
|
||||
append_vertex(data, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ());
|
||||
append_vertex(data, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
|
||||
append_vertex(data, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
|
||||
append_vertex(data, { 0.0, total_height, -half_thickness }, -Vec3f::UnitZ());
|
||||
append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
|
||||
append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
|
||||
append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ());
|
||||
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()));
|
||||
data.add_vertex(Vec3f(half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
data.add_vertex(Vec3f(0.0f, total_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
data.add_vertex(Vec3f(-half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
data.add_vertex(Vec3f(-half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
data.add_vertex(Vec3f(-half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
|
||||
|
||||
// bottom face triangles
|
||||
append_triangle(data, 7, 13, 8);
|
||||
append_triangle(data, 13, 12, 8);
|
||||
append_triangle(data, 12, 11, 10);
|
||||
append_triangle(data, 8, 12, 10);
|
||||
append_triangle(data, 9, 8, 10);
|
||||
data.add_triangle(7, 13, 8);
|
||||
data.add_triangle(13, 12, 8);
|
||||
data.add_triangle(12, 11, 10);
|
||||
data.add_triangle(8, 12, 10);
|
||||
data.add_triangle(9, 8, 10);
|
||||
|
||||
// side faces vertices
|
||||
append_vertex(data, { half_stem_width, 0.0, -half_thickness }, Vec3f::UnitX());
|
||||
append_vertex(data, { half_stem_width, stem_height, -half_thickness }, Vec3f::UnitX());
|
||||
append_vertex(data, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitX());
|
||||
append_vertex(data, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(half_stem_width, 0.0f, -half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(half_stem_width, stem_height, -half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(half_stem_width, 0.0f, half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(half_stem_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitX());
|
||||
|
||||
append_vertex(data, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY());
|
||||
data.add_vertex(Vec3f(half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(half_stem_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(half_tip_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
|
||||
Vec3f normal(tip_height, half_tip_width, 0.0f);
|
||||
normal.normalize();
|
||||
append_vertex(data, { half_tip_width, stem_height, -half_thickness }, normal);
|
||||
append_vertex(data, { 0.0, total_height, -half_thickness }, normal);
|
||||
append_vertex(data, { half_tip_width, stem_height, half_thickness }, normal);
|
||||
append_vertex(data, { 0.0, total_height, half_thickness }, normal);
|
||||
data.add_vertex(Vec3f(half_tip_width, stem_height, -half_thickness), normal);
|
||||
data.add_vertex(Vec3f(0.0f, total_height, -half_thickness), normal);
|
||||
data.add_vertex(Vec3f(half_tip_width, stem_height, half_thickness), normal);
|
||||
data.add_vertex(Vec3f(0.0f, total_height, half_thickness), normal);
|
||||
|
||||
normal = { -tip_height, half_tip_width, 0.0f };
|
||||
normal.normalize();
|
||||
append_vertex(data, { 0.0, total_height, -half_thickness }, normal);
|
||||
append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, normal);
|
||||
append_vertex(data, { 0.0, total_height, half_thickness }, normal);
|
||||
append_vertex(data, { -half_tip_width, stem_height, half_thickness }, normal);
|
||||
data.add_vertex(Vec3f(0.0f, total_height, -half_thickness), normal);
|
||||
data.add_vertex(Vec3f(-half_tip_width, stem_height, -half_thickness), normal);
|
||||
data.add_vertex(Vec3f(0.0f, total_height, half_thickness), normal);
|
||||
data.add_vertex(Vec3f(-half_tip_width, stem_height, half_thickness), normal);
|
||||
|
||||
append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { -half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY());
|
||||
data.add_vertex(Vec3f(-half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(-half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(-half_tip_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(-half_stem_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
|
||||
append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitX());
|
||||
append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitX());
|
||||
append_vertex(data, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitX());
|
||||
append_vertex(data, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitX());
|
||||
data.add_vertex(Vec3f(-half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitX()));
|
||||
data.add_vertex(Vec3f(-half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitX()));
|
||||
data.add_vertex(Vec3f(-half_stem_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitX()));
|
||||
data.add_vertex(Vec3f(-half_stem_width, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitX()));
|
||||
|
||||
append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY());
|
||||
append_vertex(data, { half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY());
|
||||
data.add_vertex(Vec3f(-half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(-half_stem_width, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
data.add_vertex(Vec3f(half_stem_width, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY()));
|
||||
|
||||
// side face triangles
|
||||
for (unsigned short i = 0; i < 7; ++i) {
|
||||
const unsigned short ii = i * 4;
|
||||
append_triangle(data, 14 + ii, 15 + ii, 17 + ii);
|
||||
append_triangle(data, 14 + ii, 17 + ii, 16 + ii);
|
||||
for (unsigned int i = 0; i < 7; ++i) {
|
||||
const unsigned int ii = i * 4;
|
||||
data.add_triangle(14 + ii, 15 + ii, 17 + ii);
|
||||
data.add_triangle(14 + ii, 17 + ii, 16 + ii);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
GLModel::Geometry diamond(unsigned short resolution)
|
||||
GLModel::Geometry diamond(unsigned int resolution)
|
||||
{
|
||||
resolution = std::max<unsigned short>(4, resolution);
|
||||
resolution = std::min<unsigned short>(65534, resolution); // ensure no unsigned short overflow of indices
|
||||
resolution = std::max<unsigned int>(4, resolution);
|
||||
|
||||
GLModel::Geometry data;
|
||||
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT };
|
||||
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
data.reserve_vertices(resolution + 2);
|
||||
data.reserve_indices((2 * (resolution + 1)) * 3);
|
||||
|
||||
const float step = 2.0f * float(PI) / float(resolution);
|
||||
|
||||
// vertices
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
float ii = float(i) * step;
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
const float ii = float(i) * step;
|
||||
const Vec3f p = { 0.5f * ::cos(ii), 0.5f * ::sin(ii), 0.0f };
|
||||
append_vertex(data, p, p.normalized());
|
||||
data.add_vertex(p, (Vec3f)p.normalized());
|
||||
}
|
||||
Vec3f p = { 0.0f, 0.0f, 0.5f };
|
||||
append_vertex(data, p, p.normalized());
|
||||
data.add_vertex(p, (Vec3f)p.normalized());
|
||||
p = { 0.0f, 0.0f, -0.5f };
|
||||
append_vertex(data, p, p.normalized());
|
||||
data.add_vertex(p, (Vec3f)p.normalized());
|
||||
|
||||
// triangles
|
||||
// top
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
append_triangle(data, i + 0, i + 1, resolution);
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
data.add_triangle(i + 0, i + 1, resolution);
|
||||
}
|
||||
append_triangle(data, resolution - 1, 0, resolution);
|
||||
data.add_triangle(resolution - 1, 0, resolution);
|
||||
|
||||
// bottom
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
append_triangle(data, i + 0, resolution + 1, i + 1);
|
||||
for (unsigned int i = 0; i < resolution; ++i) {
|
||||
data.add_triangle(i + 0, resolution + 1, i + 1);
|
||||
}
|
||||
append_triangle(data, resolution - 1, resolution + 1, 0);
|
||||
data.add_triangle(resolution - 1, resolution + 1, 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -46,23 +46,25 @@ namespace GUI {
|
|||
enum class EIndexType : unsigned char
|
||||
{
|
||||
UINT, // unsigned int
|
||||
USHORT // unsigned short
|
||||
USHORT, // unsigned short
|
||||
UBYTE // unsigned byte
|
||||
};
|
||||
|
||||
struct Format
|
||||
{
|
||||
EPrimitiveType type{ EPrimitiveType::Triangles };
|
||||
EVertexLayout vertex_layout{ EVertexLayout::P3N3 };
|
||||
EIndexType index_type{ EIndexType::UINT };
|
||||
};
|
||||
|
||||
Format format;
|
||||
std::vector<float> vertices;
|
||||
std::vector<unsigned char> indices;
|
||||
std::vector<unsigned int> indices;
|
||||
EIndexType index_type{ EIndexType::UINT };
|
||||
ColorRGBA color{ ColorRGBA::BLACK() };
|
||||
|
||||
void reserve_vertices(size_t vertices_count);
|
||||
void reserve_indices(size_t indices_count);
|
||||
void reserve_vertices(size_t vertices_count) { vertices.reserve(vertices_count * vertex_stride_floats(format)); }
|
||||
void reserve_indices(size_t indices_count) { indices.reserve(indices_count * index_stride_bytes(*this)); }
|
||||
|
||||
|
||||
void add_vertex(const Vec2f& position); // EVertexLayout::P2
|
||||
void add_vertex(const Vec2f& position, const Vec2f& tex_coord); // EVertexLayout::P2T2
|
||||
|
@ -72,36 +74,29 @@ namespace GUI {
|
|||
|
||||
void set_vertex(size_t id, const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3
|
||||
|
||||
void set_ushort_index(size_t id, unsigned short index);
|
||||
void set_uint_index(size_t id, unsigned int index);
|
||||
void set_index(size_t id, unsigned int index);
|
||||
|
||||
void add_ushort_index(unsigned short id);
|
||||
void add_uint_index(unsigned int id);
|
||||
|
||||
void add_ushort_line(unsigned short id1, unsigned short id2);
|
||||
void add_uint_line(unsigned int id1, unsigned int id2);
|
||||
|
||||
void add_ushort_triangle(unsigned short id1, unsigned short id2, unsigned short id3);
|
||||
void add_uint_triangle(unsigned int id1, unsigned int id2, unsigned int id3);
|
||||
void add_index(unsigned int id);
|
||||
void add_line(unsigned int id1, unsigned int id2);
|
||||
void add_triangle(unsigned int id1, unsigned int id2, unsigned int id3);
|
||||
|
||||
Vec2f extract_position_2(size_t id) const;
|
||||
Vec3f extract_position_3(size_t id) const;
|
||||
Vec3f extract_normal_3(size_t id) const;
|
||||
Vec2f extract_tex_coord_2(size_t id) const;
|
||||
|
||||
unsigned int extract_uint_index(size_t id) const;
|
||||
unsigned short extract_ushort_index(size_t id) const;
|
||||
unsigned int extract_index(size_t id) const;
|
||||
|
||||
void remove_vertex(size_t id);
|
||||
|
||||
bool is_empty() const { return vertices_count() == 0 || indices_count() == 0; }
|
||||
|
||||
size_t vertices_count() const { return vertices.size() / vertex_stride_floats(format); }
|
||||
size_t indices_count() const { return indices.size() / index_stride_bytes(format); }
|
||||
size_t indices_count() const { return indices.size(); }
|
||||
|
||||
size_t vertices_size_floats() const { return vertices.size(); }
|
||||
size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); }
|
||||
size_t indices_size_bytes() const { return indices.size(); }
|
||||
size_t indices_size_bytes() const { return indices.size() * index_stride_bytes(*this); }
|
||||
|
||||
static size_t vertex_stride_floats(const Format& format);
|
||||
static size_t vertex_stride_bytes(const Format& format) { return vertex_stride_floats(format) * sizeof(float); }
|
||||
|
@ -121,9 +116,7 @@ namespace GUI {
|
|||
static size_t tex_coord_offset_floats(const Format& format);
|
||||
static size_t tex_coord_offset_bytes(const Format& format) { return tex_coord_offset_floats(format) * sizeof(float); }
|
||||
|
||||
static size_t index_stride_bytes(const Format& format);
|
||||
|
||||
static EIndexType index_type(size_t vertices_count);
|
||||
static size_t index_stride_bytes(const Geometry& data);
|
||||
|
||||
static bool has_position(const Format& format);
|
||||
static bool has_normal(const Format& format);
|
||||
|
@ -164,9 +157,10 @@ namespace GUI {
|
|||
size_t vertices_size_floats() const { return vertices_count() * Geometry::vertex_stride_floats(m_render_data.geometry.format); }
|
||||
size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); }
|
||||
|
||||
size_t indices_size_bytes() const { return indices_count() * Geometry::index_stride_bytes(m_render_data.geometry.format); }
|
||||
size_t indices_size_bytes() const { return indices_count() * Geometry::index_stride_bytes(m_render_data.geometry); }
|
||||
|
||||
const Geometry& get_geometry() const { return m_render_data.geometry; }
|
||||
|
||||
void init_from(Geometry&& data);
|
||||
void init_from(const TriangleMesh& mesh);
|
||||
void init_from(const indexed_triangle_set& its);
|
||||
|
@ -217,13 +211,13 @@ namespace GUI {
|
|||
// the origin of the arrow is in the center of the stem cap
|
||||
// the arrow has its axis of symmetry along the Z axis and is pointing upward
|
||||
// used to render bed axes and sequential marker
|
||||
GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, float tip_height, float stem_radius, float stem_height);
|
||||
GLModel::Geometry stilized_arrow(unsigned int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height);
|
||||
|
||||
// create an arrow whose stem is a quarter of circle, with the given dimensions and resolution
|
||||
// the origin of the arrow is in the center of the circle
|
||||
// the arrow is contained in the 1st quadrant of the XY plane and is pointing counterclockwise
|
||||
// used to render sidebar hints for rotations
|
||||
GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness);
|
||||
GLModel::Geometry circular_arrow(unsigned int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness);
|
||||
|
||||
// create an arrow with the given dimensions
|
||||
// the origin of the arrow is in the center of the stem cap
|
||||
|
@ -234,7 +228,7 @@ namespace GUI {
|
|||
// create a diamond with the given resolution
|
||||
// the origin of the diamond is in its center
|
||||
// the diamond is contained into a box with size [1, 1, 1]
|
||||
GLModel::Geometry diamond(unsigned short resolution);
|
||||
GLModel::Geometry diamond(unsigned int resolution);
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -74,40 +74,28 @@ namespace GUI {
|
|||
if (!is_dragging())
|
||||
return;
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
float inv_zoom = (float)camera.get_inv_zoom();
|
||||
|
||||
Size cnv_size = canvas.get_canvas_size();
|
||||
float cnv_half_width = 0.5f * (float)cnv_size.get_width();
|
||||
float cnv_half_height = 0.5f * (float)cnv_size.get_height();
|
||||
if (cnv_half_width == 0.0f || cnv_half_height == 0.0f)
|
||||
const Size cnv_size = canvas.get_canvas_size();
|
||||
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)
|
||||
return;
|
||||
|
||||
Vec2d start(m_start_corner(0) - cnv_half_width, cnv_half_height - m_start_corner(1));
|
||||
Vec2d end(m_end_corner(0) - cnv_half_width, cnv_half_height - m_end_corner(1));
|
||||
|
||||
const float left = (float)std::min(start(0), end(0)) * inv_zoom;
|
||||
const float top = (float)std::max(start(1), end(1)) * inv_zoom;
|
||||
const float right = (float)std::max(start(0), end(0)) * inv_zoom;
|
||||
const float bottom = (float)std::min(start(1), end(1)) * inv_zoom;
|
||||
const float cnv_inv_width = 1.0f / cnv_width;
|
||||
const float cnv_inv_height = 1.0f / cnv_height;
|
||||
const float left = 2.0f * (get_left() * cnv_inv_width - 0.5f);
|
||||
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);
|
||||
|
||||
glsafe(::glLineWidth(1.5f));
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
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));
|
||||
|
||||
glsafe(::glPushAttrib(GL_ENABLE_BIT));
|
||||
glsafe(::glLineStipple(4, 0xAAAA));
|
||||
glsafe(::glEnable(GL_LINE_STIPPLE));
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
|
@ -117,7 +105,7 @@ namespace GUI {
|
|||
m_rectangle.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 };
|
||||
init_data.reserve_vertices(4);
|
||||
init_data.reserve_indices(4);
|
||||
|
||||
|
@ -128,23 +116,23 @@ namespace GUI {
|
|||
init_data.add_vertex(Vec2f(left, top));
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_index(0);
|
||||
init_data.add_ushort_index(1);
|
||||
init_data.add_ushort_index(2);
|
||||
init_data.add_ushort_index(3);
|
||||
init_data.add_index(0);
|
||||
init_data.add_index(1);
|
||||
init_data.add_index(2);
|
||||
init_data.add_index(3);
|
||||
|
||||
m_rectangle.init_from(std::move(init_data));
|
||||
}
|
||||
|
||||
const ColorRGBA color(0.0f, 1.0f, 0.38f, 1.0f);
|
||||
m_rectangle.set_color(color);
|
||||
shader->set_uniform("view_model_matrix", Transform3d::Identity());
|
||||
shader->set_uniform("projection_matrix", Transform3d::Identity());
|
||||
|
||||
m_rectangle.set_color({0.0f, 1.0f, 0.38f, 1.0f});
|
||||
m_rectangle.render();
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
glsafe(::glPopAttrib());
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
|
|
|
@ -36,12 +36,12 @@ public:
|
|||
bool is_dragging() const { return m_state != Off; }
|
||||
EState get_state() const { return m_state; }
|
||||
|
||||
float get_width() const { return std::abs(m_start_corner(0) - m_end_corner(0)); }
|
||||
float get_height() const { return std::abs(m_start_corner(1) - m_end_corner(1)); }
|
||||
float get_left() const { return std::min(m_start_corner(0), m_end_corner(0)); }
|
||||
float get_right() const { return std::max(m_start_corner(0), m_end_corner(0)); }
|
||||
float get_top() const { return std::max(m_start_corner(1), m_end_corner(1)); }
|
||||
float get_bottom() const { return std::min(m_start_corner(1), m_end_corner(1)); }
|
||||
float get_width() const { return std::abs(m_start_corner.x() - m_end_corner.x()); }
|
||||
float get_height() const { return std::abs(m_start_corner.y() - m_end_corner.y()); }
|
||||
float get_left() const { return std::min(m_start_corner.x(), m_end_corner.x()); }
|
||||
float get_right() const { return std::max(m_start_corner.x(), m_end_corner.x()); }
|
||||
float get_top() const { return std::max(m_start_corner.y(), m_end_corner.y()); }
|
||||
float get_bottom() const { return std::min(m_start_corner.y(), m_end_corner.y()); }
|
||||
|
||||
private:
|
||||
EState m_state{ Off };
|
||||
|
|
|
@ -296,6 +296,11 @@ void GLShaderProgram::set_uniform(int id, const Matrix3f& value) const
|
|||
glsafe(::glUniformMatrix3fv(id, 1, GL_FALSE, static_cast<const GLfloat*>(value.data())));
|
||||
}
|
||||
|
||||
void GLShaderProgram::set_uniform(int id, const Matrix3d& value) const
|
||||
{
|
||||
set_uniform(id, (Matrix3f)value.cast<float>());
|
||||
}
|
||||
|
||||
void GLShaderProgram::set_uniform(int id, const Vec3f& value) const
|
||||
{
|
||||
if (id >= 0)
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
void set_uniform(const char* name, const Transform3f& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
void set_uniform(const char* name, const Transform3d& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
void set_uniform(const char* name, const Matrix3f& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
void set_uniform(const char* name, const Matrix3d& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
void set_uniform(const char* name, const Vec3f& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
void set_uniform(const char* name, const Vec3d& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
void set_uniform(const char* name, const ColorRGB& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
|
@ -79,6 +80,7 @@ public:
|
|||
void set_uniform(int id, const Transform3f& value) const;
|
||||
void set_uniform(int id, const Transform3d& value) const;
|
||||
void set_uniform(int id, const Matrix3f& value) const;
|
||||
void set_uniform(int id, const Matrix3d& value) const;
|
||||
void set_uniform(int id, const Vec3f& value) const;
|
||||
void set_uniform(int id, const Vec3d& value) const;
|
||||
void set_uniform(int id, const ColorRGB& value) const;
|
||||
|
|
|
@ -34,25 +34,22 @@ std::pair<bool, std::string> GLShadersManager::init()
|
|||
bool valid = true;
|
||||
|
||||
// basic shader, used to render all what was previously rendered using the immediate mode
|
||||
valid &= append_shader("flat", { "flat.vs", "flat.fs" });
|
||||
valid &= append_shader("flat_attr", { "flat_attr.vs", "flat.fs" });
|
||||
// basic shader for textures, used to render textures
|
||||
valid &= append_shader("flat_texture", { "flat_texture.vs", "flat_texture.fs" });
|
||||
valid &= append_shader("flat_texture_attr", { "flat_texture_attr.vs", "flat_texture.fs" });
|
||||
// used to render 3D scene background
|
||||
valid &= append_shader("background", { "background.vs", "background.fs" });
|
||||
valid &= append_shader("background_attr", { "background_attr.vs", "background.fs" });
|
||||
// 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" });
|
||||
valid &= append_shader("gouraud_light_attr", { "gouraud_light_attr.vs", "gouraud_light.fs" });
|
||||
//used to render thumbnail
|
||||
valid &= append_shader("thumbnail_attr", {"thumbnail_attr.vs", "thumbnail.fs"});
|
||||
valid &= append_shader("thumbnail", {"thumbnail.vs", "thumbnail.fs"});
|
||||
// used to render first layer for calibration
|
||||
valid &= append_shader("cali", { "cali.vs", "cali.fs"});
|
||||
// used to render printbed
|
||||
valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" });
|
||||
valid &= append_shader("printbed_attr", { "printbed_attr.vs", "printbed.fs" });
|
||||
// used to render options in gcode preview
|
||||
if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3))
|
||||
valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" });
|
||||
// used to render extrusion and travel paths as lines in gcode preview
|
||||
valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" });
|
||||
if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) {
|
||||
valid &= append_shader("gouraud_light_instanced_attr", { "gouraud_light_instanced_attr.vs", "gouraud_light_instanced.fs" });
|
||||
}
|
||||
|
||||
// used to render objects in 3d editor
|
||||
//if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 0)) {
|
||||
|
@ -64,34 +61,26 @@ std::pair<bool, std::string> GLShadersManager::init()
|
|||
);
|
||||
}
|
||||
else {
|
||||
valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }
|
||||
valid &= append_shader("gouraud_attr", { "gouraud_attr.vs", "gouraud.fs" }
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
, { "ENABLE_ENVIRONMENT_MAP"sv }
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
);
|
||||
}
|
||||
// used to render variable layers heights in 3d editor
|
||||
valid &= append_shader("variable_layer_height", { "variable_layer_height.vs", "variable_layer_height.fs" });
|
||||
valid &= append_shader("variable_layer_height_attr", { "variable_layer_height_attr.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" });
|
||||
valid &= append_shader("mm_contour_attr", { "mm_contour_attr.vs", "mm_contour_attr.fs" });
|
||||
// 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 (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12) {
|
||||
//if (GUI::wxGetApp().plater() && GUI::wxGetApp().plater()->is_wireframe_enabled())
|
||||
// valid &= append_shader("mm_gouraud", {"mm_gouraud_wireframe.vs", "mm_gouraud_wireframe.fs"}, {"FLIP_TRIANGLE_NORMALS"sv});
|
||||
//else
|
||||
valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}, {"FLIP_TRIANGLE_NORMALS"sv});
|
||||
}
|
||||
else {
|
||||
//if (GUI::wxGetApp().plater() && GUI::wxGetApp().plater()->is_wireframe_enabled())
|
||||
// valid &= append_shader("mm_gouraud", {"mm_gouraud_wireframe.vs", "mm_gouraud_wireframe.fs"});
|
||||
//else
|
||||
valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"});
|
||||
}
|
||||
if (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12)
|
||||
valid &= append_shader("mm_gouraud_attr", { "mm_gouraud_attr.vs", "mm_gouraud_attr.fs" }, { "FLIP_TRIANGLE_NORMALS"sv });
|
||||
else
|
||||
valid &= append_shader("mm_gouraud_attr", { "mm_gouraud_attr.vs", "mm_gouraud_attr.fs" });
|
||||
|
||||
//BBS: add shader for outline
|
||||
valid &= append_shader("outline", { "outline.vs", "outline.fs" });
|
||||
|
|
|
@ -663,7 +663,7 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right,
|
|||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id));
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2 };
|
||||
init_data.reserve_vertices(4);
|
||||
init_data.reserve_indices(6);
|
||||
|
||||
|
@ -674,15 +674,17 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right,
|
|||
init_data.add_vertex(Vec2f(left, top), Vec2f(uvs.left_top.u, uvs.left_top.v));
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_triangle(0, 1, 2);
|
||||
init_data.add_ushort_triangle(2, 3, 0);
|
||||
init_data.add_triangle(0, 1, 2);
|
||||
init_data.add_triangle(2, 3, 0);
|
||||
|
||||
GLModel model;
|
||||
model.init_from(std::move(init_data));
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_texture");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_texture_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
shader->set_uniform("view_model_matrix", Transform3d::Identity());
|
||||
shader->set_uniform("projection_matrix", Transform3d::Identity());
|
||||
model.render();
|
||||
shader->stop_using();
|
||||
}
|
||||
|
|
|
@ -555,14 +555,12 @@ void GLToolbar::render(const GLCanvas3D& parent,GLToolbarItem::EType type)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
|
||||
{
|
||||
if (!m_enabled)
|
||||
return false;
|
||||
|
||||
Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY());
|
||||
const Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY());
|
||||
bool processed = false;
|
||||
|
||||
// mouse anywhere
|
||||
|
@ -610,7 +608,7 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
|
|||
return false;
|
||||
}
|
||||
|
||||
int item_id = contains_mouse(mouse_pos, parent);
|
||||
const int item_id = contains_mouse(mouse_pos, parent);
|
||||
if (item_id != -1) {
|
||||
// mouse inside toolbar
|
||||
if (evt.LeftDown() || evt.LeftDClick()) {
|
||||
|
@ -757,16 +755,12 @@ int GLToolbar::get_visible_items_cnt() const
|
|||
|
||||
void GLToolbar::do_action(GLToolbarItem::EActionType type, int item_id, GLCanvas3D& parent, bool check_hover)
|
||||
{
|
||||
if ((m_pressed_toggable_id == -1) || (m_pressed_toggable_id == item_id))
|
||||
{
|
||||
if ((0 <= item_id) && (item_id < (int)m_items.size()))
|
||||
{
|
||||
if (m_pressed_toggable_id == -1 || m_pressed_toggable_id == item_id) {
|
||||
if (0 <= item_id && item_id < (int)m_items.size()) {
|
||||
GLToolbarItem* item = m_items[item_id];
|
||||
if ((item != nullptr) && !item->is_separator() && !item->is_disabled() && (!check_hover || item->is_hovered()))
|
||||
{
|
||||
if (((type == GLToolbarItem::Right) && item->is_right_toggable()) ||
|
||||
((type == GLToolbarItem::Left) && item->is_left_toggable()))
|
||||
{
|
||||
if (item != nullptr && !item->is_separator() && !item->is_disabled() && (!check_hover || item->is_hovered())) {
|
||||
if ((type == GLToolbarItem::Right && item->is_right_toggable()) ||
|
||||
(type == GLToolbarItem::Left && item->is_left_toggable())) {
|
||||
GLToolbarItem::EState state = item->get_state();
|
||||
if (state == GLToolbarItem::Hover)
|
||||
item->set_state(GLToolbarItem::HoverPressed);
|
||||
|
@ -788,8 +782,7 @@ void GLToolbar::do_action(GLToolbarItem::EActionType type, int item_id, GLCanvas
|
|||
case GLToolbarItem::Right: { item->do_right_action(); break; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
if (m_type == Radio)
|
||||
select_item(item->get_name());
|
||||
else
|
||||
|
@ -804,8 +797,7 @@ void GLToolbar::do_action(GLToolbarItem::EActionType type, int item_id, GLCanvas
|
|||
case GLToolbarItem::Right: { item->do_right_action(); break; }
|
||||
}
|
||||
|
||||
if ((m_type == Normal) && (item->get_state() != GLToolbarItem::Disabled))
|
||||
{
|
||||
if (m_type == Normal && item->get_state() != GLToolbarItem::Disabled) {
|
||||
// the item may get disabled during the action, if not, set it back to normal state
|
||||
item->set_state(GLToolbarItem::Normal);
|
||||
parent.render();
|
||||
|
@ -831,49 +823,45 @@ void GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent)
|
|||
|
||||
void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent)
|
||||
{
|
||||
// NB: mouse_pos is already scaled appropriately
|
||||
const Size cnv_size = parent.get_canvas_size();
|
||||
const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y()));
|
||||
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
float factor = m_layout.scale * inv_zoom;
|
||||
const float icons_size = m_layout.icons_size * m_layout.scale;
|
||||
const float separator_size = m_layout.separator_size * m_layout.scale;
|
||||
const float gap_size = m_layout.gap_size * m_layout.scale;
|
||||
const float border = m_layout.border * m_layout.scale;
|
||||
|
||||
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);
|
||||
const float separator_stride = separator_size + gap_size;
|
||||
const float icon_stride = icons_size + gap_size;
|
||||
|
||||
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 + border;
|
||||
float top = m_layout.top - border;
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
else {
|
||||
float right = left + icons_size;
|
||||
const float bottom = top - icons_size;
|
||||
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
if (item->is_action_with_text())
|
||||
right += scaled_icons_size * item->get_extra_size_ratio();
|
||||
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);
|
||||
right += icons_size * item->get_extra_size_ratio();
|
||||
|
||||
const GLToolbarItem::EState state = item->get_state();
|
||||
bool inside = (left <= (float)scaled_mouse_pos.x()) &&
|
||||
((float)scaled_mouse_pos.x() <= right) &&
|
||||
(bottom <= (float)scaled_mouse_pos.y()) &&
|
||||
((float)scaled_mouse_pos.y() <= top);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case GLToolbarItem::Normal:
|
||||
{
|
||||
if (inside)
|
||||
{
|
||||
if (inside) {
|
||||
item->set_state(GLToolbarItem::Hover);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -882,8 +870,7 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D
|
|||
}
|
||||
case GLToolbarItem::Hover:
|
||||
{
|
||||
if (!inside)
|
||||
{
|
||||
if (!inside) {
|
||||
item->set_state(GLToolbarItem::Normal);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -892,8 +879,7 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D
|
|||
}
|
||||
case GLToolbarItem::Pressed:
|
||||
{
|
||||
if (inside)
|
||||
{
|
||||
if (inside) {
|
||||
item->set_state(GLToolbarItem::HoverPressed);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -902,8 +888,7 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D
|
|||
}
|
||||
case GLToolbarItem::HoverPressed:
|
||||
{
|
||||
if (!inside)
|
||||
{
|
||||
if (!inside) {
|
||||
item->set_state(GLToolbarItem::Pressed);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -912,8 +897,7 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D
|
|||
}
|
||||
case GLToolbarItem::Disabled:
|
||||
{
|
||||
if (inside)
|
||||
{
|
||||
if (inside) {
|
||||
item->set_state(GLToolbarItem::HoverDisabled);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -922,8 +906,7 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D
|
|||
}
|
||||
case GLToolbarItem::HoverDisabled:
|
||||
{
|
||||
if (!inside)
|
||||
{
|
||||
if (!inside) {
|
||||
item->set_state(GLToolbarItem::Disabled);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -939,59 +922,55 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D
|
|||
left += icon_stride;
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
if (item->is_action_with_text())
|
||||
left += scaled_icons_size * item->get_extra_size_ratio();
|
||||
left += icons_size * item->get_extra_size_ratio();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent)
|
||||
{
|
||||
// NB: mouse_pos is already scaled appropriately
|
||||
const Size cnv_size = parent.get_canvas_size();
|
||||
const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y()));
|
||||
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
float factor = m_layout.scale * inv_zoom;
|
||||
const float icons_size = m_layout.icons_size * m_layout.scale;
|
||||
const float separator_size = m_layout.separator_size * m_layout.scale;
|
||||
const float gap_size = m_layout.gap_size * m_layout.scale;
|
||||
const float border = m_layout.border * m_layout.scale;
|
||||
|
||||
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);
|
||||
const float separator_stride = separator_size + gap_size;
|
||||
const float icon_stride = icons_size + gap_size;
|
||||
|
||||
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 + border;
|
||||
float top = m_layout.top - border;
|
||||
|
||||
float left = m_layout.left + scaled_border;
|
||||
float top = m_layout.top - scaled_border;
|
||||
|
||||
for (GLToolbarItem* item : m_items)
|
||||
{
|
||||
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;
|
||||
else {
|
||||
float right = left + icons_size;
|
||||
const float bottom = top - icons_size;
|
||||
|
||||
if (item->is_action_with_text_image())
|
||||
right += m_layout.text_size * factor;
|
||||
right += m_layout.text_size * m_layout.scale;
|
||||
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
if (item->is_action_with_text())
|
||||
right += scaled_icons_size * item->get_extra_size_ratio();
|
||||
right += icons_size * item->get_extra_size_ratio();
|
||||
|
||||
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);
|
||||
const bool inside = (left <= (float)scaled_mouse_pos.x()) &&
|
||||
((float)scaled_mouse_pos.x() <= right) &&
|
||||
(bottom <= (float)scaled_mouse_pos.y()) &&
|
||||
((float)scaled_mouse_pos.y() <= top);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case GLToolbarItem::Normal:
|
||||
{
|
||||
if (inside)
|
||||
{
|
||||
if (inside) {
|
||||
item->set_state(GLToolbarItem::Hover);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -1000,8 +979,7 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D&
|
|||
}
|
||||
case GLToolbarItem::Hover:
|
||||
{
|
||||
if (!inside)
|
||||
{
|
||||
if (!inside) {
|
||||
item->set_state(GLToolbarItem::Normal);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -1010,8 +988,7 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D&
|
|||
}
|
||||
case GLToolbarItem::Pressed:
|
||||
{
|
||||
if (inside)
|
||||
{
|
||||
if (inside) {
|
||||
item->set_state(GLToolbarItem::HoverPressed);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -1020,8 +997,7 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D&
|
|||
}
|
||||
case GLToolbarItem::HoverPressed:
|
||||
{
|
||||
if (!inside)
|
||||
{
|
||||
if (!inside) {
|
||||
item->set_state(GLToolbarItem::Pressed);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -1030,8 +1006,7 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D&
|
|||
}
|
||||
case GLToolbarItem::Disabled:
|
||||
{
|
||||
if (inside)
|
||||
{
|
||||
if (inside) {
|
||||
item->set_state(GLToolbarItem::HoverDisabled);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -1040,8 +1015,7 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D&
|
|||
}
|
||||
case GLToolbarItem::HoverDisabled:
|
||||
{
|
||||
if (!inside)
|
||||
{
|
||||
if (!inside) {
|
||||
item->set_state(GLToolbarItem::Disabled);
|
||||
parent.set_as_dirty();
|
||||
}
|
||||
|
@ -1089,71 +1063,72 @@ int GLToolbar::contains_mouse(const Vec2d& mouse_pos, const GLCanvas3D& parent)
|
|||
|
||||
int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
|
||||
{
|
||||
// NB: mouse_pos is already scaled appropriately
|
||||
const Size cnv_size = parent.get_canvas_size();
|
||||
const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y()));
|
||||
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
float factor = m_layout.scale * inv_zoom;
|
||||
const float icons_size = m_layout.icons_size * m_layout.scale;
|
||||
const float separator_size = m_layout.separator_size * m_layout.scale;
|
||||
const float gap_size = m_layout.gap_size * m_layout.scale;
|
||||
const float border = m_layout.border * m_layout.scale;
|
||||
|
||||
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 left = m_layout.left + border;
|
||||
const float top = m_layout.top - border;
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (item->is_separator()) {
|
||||
float right = left + separator_size;
|
||||
const float bottom = top - 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))
|
||||
if (left <= (float)scaled_mouse_pos.x() &&
|
||||
(float)scaled_mouse_pos.x() <= right &&
|
||||
bottom <= (float)scaled_mouse_pos.y() &&
|
||||
(float)scaled_mouse_pos.y() <= top)
|
||||
return id;
|
||||
|
||||
left = right;
|
||||
right += scaled_gap_size;
|
||||
right += gap_size;
|
||||
|
||||
if (id < m_items.size() - 1)
|
||||
{
|
||||
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))
|
||||
if (left <= (float)scaled_mouse_pos.x() &&
|
||||
(float)scaled_mouse_pos.x() <= right &&
|
||||
bottom <= (float)scaled_mouse_pos.y() &&
|
||||
(float)scaled_mouse_pos.y() <= top)
|
||||
return -2;
|
||||
}
|
||||
|
||||
left = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
float right = left + scaled_icons_size;
|
||||
float bottom = top - scaled_icons_size;
|
||||
else {
|
||||
float right = left + icons_size;
|
||||
const float bottom = top - icons_size;
|
||||
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
if (item->is_action_with_text())
|
||||
right += scaled_icons_size * item->get_extra_size_ratio();
|
||||
right += icons_size * item->get_extra_size_ratio();
|
||||
|
||||
// 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))
|
||||
if (left <= (float)scaled_mouse_pos.x() &&
|
||||
(float)scaled_mouse_pos.x() <= right &&
|
||||
bottom <= (float)scaled_mouse_pos.y() &&
|
||||
(float)scaled_mouse_pos.y() <= top)
|
||||
return id;
|
||||
|
||||
left = right;
|
||||
right += scaled_gap_size;
|
||||
right += gap_size;
|
||||
|
||||
if (id < m_items.size() - 1)
|
||||
{
|
||||
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))
|
||||
if (left <= (float)scaled_mouse_pos.x() &&
|
||||
(float)scaled_mouse_pos.x() <= right &&
|
||||
bottom <= (float)scaled_mouse_pos.y() &&
|
||||
(float)scaled_mouse_pos.y() <= top)
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -1166,73 +1141,75 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3
|
|||
|
||||
int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
|
||||
{
|
||||
// NB: mouse_pos is already scaled appropriately
|
||||
const Size cnv_size = parent.get_canvas_size();
|
||||
const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y()));
|
||||
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
float factor = m_layout.scale * inv_zoom;
|
||||
const float icons_size = m_layout.icons_size * m_layout.scale;
|
||||
const float separator_size = m_layout.separator_size * m_layout.scale;
|
||||
const float gap_size = m_layout.gap_size * m_layout.scale;
|
||||
const float border = m_layout.border * m_layout.scale;
|
||||
|
||||
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);
|
||||
const float left = m_layout.left + border;
|
||||
float top = m_layout.top - border;
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (item->is_separator()) {
|
||||
const float right = left + icons_size;
|
||||
float bottom = top - 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))
|
||||
if (left <= (float)scaled_mouse_pos.x() &&
|
||||
(float)scaled_mouse_pos.x() <= right &&
|
||||
bottom <= (float)scaled_mouse_pos.y() &&
|
||||
(float)scaled_mouse_pos.y() <= top)
|
||||
return id;
|
||||
|
||||
top = bottom;
|
||||
bottom -= scaled_gap_size;
|
||||
bottom -= gap_size;
|
||||
|
||||
if (id < m_items.size() - 1)
|
||||
{
|
||||
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))
|
||||
if (left <= (float)scaled_mouse_pos.x() &&
|
||||
(float)scaled_mouse_pos.x() <= right &&
|
||||
bottom <= (float)scaled_mouse_pos.y() &&
|
||||
(float)scaled_mouse_pos.y() <= top)
|
||||
return -2;
|
||||
}
|
||||
|
||||
top = bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
float right = left + scaled_icons_size;
|
||||
float bottom = top - scaled_icons_size;
|
||||
else {
|
||||
float right = left + icons_size;
|
||||
float bottom = top - icons_size;
|
||||
|
||||
if (item->is_action_with_text_image())
|
||||
right += m_layout.text_size * factor;
|
||||
right += m_layout.text_size * m_layout.scale;
|
||||
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
if (item->is_action_with_text())
|
||||
right += scaled_icons_size * item->get_extra_size_ratio();
|
||||
right += icons_size * item->get_extra_size_ratio();
|
||||
|
||||
// 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))
|
||||
if (left <= (float)scaled_mouse_pos.x() &&
|
||||
(float)scaled_mouse_pos.x() <= right &&
|
||||
bottom <= (float)scaled_mouse_pos.y() &&
|
||||
(float)scaled_mouse_pos.y() <= top)
|
||||
return id;
|
||||
|
||||
top = bottom;
|
||||
bottom -= scaled_gap_size;
|
||||
bottom -= gap_size;
|
||||
|
||||
if (id < m_items.size() - 1)
|
||||
{
|
||||
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))
|
||||
if (left <= (float)scaled_mouse_pos.x() &&
|
||||
(float)scaled_mouse_pos.x() <= right &&
|
||||
bottom <= (float)scaled_mouse_pos.y() &&
|
||||
(float)scaled_mouse_pos.y() <= top)
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -1243,33 +1220,32 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D&
|
|||
return -1;
|
||||
}
|
||||
|
||||
void GLToolbar::render_background(float left, float top, float right, float bottom, float border) const
|
||||
void GLToolbar::render_background(float left, float top, float right, float bottom, float border_w, float border_h) 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;
|
||||
const unsigned int tex_id = m_background_texture.texture.get_id();
|
||||
const float tex_width = (float)m_background_texture.texture.get_width();
|
||||
const float tex_height = (float)m_background_texture.texture.get_height();
|
||||
if (tex_id != 0 && tex_width > 0.0f && tex_height > 0.0f) {
|
||||
const float inv_tex_width = 1.0f / tex_width;
|
||||
const float inv_tex_height = 1.0f / tex_height;
|
||||
|
||||
float internal_left = left + border;
|
||||
float internal_right = right - border;
|
||||
float internal_top = top - border;
|
||||
float internal_bottom = bottom + border;
|
||||
const float internal_left = left + border_w;
|
||||
const float internal_right = right - border_w;
|
||||
const float internal_top = top - border_h;
|
||||
const float internal_bottom = bottom + border_w;
|
||||
|
||||
float left_uv = 0.0f;
|
||||
float right_uv = 1.0f;
|
||||
float top_uv = 1.0f;
|
||||
float bottom_uv = 0.0f;
|
||||
const float left_uv = 0.0f;
|
||||
const float right_uv = 1.0f;
|
||||
const float top_uv = 1.0f;
|
||||
const 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;
|
||||
const float internal_left_uv = (float)m_background_texture.metadata.left * inv_tex_width;
|
||||
const float internal_right_uv = 1.0f - (float)m_background_texture.metadata.right * inv_tex_width;
|
||||
const float internal_top_uv = 1.0f - (float)m_background_texture.metadata.top * inv_tex_height;
|
||||
const 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))
|
||||
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 } });
|
||||
|
@ -1281,7 +1257,7 @@ void GLToolbar::render_background(float left, float top, float right, float bott
|
|||
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))
|
||||
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 } });
|
||||
|
@ -1302,7 +1278,7 @@ void GLToolbar::render_background(float left, float top, float right, float bott
|
|||
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))
|
||||
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 } });
|
||||
|
@ -1314,7 +1290,7 @@ void GLToolbar::render_background(float left, float top, float right, float bott
|
|||
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))
|
||||
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 } });
|
||||
|
@ -1389,41 +1365,48 @@ void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighte
|
|||
|
||||
void GLToolbar::render_horizontal(const GLCanvas3D& parent,GLToolbarItem::EType type)
|
||||
{
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
float factor = inv_zoom * m_layout.scale;
|
||||
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();
|
||||
|
||||
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;
|
||||
if (cnv_w == 0 || cnv_h == 0)
|
||||
return;
|
||||
|
||||
float separator_stride = scaled_separator_size + scaled_gap_size;
|
||||
float icon_stride = scaled_icons_size + scaled_gap_size;
|
||||
const float inv_cnv_w = 1.0f / cnv_w;
|
||||
const float inv_cnv_h = 1.0f / cnv_h;
|
||||
|
||||
float left = m_layout.left;
|
||||
float top = m_layout.top;
|
||||
float right = left + scaled_width;
|
||||
const float icons_size_x = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_w;
|
||||
const float icons_size_y = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_h;
|
||||
const float separator_size = 2.0f * m_layout.separator_size * m_layout.scale * inv_cnv_w;
|
||||
const float gap_size = 2.0f * m_layout.gap_size * m_layout.scale * inv_cnv_w;
|
||||
const float border_w = 2.0f * m_layout.border * m_layout.scale * inv_cnv_w;
|
||||
const float border_h = 2.0f * m_layout.border * m_layout.scale * inv_cnv_h;
|
||||
const float width = 2.0f * get_width() * inv_cnv_w;
|
||||
const float height = 2.0f * get_height() * inv_cnv_h;
|
||||
|
||||
const float separator_stride = separator_size + gap_size;
|
||||
const float icon_stride = icons_size_x + gap_size;
|
||||
|
||||
float left = 2.0f * m_layout.left * inv_cnv_w;
|
||||
float top = 2.0f * m_layout.top * inv_cnv_h;
|
||||
float right = left + width;
|
||||
if (type == GLToolbarItem::SeparatorLine)
|
||||
right = left + scaled_width * 0.5;
|
||||
float bottom = top - scaled_height;
|
||||
right = left + width * 0.5;
|
||||
const float bottom = top - height;
|
||||
|
||||
render_background(left, top, right, bottom, scaled_border);
|
||||
render_background(left, top, right, bottom, border_w, border_h);
|
||||
|
||||
left += scaled_border;
|
||||
top -= scaled_border;
|
||||
left += border_w;
|
||||
top -= border_h;
|
||||
|
||||
// renders icons
|
||||
for (const GLToolbarItem* item : m_items)
|
||||
{
|
||||
for (const GLToolbarItem* item : m_items) {
|
||||
if (!item->is_visible())
|
||||
continue;
|
||||
|
||||
if (item->is_separator())
|
||||
left += separator_stride;
|
||||
else
|
||||
{
|
||||
else {
|
||||
//BBS GUI refactor
|
||||
item->render_left_pos = left;
|
||||
if (!item->is_action_with_text_image()) {
|
||||
|
@ -1432,13 +1415,13 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent,GLToolbarItem::EType
|
|||
int tex_height = m_icons_texture.get_height();
|
||||
if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0))
|
||||
return;
|
||||
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));
|
||||
item->render(tex_id, left, left + icons_size_x, top - icons_size_y, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale));
|
||||
}
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
if (item->is_action_with_text())
|
||||
{
|
||||
float scaled_text_size = item->get_extra_size_ratio() * scaled_icons_size;
|
||||
item->render_text(left + scaled_icons_size, left + scaled_icons_size + scaled_text_size, top - scaled_icons_size, top);
|
||||
float scaled_text_size = item->get_extra_size_ratio() * icons_size_x;
|
||||
item->render_text(left + icons_size_x, left + icons_size_x + scaled_text_size, top - icons_size_y, top);
|
||||
left += scaled_text_size;
|
||||
}
|
||||
left += icon_stride;
|
||||
|
@ -1448,28 +1431,37 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent,GLToolbarItem::EType
|
|||
|
||||
void GLToolbar::render_vertical(const GLCanvas3D& parent)
|
||||
{
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
float factor = inv_zoom * m_layout.scale;
|
||||
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();
|
||||
|
||||
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;
|
||||
if (cnv_w == 0 || cnv_h == 0)
|
||||
return;
|
||||
|
||||
float separator_stride = scaled_separator_size + scaled_gap_size;
|
||||
float icon_stride = scaled_icons_size + scaled_gap_size;
|
||||
const float inv_cnv_w = 1.0f / cnv_w;
|
||||
const float inv_cnv_h = 1.0f / cnv_h;
|
||||
|
||||
float left = m_layout.left;
|
||||
float top = m_layout.top;
|
||||
float right = left + scaled_width;
|
||||
float bottom = top - scaled_height;
|
||||
const float icons_size_x = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_w;
|
||||
const float icons_size_y = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_h;
|
||||
const float separator_size = 2.0f * m_layout.separator_size * m_layout.scale * inv_cnv_h;
|
||||
const float gap_size = 2.0f * m_layout.gap_size * m_layout.scale * inv_cnv_h;
|
||||
const float border_w = 2.0f * m_layout.border * m_layout.scale * inv_cnv_w;
|
||||
const float border_h = 2.0f * m_layout.border * m_layout.scale * inv_cnv_h;
|
||||
const float width = 2.0f * get_width() * inv_cnv_w;
|
||||
const float height = 2.0f * get_height() * inv_cnv_h;
|
||||
|
||||
render_background(left, top, right, bottom, scaled_border);
|
||||
const float separator_stride = separator_size + gap_size;
|
||||
const float icon_stride = icons_size_y + gap_size;
|
||||
|
||||
left += scaled_border;
|
||||
top -= scaled_border;
|
||||
float left = 2.0f * m_layout.left * inv_cnv_w;
|
||||
float top = 2.0f * m_layout.top * inv_cnv_h;
|
||||
const float right = left + width;
|
||||
const float bottom = top - height;
|
||||
|
||||
render_background(left, top, right, bottom, border_w, border_h);
|
||||
|
||||
left += border_w;
|
||||
top -= border_h;
|
||||
|
||||
// renders icons
|
||||
for (const GLToolbarItem* item : m_items) {
|
||||
|
@ -1482,10 +1474,10 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent)
|
|||
unsigned int tex_id;
|
||||
int tex_width, tex_height;
|
||||
if (item->is_action_with_text_image()) {
|
||||
float scaled_text_size = m_layout.text_size * factor;
|
||||
float scaled_text_width = item->get_extra_size_ratio() * scaled_icons_size;
|
||||
float scaled_text_border = 2.5 * factor;
|
||||
float scaled_text_height = scaled_icons_size / 2.0f;
|
||||
float scaled_text_size = m_layout.text_size * m_layout.scale * inv_cnv_w;
|
||||
float scaled_text_width = item->get_extra_size_ratio() * icons_size_x;
|
||||
float scaled_text_border = 2.5 * m_layout.scale * inv_cnv_h;
|
||||
float scaled_text_height = icons_size_y / 2.0f;
|
||||
item->render_text(left, left + scaled_text_size, top - scaled_text_border - scaled_text_height, top - scaled_text_border);
|
||||
|
||||
float image_left = left + scaled_text_size;
|
||||
|
@ -1494,7 +1486,7 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent)
|
|||
tex_height = item->m_data.image_texture.get_height();
|
||||
if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0))
|
||||
return;
|
||||
item->render_image(tex_id, image_left, image_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));
|
||||
item->render_image(tex_id, image_left, image_left + icons_size_x, top - icons_size_y, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale));
|
||||
}
|
||||
else {
|
||||
tex_id = m_icons_texture.get_id();
|
||||
|
@ -1502,14 +1494,14 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent)
|
|||
tex_height = m_icons_texture.get_height();
|
||||
if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0))
|
||||
return;
|
||||
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));
|
||||
item->render(tex_id, left, left + icons_size_x, top - icons_size_y, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale));
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
}
|
||||
if (item->is_action_with_text())
|
||||
{
|
||||
float scaled_text_width = item->get_extra_size_ratio() * scaled_icons_size;
|
||||
float scaled_text_height = scaled_icons_size;
|
||||
item->render_text(left + scaled_icons_size, left + scaled_icons_size + scaled_text_width, top - scaled_text_height, top);
|
||||
float scaled_text_width = item->get_extra_size_ratio() * icons_size_x;
|
||||
float scaled_text_height = icons_size_y;
|
||||
item->render_text(left + icons_size_x, left + icons_size_x + scaled_text_width, top - scaled_text_height, top);
|
||||
}
|
||||
top -= icon_stride;
|
||||
}
|
||||
|
|
|
@ -436,7 +436,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;
|
||||
|
||||
void render_background(float left, float top, float right, float bottom, float border) const;
|
||||
void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const;
|
||||
void render_horizontal(const GLCanvas3D &parent, GLToolbarItem::EType type);
|
||||
void render_vertical(const GLCanvas3D& parent);
|
||||
|
||||
|
|
|
@ -492,8 +492,6 @@ void GLGizmoAdvancedCut::on_render_for_picking()
|
|||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
|
||||
BoundingBoxf3 box = m_parent.get_selection().get_bounding_box();
|
||||
#if ENABLE_FIXED_GRABBER
|
||||
float mean_size = (float)(GLGizmoBase::Grabber::FixedGrabberSize);
|
||||
|
@ -502,17 +500,17 @@ void GLGizmoAdvancedCut::on_render_for_picking()
|
|||
#endif
|
||||
|
||||
m_move_grabber.color = picking_color_component(0);
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
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());
|
||||
m_move_grabber.render_for_picking(mean_size);
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
auto inst_id = m_c->selection_info()->get_active_instance();
|
||||
if (inst_id < 0)
|
||||
|
@ -868,7 +866,7 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers()
|
|||
glsafe(::glEnable(GL_BLEND));
|
||||
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
|
@ -877,7 +875,7 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers()
|
|||
m_plane.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.color = { 0.8f, 0.8f, 0.8f, 0.5f };
|
||||
init_data.reserve_vertices(4);
|
||||
init_data.reserve_vertices(6);
|
||||
|
@ -888,11 +886,14 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers()
|
|||
}
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_triangle(0, 1, 2);
|
||||
init_data.add_ushort_triangle(2, 3, 0);
|
||||
init_data.add_triangle(0, 1, 2);
|
||||
init_data.add_triangle(2, 3, 0);
|
||||
|
||||
m_plane.init_from(std::move(init_data));
|
||||
}
|
||||
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());
|
||||
m_plane.render();
|
||||
|
||||
glsafe(::glEnable(GL_CULL_FACE));
|
||||
|
@ -907,17 +908,17 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers()
|
|||
m_grabber_connection.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.color = ColorRGBA::YELLOW();
|
||||
init_data.vertices.reserve(2 * GLModel::Geometry::vertex_stride_floats(init_data.format));
|
||||
init_data.indices.reserve(2 * GLModel::Geometry::index_stride_bytes(init_data.format));
|
||||
init_data.reserve_vertices(2);
|
||||
init_data.reserve_vertices(2);
|
||||
|
||||
// vertices
|
||||
init_data.add_vertex((Vec3f)plane_center_rot.cast<float>());
|
||||
init_data.add_vertex((Vec3f)m_move_grabber.center.cast<float>());
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_line(0, 1);
|
||||
init_data.add_line(0, 1);
|
||||
|
||||
m_grabber_connection.init_from(std::move(init_data));
|
||||
}
|
||||
|
@ -933,7 +934,7 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers()
|
|||
}
|
||||
|
||||
{
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("gouraud_light");
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("gouraud_light_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
shader->start_using();
|
||||
|
@ -960,13 +961,15 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers()
|
|||
|
||||
cube.set_color(render_color);
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(m_move_grabber.center.x(), m_move_grabber.center.y(), m_move_grabber.center.z()));
|
||||
glsafe(::glMultMatrixd(m_rotate_matrix.data()));
|
||||
|
||||
glsafe(::glScaled(fullsize, fullsize, fullsize));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::assemble_transform(m_move_grabber.center) *
|
||||
m_rotate_matrix *
|
||||
Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), fullsize * Vec3d::Ones());
|
||||
const Transform3d& projection_matrix = camera.get_projection_matrix();
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d) view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
cube.render();
|
||||
glsafe(::glPopMatrix());
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
|
@ -1064,23 +1067,26 @@ void GLGizmoAdvancedCut::render_cut_line()
|
|||
|
||||
void GLGizmoAdvancedCut::render_connector_model(GLModel &model, const ColorRGBA &color, Transform3d view_model_matrix, bool for_picking)
|
||||
{
|
||||
glPushMatrix();
|
||||
GLShaderProgram *shader = nullptr;
|
||||
if (for_picking)
|
||||
shader = wxGetApp().get_shader("cali");
|
||||
shader = wxGetApp().get_shader("flat_attr");
|
||||
else
|
||||
shader = wxGetApp().get_shader("gouraud_light");
|
||||
shader = wxGetApp().get_shader("gouraud_light_attr");
|
||||
if (shader) {
|
||||
shader->start_using();
|
||||
|
||||
glsafe(::glMultMatrixd(view_model_matrix.data()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
view_model_matrix = camera.get_view_matrix() * view_model_matrix;
|
||||
const Transform3d &projection_matrix = camera.get_projection_matrix();
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d) view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
|
||||
model.set_color(color);
|
||||
model.render();
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void GLGizmoAdvancedCut::clear_selection()
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <GL/glew.h>
|
||||
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/GUI_Colors.hpp"
|
||||
|
||||
// TODO: Display tooltips quicker on Linux
|
||||
|
@ -97,11 +98,15 @@ GLModel& GLGizmoBase::Grabber::get_cube()
|
|||
|
||||
void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, bool picking)
|
||||
{
|
||||
GLShaderProgram* shader = wxGetApp().get_current_shader();
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
if (!m_cube.is_initialized()) {
|
||||
// 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., 1., 1.);
|
||||
its_translate(its, Vec3f(-0.5, -0.5, -0.5));
|
||||
its_translate(its, -0.5f * Vec3f::Ones());
|
||||
m_cube.init_from(its);
|
||||
}
|
||||
|
||||
|
@ -115,14 +120,14 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, boo
|
|||
|
||||
m_cube.set_color(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(fullsize, fullsize, fullsize));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() * matrix * Geometry::assemble_transform(center, angles, fullsize * Vec3d::Ones());
|
||||
const Transform3d& projection_matrix = camera.get_projection_matrix();
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_cube.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
||||
|
@ -257,7 +262,7 @@ void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const
|
|||
|
||||
void GLGizmoBase::render_grabbers(float size) const
|
||||
{
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
shader->start_using();
|
||||
|
@ -271,7 +276,7 @@ void GLGizmoBase::render_grabbers(float size) const
|
|||
|
||||
void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const
|
||||
{
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ protected:
|
|||
bool dragging{ false };
|
||||
Vec3d center{ Vec3d::Zero() };
|
||||
Vec3d angles{ Vec3d::Zero() };
|
||||
Transform3d matrix{ Transform3d::Identity() };
|
||||
ColorRGBA color{GRABBER_NORMAL_COL};
|
||||
ColorRGBA hover_color{GRABBER_HOVER_COL};
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ bool GLGizmoFdmSupports::on_key_down_select_tool_type(int keyCode) {
|
|||
void GLGizmoFdmSupports::render_triangles(const Selection& selection) const
|
||||
{
|
||||
ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data();
|
||||
auto* shader = wxGetApp().get_shader("mm_gouraud");
|
||||
auto* shader = wxGetApp().get_shader("mm_gouraud_attr");
|
||||
if (!shader)
|
||||
return;
|
||||
shader->start_using();
|
||||
|
@ -177,8 +177,11 @@ void GLGizmoFdmSupports::render_triangles(const Selection& selection) const
|
|||
if (is_left_handed)
|
||||
glsafe(::glFrontFace(GL_CW));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glMultMatrixd(trafo_matrix.data()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d matrix = camera.get_view_matrix() * trafo_matrix;
|
||||
shader->set_uniform("view_model_matrix", matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
|
||||
float normal_z = -::cos(Geometry::deg2rad(m_highlight_by_angle_threshold_deg));
|
||||
Matrix3f normal_matrix = static_cast<Matrix3f>(trafo_matrix.matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>());
|
||||
|
@ -188,9 +191,8 @@ void GLGizmoFdmSupports::render_triangles(const Selection& selection) const
|
|||
shader->set_uniform("slope.actived", m_parent.is_using_slope());
|
||||
shader->set_uniform("slope.volume_world_normal_matrix", normal_matrix);
|
||||
shader->set_uniform("slope.normal_z", normal_z);
|
||||
m_triangle_selectors[mesh_id]->render(m_imgui);
|
||||
m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix);
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
if (is_left_handed)
|
||||
glsafe(::glFrontFace(GL_CCW));
|
||||
}
|
||||
|
@ -895,7 +897,7 @@ void GLGizmoFdmSupports::run_thread()
|
|||
goto _finished;
|
||||
}
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
for (const SupportLayer *support_layer : m_print_instance.print_object->support_layers())
|
||||
{
|
||||
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "GLGizmoFlatten.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
|
||||
|
||||
#include "libslic3r/Geometry/ConvexHull.hpp"
|
||||
|
@ -63,7 +64,7 @@ void GLGizmoFlatten::on_render()
|
|||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -75,16 +76,18 @@ void GLGizmoFlatten::on_render()
|
|||
|
||||
if (selection.is_single_full_instance()) {
|
||||
const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix();
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z()));
|
||||
glsafe(::glMultMatrixd(m.data()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() *
|
||||
Geometry::assemble_transform(selection.get_volume(*selection.get_volume_idxs().begin())->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());
|
||||
if (this->is_plane_update_necessary())
|
||||
update_planes();
|
||||
for (int i = 0; i < (int)m_planes.size(); ++i) {
|
||||
m_planes[i].vbo.set_color(i == m_hover_id ? GLGizmoBase::FLATTEN_HOVER_COLOR : GLGizmoBase::FLATTEN_COLOR);
|
||||
m_planes[i].vbo.render();
|
||||
}
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
glsafe(::glEnable(GL_CULL_FACE));
|
||||
|
@ -95,7 +98,7 @@ void GLGizmoFlatten::on_render()
|
|||
void GLGizmoFlatten::on_render_for_picking()
|
||||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -106,16 +109,18 @@ void GLGizmoFlatten::on_render_for_picking()
|
|||
|
||||
if (selection.is_single_full_instance() && !wxGetKeyState(WXK_CONTROL)) {
|
||||
const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix();
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z()));
|
||||
glsafe(::glMultMatrixd(m.data()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() *
|
||||
Geometry::assemble_transform(selection.get_volume(*selection.get_volume_idxs().begin())->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());
|
||||
if (this->is_plane_update_necessary())
|
||||
update_planes();
|
||||
for (int i = 0; i < (int)m_planes.size(); ++i) {
|
||||
m_planes[i].vbo.set_color(picking_color_component(i));
|
||||
m_planes[i].vbo.render();
|
||||
}
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
glsafe(::glEnable(GL_CULL_FACE));
|
||||
|
@ -337,16 +342,13 @@ void GLGizmoFlatten::update_planes()
|
|||
// the vertices in order, so triangulation is trivial.
|
||||
for (auto& plane : m_planes) {
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::TriangleFan, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(plane.vertices.size()) };
|
||||
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>());
|
||||
if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
||||
init_data.add_ushort_index((unsigned short)i);
|
||||
else
|
||||
init_data.add_uint_index((unsigned int)i);
|
||||
init_data.add_index((unsigned int)i);
|
||||
}
|
||||
plane.vbo.init_from(std::move(init_data));
|
||||
// FIXME: vertices should really be local, they need not
|
||||
|
|
|
@ -103,7 +103,7 @@ void GLGizmoHollow::on_render_for_picking()
|
|||
|
||||
void GLGizmoHollow::render_points(const Selection& selection, bool picking)
|
||||
{
|
||||
GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat") : wxGetApp().get_shader("gouraud_light");
|
||||
GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat_attr") : wxGetApp().get_shader("gouraud_light_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -111,20 +111,22 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
|
|||
ScopeGuard guard([shader]() { shader->stop_using(); });
|
||||
|
||||
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
|
||||
const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
|
||||
const Transform3d instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
|
||||
const Transform3d instance_matrix = Geometry::assemble_transform(m_c->selection_info()->get_sla_shift() * Vec3d::UnitZ()) * vol->get_instance_transformation().get_matrix();
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(0.0, 0.0, m_c->selection_info()->get_sla_shift()));
|
||||
glsafe(::glMultMatrixd(instance_matrix.data()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
const Transform3d& projection_matrix = camera.get_projection_matrix();
|
||||
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
|
||||
ColorRGBA render_color;
|
||||
const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
|
||||
size_t cache_size = drain_holes.size();
|
||||
const size_t cache_size = drain_holes.size();
|
||||
|
||||
for (size_t i = 0; i < cache_size; ++i) {
|
||||
const sla::DrainHole& drain_hole = drain_holes[i];
|
||||
const bool& point_selected = m_selected[i];
|
||||
const bool point_selected = m_selected[i];
|
||||
|
||||
if (is_mesh_point_clipped(drain_hole.pos.cast<double>()))
|
||||
continue;
|
||||
|
@ -147,9 +149,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
|
|||
m_cylinder.set_color(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()));
|
||||
const Transform3d hole_matrix = Geometry::assemble_transform(drain_hole.pos.cast<double>()) * instance_scaling_matrix_inverse;
|
||||
|
||||
if (vol->is_left_handed())
|
||||
glFrontFace(GL_CW);
|
||||
|
@ -157,18 +157,17 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
|
|||
// Matrices set, we can render the point mark now.
|
||||
Eigen::Quaterniond q;
|
||||
q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * (-drain_hole.normal).cast<double>());
|
||||
Eigen::AngleAxisd aa(q);
|
||||
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));
|
||||
const Eigen::AngleAxisd aa(q);
|
||||
const Transform3d view_model_matrix = view_matrix * instance_matrix * hole_matrix * Transform3d(aa.toRotationMatrix()) *
|
||||
Geometry::assemble_transform(-drain_hole.height * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength));
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_cylinder.render();
|
||||
|
||||
if (vol->is_left_handed())
|
||||
glFrontFace(GL_CCW);
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
bool GLGizmoHollow::is_mesh_point_clipped(const Vec3d& point) const
|
||||
|
|
|
@ -192,7 +192,7 @@ void GLGizmoMmuSegmentation::set_painter_gizmo_data(const Selection &selection)
|
|||
void GLGizmoMmuSegmentation::render_triangles(const Selection &selection) const
|
||||
{
|
||||
ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data();
|
||||
auto *shader = wxGetApp().get_shader("mm_gouraud");
|
||||
auto* shader = wxGetApp().get_shader("mm_gouraud_attr");
|
||||
if (!shader)
|
||||
return;
|
||||
shader->start_using();
|
||||
|
@ -221,18 +221,20 @@ void GLGizmoMmuSegmentation::render_triangles(const Selection &selection) const
|
|||
trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix()* mv->get_matrix();
|
||||
}
|
||||
|
||||
bool is_left_handed = trafo_matrix.matrix().determinant() < 0.;
|
||||
const bool is_left_handed = trafo_matrix.matrix().determinant() < 0.0;
|
||||
if (is_left_handed)
|
||||
glsafe(::glFrontFace(GL_CW));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glMultMatrixd(trafo_matrix.data()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d matrix = camera.get_view_matrix() * trafo_matrix;
|
||||
shader->set_uniform("view_model_matrix", matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
|
||||
shader->set_uniform("volume_world_matrix", trafo_matrix);
|
||||
shader->set_uniform("volume_mirrored", is_left_handed);
|
||||
m_triangle_selectors[mesh_id]->render(m_imgui);
|
||||
m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix);
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
if (is_left_handed)
|
||||
glsafe(::glFrontFace(GL_CCW));
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ void GLGizmoMove3D::on_render()
|
|||
m_grabber_connections[id].model.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.color = AXES_COLOR[id];
|
||||
init_data.reserve_vertices(2);
|
||||
init_data.reserve_indices(2);
|
||||
|
@ -150,7 +150,7 @@ void GLGizmoMove3D::on_render()
|
|||
init_data.add_vertex((Vec3f)m_grabbers[id].center.cast<float>());
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_line(0, 1);
|
||||
init_data.add_line(0, 1);
|
||||
|
||||
m_grabber_connections[id].model.init_from(std::move(init_data));
|
||||
//}
|
||||
|
@ -162,11 +162,13 @@ void GLGizmoMove3D::on_render()
|
|||
}
|
||||
};
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
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());
|
||||
|
||||
// draw axes line
|
||||
// draw axes
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
render_grabber_connection(i);
|
||||
|
@ -240,12 +242,12 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const
|
|||
void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box, bool picking)
|
||||
{
|
||||
#if ENABLE_FIXED_GRABBER
|
||||
float mean_size = (float)(GLGizmoBase::Grabber::FixedGrabberSize);
|
||||
const float mean_size = (float)(GLGizmoBase::Grabber::FixedGrabberSize);
|
||||
#else
|
||||
float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0);
|
||||
const float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0);
|
||||
#endif
|
||||
|
||||
double size = 0.75 * GLGizmoBase::Grabber::FixedGrabberSize * GLGizmoBase::INV_ZOOM;
|
||||
const double size = 0.75 * GLGizmoBase::Grabber::FixedGrabberSize * GLGizmoBase::INV_ZOOM;
|
||||
|
||||
ColorRGBA color = m_grabbers[axis].color;
|
||||
if (!picking && m_hover_id != -1) {
|
||||
|
@ -254,7 +256,7 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box
|
|||
}
|
||||
}
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat_attr" : "gouraud_light_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -262,22 +264,21 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box
|
|||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.1f);
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(m_grabbers[axis].center.x(), m_grabbers[axis].center.y(), m_grabbers[axis].center.z()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::assemble_transform(m_grabbers[axis].center);
|
||||
if (axis == X)
|
||||
glsafe(::glRotated(90.0, 0.0, 1.0, 0.0));
|
||||
view_model_matrix = view_model_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitY());
|
||||
else if (axis == Y)
|
||||
glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0));
|
||||
view_model_matrix = view_model_matrix * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitX());
|
||||
view_model_matrix = view_model_matrix * Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 2.0 * size));
|
||||
|
||||
//glsafe(::glTranslated(0.0, 0.0, 2.0 * size));
|
||||
glsafe(::glScaled(0.75 * size, 0.75 * size, 2.0 * size));
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_cone.render();
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -75,7 +75,7 @@ GLGizmoPainterBase::ClippingPlaneDataWrapper GLGizmoPainterBase::get_clipping_pl
|
|||
|
||||
void GLGizmoPainterBase::render_triangles(const Selection& selection) const
|
||||
{
|
||||
auto* shader = wxGetApp().get_shader("gouraud");
|
||||
auto* shader = wxGetApp().get_shader("gouraud_attr");
|
||||
if (! shader)
|
||||
return;
|
||||
shader->start_using();
|
||||
|
@ -105,8 +105,11 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const
|
|||
if (is_left_handed)
|
||||
glsafe(::glFrontFace(GL_CW));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glMultMatrixd(trafo_matrix.data()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d matrix = camera.get_view_matrix() * trafo_matrix;
|
||||
shader->set_uniform("view_model_matrix", matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
|
||||
// For printers with multiple extruders, it is necessary to pass trafo_matrix
|
||||
// to the shader input variable print_box.volume_world_matrix before
|
||||
|
@ -114,9 +117,8 @@ 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);
|
||||
|
||||
m_triangle_selectors[mesh_id]->render(m_imgui);
|
||||
m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix);
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
if (is_left_handed)
|
||||
glsafe(::glFrontFace(GL_CCW));
|
||||
}
|
||||
|
@ -165,43 +167,34 @@ void GLGizmoPainterBase::render_cursor()
|
|||
|
||||
void GLGizmoPainterBase::render_cursor_circle()
|
||||
{
|
||||
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;
|
||||
|
||||
const Size cnv_size = m_parent.get_canvas_size();
|
||||
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)
|
||||
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)
|
||||
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;
|
||||
|
||||
const float cnv_inv_width = 1.0f / cnv_width;
|
||||
const float cnv_inv_height = 1.0f / cnv_height;
|
||||
|
||||
const Vec2d center = m_parent.get_local_mouse_position();
|
||||
const float radius = m_cursor_radius * float(wxGetApp().plater()->get_camera().get_zoom());
|
||||
|
||||
glsafe(::glLineWidth(1.5f));
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
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));
|
||||
|
||||
glsafe(::glPushAttrib(GL_ENABLE_BIT));
|
||||
glsafe(::glLineStipple(4, 0xAAAA));
|
||||
glsafe(::glEnable(GL_LINE_STIPPLE));
|
||||
|
||||
if (!m_circle.is_initialized() || !m_old_center.isApprox(center) || std::abs(m_old_cursor_radius - m_cursor_radius) > EPSILON) {
|
||||
if (!m_circle.is_initialized() || !m_old_center.isApprox(center) || std::abs(m_old_cursor_radius - radius) > EPSILON) {
|
||||
m_old_cursor_radius = radius;
|
||||
m_old_center = center;
|
||||
m_old_cursor_radius = m_cursor_radius;
|
||||
m_circle.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
static const unsigned int StepsCount = 32;
|
||||
static const float StepSize = 2.0f * float(PI) / float(StepsCount);
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 };
|
||||
init_data.color = { 0.0f, 1.0f, 0.3f, 1.0f };
|
||||
init_data.reserve_vertices(StepsCount);
|
||||
init_data.reserve_indices(StepsCount);
|
||||
|
@ -209,8 +202,9 @@ void GLGizmoPainterBase::render_cursor_circle()
|
|||
// vertices + indices
|
||||
for (unsigned short i = 0; i < StepsCount; ++i) {
|
||||
const float angle = float(i * StepSize);
|
||||
init_data.add_vertex(Vec2f(center.x() + ::cos(angle) * m_cursor_radius, center.y() + ::sin(angle) * m_cursor_radius));
|
||||
init_data.add_ushort_index(i);
|
||||
init_data.add_vertex(Vec2f(2.0f * ((center.x() + ::cos(angle) * radius) * cnv_inv_width - 0.5f),
|
||||
-2.0f * ((center.y() + ::sin(angle) * radius) * cnv_inv_height - 0.5f)));
|
||||
init_data.add_index(i);
|
||||
}
|
||||
|
||||
m_circle.init_from(std::move(init_data));
|
||||
|
@ -225,15 +219,16 @@ void GLGizmoPainterBase::render_cursor_circle()
|
|||
|
||||
m_circle.set_color(render_color);
|
||||
|
||||
GLShaderProgram* shader = GUI::wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
shader->set_uniform("view_model_matrix", Transform3d::Identity());
|
||||
shader->set_uniform("projection_matrix", Transform3d::Identity());
|
||||
m_circle.render();
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
glsafe(::glPopAttrib());
|
||||
glsafe(::glPopMatrix());
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
}
|
||||
|
||||
|
@ -245,20 +240,13 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
|
|||
s_sphere->init_from(its_make_sphere(1.0, double(PI) / 12.0));
|
||||
}
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_matrix(true, true, false, true).inverse();
|
||||
const bool is_left_handed = Geometry::Transformation(trafo).is_left_handed();
|
||||
|
||||
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));
|
||||
|
||||
if (is_left_handed)
|
||||
glFrontFace(GL_CW);
|
||||
|
||||
|
@ -270,6 +258,14 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
|
|||
render_color = this->get_cursor_sphere_right_button_color();
|
||||
shader->start_using();
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
Transform3d view_model_matrix = camera.get_view_matrix() * trafo *
|
||||
Geometry::assemble_transform(m_rr.hit.cast<double>()) * complete_scaling_matrix_inverse *
|
||||
Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), m_cursor_radius * Vec3d::Ones());
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
assert(s_sphere != nullptr);
|
||||
s_sphere->set_color(render_color);
|
||||
s_sphere->render();
|
||||
|
@ -277,13 +273,17 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
|
|||
shader->stop_using();
|
||||
if (is_left_handed)
|
||||
glFrontFace(GL_CCW);
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
// BBS
|
||||
void GLGizmoPainterBase::render_cursor_height_range(const Transform3d& trafo) const
|
||||
{
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
shader->start_using();
|
||||
|
||||
const BoundingBoxf3 box = bounding_box();
|
||||
Vec3d hit_world = trafo * Vec3d(m_rr.hit(0), m_rr.hit(1), m_rr.hit(2));
|
||||
float max_z = (float)box.max.z();
|
||||
|
@ -309,14 +309,18 @@ void GLGizmoPainterBase::render_cursor_height_range(const Transform3d& trafo) co
|
|||
for (int i = 0; i < zs.size(); i++) {
|
||||
update_contours(vol_mesh, zs[i], max_z, min_z);
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::assemble_transform(m_cut_contours.shift);
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
glsafe(::glLineWidth(2.0f));
|
||||
m_cut_contours.contours.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
BoundingBoxf3 GLGizmoPainterBase::bounding_box() const
|
||||
|
@ -1056,7 +1060,7 @@ ColorRGBA TriangleSelectorGUI::get_seed_fill_color(const ColorRGBA& base_color)
|
|||
1.f};
|
||||
}
|
||||
|
||||
void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
|
||||
void TriangleSelectorGUI::render(ImGuiWrapper* imgui, const Transform3d& matrix)
|
||||
{
|
||||
if (m_update_render_data) {
|
||||
update_render_data();
|
||||
|
@ -1066,7 +1070,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
|
|||
auto* shader = wxGetApp().get_current_shader();
|
||||
if (! shader)
|
||||
return;
|
||||
assert(shader->get_name() == "gouraud");
|
||||
assert(shader->get_name() == "gouraud_attr" || shader->get_name() == "mm_gouraud_attr");
|
||||
ScopeGuard guard([shader]() { if (shader) shader->set_uniform("offset_depth_buffer", false);});
|
||||
shader->set_uniform("offset_depth_buffer", true);
|
||||
for (auto iva : {std::make_pair(&m_iva_enforcers, enforcers_color),
|
||||
|
@ -1084,7 +1088,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
|
|||
iva.render();
|
||||
}
|
||||
|
||||
render_paint_contour();
|
||||
render_paint_contour(matrix);
|
||||
|
||||
#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
|
||||
if (imgui)
|
||||
|
@ -1109,12 +1113,12 @@ void TriangleSelectorGUI::update_render_data()
|
|||
}
|
||||
|
||||
GLModel::Geometry iva_enforcers_data;
|
||||
iva_enforcers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
|
||||
iva_enforcers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
GLModel::Geometry iva_blockers_data;
|
||||
iva_blockers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
|
||||
iva_blockers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
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, GLModel::Geometry::EIndexType::UINT };
|
||||
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
|
||||
for (const Triangle &tr : m_triangles) {
|
||||
bool is_valid = tr.valid();
|
||||
|
@ -1140,7 +1144,7 @@ void TriangleSelectorGUI::update_render_data()
|
|||
iva.add_vertex(v0, n);
|
||||
iva.add_vertex(v1, n);
|
||||
iva.add_vertex(v2, n);
|
||||
iva.add_uint_triangle((unsigned int)cnt, (unsigned int)cnt + 1, (unsigned int)cnt + 2);
|
||||
iva.add_triangle((unsigned int)cnt, (unsigned int)cnt + 1, (unsigned int)cnt + 2);
|
||||
cnt += 3;
|
||||
}
|
||||
|
||||
|
@ -1164,7 +1168,7 @@ bool TrianglePatch::is_fragment() const
|
|||
|
||||
float TriangleSelectorPatch::gap_area = TriangleSelectorPatch::GapAreaMin;
|
||||
|
||||
void TriangleSelectorPatch::render(ImGuiWrapper* imgui)
|
||||
void TriangleSelectorPatch::render(ImGuiWrapper* imgui, const Transform3d& matrix)
|
||||
{
|
||||
if (m_update_render_data) {
|
||||
update_render_data();
|
||||
|
@ -1174,7 +1178,7 @@ void TriangleSelectorPatch::render(ImGuiWrapper* imgui)
|
|||
auto* shader = wxGetApp().get_current_shader();
|
||||
if (!shader)
|
||||
return;
|
||||
assert(shader->get_name() == "mm_gouraud");
|
||||
assert(shader->get_name() == "gouraud_attr" || shader->get_name() == "mm_gouraud_attr");
|
||||
GLint position_id = -1;
|
||||
GLint barycentric_id = -1;
|
||||
if (wxGetApp().plater()->is_wireframe_enabled()) {
|
||||
|
@ -1212,7 +1216,7 @@ void TriangleSelectorPatch::render(ImGuiWrapper* imgui)
|
|||
}
|
||||
}
|
||||
|
||||
render_paint_contour();
|
||||
render_paint_contour(matrix);
|
||||
}
|
||||
|
||||
void TriangleSelectorPatch::update_triangles_per_type()
|
||||
|
@ -1631,10 +1635,14 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
|
|||
if (curr_shader != nullptr)
|
||||
curr_shader->stop_using();
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
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());
|
||||
|
||||
::glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
|
||||
for (vtype i : {ORIGINAL, SPLIT, INVALID}) {
|
||||
GLModel& va = m_varrays[i];
|
||||
|
@ -1661,35 +1669,37 @@ void TriangleSelectorGUI::update_paint_contour()
|
|||
|
||||
GLModel::Geometry init_data;
|
||||
const std::vector<Vec2i> contour_edges = this->get_seed_fill_contour();
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(2 * contour_edges.size()) };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(2 * contour_edges.size());
|
||||
init_data.reserve_indices(2 * contour_edges.size());
|
||||
init_data.color = ColorRGBA::WHITE();
|
||||
// vertices + indices
|
||||
unsigned int vertices_count = 0;
|
||||
for (const Vec2i& edge : contour_edges) {
|
||||
init_data.add_vertex(m_vertices[edge(0)].v);
|
||||
init_data.add_vertex(m_vertices[edge(1)].v);
|
||||
vertices_count += 2;
|
||||
if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
||||
init_data.add_ushort_line((unsigned short)vertices_count - 2, (unsigned short)vertices_count - 1);
|
||||
else
|
||||
init_data.add_uint_line(vertices_count - 2, vertices_count - 1);
|
||||
init_data.add_line(vertices_count - 2, vertices_count - 1);
|
||||
}
|
||||
|
||||
if (!init_data.is_empty())
|
||||
m_paint_contour.init_from(std::move(init_data));
|
||||
}
|
||||
|
||||
void TriangleSelectorGUI::render_paint_contour()
|
||||
void TriangleSelectorGUI::render_paint_contour(const Transform3d& matrix)
|
||||
{
|
||||
auto* curr_shader = wxGetApp().get_current_shader();
|
||||
if (curr_shader != nullptr)
|
||||
curr_shader->stop_using();
|
||||
|
||||
auto* contour_shader = wxGetApp().get_shader("mm_contour");
|
||||
auto* contour_shader = wxGetApp().get_shader("mm_contour_attr");
|
||||
if (contour_shader != nullptr) {
|
||||
contour_shader->start_using();
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
contour_shader->set_uniform("view_model_matrix", camera.get_view_matrix() * matrix);
|
||||
contour_shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
glsafe(::glDepthFunc(GL_LEQUAL));
|
||||
m_paint_contour.render();
|
||||
glsafe(::glDepthFunc(GL_LESS));
|
||||
|
|
|
@ -34,10 +34,8 @@ public:
|
|||
: TriangleSelector(mesh, edge_limit) {}
|
||||
virtual ~TriangleSelectorGUI() = default;
|
||||
|
||||
// Render current selection. Transformation matrices are supposed
|
||||
// to be already set.
|
||||
virtual void render(ImGuiWrapper *imgui);
|
||||
void render() { this->render(nullptr); }
|
||||
virtual void render(ImGuiWrapper* imgui, const Transform3d& matrix);
|
||||
void render(const Transform3d& matrix) { this->render(nullptr, matrix); }
|
||||
void set_wireframe_needed(bool need_wireframe) { m_need_wireframe = need_wireframe; }
|
||||
bool get_wireframe_needed() { return m_need_wireframe; }
|
||||
|
||||
|
@ -79,7 +77,7 @@ protected:
|
|||
GLModel m_paint_contour;
|
||||
|
||||
void update_paint_contour();
|
||||
void render_paint_contour();
|
||||
void render_paint_contour(const Transform3d& matrix);
|
||||
|
||||
bool m_need_wireframe {false};
|
||||
};
|
||||
|
@ -105,7 +103,7 @@ public:
|
|||
|
||||
// Render current selection. Transformation matrices are supposed
|
||||
// to be already set.
|
||||
void render(ImGuiWrapper* imgui) override;
|
||||
void render(ImGuiWrapper* imgui, const Transform3d& matrix) override;
|
||||
// TriangleSelector.m_triangles => m_gizmo_scene.triangle_patches
|
||||
void update_triangles_per_type();
|
||||
// m_gizmo_scene.triangle_patches => TriangleSelector.m_triangles
|
||||
|
|
|
@ -126,14 +126,19 @@ void GLGizmoRotate::on_render()
|
|||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
transform_to_local(selection);
|
||||
m_grabbers.front().matrix = local_transform(selection);
|
||||
|
||||
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
Transform3d view_model_matrix = camera.get_view_matrix() * m_grabbers.front().matrix;
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
const bool radius_changed = std::abs(m_old_radius - m_radius) > EPSILON;
|
||||
m_old_radius = m_radius;
|
||||
|
||||
|
@ -152,6 +157,8 @@ void GLGizmoRotate::on_render()
|
|||
render_grabber_connection(color, radius_changed);
|
||||
shader->stop_using();
|
||||
}
|
||||
glsafe(::glPushMatrix());
|
||||
transform_to_local(selection);
|
||||
|
||||
render_grabber(box);
|
||||
render_grabber_extension(box, false);
|
||||
|
@ -165,15 +172,11 @@ void GLGizmoRotate::on_render_for_picking()
|
|||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
|
||||
transform_to_local(selection);
|
||||
m_grabbers.front().matrix = local_transform(selection);
|
||||
|
||||
const BoundingBoxf3& box = selection.get_bounding_box();
|
||||
render_grabbers_for_picking(box);
|
||||
render_grabber_extension(box, true);
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
//BBS: add input window for move
|
||||
|
@ -214,7 +217,7 @@ void GLGizmoRotate::render_circle(const ColorRGBA& color, bool radius_changed)
|
|||
m_circle.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(ScaleStepsCount);
|
||||
init_data.reserve_indices(ScaleStepsCount);
|
||||
|
||||
|
@ -222,7 +225,7 @@ void GLGizmoRotate::render_circle(const ColorRGBA& color, bool radius_changed)
|
|||
for (unsigned short i = 0; i < ScaleStepsCount; ++i) {
|
||||
const float angle = float(i * ScaleStepRad);
|
||||
init_data.add_vertex(Vec3f(::cos(angle) * m_radius, ::sin(angle) * m_radius, 0.0f));
|
||||
init_data.add_ushort_index(i);
|
||||
init_data.add_index(i);
|
||||
}
|
||||
|
||||
m_circle.init_from(std::move(init_data));
|
||||
|
@ -241,7 +244,7 @@ void GLGizmoRotate::render_scale(const ColorRGBA& color, bool radius_changed)
|
|||
m_scale.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(2 * ScaleStepsCount);
|
||||
init_data.reserve_indices(2 * ScaleStepsCount);
|
||||
|
||||
|
@ -257,8 +260,8 @@ void GLGizmoRotate::render_scale(const ColorRGBA& color, bool radius_changed)
|
|||
|
||||
init_data.add_vertex(Vec3f(in_x, in_y, 0.0f));
|
||||
init_data.add_vertex(Vec3f(out_x, out_y, 0.0f));
|
||||
init_data.add_ushort_index(i * 2);
|
||||
init_data.add_ushort_index(i * 2 + 1);
|
||||
init_data.add_index(i * 2);
|
||||
init_data.add_index(i * 2 + 1);
|
||||
}
|
||||
|
||||
m_scale.init_from(std::move(init_data));
|
||||
|
@ -278,7 +281,7 @@ void GLGizmoRotate::render_snap_radii(const ColorRGBA& color, bool radius_change
|
|||
m_snap_radii.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(2 * ScaleStepsCount);
|
||||
init_data.reserve_indices(2 * ScaleStepsCount);
|
||||
|
||||
|
@ -294,8 +297,8 @@ void GLGizmoRotate::render_snap_radii(const ColorRGBA& color, bool radius_change
|
|||
|
||||
init_data.add_vertex(Vec3f(in_x, in_y, 0.0f));
|
||||
init_data.add_vertex(Vec3f(out_x, out_y, 0.0f));
|
||||
init_data.add_ushort_index(i * 2);
|
||||
init_data.add_ushort_index(i * 2 + 1);
|
||||
init_data.add_index(i * 2);
|
||||
init_data.add_index(i * 2 + 1);
|
||||
}
|
||||
|
||||
m_snap_radii.init_from(std::move(init_data));
|
||||
|
@ -311,7 +314,7 @@ void GLGizmoRotate::render_reference_radius(const ColorRGBA& color, bool radius_
|
|||
m_reference_radius.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(2);
|
||||
init_data.reserve_indices(2);
|
||||
|
||||
|
@ -320,7 +323,7 @@ void GLGizmoRotate::render_reference_radius(const ColorRGBA& color, bool radius_
|
|||
init_data.add_vertex(Vec3f(m_radius * (1.0f + GrabberOffset), 0.0f, 0.0f));
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_line(0, 1);
|
||||
init_data.add_line(0, 1);
|
||||
|
||||
m_reference_radius.init_from(std::move(init_data));
|
||||
}
|
||||
|
@ -341,7 +344,7 @@ void GLGizmoRotate::render_angle_arc(const ColorRGBA& color, bool radius_changed
|
|||
m_angle_arc.reset();
|
||||
if (m_angle > 0.0f) {
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(1 + AngleResolution);
|
||||
init_data.reserve_indices(1 + AngleResolution);
|
||||
|
||||
|
@ -349,7 +352,7 @@ void GLGizmoRotate::render_angle_arc(const ColorRGBA& color, bool radius_changed
|
|||
for (unsigned short i = 0; i <= AngleResolution; ++i) {
|
||||
const float angle = float(i) * step_angle;
|
||||
init_data.add_vertex(Vec3f(::cos(angle) * ex_radius, ::sin(angle) * ex_radius, 0.0f));
|
||||
init_data.add_ushort_index(i);
|
||||
init_data.add_index(i);
|
||||
}
|
||||
|
||||
m_angle_arc.init_from(std::move(init_data));
|
||||
|
@ -367,7 +370,7 @@ void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radiu
|
|||
m_grabber_connection.old_center = m_grabbers.front().center;
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(2);
|
||||
init_data.reserve_indices(2);
|
||||
|
||||
|
@ -376,7 +379,7 @@ void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radiu
|
|||
init_data.add_vertex((Vec3f)m_grabbers.front().center.cast<float>());
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_line(0, 1);
|
||||
init_data.add_line(0, 1);
|
||||
|
||||
m_grabber_connection.model.init_from(std::move(init_data));
|
||||
}
|
||||
|
@ -401,36 +404,69 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick
|
|||
if (!picking && m_hover_id != -1)
|
||||
color = m_grabbers.front().hover_color;
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat_attr" : "gouraud_light_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
m_cone.set_color(color);
|
||||
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.1f);
|
||||
|
||||
const Vec3d& center = m_grabbers.front().center;
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||
glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0));
|
||||
glsafe(::glRotated(90.0, 1.0, 0.0, 0.0));
|
||||
glsafe(::glTranslated(0.0, 0.0, 1.5 * size));
|
||||
glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
Transform3d view_model_matrix = view_matrix * m_grabbers.front().matrix *
|
||||
Geometry::assemble_transform(center, Vec3d(0.5 * PI, 0.0, m_angle)) *
|
||||
Geometry::assemble_transform(1.5 * size * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 3.0 * size));
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_cone.render();
|
||||
glsafe(::glPopMatrix());
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||
glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0));
|
||||
glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0));
|
||||
glsafe(::glTranslated(0.0, 0.0, 1.5 * size));
|
||||
glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size));
|
||||
view_model_matrix = view_matrix * m_grabbers.front().matrix *
|
||||
Geometry::assemble_transform(center, Vec3d(-0.5 * PI, 0.0, m_angle)) *
|
||||
Geometry::assemble_transform(1.5 * size * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 3.0 * size));
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_cone.render();
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
Transform3d GLGizmoRotate::local_transform(const Selection& selection) const
|
||||
{
|
||||
Transform3d ret;
|
||||
|
||||
switch (m_axis)
|
||||
{
|
||||
case X:
|
||||
{
|
||||
ret = Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.5 * PI, 0.0)) * Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.0, -0.5 * PI));
|
||||
break;
|
||||
}
|
||||
case Y:
|
||||
{
|
||||
ret = Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.0, -0.5 * PI)) * Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, -0.5 * PI, 0.0));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case Z:
|
||||
{
|
||||
ret = Transform3d::Identity();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes())
|
||||
ret = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(true, false, true, true) * ret;
|
||||
|
||||
return Geometry::assemble_transform(m_center) * ret;
|
||||
}
|
||||
|
||||
void GLGizmoRotate::transform_to_local(const Selection& selection) const
|
||||
{
|
||||
glsafe(::glTranslated(m_center.x(), m_center.y(), m_center.z()));
|
||||
|
|
|
@ -85,6 +85,8 @@ private:
|
|||
void render_grabber(const BoundingBoxf3& box);
|
||||
void render_grabber_extension(const BoundingBoxf3& box, bool picking);
|
||||
|
||||
Transform3d local_transform(const Selection& selection) const;
|
||||
|
||||
void transform_to_local(const Selection& selection) const;
|
||||
// returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate
|
||||
Vec3d mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "GLGizmoScale.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
|
@ -185,11 +186,11 @@ void GLGizmoScale3D::on_render()
|
|||
m_box = selection.get_bounding_box();
|
||||
|
||||
const Vec3d& center = m_box.center();
|
||||
Vec3d offset_x = offsets_transform * Vec3d((double)Offset, 0.0, 0.0);
|
||||
Vec3d offset_y = offsets_transform * Vec3d(0.0, (double)Offset, 0.0);
|
||||
Vec3d offset_z = offsets_transform * Vec3d(0.0, 0.0, (double)Offset);
|
||||
const Vec3d offset_x = offsets_transform * Vec3d((double)Offset, 0.0, 0.0);
|
||||
const Vec3d offset_y = offsets_transform * Vec3d(0.0, (double)Offset, 0.0);
|
||||
const Vec3d offset_z = offsets_transform * Vec3d(0.0, 0.0, (double)Offset);
|
||||
|
||||
bool ctrl_down = (m_dragging && m_starting.ctrl_down) || (!m_dragging && wxGetKeyState(WXK_CONTROL));
|
||||
const bool ctrl_down = (m_dragging && m_starting.ctrl_down) || (!m_dragging && wxGetKeyState(WXK_CONTROL));
|
||||
|
||||
// x axis
|
||||
m_grabbers[0].center = m_transform * Vec3d(m_box.min.x(), center.y(), m_box.min.z());
|
||||
|
@ -230,14 +231,17 @@ void GLGizmoScale3D::on_render()
|
|||
|
||||
const BoundingBoxf3& selection_box = selection.get_bounding_box();
|
||||
|
||||
float grabber_mean_size = (float)((selection_box.size().x() + selection_box.size().y() + selection_box.size().z()) / 3.0);
|
||||
const float grabber_mean_size = (float)((selection_box.size().x() + selection_box.size().y() + selection_box.size().z()) / 3.0);
|
||||
|
||||
//draw connections
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
// BBS: when select multiple objects, uniform scale can be deselected, display the connection(4,5)
|
||||
//if (single_instance || single_volume) {
|
||||
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());
|
||||
if (m_grabbers[4].enabled && m_grabbers[5].enabled)
|
||||
render_grabbers_connection(4, 5, m_grabbers[4].color);
|
||||
render_grabbers_connection(6, 7, m_grabbers[2].color);
|
||||
|
@ -279,7 +283,7 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int
|
|||
m_grabber_connections[id].model.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(2);
|
||||
init_data.reserve_indices(2);
|
||||
|
||||
|
@ -288,7 +292,7 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int
|
|||
init_data.add_vertex((Vec3f)m_grabbers[id_2].center.cast<float>());
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_line(0, 1);
|
||||
init_data.add_line(0, 1);
|
||||
|
||||
m_grabber_connections[id].model.init_from(std::move(init_data));
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ bool GLGizmoSeam::on_key_down_select_tool_type(int keyCode) {
|
|||
void GLGizmoSeam::render_triangles(const Selection& selection) const
|
||||
{
|
||||
ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data();
|
||||
auto* shader = wxGetApp().get_shader("mm_gouraud");
|
||||
auto* shader = wxGetApp().get_shader("mm_gouraud_attr");
|
||||
if (!shader)
|
||||
return;
|
||||
shader->start_using();
|
||||
|
@ -120,8 +120,11 @@ void GLGizmoSeam::render_triangles(const Selection& selection) const
|
|||
if (is_left_handed)
|
||||
glsafe(::glFrontFace(GL_CW));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glMultMatrixd(trafo_matrix.data()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d matrix = camera.get_view_matrix() * trafo_matrix;
|
||||
shader->set_uniform("view_model_matrix", matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
|
||||
float normal_z = -::cos(Geometry::deg2rad(m_highlight_by_angle_threshold_deg));
|
||||
Matrix3f normal_matrix = static_cast<Matrix3f>(trafo_matrix.matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>());
|
||||
|
@ -129,11 +132,10 @@ void GLGizmoSeam::render_triangles(const Selection& selection) const
|
|||
shader->set_uniform("volume_world_matrix", trafo_matrix);
|
||||
shader->set_uniform("volume_mirrored", is_left_handed);
|
||||
shader->set_uniform("slope.actived", m_parent.is_using_slope());
|
||||
shader->set_uniform("slope.volume_world_normal_matrix", static_cast<Matrix3f>(trafo_matrix.matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>()));
|
||||
shader->set_uniform("slope.volume_world_normal_matrix", normal_matrix);
|
||||
shader->set_uniform("slope.normal_z", normal_z);
|
||||
m_triangle_selectors[mesh_id]->render(m_imgui);
|
||||
m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix);
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
if (is_left_handed)
|
||||
glsafe(::glFrontFace(GL_CCW));
|
||||
}
|
||||
|
|
|
@ -641,19 +641,25 @@ void GLGizmoSimplify::on_render()
|
|||
return;
|
||||
|
||||
const Transform3d trafo_matrix = selected_volume->world_matrix();
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glMultMatrixd(trafo_matrix.data()));
|
||||
|
||||
auto *gouraud_shader = wxGetApp().get_shader("gouraud_light");
|
||||
auto* gouraud_shader = wxGetApp().get_shader("gouraud_light_attr");
|
||||
glsafe(::glPushAttrib(GL_DEPTH_TEST));
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
gouraud_shader->start_using();
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() * trafo_matrix;
|
||||
gouraud_shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
gouraud_shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
gouraud_shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_glmodel.render();
|
||||
gouraud_shader->stop_using();
|
||||
|
||||
if (m_show_wireframe) {
|
||||
auto* contour_shader = wxGetApp().get_shader("mm_contour");
|
||||
auto* contour_shader = wxGetApp().get_shader("mm_contour_attr");
|
||||
contour_shader->start_using();
|
||||
contour_shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
contour_shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
const ColorRGBA color = m_glmodel.get_color();
|
||||
m_glmodel.set_color(ColorRGBA::WHITE());
|
||||
glsafe(::glLineWidth(1.0f));
|
||||
glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE));
|
||||
//ScopeGuard offset_fill_guard([]() { glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); });
|
||||
|
@ -661,11 +667,11 @@ void GLGizmoSimplify::on_render()
|
|||
//glsafe(::glPolygonOffset(5.0, 5.0));
|
||||
m_glmodel.render();
|
||||
glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL));
|
||||
m_glmodel.set_color(color);
|
||||
contour_shader->stop_using();
|
||||
}
|
||||
|
||||
glsafe(::glPopAttrib());
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
|||
if (! has_points && ! has_holes)
|
||||
return;
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light");
|
||||
GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat_attr") : wxGetApp().get_shader("gouraud_light_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -136,12 +136,13 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
|||
|
||||
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
const Transform3d instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
|
||||
const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
|
||||
const float z_shift = m_c->selection_info()->get_sla_shift();
|
||||
const Transform3d instance_matrix = Geometry::assemble_transform(m_c->selection_info()->get_sla_shift() * Vec3d::UnitZ()) * vol->get_instance_transformation().get_matrix();
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(0.0, 0.0, z_shift));
|
||||
glsafe(::glMultMatrixd(instance_matrix.data()));
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
const Transform3d& projection_matrix = camera.get_projection_matrix();
|
||||
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
|
||||
ColorRGBA render_color;
|
||||
for (size_t i = 0; i < cache_size; ++i) {
|
||||
|
@ -179,9 +180,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
|||
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.
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslatef(support_point.pos.x(), support_point.pos.y(), support_point.pos.z()));
|
||||
glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data()));
|
||||
const Transform3d support_matrix = Geometry::assemble_transform(support_point.pos.cast<double>()) * instance_scaling_matrix_inverse;
|
||||
|
||||
if (vol->is_left_handed())
|
||||
glFrontFace(GL_CW);
|
||||
|
@ -194,27 +193,29 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
|||
m_c->raycaster()->raycaster()->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal);
|
||||
|
||||
Eigen::Quaterniond q;
|
||||
q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast<double>());
|
||||
q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast<double>());
|
||||
const Eigen::AngleAxisd aa(q);
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis().x(), aa.axis().y(), aa.axis().z()));
|
||||
const double cone_radius = 0.25; // mm
|
||||
const double cone_height = 0.75;
|
||||
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));
|
||||
const Transform3d view_model_matrix = view_matrix * instance_matrix * support_matrix * Transform3d(aa.toRotationMatrix()) *
|
||||
Geometry::assemble_transform((cone_height + support_point.head_front_radius * RenderPointScale) * Vec3d::UnitZ(),
|
||||
Vec3d(PI, 0.0, 0.0), Vec3d(cone_radius, cone_radius, cone_height));
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_cone.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
const double radius = (double)support_point.head_front_radius * RenderPointScale;
|
||||
glsafe(::glScaled(radius, radius, radius));
|
||||
const Transform3d view_model_matrix = view_matrix * instance_matrix * support_matrix *
|
||||
Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), radius * Vec3d::Ones());
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_sphere.render();
|
||||
|
||||
if (vol->is_left_handed())
|
||||
glFrontFace(GL_CCW);
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
// Now render the drain holes:
|
||||
|
@ -226,31 +227,26 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
|||
if (is_mesh_point_clipped(drain_hole.pos.cast<double>()))
|
||||
continue;
|
||||
|
||||
// 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()));
|
||||
const Transform3d hole_matrix = Geometry::assemble_transform(drain_hole.pos.cast<double>()) * instance_scaling_matrix_inverse;
|
||||
|
||||
if (vol->is_left_handed())
|
||||
glFrontFace(GL_CW);
|
||||
|
||||
// Matrices set, we can render the point mark now.
|
||||
|
||||
Eigen::Quaterniond q;
|
||||
q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * (-drain_hole.normal).cast<double>());
|
||||
q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * (-drain_hole.normal).cast<double>());
|
||||
const Eigen::AngleAxisd aa(q);
|
||||
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));
|
||||
const Transform3d view_model_matrix = view_matrix * instance_matrix * hole_matrix * Transform3d(aa.toRotationMatrix()) *
|
||||
Geometry::assemble_transform(-drain_hole.height * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength));
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_cylinder.render();
|
||||
|
||||
if (vol->is_left_handed())
|
||||
glFrontFace(GL_CCW);
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
}
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -448,7 +448,7 @@ void GLGizmoText::on_render()
|
|||
ColorRGBA color = picking_color_component(0);
|
||||
m_grabbers[0].color = color;
|
||||
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("gouraud_light");
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("gouraud_light_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
m_grabbers[0].render_for_picking(mean_size);
|
||||
|
@ -500,14 +500,12 @@ void GLGizmoText::on_render_for_picking()
|
|||
ColorRGBA color = picking_color_component(0);
|
||||
m_grabbers[0].color = color;
|
||||
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
glsafe(::glPushMatrix());
|
||||
shader->start_using();
|
||||
m_grabbers[0].render_for_picking(mean_size);
|
||||
|
||||
shader->stop_using();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,15 +214,14 @@ void InstancesHider::render_cut() const
|
|||
ClippingPlane clp = *get_pool()->object_clipper()->get_clipping_plane();
|
||||
clp.set_normal(-clp.get_normal());
|
||||
clipper->set_limiting_plane(clp);
|
||||
} else
|
||||
}
|
||||
else
|
||||
clipper->set_limiting_plane(ClippingPlane::ClipsNothing());
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glPushAttrib(GL_DEPTH_TEST));
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
clipper->render_cut(mv->is_model_part() ? ColorRGBA(0.8f, 0.3f, 0.0f, 1.0f) : color_from_model_volume(*mv));
|
||||
glsafe(::glPopAttrib());
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
++clipper_id;
|
||||
}
|
||||
|
@ -412,7 +411,7 @@ void ObjectClipper::render_cut() const
|
|||
|
||||
size_t clipper_id = 0;
|
||||
for (const ModelVolume* mv : mo->volumes) {
|
||||
Geometry::Transformation vol_trafo = mv->get_transformation();
|
||||
const Geometry::Transformation vol_trafo = mv->get_transformation();
|
||||
Geometry::Transformation trafo = inst_trafo * vol_trafo;
|
||||
if (is_assem_cnv) {
|
||||
trafo.set_offset(trafo.get_offset() + offset_to_assembly * (GLVolume::explosion_ratio - 1.0) + vol_trafo.get_offset() * (GLVolume::explosion_ratio - 1.0));
|
||||
|
@ -427,10 +426,8 @@ void ObjectClipper::render_cut() const
|
|||
clipper->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), std::numeric_limits<double>::max()));
|
||||
else
|
||||
clipper->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD));
|
||||
glsafe(::glPushMatrix());
|
||||
// BBS
|
||||
clipper->render_cut({ 0.25f, 0.25f, 0.25f, 1.0f });
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
++clipper_id;
|
||||
}
|
||||
|
@ -557,7 +554,7 @@ void SupportsClipper::render_cut() const
|
|||
|
||||
const SelectionInfo* sel_info = get_pool()->selection_info();
|
||||
const ModelObject* mo = sel_info->model_object();
|
||||
Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation();
|
||||
const Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation();
|
||||
//Geometry::Transformation vol_trafo = mo->volumes.front()->get_transformation();
|
||||
Geometry::Transformation trafo = inst_trafo;// * vol_trafo;
|
||||
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift()));
|
||||
|
@ -576,9 +573,7 @@ void SupportsClipper::render_cut() const
|
|||
m_clipper->set_plane(*ocl->get_clipping_plane());
|
||||
m_clipper->set_transformation(supports_trafo);
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
m_clipper->render_cut({ 1.0f, 0.f, 0.37f, 1.0f });
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -85,7 +85,9 @@ size_t GLGizmosManager::get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const
|
|||
float width = get_scaled_total_width();
|
||||
#if BBS_TOOLBAR_ON_TOP
|
||||
//float space_width = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale();;
|
||||
float top_x = std::max(m_parent.get_main_toolbar_width() + border, 0.5f * (cnv_w - width + m_parent.get_main_toolbar_width() + m_parent.get_collapse_toolbar_width() - m_parent.get_assemble_view_toolbar_width()) + border);
|
||||
const float separator_width = m_parent.get_separator_toolbar_width();
|
||||
float top_x = std::max(0.0f, 0.5f * (cnv_w - (width + separator_width + m_parent.get_main_toolbar_width() - m_parent.get_collapse_toolbar_width() + m_parent.get_assemble_view_toolbar_width())));
|
||||
top_x += m_parent.get_main_toolbar_width() + separator_width / 2 + border;
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView)
|
||||
top_x = 0.5f * cnv_w + 0.5f * (m_parent.get_assembly_paint_toolbar_width());
|
||||
float top_y = 0;
|
||||
|
@ -1277,28 +1279,28 @@ void GLGizmosManager::update_after_undo_redo(const UndoRedo::Snapshot& snapshot)
|
|||
dynamic_cast<GLGizmoSlaSupports*>(m_gizmos[SlaSupports].get())->reslice_SLA_supports(true);
|
||||
}
|
||||
|
||||
void GLGizmosManager::render_background(float left, float top, float right, float bottom, float border) const
|
||||
void GLGizmosManager::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();
|
||||
const float tex_width = float(m_background_texture.texture.get_width());
|
||||
const float tex_height = float(m_background_texture.texture.get_height());
|
||||
if (tex_id != 0 && tex_width > 0 && tex_height > 0) {
|
||||
//BBS: GUI refactor: remove the corners of gizmo
|
||||
const float inv_tex_width = (tex_width != 0.0f) ? 1.0f / tex_width : 0.0f;
|
||||
const float inv_tex_height = (tex_height != 0.0f) ? 1.0f / tex_height : 0.0f;
|
||||
const float inv_tex_width = 1.0f / tex_width;
|
||||
const float inv_tex_height = 1.0f / tex_height;
|
||||
|
||||
const float internal_left_uv = (float)m_background_texture.metadata.left * inv_tex_width;
|
||||
const float internal_right_uv = 1.0f - (float)m_background_texture.metadata.right * inv_tex_width;
|
||||
const float internal_top_uv = 1.0f - (float)m_background_texture.metadata.top * inv_tex_height;
|
||||
const float internal_bottom_uv = (float)m_background_texture.metadata.bottom * inv_tex_height;
|
||||
const float internal_left_uv = float(m_background_texture.metadata.left) * inv_tex_width;
|
||||
const float internal_right_uv = 1.0f - float(m_background_texture.metadata.right) * inv_tex_width;
|
||||
const float internal_top_uv = 1.0f - float(m_background_texture.metadata.top) * inv_tex_height;
|
||||
const float internal_bottom_uv = float(m_background_texture.metadata.bottom) * inv_tex_height;
|
||||
|
||||
GLTexture::render_sub_texture(tex_id, left, right, bottom, 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 } });
|
||||
|
||||
/*
|
||||
const float internal_left = left + border;
|
||||
const float internal_right = right - border;
|
||||
const float internal_top = top - border;
|
||||
const float internal_bottom = bottom + border;
|
||||
const float internal_left = left + border_w;
|
||||
const float internal_right = right - border_w;
|
||||
const float internal_top = top - border_h;
|
||||
const float internal_bottom = bottom + border_h;
|
||||
|
||||
// float left_uv = 0.0f;
|
||||
const float right_uv = 1.0f;
|
||||
|
@ -1383,119 +1385,98 @@ void GLGizmosManager::render_arrow(const GLCanvas3D& parent, EType highlighted_t
|
|||
//when rendering, {0, 0} is at the center, {-0.5, 0.5} at the left-top
|
||||
void GLGizmosManager::do_render_overlay() const
|
||||
{
|
||||
std::vector<size_t> selectable_idxs = get_selectable_idxs();
|
||||
const std::vector<size_t> selectable_idxs = get_selectable_idxs();
|
||||
if (selectable_idxs.empty())
|
||||
return;
|
||||
|
||||
float cnv_w = (float)m_parent.get_canvas_size().get_width();
|
||||
float cnv_h = (float)m_parent.get_canvas_size().get_height();
|
||||
float zoom = (float)wxGetApp().plater()->get_camera().get_zoom();
|
||||
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
const Size cnv_size = m_parent.get_canvas_size();
|
||||
const float cnv_w = (float)cnv_size.get_width();
|
||||
const float cnv_h = (float)cnv_size.get_height();
|
||||
|
||||
float height = get_scaled_total_height();
|
||||
float width = get_scaled_total_width();
|
||||
float zoomed_border = m_layout.scaled_border() * inv_zoom;
|
||||
if (cnv_w == 0 || cnv_h == 0)
|
||||
return;
|
||||
|
||||
float zoomed_top_x;
|
||||
const float inv_cnv_w = 1.0f / cnv_w;
|
||||
const float inv_cnv_h = 1.0f / cnv_h;
|
||||
|
||||
const float height = 2.0f * get_scaled_total_height() * inv_cnv_h;
|
||||
const float width = 2.0f * get_scaled_total_width() * inv_cnv_w;
|
||||
const float border_h = 2.0f * m_layout.scaled_border() * inv_cnv_h;
|
||||
const float border_w = 2.0f * m_layout.scaled_border() * inv_cnv_w;
|
||||
|
||||
float top_x;
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
zoomed_top_x = 0.5f * m_parent.get_assembly_paint_toolbar_width() * inv_zoom;
|
||||
top_x = m_parent.get_assembly_paint_toolbar_width() * inv_cnv_w;
|
||||
}
|
||||
else {
|
||||
//BBS: GUI refactor: GLToolbar&&Gizmo adjust
|
||||
#if BBS_TOOLBAR_ON_TOP
|
||||
float main_toolbar_width = (float)m_parent.get_main_toolbar_width();
|
||||
float assemble_view_width = (float)m_parent.get_assemble_view_toolbar_width();
|
||||
float collapse_width = (float)m_parent.get_collapse_toolbar_width();
|
||||
float separator_width = (float)m_parent.get_separator_toolbar_width();
|
||||
//float space_width = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale();
|
||||
//float zoomed_top_x = 0.5f *(cnv_w + main_toolbar_width - 2 * space_width - width) * inv_zoom;
|
||||
|
||||
float main_toolbar_left = std::max(-0.5f * cnv_w, -0.5f * (main_toolbar_width + get_scaled_total_width() + assemble_view_width - collapse_width)) * inv_zoom;
|
||||
float main_toolbar_left = std::max(-0.5f * cnv_w, -0.5f * (main_toolbar_width + get_scaled_total_width() + assemble_view_width + separator_width - collapse_width));
|
||||
//float zoomed_top_x = 0.5f *(main_toolbar_width + collapse_width - width - assemble_view_width) * inv_zoom;
|
||||
zoomed_top_x = main_toolbar_left + (main_toolbar_width)*inv_zoom;
|
||||
top_x = main_toolbar_left + main_toolbar_width + separator_width / 2;
|
||||
top_x = top_x * inv_cnv_w * 2;
|
||||
}
|
||||
float zoomed_top_y = 0.5f * cnv_h * inv_zoom;
|
||||
#else
|
||||
//float zoomed_top_x = (-0.5f * cnv_w) * inv_zoom;
|
||||
//float zoomed_top_y = (0.5f * height) * inv_zoom;
|
||||
float zoomed_top_x = (0.5f * cnv_w - width) * inv_zoom;
|
||||
float main_toolbar_height = (float)m_parent.get_main_toolbar_height();
|
||||
float assemble_view_height = (float)m_parent.get_assemble_view_toolbar_height();
|
||||
//float space_height = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale();
|
||||
float zoomed_top_y = 0.5f * (height + assemble_view_height - main_toolbar_height) * inv_zoom;
|
||||
#endif
|
||||
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": zoomed_top_y %1%, space_height %2%, main_toolbar_height %3% zoomed_top_x %4%") % zoomed_top_y % space_height % main_toolbar_height % zoomed_top_x;
|
||||
float top_y = 1.0f;
|
||||
|
||||
float zoomed_left = zoomed_top_x;
|
||||
float zoomed_top = zoomed_top_y;
|
||||
float zoomed_right = zoomed_left + width * inv_zoom;
|
||||
float zoomed_bottom = zoomed_top - height * inv_zoom;
|
||||
render_background(top_x, top_y, top_x + width, top_y - height, border_w, border_h);
|
||||
|
||||
render_background(zoomed_left, zoomed_top, zoomed_right, zoomed_bottom, zoomed_border);
|
||||
top_x += border_w;
|
||||
top_y -= border_h;
|
||||
|
||||
zoomed_top_x += zoomed_border;
|
||||
zoomed_top_y -= zoomed_border;
|
||||
|
||||
float icons_size = m_layout.scaled_icons_size();
|
||||
float zoomed_icons_size = icons_size * inv_zoom;
|
||||
float zoomed_stride_y = m_layout.scaled_stride_y() * inv_zoom;
|
||||
const float icons_size_x = 2.0f * m_layout.scaled_icons_size() * inv_cnv_w;
|
||||
const float icons_size_y = 2.0f * m_layout.scaled_icons_size() * inv_cnv_h;
|
||||
//BBS: GUI refactor: GLToolbar&&Gizmo adjust
|
||||
float zoomed_stride_x = m_layout.scaled_stride_x() * inv_zoom;
|
||||
const float stride_x = 2.0f * m_layout.scaled_stride_x() * inv_cnv_w;
|
||||
|
||||
unsigned int icons_texture_id = m_icons_texture.get_id();
|
||||
int tex_width = m_icons_texture.get_width();
|
||||
int tex_height = m_icons_texture.get_height();
|
||||
const unsigned int icons_texture_id = m_icons_texture.get_id();
|
||||
const int tex_width = m_icons_texture.get_width();
|
||||
const int tex_height = m_icons_texture.get_height();
|
||||
|
||||
if ((icons_texture_id == 0) || (tex_width <= 1) || (tex_height <= 1))
|
||||
if (icons_texture_id == 0 || tex_width <= 1 || tex_height <= 1)
|
||||
return;
|
||||
|
||||
float du = (float)(tex_width - 1) / (6.0f * (float)tex_width); // 6 is the number of possible states if the icons
|
||||
float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height);
|
||||
const float du = (float)(tex_width - 1) / (6.0f * (float)tex_width); // 6 is the number of possible states if the icons
|
||||
const float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height);
|
||||
|
||||
// tiles in the texture are spaced by 1 pixel
|
||||
float u_offset = 1.0f / (float)tex_width;
|
||||
float v_offset = 1.0f / (float)tex_height;
|
||||
const float u_offset = 1.0f / (float)tex_width;
|
||||
const float v_offset = 1.0f / (float)tex_height;
|
||||
|
||||
bool is_render_current = false;
|
||||
|
||||
for (size_t idx : selectable_idxs)
|
||||
{
|
||||
for (size_t idx : selectable_idxs) {
|
||||
GLGizmoBase* gizmo = m_gizmos[idx].get();
|
||||
unsigned int sprite_id = gizmo->get_sprite_id();
|
||||
const unsigned int sprite_id = gizmo->get_sprite_id();
|
||||
// higlighted state needs to be decided first so its highlighting in every other state
|
||||
int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable()? 0 : 3)));
|
||||
const int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable()? 0 : 3)));
|
||||
|
||||
float v_top = v_offset + sprite_id * dv;
|
||||
float u_left = u_offset + icon_idx * du;
|
||||
float v_bottom = v_top + dv - v_offset;
|
||||
float u_right = u_left + du - u_offset;
|
||||
|
||||
GLTexture::render_sub_texture(icons_texture_id, zoomed_top_x, zoomed_top_x + zoomed_icons_size, zoomed_top_y - zoomed_icons_size, zoomed_top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } });
|
||||
const float u_left = u_offset + icon_idx * du;
|
||||
const float u_right = u_left + du - u_offset;
|
||||
const float v_top = v_offset + sprite_id * dv;
|
||||
const float v_bottom = v_top + dv - v_offset;
|
||||
|
||||
GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + icons_size_x, top_y - icons_size_y, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } });
|
||||
if (idx == m_current) {
|
||||
//BBS: GUI refactor: GLToolbar&&Gizmo adjust
|
||||
//render_input_window uses a different coordination(imgui)
|
||||
//1. no need to scale by camera zoom, set {0,0} at left-up corner for imgui
|
||||
#if BBS_TOOLBAR_ON_TOP
|
||||
//gizmo->render_input_window(width, 0.5f * cnv_h - zoomed_top_y * zoom, toolbar_top);
|
||||
gizmo->render_input_window(0.5 * cnv_w + zoomed_top_x * zoom, height, cnv_h);
|
||||
gizmo->render_input_window(0.5 * cnv_w + 0.5f * top_x * cnv_w, get_scaled_total_height(), cnv_h);
|
||||
|
||||
is_render_current = true;
|
||||
#else
|
||||
float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height();
|
||||
//gizmo->render_input_window(width, 0.5f * cnv_h - zoomed_top_y * zoom, toolbar_top);
|
||||
gizmo->render_input_window(cnv_w - width, 0.5f * cnv_h - zoomed_top_y * zoom, toolbar_top);
|
||||
#endif
|
||||
}
|
||||
#if BBS_TOOLBAR_ON_TOP
|
||||
zoomed_top_x += zoomed_stride_x;
|
||||
#else
|
||||
zoomed_top_y -= zoomed_stride_y;
|
||||
#endif
|
||||
top_x += stride_x;
|
||||
}
|
||||
|
||||
// BBS simplify gizmo is not a selected gizmo and need to render input window
|
||||
if (!is_render_current && m_current != Undefined) {
|
||||
m_gizmos[m_current]->render_input_window(0.5 * cnv_w + zoomed_top_x * zoom, height, cnv_h);
|
||||
m_gizmos[m_current]->render_input_window(0.5 * cnv_w + 0.5f * top_x * cnv_w, get_scaled_total_height(), cnv_h);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1542,14 +1523,12 @@ GLGizmosManager::EType GLGizmosManager::get_gizmo_from_name(const std::string& g
|
|||
return GLGizmosManager::EType::Undefined;
|
||||
}
|
||||
|
||||
bool GLGizmosManager::generate_icons_texture() const
|
||||
bool GLGizmosManager::generate_icons_texture()
|
||||
{
|
||||
std::string path = resources_dir() + "/images/";
|
||||
std::vector<std::string> filenames;
|
||||
for (size_t idx=0; idx<m_gizmos.size(); ++idx)
|
||||
{
|
||||
if (m_gizmos[idx] != nullptr)
|
||||
{
|
||||
for (size_t idx = 0; idx<m_gizmos.size(); ++idx) {
|
||||
if (m_gizmos[idx] != nullptr) {
|
||||
const std::string& icon_filename = m_gizmos[idx]->get_icon_filename();
|
||||
if (!icon_filename.empty())
|
||||
filenames.push_back(path + icon_filename);
|
||||
|
|
|
@ -325,11 +325,11 @@ public:
|
|||
bool get_uniform_scaling() const { return m_object_manipulation.get_uniform_scaling();}
|
||||
|
||||
private:
|
||||
void render_background(float left, float top, float right, float bottom, float border) const;
|
||||
void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const;
|
||||
|
||||
void do_render_overlay() const;
|
||||
|
||||
bool generate_icons_texture() const;
|
||||
bool generate_icons_texture();
|
||||
|
||||
void update_on_off_state(const Vec2d& mouse_pos);
|
||||
std::string update_hover_state(const Vec2d& mouse_pos);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Camera.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
|
@ -73,13 +74,19 @@ void MeshClipper::render_cut(const ColorRGBA& color)
|
|||
if (! m_triangles_valid)
|
||||
recalculate_triangles();
|
||||
|
||||
if (m_model.vertices_count() == 0 || m_model.indices_count() == 0)
|
||||
return;
|
||||
|
||||
GLShaderProgram* curr_shader = wxGetApp().get_current_shader();
|
||||
if (curr_shader != nullptr)
|
||||
curr_shader->stop_using();
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
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());
|
||||
m_model.set_color(color);
|
||||
m_model.render();
|
||||
shader->stop_using();
|
||||
|
@ -205,7 +212,7 @@ void MeshClipper::recalculate_triangles()
|
|||
m_model.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(m_triangles2d.size()) };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
init_data.reserve_vertices(m_triangles2d.size());
|
||||
init_data.reserve_indices(m_triangles2d.size());
|
||||
|
||||
|
@ -215,10 +222,7 @@ void MeshClipper::recalculate_triangles()
|
|||
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 1)).x(), (*(it + 1)).y(), height_mesh)).cast<float>(), (Vec3f)up.cast<float>());
|
||||
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 2)).x(), (*(it + 2)).y(), height_mesh)).cast<float>(), (Vec3f)up.cast<float>());
|
||||
const size_t idx = it - m_triangles2d.cbegin();
|
||||
if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
||||
init_data.add_ushort_triangle((unsigned short)idx, (unsigned short)idx + 1, (unsigned short)idx + 2);
|
||||
else
|
||||
init_data.add_uint_triangle((unsigned int)idx, (unsigned int)idx + 1, (unsigned int)idx + 2);
|
||||
init_data.add_triangle((unsigned int)idx, (unsigned int)idx + 1, (unsigned int)idx + 2);
|
||||
}
|
||||
|
||||
if (!init_data.is_empty())
|
||||
|
|
|
@ -351,7 +351,7 @@ static bool init_model_from_lines(GLModel &model, const Lines &lines, float z)
|
|||
{
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(2 * lines.size()) };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(2 * lines.size());
|
||||
init_data.reserve_indices(2 * lines.size());
|
||||
|
||||
|
@ -359,10 +359,7 @@ static bool init_model_from_lines(GLModel &model, const Lines &lines, float z)
|
|||
init_data.add_vertex(Vec3f(unscale<float>(l.a.x()), unscale<float>(l.a.y()), z));
|
||||
init_data.add_vertex(Vec3f(unscale<float>(l.b.x()), unscale<float>(l.b.y()), z));
|
||||
const unsigned int vertices_counter = (unsigned int)init_data.vertices_count();
|
||||
if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
||||
init_data.add_ushort_line((unsigned short)vertices_counter - 2, (unsigned short)vertices_counter - 1);
|
||||
else
|
||||
init_data.add_uint_line(vertices_counter - 2, vertices_counter - 1);
|
||||
init_data.add_line(vertices_counter - 2, vertices_counter - 1);
|
||||
}
|
||||
|
||||
model.init_from(std::move(init_data));
|
||||
|
@ -374,7 +371,7 @@ static bool init_model_from_lines(GLModel &model, const Lines3 &lines)
|
|||
{
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = {GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(2 * lines.size())};
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(2 * lines.size());
|
||||
init_data.reserve_indices(2 * lines.size());
|
||||
|
||||
|
@ -382,10 +379,7 @@ static bool init_model_from_lines(GLModel &model, const Lines3 &lines)
|
|||
init_data.add_vertex(Vec3f(unscale<float>(l.a.x()), unscale<float>(l.a.y()), unscale<float>(l.a.z())));
|
||||
init_data.add_vertex(Vec3f(unscale<float>(l.b.x()), unscale<float>(l.b.y()), unscale<float>(l.b.z())));
|
||||
const unsigned int vertices_counter = (unsigned int) init_data.vertices_count();
|
||||
if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
|
||||
init_data.add_ushort_line((unsigned short) vertices_counter - 2, (unsigned short) vertices_counter - 1);
|
||||
else
|
||||
init_data.add_uint_line(vertices_counter - 2, vertices_counter - 1);
|
||||
init_data.add_line(vertices_counter - 2, vertices_counter - 1);
|
||||
}
|
||||
|
||||
model.init_from(std::move(init_data));
|
||||
|
@ -583,9 +577,12 @@ void PartPlate::render_logo_texture(GLTexture &logo_texture, GLModel& logo_buffe
|
|||
}
|
||||
|
||||
if (logo_buffer.is_initialized()) {
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("printbed");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("printbed_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
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());
|
||||
shader->set_uniform("transparent_background", 0);
|
||||
shader->set_uniform("svg_source", 0);
|
||||
|
||||
|
@ -852,9 +849,12 @@ void PartPlate::show_tooltip(const std::string tooltip)
|
|||
|
||||
void PartPlate::render_icons(bool bottom, bool only_name, int hover_id)
|
||||
{
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("printbed");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("printbed_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
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());
|
||||
shader->set_uniform("transparent_background", bottom);
|
||||
//shader->set_uniform("svg_source", boost::algorithm::iends_with(m_partplate_list->m_del_texture.get_source(), ".svg"));
|
||||
shader->set_uniform("svg_source", 0);
|
||||
|
@ -940,9 +940,12 @@ void PartPlate::render_icons(bool bottom, bool only_name, int hover_id)
|
|||
|
||||
void PartPlate::render_only_numbers(bool bottom)
|
||||
{
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("printbed");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("printbed_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
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());
|
||||
shader->set_uniform("transparent_background", bottom);
|
||||
//shader->set_uniform("svg_source", boost::algorithm::iends_with(m_partplate_list->m_del_texture.get_source(), ".svg"));
|
||||
shader->set_uniform("svg_source", 0);
|
||||
|
@ -968,14 +971,17 @@ void PartPlate::render_only_numbers(bool bottom)
|
|||
}
|
||||
}
|
||||
|
||||
void PartPlate::render_rectangle_for_picking(GLModel &buffer, const ColorRGBA render_color)
|
||||
void PartPlate::render_rectangle_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix, GLModel &buffer, const ColorRGBA render_color)
|
||||
{
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
|
||||
//glsafe(::glDepthMask(GL_FALSE));
|
||||
buffer.set_color(render_color);
|
||||
buffer.render();
|
||||
|
@ -1203,36 +1209,36 @@ void PartPlate::render_right_arrow(const ColorRGBA render_color, bool use_lighti
|
|||
}
|
||||
*/
|
||||
|
||||
void PartPlate::on_render_for_picking() {
|
||||
void PartPlate::on_render_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix) {
|
||||
//glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
int hover_id = 0;
|
||||
ColorRGBA color = picking_color_component(hover_id);
|
||||
m_grabber_color = color;
|
||||
//render_grabber(m_grabber_color, false);
|
||||
render_rectangle_for_picking(m_triangles, m_grabber_color);
|
||||
render_rectangle_for_picking(view_matrix, projection_matrix, m_triangles, m_grabber_color);
|
||||
hover_id = 1;
|
||||
color = picking_color_component(hover_id);
|
||||
m_grabber_color = color;
|
||||
//render_left_arrow(m_grabber_color, false);
|
||||
render_rectangle_for_picking(m_del_icon, m_grabber_color);
|
||||
render_rectangle_for_picking(view_matrix, projection_matrix, m_del_icon, m_grabber_color);
|
||||
hover_id = 2;
|
||||
color = picking_color_component(hover_id);
|
||||
m_grabber_color = color;
|
||||
render_rectangle_for_picking(m_orient_icon, m_grabber_color);
|
||||
render_rectangle_for_picking(view_matrix, projection_matrix, m_orient_icon, m_grabber_color);
|
||||
hover_id = 3;
|
||||
color = picking_color_component(hover_id);
|
||||
m_grabber_color = color;
|
||||
render_rectangle_for_picking(m_arrange_icon, m_grabber_color);
|
||||
render_rectangle_for_picking(view_matrix, projection_matrix, m_arrange_icon, m_grabber_color);
|
||||
hover_id = 4;
|
||||
color = picking_color_component(hover_id);
|
||||
m_grabber_color = color;
|
||||
//render_right_arrow(m_grabber_color, false);
|
||||
render_rectangle_for_picking(m_lock_icon, m_grabber_color);
|
||||
render_rectangle_for_picking(view_matrix, projection_matrix, m_lock_icon, m_grabber_color);
|
||||
hover_id = 5;
|
||||
color = picking_color_component(hover_id);
|
||||
m_grabber_color = color;
|
||||
if (m_partplate_list->render_plate_settings)
|
||||
render_rectangle_for_picking(m_plate_settings_icon, m_grabber_color);
|
||||
render_rectangle_for_picking(view_matrix, projection_matrix, m_plate_settings_icon, m_grabber_color);
|
||||
}
|
||||
|
||||
ColorRGBA PartPlate::picking_color_component(int idx) const
|
||||
|
@ -2494,7 +2500,7 @@ bool PartPlate::intersects(const BoundingBoxf3& bb) const
|
|||
return print_volume.intersects(bb);
|
||||
}
|
||||
|
||||
void PartPlate::render(bool bottom, bool only_body, bool force_background_color, HeightLimitMode mode, int hover_id, bool render_cali)
|
||||
void PartPlate::render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_body, bool force_background_color, HeightLimitMode mode, int hover_id, bool render_cali)
|
||||
{
|
||||
GLShaderProgram *shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader != nullptr) {
|
||||
|
@ -2503,8 +2509,8 @@ void PartPlate::render(bool bottom, bool only_body, bool force_background_color,
|
|||
glsafe(::glEnable(GL_BLEND));
|
||||
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
|
||||
const Transform3d matrix = wxGetApp().plater()->get_camera().get_projection_view_matrix();
|
||||
shader->set_uniform("projection_view_model_matrix", matrix);
|
||||
shader->set_uniform("view_model_matrix", view_matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
|
||||
if (!bottom) {
|
||||
// draw background
|
||||
|
@ -4352,7 +4358,7 @@ void PartPlateList::postprocess_arrange_polygon(arrangement::ArrangePolygon& arr
|
|||
|
||||
/*rendering related functions*/
|
||||
//render
|
||||
void PartPlateList::render(bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali)
|
||||
void PartPlateList::render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali)
|
||||
{
|
||||
const std::lock_guard<std::mutex> local_lock(m_plates_mutex);
|
||||
std::vector<PartPlate*>::iterator it = m_plate_list.begin();
|
||||
|
@ -4377,25 +4383,25 @@ void PartPlateList::render(bool bottom, bool only_current, bool only_body, int h
|
|||
if (current_index == m_current_plate) {
|
||||
PartPlate::HeightLimitMode height_mode = (only_current)?PartPlate::HEIGHT_LIMIT_NONE:m_height_limit_mode;
|
||||
if (plate_hover_index == current_index)
|
||||
(*it)->render(bottom, only_body, false, height_mode, plate_hover_action, render_cali);
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, height_mode, plate_hover_action, render_cali);
|
||||
else
|
||||
(*it)->render(bottom, only_body, false, height_mode, -1, render_cali);
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, height_mode, -1, render_cali);
|
||||
}
|
||||
else {
|
||||
if (plate_hover_index == current_index)
|
||||
(*it)->render(bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, plate_hover_action, render_cali);
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, plate_hover_action, render_cali);
|
||||
else
|
||||
(*it)->render(bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, -1, render_cali);
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, -1, render_cali);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PartPlateList::render_for_picking_pass()
|
||||
void PartPlateList::render_for_picking_pass(const Transform3d &view_matrix, const Transform3d &projection_matrix)
|
||||
{
|
||||
const std::lock_guard<std::mutex> local_lock(m_plates_mutex);
|
||||
std::vector<PartPlate*>::iterator it = m_plate_list.begin();
|
||||
for (it = m_plate_list.begin(); it != m_plate_list.end(); it++) {
|
||||
(*it)->render_for_picking();
|
||||
(*it)->render_for_picking(view_matrix, projection_matrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -181,8 +181,8 @@ private:
|
|||
void render_icons(bool bottom, bool only_name = false, int hover_id = -1);
|
||||
void render_only_numbers(bool bottom);
|
||||
void render_plate_name_texture();
|
||||
void render_rectangle_for_picking(GLModel &buffer, const ColorRGBA render_color);
|
||||
void on_render_for_picking();
|
||||
void render_rectangle_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix, GLModel &buffer, const ColorRGBA render_color);
|
||||
void on_render_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix);
|
||||
ColorRGBA picking_color_component(int idx) const;
|
||||
|
||||
public:
|
||||
|
@ -341,8 +341,8 @@ public:
|
|||
bool contains(const BoundingBoxf3& bb) const;
|
||||
bool intersects(const BoundingBoxf3& bb) const;
|
||||
|
||||
void render(bool bottom, bool only_body = false, bool force_background_color = false, HeightLimitMode mode = HEIGHT_LIMIT_NONE, int hover_id = -1, bool render_cali = false);
|
||||
void render_for_picking() { on_render_for_picking(); }
|
||||
void render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_body = false, bool force_background_color = false, HeightLimitMode mode = HEIGHT_LIMIT_NONE, int hover_id = -1, bool render_cali = false);
|
||||
void render_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix) { on_render_for_picking(view_matrix, projection_matrix); }
|
||||
void set_selected();
|
||||
void set_unselected();
|
||||
void set_hover_id(int id) { m_hover_id = id; }
|
||||
|
@ -740,8 +740,8 @@ public:
|
|||
|
||||
/*rendering related functions*/
|
||||
void on_change_color_mode(bool is_dark) { m_is_dark = is_dark; }
|
||||
void render(bool bottom, bool only_current = false, bool only_body = false, int hover_id = -1, bool render_cali = false);
|
||||
void render_for_picking_pass();
|
||||
void render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current = false, bool only_body = false, int hover_id = -1, bool render_cali = false);
|
||||
void render_for_picking_pass(const Transform3d& view_matrix, const Transform3d& projection_matrix);
|
||||
void set_render_option(bool bedtype_texture, bool plate_settings);
|
||||
void set_render_cali(bool value = true) { render_cali_logo = value; }
|
||||
BoundingBoxf3& get_bounding_box() { return m_bounding_box; }
|
||||
|
|
|
@ -1570,22 +1570,26 @@ void Selection::render_center(bool gizmo_is_dragging)
|
|||
if (!m_valid || is_empty())
|
||||
return;
|
||||
|
||||
const Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center();
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
shader->start_using();
|
||||
m_vbo_sphere.set_color(-1, ColorRGBA::WHITE());
|
||||
|
||||
const Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center();
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::assemble_transform(center);
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
m_vbo_sphere.set_color(ColorRGBA::WHITE());
|
||||
m_vbo_sphere.render();
|
||||
|
||||
shader->stop_using();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||
|
||||
|
@ -1596,7 +1600,7 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, bool unif
|
|||
if (sidebar_field.empty())
|
||||
return;
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader(boost::starts_with(sidebar_field, "layer") ? "flat" : "gouraud_light");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader(boost::starts_with(sidebar_field, "layer") ? "flat_attr" : "gouraud_light_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -1604,16 +1608,14 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, bool unif
|
|||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
const Transform3d base_matrix = Geometry::assemble_transform(get_bounding_box().center());
|
||||
Transform3d orient_matrix = Transform3d::Identity();
|
||||
|
||||
if (!boost::starts_with(sidebar_field, "layer")) {
|
||||
const Vec3d& center = get_bounding_box().center();
|
||||
|
||||
shader->set_uniform("emission_factor", 0.05f);
|
||||
// BBS
|
||||
if (is_single_full_instance()/* && !wxGetApp().obj_manipul()->get_world_coordinates()*/) {
|
||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||
if (!boost::starts_with(sidebar_field, "position")) {
|
||||
Transform3d orient_matrix = Transform3d::Identity();
|
||||
if (boost::starts_with(sidebar_field, "scale"))
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
else if (boost::starts_with(sidebar_field, "rotation")) {
|
||||
|
@ -1621,51 +1623,45 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, bool unif
|
|||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
else if (boost::ends_with(sidebar_field, "y")) {
|
||||
const Vec3d& rotation = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation();
|
||||
if (rotation(0) == 0.0)
|
||||
if (rotation.x() == 0.0)
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
else
|
||||
orient_matrix.rotate(Eigen::AngleAxisd(rotation(2), Vec3d::UnitZ()));
|
||||
orient_matrix.rotate(Eigen::AngleAxisd(rotation.z(), Vec3d::UnitZ()));
|
||||
}
|
||||
}
|
||||
|
||||
glsafe(::glMultMatrixd(orient_matrix.data()));
|
||||
}
|
||||
} else if (is_single_volume() || is_single_modifier()) {
|
||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||
Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
}
|
||||
else if (is_single_volume() || is_single_modifier()) {
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
if (!boost::starts_with(sidebar_field, "position"))
|
||||
orient_matrix = orient_matrix * (*m_volumes)[*m_list.begin()]->get_volume_transformation().get_matrix(true, false, true, true);
|
||||
|
||||
glsafe(::glMultMatrixd(orient_matrix.data()));
|
||||
} else {
|
||||
glsafe(::glTranslated(center(0), center(1), center(2)));
|
||||
if (requires_local_axes()) {
|
||||
const Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
glsafe(::glMultMatrixd(orient_matrix.data()));
|
||||
}
|
||||
else {
|
||||
if (requires_local_axes())
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!boost::starts_with(sidebar_field, "layer"))
|
||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||
if (boost::starts_with(sidebar_field, "position"))
|
||||
render_sidebar_position_hints(sidebar_field);
|
||||
render_sidebar_position_hints(sidebar_field, *shader, base_matrix * orient_matrix);
|
||||
else if (boost::starts_with(sidebar_field, "rotation"))
|
||||
render_sidebar_rotation_hints(sidebar_field);
|
||||
render_sidebar_rotation_hints(sidebar_field, *shader, base_matrix * orient_matrix);
|
||||
else if (boost::starts_with(sidebar_field, "scale") || boost::starts_with(sidebar_field, "size"))
|
||||
//BBS: GUI refactor: add uniform_scale from gizmo
|
||||
render_sidebar_scale_hints(sidebar_field, uniform_scale);
|
||||
render_sidebar_scale_hints(sidebar_field, uniform_scale, *shader, base_matrix * orient_matrix);
|
||||
else if (boost::starts_with(sidebar_field, "layer"))
|
||||
render_sidebar_layers_hints(sidebar_field);
|
||||
render_sidebar_layers_hints(sidebar_field, *shader);
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
bool Selection::requires_local_axes() const
|
||||
{
|
||||
return (m_mode == Volume) && is_from_single_instance();
|
||||
return m_mode == Volume && is_from_single_instance();
|
||||
}
|
||||
|
||||
void Selection::cut_to_clipboard()
|
||||
|
@ -1681,8 +1677,7 @@ void Selection::copy_to_clipboard()
|
|||
|
||||
m_clipboard.reset();
|
||||
|
||||
for (const ObjectIdxsToInstanceIdxsMap::value_type& object : m_cache.content)
|
||||
{
|
||||
for (const ObjectIdxsToInstanceIdxsMap::value_type& object : m_cache.content) {
|
||||
ModelObject* src_object = m_model->objects[object.first];
|
||||
ModelObject* dst_object = m_clipboard.add_object();
|
||||
dst_object->name = src_object->name;
|
||||
|
@ -1695,26 +1690,22 @@ void Selection::copy_to_clipboard()
|
|||
dst_object->layer_height_profile.assign(src_object->layer_height_profile);
|
||||
dst_object->origin_translation = src_object->origin_translation;
|
||||
|
||||
for (int i : object.second)
|
||||
{
|
||||
for (int i : object.second) {
|
||||
dst_object->add_instance(*src_object->instances[i]);
|
||||
}
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
for (unsigned int i : m_list) {
|
||||
// Copy the ModelVolumes only for the selected GLVolumes of the 1st selected instance.
|
||||
const GLVolume* volume = (*m_volumes)[i];
|
||||
if ((volume->object_idx() == object.first) && (volume->instance_idx() == *object.second.begin()))
|
||||
{
|
||||
if (volume->object_idx() == object.first && volume->instance_idx() == *object.second.begin()) {
|
||||
int volume_idx = volume->volume_idx();
|
||||
if ((0 <= volume_idx) && (volume_idx < (int)src_object->volumes.size()))
|
||||
{
|
||||
if (0 <= volume_idx && volume_idx < (int)src_object->volumes.size()) {
|
||||
ModelVolume* src_volume = src_object->volumes[volume_idx];
|
||||
ModelVolume* dst_volume = dst_object->add_volume(*src_volume);
|
||||
dst_volume->set_new_unique_id();
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2167,7 +2158,7 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& co
|
|||
const Vec3f size = 0.2f * box.size().cast<float>();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(48);
|
||||
init_data.reserve_indices(48);
|
||||
|
||||
|
@ -2230,7 +2221,7 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& co
|
|||
|
||||
// indices
|
||||
for (unsigned short i = 0; i < 48; ++i) {
|
||||
init_data.add_ushort_index(i);
|
||||
init_data.add_index(i);
|
||||
}
|
||||
|
||||
m_box.init_from(std::move(init_data));
|
||||
|
@ -2240,11 +2231,14 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& co
|
|||
|
||||
glsafe(::glLineWidth(2.0f * m_scale_factor));
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
shader->start_using();
|
||||
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());
|
||||
m_box.set_color(to_rgba(color));
|
||||
m_box.render();
|
||||
shader->stop_using();
|
||||
|
@ -2255,91 +2249,103 @@ static ColorRGBA get_color(Axis axis)
|
|||
return GLGizmoBase::AXES_COLOR[axis];
|
||||
}
|
||||
|
||||
void Selection::render_sidebar_position_hints(const std::string& sidebar_field)
|
||||
void Selection::render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix)
|
||||
{
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d view_matrix = camera.get_view_matrix() * matrix;
|
||||
shader.set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
if (boost::ends_with(sidebar_field, "x")) {
|
||||
glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0));
|
||||
const Transform3d view_model_matrix = view_matrix * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitZ());
|
||||
shader.set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_arrow.set_color(get_color(X));
|
||||
m_arrow.render();
|
||||
}
|
||||
else if (boost::ends_with(sidebar_field, "y")) {
|
||||
shader.set_uniform("view_model_matrix", view_matrix);
|
||||
shader.set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_arrow.set_color(get_color(Y));
|
||||
m_arrow.render();
|
||||
}
|
||||
else if (boost::ends_with(sidebar_field, "z")) {
|
||||
glsafe(::glRotated(90.0, 1.0, 0.0, 0.0));
|
||||
const Transform3d view_model_matrix = view_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitX());
|
||||
shader.set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_arrow.set_color(get_color(Z));
|
||||
m_arrow.render();
|
||||
}
|
||||
}
|
||||
|
||||
void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field)
|
||||
void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix)
|
||||
{
|
||||
auto render_sidebar_rotation_hint = [this]() {
|
||||
auto render_sidebar_rotation_hint = [this](GLShaderProgram& shader, const Transform3d& matrix) {
|
||||
Transform3d view_model_matrix = matrix;
|
||||
shader.set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_curved_arrow.render();
|
||||
glsafe(::glRotated(180.0, 0.0, 0.0, 1.0));
|
||||
view_model_matrix = matrix * Geometry::assemble_transform(Vec3d::Zero(), PI * Vec3d::UnitZ());
|
||||
shader.set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_curved_arrow.render();
|
||||
};
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d view_matrix = camera.get_view_matrix() * matrix;
|
||||
shader.set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
if (boost::ends_with(sidebar_field, "x")) {
|
||||
glsafe(::glRotated(90.0, 0.0, 1.0, 0.0));
|
||||
m_curved_arrow.set_color(get_color(X));
|
||||
render_sidebar_rotation_hint();
|
||||
render_sidebar_rotation_hint(shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitY()));
|
||||
}
|
||||
else if (boost::ends_with(sidebar_field, "y")) {
|
||||
glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0));
|
||||
m_curved_arrow.set_color(get_color(Y));
|
||||
render_sidebar_rotation_hint();
|
||||
render_sidebar_rotation_hint(shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitX()));
|
||||
}
|
||||
else if (boost::ends_with(sidebar_field, "z")) {
|
||||
m_curved_arrow.set_color(get_color(Z));
|
||||
render_sidebar_rotation_hint();
|
||||
render_sidebar_rotation_hint(shader, view_matrix);
|
||||
}
|
||||
}
|
||||
|
||||
//BBS: GUI refactor: add gizmo uniform_scale
|
||||
void Selection::render_sidebar_scale_hints(const std::string& sidebar_field, bool gizmo_uniform_scale)
|
||||
void Selection::render_sidebar_scale_hints(const std::string& sidebar_field, bool gizmo_uniform_scale, GLShaderProgram& shader, const Transform3d& matrix)
|
||||
{
|
||||
// BBS
|
||||
//bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling();
|
||||
bool uniform_scale = requires_uniform_scale() || gizmo_uniform_scale;
|
||||
|
||||
auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis) {
|
||||
auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis, GLShaderProgram& shader, const Transform3d& matrix) {
|
||||
m_arrow.set_color(uniform_scale ? UNIFORM_SCALE_COLOR : get_color(axis));
|
||||
GLShaderProgram* shader = wxGetApp().get_current_shader();
|
||||
if (shader != nullptr)
|
||||
shader->set_uniform("emission_factor", 0.0f);
|
||||
|
||||
glsafe(::glTranslated(0.0, 5.0, 0.0));
|
||||
Transform3d view_model_matrix = matrix * Geometry::assemble_transform(5.0 * Vec3d::UnitY());
|
||||
shader.set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_arrow.render();
|
||||
|
||||
glsafe(::glTranslated(0.0, -10.0, 0.0));
|
||||
glsafe(::glRotated(180.0, 0.0, 0.0, 1.0));
|
||||
view_model_matrix = matrix * Geometry::assemble_transform(-5.0 * Vec3d::UnitY(), PI * Vec3d::UnitZ());
|
||||
shader.set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
m_arrow.render();
|
||||
};
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d view_matrix = camera.get_view_matrix() * matrix;
|
||||
shader.set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
if (boost::ends_with(sidebar_field, "x") || uniform_scale) {
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0));
|
||||
render_sidebar_scale_hint(X);
|
||||
glsafe(::glPopMatrix());
|
||||
render_sidebar_scale_hint(X, shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitZ()));
|
||||
}
|
||||
|
||||
if (boost::ends_with(sidebar_field, "y") || uniform_scale) {
|
||||
glsafe(::glPushMatrix());
|
||||
render_sidebar_scale_hint(Y);
|
||||
glsafe(::glPopMatrix());
|
||||
render_sidebar_scale_hint(Y, shader, view_matrix);
|
||||
}
|
||||
|
||||
if (boost::ends_with(sidebar_field, "z") || uniform_scale) {
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glRotated(90.0, 1.0, 0.0, 0.0));
|
||||
render_sidebar_scale_hint(Z);
|
||||
glsafe(::glPopMatrix());
|
||||
render_sidebar_scale_hint(Z, shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitX()));
|
||||
}
|
||||
}
|
||||
|
||||
void Selection::render_sidebar_layers_hints(const std::string& sidebar_field)
|
||||
void Selection::render_sidebar_layers_hints(const std::string& sidebar_field, GLShaderProgram& shader)
|
||||
{
|
||||
static const float Margin = 10.0f;
|
||||
|
||||
|
@ -2388,7 +2394,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field)
|
|||
m_planes.models[0].reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(4);
|
||||
init_data.reserve_indices(6);
|
||||
|
||||
|
@ -2399,8 +2405,8 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field)
|
|||
init_data.add_vertex(Vec3f(p1.x(), p2.y(), z1));
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_triangle(0, 1, 2);
|
||||
init_data.add_ushort_triangle(2, 3, 0);
|
||||
init_data.add_triangle(0, 1, 2);
|
||||
init_data.add_triangle(2, 3, 0);
|
||||
|
||||
m_planes.models[0].init_from(std::move(init_data));
|
||||
}
|
||||
|
@ -2410,7 +2416,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field)
|
|||
m_planes.models[1].reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 };
|
||||
init_data.reserve_vertices(4);
|
||||
init_data.reserve_indices(6);
|
||||
|
||||
|
@ -2421,12 +2427,16 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field)
|
|||
init_data.add_vertex(Vec3f(p1.x(), p2.y(), z2));
|
||||
|
||||
// indices
|
||||
init_data.add_ushort_triangle(0, 1, 2);
|
||||
init_data.add_ushort_triangle(2, 3, 0);
|
||||
init_data.add_triangle(0, 1, 2);
|
||||
init_data.add_triangle(2, 3, 0);
|
||||
|
||||
m_planes.models[1].init_from(std::move(init_data));
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
m_planes.models[0].set_color((camera_on_top && type == 1) || (!camera_on_top && type == 2) ? SOLID_PLANE_COLOR : TRANSPARENT_PLANE_COLOR);
|
||||
m_planes.models[0].render();
|
||||
m_planes.models[1].set_color((camera_on_top && type == 2) || (!camera_on_top && type == 1) ? SOLID_PLANE_COLOR : TRANSPARENT_PLANE_COLOR);
|
||||
|
|
|
@ -408,11 +408,11 @@ private:
|
|||
void set_bounding_boxes_dirty() { m_bounding_box.reset(); m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset(); }
|
||||
void render_synchronized_volumes();
|
||||
void render_bounding_box(const BoundingBoxf3& box, const ColorRGB& color);
|
||||
void render_sidebar_position_hints(const std::string& sidebar_field);
|
||||
void render_sidebar_rotation_hints(const std::string& sidebar_field);
|
||||
void render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix);
|
||||
void render_sidebar_rotation_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix);
|
||||
//BBS: GUI refactor: add uniform_scale from gizmo
|
||||
void render_sidebar_scale_hints(const std::string& sidebar_field, bool gizmo_uniform_scale);
|
||||
void render_sidebar_layers_hints(const std::string& sidebar_field);
|
||||
void render_sidebar_scale_hints(const std::string& sidebar_field, bool gizmo_uniform_scale, GLShaderProgram& shader, const Transform3d& matrix);
|
||||
void render_sidebar_layers_hints(const std::string& sidebar_field, GLShaderProgram& shader);
|
||||
|
||||
public:
|
||||
enum SyncRotationType {
|
||||
|
|
|
@ -917,7 +917,7 @@ void CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f
|
|||
ThumbnailData* thumbnail_data = &plate_data_list[0]->plate_thumbnail;
|
||||
unsigned int thumbnail_width = 512, thumbnail_height = 512;
|
||||
const ThumbnailsParams thumbnail_params = {{}, false, true, true, true, 0};
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("thumbnail");
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("thumbnail_attr");
|
||||
|
||||
for (unsigned int obj_idx = 0; obj_idx < (unsigned int)model->objects.size(); ++ obj_idx) {
|
||||
const ModelObject &model_object = *model->objects[obj_idx];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue