mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2026-01-29 12:20:50 -07:00
Port libvgcode/improved G-code viewer from PrusaSlicer 2.8.0 (#10735)
# Description Fixes #6813 Fixes #7782 Fixes #6367 This is a port of libvgcode, OpenGL Core Profile (libvgcode requires OpenGL 3.2+), and probably other stuff I forgot from PrusaSlicer. libvgcode is also known as "Improved G-code Viewer" which was introduced in [PrusaSlicer 2.8.0](https://github.com/prusa3d/PrusaSlicer/releases/tag/version_2.8.0-alpha5). It significantly improves performance of the G-code preview and allows displaying the actual speed and volumetric flow rate. ## TODO - [x] Make the sliders work properly again - [x] Make view type selection work - [x] Fix toggling of feature type visibility - [x] Expose actual speed/actual flow view types - [x] Fix display of G2/G3 arcs - [x] Wire up actual speed graph widgets - [x] Fix painter gizmos - [x] Fix crash when selecting filament view type on Windows - [ ] Figure out display color management (#10827) - [x] Fix incorrect rendering of small area flow compensation (or any extrusions with varying flow) - [ ] Localization - [ ] Testing - [ ] Code cleanup, performance optimization ## Removed functionality Some functionality is not supported by libvgcode: - Toggling visibility of tools - Toggling visibility of colors in color print view - Support for systems with OpenGL <3.2 - Bambu's implementation of G2/G3 arcs was replaced with PrusaSlicer's implementation # Screenshots/Recordings/Graphs https://github.com/user-attachments/assets/c1413a82-3058-4541-b96c-3d5f7cdef174 <details> <summary>Outdated Stuff</summary> https://github.com/user-attachments/assets/ca172ef4-0828-4d21-8768-b08a4132c9ab <img width="1611" height="1145" alt="image" src="https://github.com/user-attachments/assets/5e0d04ff-8046-4636-a08a-cdedc60303bc" /> </details> ## Tests - [x] Normally sliced G-code - [ ] G-code viewer mode - [x] Arc fitting enabled - [x] Spiral Z-hops - [x] Multi-extruder/multi-color - [x] Vase mode - [x] Skirt/brim - [x] Supports - [ ] Support transition (whatever this is) - [x] Painter gizmos - [x] Measurement gizmo - [x] Move/rotate/scale gizmos - [x] H2D/H2S support (oh no) - [ ] Windows - [x] macOS - [ ] Linux
This commit is contained in:
commit
ba5f0e707d
117 changed files with 19332 additions and 6172 deletions
|
|
@ -153,6 +153,8 @@ namespace ImGui
|
|||
// const wchar_t CustomSupportsMarker = 0x1D;
|
||||
// const wchar_t CustomSeamMarker = 0x1E;
|
||||
// const wchar_t MmuSegmentationMarker = 0x1F;
|
||||
const wchar_t HorizontalHide = 0xB1;
|
||||
const wchar_t HorizontalShow = 0xB2;
|
||||
|
||||
// Do not forget use following letters only in wstring
|
||||
//BBS use 08xx to avoid unicode character which may be used
|
||||
|
|
|
|||
46
resources/images/horizontal_hide.svg
Normal file
46
resources/images/horizontal_hide.svg
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
version="1.0"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 16 16"
|
||||
enable-background="new 0 0 16 16"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="hide_horizontal.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs945">
|
||||
|
||||
|
||||
|
||||
</defs><sodipodi:namedview
|
||||
id="namedview943"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="50.75"
|
||||
inkscape:cx="7.9901478"
|
||||
inkscape:cy="8.0098522"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1001"
|
||||
inkscape:window-x="3191"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<polygon
|
||||
fill="#009688"
|
||||
points="1,8 1,11 8,16 15,11 15,8 "
|
||||
style="stroke:none;stroke-width:1"
|
||||
id="polygon937"
|
||||
transform="translate(0,-4)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
46
resources/images/horizontal_show.svg
Normal file
46
resources/images/horizontal_show.svg
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
version="1.0"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 16 16"
|
||||
enable-background="new 0 0 16 16"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="show_horizontal.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1127">
|
||||
|
||||
|
||||
|
||||
</defs><sodipodi:namedview
|
||||
id="namedview1125"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="50.75"
|
||||
inkscape:cx="7.9901478"
|
||||
inkscape:cy="8.0098522"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1001"
|
||||
inkscape:window-x="3191"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<polygon
|
||||
fill="#009688"
|
||||
points="15,7 15,5 8,0 1,5 1,7 1,8 15,8 "
|
||||
style="stroke:none;stroke-width:1"
|
||||
id="polygon1119"
|
||||
transform="translate(0,4)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -5,7 +5,9 @@ uniform vec4 bottom_color;
|
|||
|
||||
in vec2 tex_coord;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = mix(bottom_color, top_color, tex_coord.y);
|
||||
out_color = mix(bottom_color, top_color, tex_coord.y);
|
||||
}
|
||||
|
|
|
|||
34
resources/shaders/140/dashed_thick_lines.fs
Normal file
34
resources/shaders/140/dashed_thick_lines.fs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#version 150
|
||||
|
||||
// see as reference: https://github.com/mhalber/Lines/blob/master/geometry_shader_lines.h
|
||||
// https://stackoverflow.com/questions/52928678/dashed-line-in-opengl3
|
||||
|
||||
const float aa_radius = 0.5;
|
||||
|
||||
uniform float dash_size;
|
||||
uniform float gap_size;
|
||||
uniform vec4 uniform_color;
|
||||
|
||||
in float line_width;
|
||||
// x = v tex coord, y = s coord
|
||||
in vec2 seg_params;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
float inv_stride = 1.0 / (dash_size + gap_size);
|
||||
if (gap_size > 0.0 && fract(seg_params.y * inv_stride) > dash_size * inv_stride)
|
||||
discard;
|
||||
|
||||
// We render a quad that is fattened by r, giving total width of the line to be w+r. We want smoothing to happen
|
||||
// around w, so that the edge is properly smoothed out. As such, in the smoothstep function we have:
|
||||
// Far edge : 1.0 = (w+r) / (w+r)
|
||||
// Close edge : 1.0 - (2r / (w+r)) = (w+r)/(w+r) - 2r/(w+r)) = (w-r) / (w+r)
|
||||
// This way the smoothing is centered around 'w'.
|
||||
|
||||
out_color = uniform_color;
|
||||
float inv_line_width = 1.0 / line_width;
|
||||
float aa = 1.0 - smoothstep(1.0 - (2.0 * aa_radius * inv_line_width), 1.0, abs(seg_params.x * inv_line_width));
|
||||
out_color.a *= aa;
|
||||
}
|
||||
50
resources/shaders/140/dashed_thick_lines.gs
Normal file
50
resources/shaders/140/dashed_thick_lines.gs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#version 150
|
||||
|
||||
// see as reference: https://github.com/mhalber/Lines/blob/master/geometry_shader_lines.h
|
||||
// https://stackoverflow.com/questions/52928678/dashed-line-in-opengl3
|
||||
|
||||
layout(lines) in;
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
|
||||
const float aa_radius = 0.5;
|
||||
|
||||
uniform vec2 viewport_size;
|
||||
uniform float width;
|
||||
|
||||
in float coord_s[];
|
||||
|
||||
out float line_width;
|
||||
// x = v tex coord, y = s coord
|
||||
out vec2 seg_params;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 ndc_0 = gl_in[0].gl_Position.xy / gl_in[0].gl_Position.w;
|
||||
vec2 ndc_1 = gl_in[1].gl_Position.xy / gl_in[1].gl_Position.w;
|
||||
|
||||
vec2 dir = normalize((ndc_1 - ndc_0) * viewport_size);
|
||||
vec2 normal_dir = vec2(-dir.y, dir.x);
|
||||
|
||||
line_width = max(1.0, width) + 2.0 * aa_radius;
|
||||
float half_line_width = 0.5 * line_width;
|
||||
|
||||
vec2 normal = vec2(line_width / viewport_size[0], line_width / viewport_size[1]) * normal_dir;
|
||||
|
||||
seg_params = vec2(-half_line_width, coord_s[0]);
|
||||
gl_Position = vec4((ndc_0 + normal) * gl_in[0].gl_Position.w, gl_in[0].gl_Position.zw);
|
||||
EmitVertex();
|
||||
|
||||
seg_params = vec2(-half_line_width, coord_s[0]);
|
||||
gl_Position = vec4((ndc_0 - normal) * gl_in[0].gl_Position.w, gl_in[0].gl_Position.zw);
|
||||
EmitVertex();
|
||||
|
||||
seg_params = vec2(half_line_width, coord_s[1]);
|
||||
gl_Position = vec4((ndc_1 + normal) * gl_in[1].gl_Position.w, gl_in[1].gl_Position.zw);
|
||||
EmitVertex();
|
||||
|
||||
seg_params = vec2(half_line_width, coord_s[1]);
|
||||
gl_Position = vec4((ndc_1 - normal) * gl_in[1].gl_Position.w, gl_in[1].gl_Position.zw);
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
18
resources/shaders/140/dashed_thick_lines.vs
Normal file
18
resources/shaders/140/dashed_thick_lines.vs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#version 150
|
||||
|
||||
// see as reference: https://github.com/mhalber/Lines/blob/master/geometry_shader_lines.h
|
||||
// https://stackoverflow.com/questions/52928678/dashed-line-in-opengl3
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
// v_position.w = coordinate along the line
|
||||
in vec4 v_position;
|
||||
|
||||
out float coord_s;
|
||||
|
||||
void main()
|
||||
{
|
||||
coord_s = v_position.w;
|
||||
gl_Position = projection_matrix * view_model_matrix * vec4(v_position.xyz, 1.0);
|
||||
}
|
||||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
uniform vec4 uniform_color;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = uniform_color;
|
||||
out_color = uniform_color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ uniform sampler2D uniform_texture;
|
|||
|
||||
in vec2 tex_coord;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture(uniform_texture, tex_coord);
|
||||
out_color = texture(uniform_texture, tex_coord);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ uniform float emission_factor;
|
|||
// x = tainted, y = specular;
|
||||
in vec2 intensity;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
|
||||
out_color = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ uniform float emission_factor;
|
|||
// x = tainted, y = specular;
|
||||
in vec2 intensity;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
|
||||
out_color = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
|
||||
}
|
||||
|
|
|
|||
46
resources/shaders/140/hotbed.fs
Normal file
46
resources/shaders/140/hotbed.fs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#version 140
|
||||
|
||||
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
|
||||
const vec3 WHITE = vec3(1.0, 1.0, 1.0);
|
||||
struct PrintVolumeDetection
|
||||
{
|
||||
// 0 = rectangle, 1 = circle, 2 = custom, 3 = invalid
|
||||
int type;
|
||||
// type = 0 (rectangle):
|
||||
// x = min.x, y = min.y, z = max.x, w = max.y
|
||||
// type = 1 (circle):
|
||||
// x = center.x, y = center.y, z = radius
|
||||
vec4 xy_data;
|
||||
// x = min z, y = max z
|
||||
vec2 z_data;
|
||||
};
|
||||
|
||||
uniform vec4 uniform_color;
|
||||
uniform float emission_factor;
|
||||
uniform PrintVolumeDetection print_volume;
|
||||
// x = diffuse, y = specular;
|
||||
in vec2 intensity;
|
||||
in vec4 world_pos;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = uniform_color.rgb;
|
||||
float alpha = uniform_color.a;
|
||||
// if the fragment is outside the print volume -> use darker color
|
||||
vec3 pv_check_min = ZERO;
|
||||
vec3 pv_check_max = ZERO;
|
||||
if (print_volume.type == 0) {// rectangle
|
||||
pv_check_min = world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, print_volume.z_data.x);
|
||||
pv_check_max = world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, print_volume.z_data.y);
|
||||
}
|
||||
else if (print_volume.type == 1) {// circle
|
||||
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
|
||||
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
|
||||
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
|
||||
}
|
||||
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, WHITE, 0.3333) : color;
|
||||
//out_color = vec4(vec3(intensity.y) + color * intensity.x, alpha);
|
||||
out_color = vec4(vec3(intensity.y) + color * (intensity.x + emission_factor), alpha);
|
||||
}
|
||||
47
resources/shaders/140/hotbed.vs
Normal file
47
resources/shaders/140/hotbed.vs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#version 140
|
||||
|
||||
#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
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat3 view_normal_matrix;
|
||||
uniform mat4 volume_world_matrix;
|
||||
|
||||
in vec3 v_position;
|
||||
in vec3 v_normal;
|
||||
|
||||
// x = tainted, y = specular;
|
||||
out vec2 intensity;
|
||||
out vec4 world_pos;
|
||||
void main()
|
||||
{
|
||||
// First transform the normal into camera space and normalize the result.
|
||||
vec3 normal = normalize(view_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;
|
||||
world_pos = volume_world_matrix * vec4(v_position, 1.0);
|
||||
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;
|
||||
}
|
||||
|
|
@ -5,7 +5,9 @@ uniform sampler2D Texture;
|
|||
in vec2 Frag_UV;
|
||||
in vec4 Frag_Color;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = Frag_Color * texture(Texture, Frag_UV.st);
|
||||
out_color = Frag_Color * texture(Texture, Frag_UV.st);
|
||||
}
|
||||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
uniform vec4 uniform_color;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = uniform_color;
|
||||
out_color = uniform_color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,13 +9,15 @@ in vec2 intensity;
|
|||
//varying float drop;
|
||||
in vec4 world_pos;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
if (world_pos.z < 0.0)
|
||||
discard;
|
||||
if(ban_light){
|
||||
gl_FragColor = uniform_color;
|
||||
out_color = uniform_color;
|
||||
} else{
|
||||
gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
|
||||
out_color = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ in vec2 intensity;
|
|||
|
||||
in float object_z;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
float object_z_row = z_to_texture_row * object_z;
|
||||
|
|
@ -37,5 +39,5 @@ void main()
|
|||
color = mix(texture(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.),
|
||||
texture(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.), lod);
|
||||
// Mix the final color.
|
||||
gl_FragColor = vec4(vec3(intensity.y), 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend);
|
||||
out_color = vec4(vec3(intensity.y), 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ add_subdirectory(libslic3r)
|
|||
|
||||
if (SLIC3R_GUI)
|
||||
# imgui, imguizmo, and hidapi are now included from deps_src
|
||||
add_subdirectory(libvgcode)
|
||||
|
||||
if(WIN32)
|
||||
message(STATUS "WXWIN environment set to: $ENV{WXWIN}")
|
||||
|
|
|
|||
|
|
@ -190,6 +190,9 @@ void AppConfig::set_defaults()
|
|||
#endif // _WIN32
|
||||
}
|
||||
|
||||
if (get("seq_top_layer_only").empty())
|
||||
set("seq_top_layer_only", "1");
|
||||
|
||||
if (get("use_perspective_camera").empty())
|
||||
set_bool("use_perspective_camera", true);
|
||||
|
||||
|
|
|
|||
|
|
@ -565,40 +565,6 @@ inline bool all_inside_vertices_normals_interleaved(const std::vector<float> &pa
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::vector<float>& paths, const Eigen::AlignedBox<float, 3>& paths_bbox, bool ignore_bottom) const
|
||||
{
|
||||
assert(paths.size() % 6 == 0);
|
||||
static constexpr const double epsilon = BedEpsilon;
|
||||
switch (m_type) {
|
||||
case BuildVolume_Type::Rectangle:
|
||||
{
|
||||
BoundingBox3Base<Vec3d> build_volume = this->bounding_volume().inflated(epsilon);
|
||||
if (m_max_print_height == 0.0)
|
||||
build_volume.max.z() = std::numeric_limits<double>::max();
|
||||
if (ignore_bottom)
|
||||
build_volume.min.z() = -std::numeric_limits<double>::max();
|
||||
return build_volume.contains(paths_bbox.min().cast<double>()) && build_volume.contains(paths_bbox.max().cast<double>());
|
||||
}
|
||||
case BuildVolume_Type::Circle:
|
||||
{
|
||||
const Vec2f c = unscaled<float>(m_circle.center);
|
||||
const float r = unscaled<double>(m_circle.radius) + float(epsilon);
|
||||
const float r2 = sqr(r);
|
||||
return m_max_print_height == 0.0 ?
|
||||
all_inside_vertices_normals_interleaved(paths, [c, r2](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2; }) :
|
||||
all_inside_vertices_normals_interleaved(paths, [c, r2, z = m_max_print_height + epsilon](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2 && p.z() <= z; });
|
||||
}
|
||||
case BuildVolume_Type::Convex:
|
||||
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
|
||||
case BuildVolume_Type::Custom:
|
||||
return m_max_print_height == 0.0 ?
|
||||
all_inside_vertices_normals_interleaved(paths, [this](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast<double>()); }) :
|
||||
all_inside_vertices_normals_interleaved(paths, [this, z = m_max_print_height + epsilon](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast<double>()) && p.z() <= z; });
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::string_view BuildVolume::type_name(BuildVolume_Type type)
|
||||
{
|
||||
using namespace std::literals;
|
||||
|
|
|
|||
|
|
@ -118,8 +118,6 @@ public:
|
|||
// Called on final G-code paths.
|
||||
//FIXME The test does not take the thickness of the extrudates into account!
|
||||
bool all_paths_inside(const GCodeProcessorResult& paths, const BoundingBoxf3& paths_bbox, bool ignore_bottom = true) const;
|
||||
// Called on initial G-code preview on OpenGL vertex buffer interleaved normals and vertices.
|
||||
bool all_paths_inside_vertices_and_normals_interleaved(const std::vector<float>& paths, const Eigen::AlignedBox<float, 3>& bbox, bool ignore_bottom = true) const;
|
||||
|
||||
int get_extruder_area_count() const { return m_extruder_volumes.size(); }
|
||||
const BuildExtruderVolume& get_extruder_area_volume(int index) const;
|
||||
|
|
|
|||
|
|
@ -251,6 +251,8 @@ set(lisbslic3r_sources
|
|||
GCode/WipeTower.hpp
|
||||
GCodeWriter.cpp
|
||||
GCodeWriter.hpp
|
||||
Geometry/ArcWelder.hpp
|
||||
Geometry/ArcWelder.cpp
|
||||
Geometry/Bicubic.hpp
|
||||
Geometry/Circle.cpp
|
||||
Geometry/Circle.hpp
|
||||
|
|
|
|||
|
|
@ -2006,6 +2006,7 @@ namespace DoExport {
|
|||
silent_time_estimator_enabled = (config.gcode_flavor == gcfMarlinLegacy || config.gcode_flavor == gcfMarlinFirmware)
|
||||
&& config.silent_mode;
|
||||
processor.reset();
|
||||
processor.initialize_result_moves();
|
||||
processor.apply_config(config);
|
||||
processor.enable_stealth_time_estimator(silent_time_estimator_enabled);
|
||||
}
|
||||
|
|
@ -2241,9 +2242,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||
m_max_layer_z = 0.f;
|
||||
m_last_width = 0.f;
|
||||
m_is_role_based_fan_on.fill(false);
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
m_last_mm3_per_mm = 0.;
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
|
||||
m_fan_mover.release();
|
||||
|
||||
|
|
@ -6335,14 +6333,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||
gcode += buf;
|
||||
}
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
if (last_was_wipe_tower || (m_last_mm3_per_mm != path.mm3_per_mm)) {
|
||||
m_last_mm3_per_mm = path.mm3_per_mm;
|
||||
sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm);
|
||||
gcode += buf;
|
||||
}
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
|
||||
if (last_was_wipe_tower || std::abs(m_last_height - path.height) > EPSILON) {
|
||||
m_last_height = path.height;
|
||||
sprintf(buf, ";%s%g\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height).c_str(), m_last_height);
|
||||
|
|
|
|||
|
|
@ -572,9 +572,6 @@ private:
|
|||
float m_last_layer_z{ 0.0f };
|
||||
float m_max_layer_z{ 0.0f };
|
||||
float m_last_width{ 0.0f };
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
double m_last_mm3_per_mm;
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
|
||||
// Always check gcode placeholders when building in debug mode.
|
||||
#if !defined(NDEBUG)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -57,21 +57,12 @@ class Print;
|
|||
float time;
|
||||
float prepare_time;
|
||||
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> custom_gcode_times;
|
||||
std::vector<std::pair<EMoveType, float>> moves_times;
|
||||
std::vector<std::pair<ExtrusionRole, float>> roles_times;
|
||||
std::vector<float> layers_times;
|
||||
|
||||
void reset() {
|
||||
time = 0.0f;
|
||||
prepare_time = 0.0f;
|
||||
custom_gcode_times.clear();
|
||||
custom_gcode_times.shrink_to_fit();
|
||||
moves_times.clear();
|
||||
moves_times.shrink_to_fit();
|
||||
roles_times.clear();
|
||||
roles_times.shrink_to_fit();
|
||||
layers_times.clear();
|
||||
layers_times.shrink_to_fit();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -125,7 +116,7 @@ class Print;
|
|||
|
||||
struct GCodeCheckResult
|
||||
{
|
||||
int error_code = 0; // 0 means succeed, 0b 0001 multi extruder printable area error, 0b 0010 multi extruder printable height error,
|
||||
int error_code = 0; // 0 means succeed, 0b 0001 multi extruder printable area error, 0b 0010 multi extruder printable height error,
|
||||
// 0b 0100 plate printable area error, 0b 1000 plate printable height error, 0b 10000 wrapping detection area error
|
||||
std::map<int, std::vector<std::pair<int, int>>> print_area_error_infos; // printable_area extruder_id to <filament_id - object_label_id> which cannot printed in this extruder
|
||||
std::map<int, std::vector<std::pair<int, int>>> print_height_error_infos; // printable_height extruder_id to <filament_id - object_label_id> which cannot printed in this extruder
|
||||
|
|
@ -186,31 +177,23 @@ class Print;
|
|||
Vec3f position{ Vec3f::Zero() }; // mm
|
||||
float delta_extruder{ 0.0f }; // mm
|
||||
float feedrate{ 0.0f }; // mm/s
|
||||
float actual_feedrate{ 0.0f }; // mm/s
|
||||
float width{ 0.0f }; // mm
|
||||
float height{ 0.0f }; // mm
|
||||
float mm3_per_mm{ 0.0f };
|
||||
float travel_dist{ 0.0f }; // mm
|
||||
float fan_speed{ 0.0f }; // percentage
|
||||
float temperature{ 0.0f }; // Celsius degrees
|
||||
float time{ 0.0f }; // s
|
||||
float layer_duration{ 0.0f }; // s (layer id before finalize)
|
||||
std::array<float, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> time{ 0.0f, 0.0f }; // s
|
||||
unsigned int layer_id{ 0 };
|
||||
bool internal_only{ false };
|
||||
|
||||
|
||||
//BBS: arc move related data
|
||||
EMovePathType move_path_type{ EMovePathType::Noop_move };
|
||||
Vec3f arc_center_position{ Vec3f::Zero() }; // mm
|
||||
std::vector<Vec3f> interpolation_points; // interpolation points of arc for drawing
|
||||
//BBS
|
||||
int object_label_id{-1};
|
||||
float print_z{0.0f};
|
||||
|
||||
float volumetric_rate() const { return feedrate * mm3_per_mm; }
|
||||
//BBS: new function to support arc move
|
||||
bool is_arc_move_with_interpolation_points() const {
|
||||
return (move_path_type == EMovePathType::Arc_move_ccw || move_path_type == EMovePathType::Arc_move_cw) && interpolation_points.size();
|
||||
}
|
||||
bool is_arc_move() const {
|
||||
return move_path_type == EMovePathType::Arc_move_ccw || move_path_type == EMovePathType::Arc_move_cw;
|
||||
}
|
||||
float actual_volumetric_rate() const { return actual_feedrate * mm3_per_mm; }
|
||||
};
|
||||
|
||||
struct SliceWarning {
|
||||
|
|
@ -240,6 +223,7 @@ class Print;
|
|||
int timelapse_warning_code {0};
|
||||
bool support_traditional_timelapse{true};
|
||||
float printable_height;
|
||||
float z_offset;
|
||||
SettingsIds settings_ids;
|
||||
size_t filaments_count;
|
||||
bool backtrace_enabled;
|
||||
|
|
@ -253,7 +237,7 @@ class Print;
|
|||
std::vector<int> limit_filament_maps;
|
||||
PrintEstimatedStatistics print_statistics;
|
||||
std::vector<CustomGCode::Item> custom_gcode_per_print_z;
|
||||
std::vector<std::pair<float, std::pair<size_t, size_t>>> spiral_vase_layers;
|
||||
bool spiral_vase_mode;
|
||||
//BBS
|
||||
std::vector<SliceWarning> warnings;
|
||||
int nozzle_hrc;
|
||||
|
|
@ -264,9 +248,6 @@ class Print;
|
|||
std::map<std::pair<int,int>, int > filament_change_count_map;
|
||||
|
||||
BedType bed_type = BedType::btCount;
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
int64_t time{ 0 };
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
void reset();
|
||||
|
||||
//BBS: add mutex for protection of gcode result
|
||||
|
|
@ -293,7 +274,7 @@ class Print;
|
|||
filament_costs = other.filament_costs;
|
||||
print_statistics = other.print_statistics;
|
||||
custom_gcode_per_print_z = other.custom_gcode_per_print_z;
|
||||
spiral_vase_layers = other.spiral_vase_layers;
|
||||
spiral_vase_mode = other.spiral_vase_mode;
|
||||
warnings = other.warnings;
|
||||
bed_type = other.bed_type;
|
||||
gcode_check_result = other.gcode_check_result;
|
||||
|
|
@ -378,10 +359,6 @@ class Print;
|
|||
|
||||
static bool s_IsBBLPrinter;
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
static const std::string Mm3_Per_Mm_Tag;
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
|
||||
private:
|
||||
using AxisCoords = std::array<double, 4>;
|
||||
using ExtruderColors = std::vector<unsigned char>;
|
||||
|
|
@ -430,9 +407,12 @@ class Print;
|
|||
float cruise_feedrate{ 0.0f }; // mm/sec
|
||||
|
||||
float acceleration_time(float entry_feedrate, float acceleration) const;
|
||||
float cruise_time() const;
|
||||
float cruise_time() const { return (cruise_feedrate != 0.0f) ? cruise_distance() / cruise_feedrate : 0.0f; }
|
||||
float deceleration_time(float distance, float acceleration) const;
|
||||
float cruise_distance() const;
|
||||
float acceleration_distance() const { return accelerate_until; }
|
||||
float cruise_distance() const { return decelerate_after - accelerate_until; }
|
||||
float deceleration_distance(float distance) const { return distance - decelerate_after; }
|
||||
bool is_cruise_only(float distance) const { return std::abs(cruise_distance() - distance) < EPSILON; }
|
||||
};
|
||||
|
||||
struct TimeBlock
|
||||
|
|
@ -446,6 +426,7 @@ class Print;
|
|||
|
||||
EMoveType move_type{ EMoveType::Noop };
|
||||
ExtrusionRole role{ erNone };
|
||||
unsigned int move_id{ 0 };
|
||||
unsigned int g1_line_id{ 0 };
|
||||
unsigned int remaining_internal_g1_lines{ 0 };
|
||||
unsigned int layer_id{ 0 };
|
||||
|
|
@ -460,7 +441,10 @@ class Print;
|
|||
// Calculates this block's trapezoid
|
||||
void calculate_trapezoid();
|
||||
|
||||
float time() const;
|
||||
float time() const {
|
||||
return trapezoid.acceleration_time(feedrate_profile.entry, acceleration) +
|
||||
trapezoid.cruise_time() + trapezoid.deceleration_time(distance, acceleration);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -477,7 +461,7 @@ class Print;
|
|||
AxisCoords axis_feedrate; // mm/s
|
||||
AxisCoords abs_axis_feedrate; // mm/s
|
||||
|
||||
//BBS: unit vector of enter speed and exit speed in x-y-z space.
|
||||
//BBS: unit vector of enter speed and exit speed in x-y-z space.
|
||||
//For line move, there are same. For arc move, there are different.
|
||||
Vec3f enter_direction;
|
||||
Vec3f exit_direction;
|
||||
|
|
@ -501,6 +485,20 @@ class Print;
|
|||
float elapsed_time;
|
||||
};
|
||||
|
||||
struct ActualSpeedMove
|
||||
{
|
||||
unsigned int move_id{ 0 };
|
||||
std::optional<Vec3f> position;
|
||||
float actual_feedrate{ 0.0f };
|
||||
std::optional<float> delta_extruder;
|
||||
std::optional<float> feedrate;
|
||||
std::optional<float> width;
|
||||
std::optional<float> height;
|
||||
std::optional<float> mm3_per_mm;
|
||||
std::optional<float> fan_speed;
|
||||
std::optional<float> temperature;
|
||||
};
|
||||
|
||||
bool enabled;
|
||||
float acceleration; // mm/s^2
|
||||
// hard limit for the acceleration, to which the firmware will clamp.
|
||||
|
|
@ -512,7 +510,9 @@ class Print;
|
|||
// hard limit for the travel acceleration, to which the firmware will clamp.
|
||||
float max_travel_acceleration; // mm/s^2
|
||||
float extrude_factor_override_percentage;
|
||||
float time; // s
|
||||
// We accumulate total print time in doubles to reduce the loss of precision
|
||||
// while adding big floating numbers with small float numbers.
|
||||
double time; // s
|
||||
struct StopTime
|
||||
{
|
||||
unsigned int g1_line_id;
|
||||
|
|
@ -526,17 +526,14 @@ class Print;
|
|||
CustomGCodeTime gcode_time;
|
||||
std::vector<TimeBlock> blocks;
|
||||
std::vector<G1LinesCacheItem> g1_times_cache;
|
||||
std::array<float, static_cast<size_t>(EMoveType::Count)> moves_time;
|
||||
std::array<float, static_cast<size_t>(ExtrusionRole::erCount)> roles_time;
|
||||
std::vector<float> layers_time;
|
||||
float first_layer_time;
|
||||
std::vector<ActualSpeedMove> actual_speed_moves;
|
||||
//BBS: prepare stage time before print model, including start gcode time and mostly same with start gcode time
|
||||
float prepare_time;
|
||||
|
||||
void reset();
|
||||
|
||||
// Simulates firmware st_synchronize() call
|
||||
void simulate_st_synchronize(float additional_time = 0.0f);
|
||||
void calculate_time(size_t keep_last_n_blocks = 0, float additional_time = 0.0f);
|
||||
void calculate_time(GCodeProcessorResult& result, PrintEstimatedStatistics::ETimeMode mode, size_t keep_last_n_blocks = 0, float additional_time = 0.0f);
|
||||
};
|
||||
|
||||
struct UsedFilaments // filaments per ColorChange
|
||||
|
|
@ -765,10 +762,6 @@ class Print;
|
|||
//BBS: x, y offset for gcode generated
|
||||
double m_x_offset{ 0 };
|
||||
double m_y_offset{ 0 };
|
||||
//BBS: arc move related data
|
||||
EMovePathType m_move_path_type{ EMovePathType::Noop_move };
|
||||
Vec3f m_arc_center{ Vec3f::Zero() }; // mm
|
||||
std::vector<Vec3f> m_interpolation_points;
|
||||
|
||||
unsigned int m_line_id;
|
||||
unsigned int m_last_line_id;
|
||||
|
|
@ -807,9 +800,6 @@ class Print;
|
|||
float m_preheat_time;
|
||||
int m_preheat_steps;
|
||||
bool m_disable_m73;
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> m_start_time;
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
||||
enum class EProducer
|
||||
{
|
||||
|
|
@ -836,12 +826,6 @@ class Print;
|
|||
GCodeProcessorResult m_result;
|
||||
static unsigned int s_result_id;
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
DataChecker m_mm3_per_mm_compare{ "mm3_per_mm", 0.01f };
|
||||
DataChecker m_height_compare{ "height", 0.01f };
|
||||
DataChecker m_width_compare{ "width", 0.01f };
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
|
||||
public:
|
||||
GCodeProcessor();
|
||||
void init_filament_maps_and_nozzle_type_when_import_only_gcode();
|
||||
|
|
@ -876,6 +860,11 @@ class Print;
|
|||
|
||||
// Streaming interface, for processing G-codes just generated by PrusaSlicer in a pipelined fashion.
|
||||
void initialize(const std::string& filename);
|
||||
void initialize_result_moves() {
|
||||
// 1st move must be a dummy move
|
||||
assert(m_result.moves.empty());
|
||||
m_result.moves.emplace_back(GCodeProcessorResult::MoveVertex());
|
||||
}
|
||||
void process_buffer(const std::string& buffer);
|
||||
void finalize(bool post_process);
|
||||
|
||||
|
|
@ -884,9 +873,7 @@ class Print;
|
|||
std::string get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const;
|
||||
|
||||
std::vector<std::pair<EMoveType, float>> get_moves_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||
std::vector<std::pair<ExtrusionRole, float>> get_roles_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||
std::vector<float> get_layers_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||
float get_first_layer_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||
|
||||
//BBS: set offset for gcode writer
|
||||
void set_xy_offset(double x, double y) { m_x_offset = x; m_y_offset = y; }
|
||||
|
|
@ -917,7 +904,16 @@ class Print;
|
|||
// Move
|
||||
void process_G0(const GCodeReader::GCodeLine& line);
|
||||
void process_G1(const GCodeReader::GCodeLine& line, const std::optional<unsigned int>& remaining_internal_g1_lines = std::nullopt);
|
||||
void process_G2_G3(const GCodeReader::GCodeLine& line);
|
||||
enum class G1DiscretizationOrigin {
|
||||
G1,
|
||||
G2G3,
|
||||
};
|
||||
void process_G1(const std::array<std::optional<double>, 4>& axes = { std::nullopt, std::nullopt, std::nullopt, std::nullopt },
|
||||
const std::optional<double>& feedrate = std::nullopt, G1DiscretizationOrigin origin = G1DiscretizationOrigin::G1,
|
||||
const std::optional<unsigned int>& remaining_internal_g1_lines = std::nullopt);
|
||||
|
||||
// Arc Move
|
||||
void process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise);
|
||||
|
||||
void process_VG1(const GCodeReader::GCodeLine& line);
|
||||
|
||||
|
|
@ -1054,7 +1050,7 @@ class Print;
|
|||
void run_post_process();
|
||||
|
||||
//BBS: different path_type is only used for arc move
|
||||
void store_move_vertex(EMoveType type, EMovePathType path_type = EMovePathType::Noop_move);
|
||||
void store_move_vertex(EMoveType type, EMovePathType path_type = EMovePathType::Noop_move, bool internal_only = false);
|
||||
|
||||
void set_extrusion_role(ExtrusionRole role);
|
||||
|
||||
|
|
@ -1077,10 +1073,15 @@ class Print;
|
|||
void process_custom_gcode_time(CustomGCode::Type code);
|
||||
void process_filaments(CustomGCode::Type code);
|
||||
|
||||
void calculate_time(GCodeProcessorResult& result, size_t keep_last_n_blocks = 0, float additional_time = 0.0f);
|
||||
|
||||
// Simulates firmware st_synchronize() call
|
||||
void simulate_st_synchronize(float additional_time = 0.0f);
|
||||
|
||||
void update_estimated_times_stats();
|
||||
|
||||
double extract_absolute_position_on_axis(Axis axis, const GCodeReader::GCodeLine& line, double area_filament_cross_section);
|
||||
|
||||
//BBS:
|
||||
void update_slice_warnings();
|
||||
|
||||
|
|
|
|||
|
|
@ -528,12 +528,9 @@ public:
|
|||
m_extrusion_flow(0.f),
|
||||
m_preview_suppressed(false),
|
||||
m_elapsed_time(0.f),
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
m_default_analyzer_line_width(line_width),
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
m_gcode_flavor(flavor),
|
||||
m_filpar(filament_parameters)
|
||||
{
|
||||
m_gcode_flavor(flavor),
|
||||
m_filpar(filament_parameters)
|
||||
{
|
||||
// ORCA: This class is only used by BBL printers, so set the parameter appropriately.
|
||||
// This fixes an issue where the wipe tower was using BBL tags resulting in statistics for purging in the purge tower not being displayed.
|
||||
GCodeProcessor::s_IsBBLPrinter = true;
|
||||
|
|
@ -553,18 +550,6 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) {
|
||||
static const float area = float(M_PI) * 1.75f * 1.75f / 4.f;
|
||||
float mm3_per_mm = (len == 0.f ? 0.f : area * e / len);
|
||||
// adds tag for processor:
|
||||
std::stringstream str;
|
||||
str << ";" << GCodeProcessor::Mm3_Per_Mm_Tag << mm3_per_mm << "\n";
|
||||
m_gcode += str.str();
|
||||
return *this;
|
||||
}
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
|
||||
WipeTowerWriter& set_initial_position(const Vec2f &pos, float width = 0.f, float depth = 0.f, float internal_angle = 0.f) {
|
||||
m_wipe_tower_width = width;
|
||||
m_wipe_tower_depth = depth;
|
||||
|
|
@ -602,13 +587,8 @@ public:
|
|||
// Suppress / resume G-code preview in Slic3r. Slic3r will have difficulty to differentiate the various
|
||||
// filament loading and cooling moves from normal extrusion moves. Therefore the writer
|
||||
// is asked to suppres output of some lines, which look like extrusions.
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
WipeTowerWriter& suppress_preview() { change_analyzer_line_width(0.f); m_preview_suppressed = true; return *this; }
|
||||
WipeTowerWriter& resume_preview() { change_analyzer_line_width(m_default_analyzer_line_width); m_preview_suppressed = false; return *this; }
|
||||
#else
|
||||
WipeTowerWriter& suppress_preview() { m_preview_suppressed = true; return *this; }
|
||||
WipeTowerWriter& resume_preview() { m_preview_suppressed = false; return *this; }
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
WipeTowerWriter& resume_preview() { m_preview_suppressed = false; return *this; }
|
||||
|
||||
WipeTowerWriter& feedrate(float f)
|
||||
{
|
||||
|
|
@ -647,12 +627,9 @@ public:
|
|||
Vec2f rot(this->rotate(Vec2f(x,y))); // this is where we want to go
|
||||
|
||||
if (! m_preview_suppressed && e > 0.f && len > 0.f) {
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
change_analyzer_mm3_per_mm(len, e);
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
// Width of a squished extrusion, corrected for the roundings of the squished extrusions.
|
||||
// Width of a squished extrusion, corrected for the roundings of the squished extrusions.
|
||||
// This is left zero if it is a travel move.
|
||||
float width = e * m_filpar[0].filament_area / (len * m_layer_height);
|
||||
float width = e * m_filpar[0].filament_area / (len * m_layer_height);
|
||||
// Correct for the roundings of a squished extrusion.
|
||||
width += m_layer_height * float(1. - M_PI / 4.);
|
||||
if (m_extrusions.empty() || m_extrusions.back().pos != rotated_current_pos)
|
||||
|
|
@ -1212,9 +1189,6 @@ private:
|
|||
float m_wipe_tower_depth = 0.f;
|
||||
unsigned m_last_fan_speed = 0;
|
||||
int current_temp = -1;
|
||||
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
const float m_default_analyzer_line_width;
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
float m_used_filament_length = 0.f;
|
||||
GCodeFlavor m_gcode_flavor;
|
||||
const std::vector<WipeTower::FilamentParameters>& m_filpar;
|
||||
|
|
|
|||
|
|
@ -222,6 +222,28 @@ bool GCodeReader::parse_file_raw(const std::string &filename, raw_line_callback_
|
|||
[](size_t){});
|
||||
}
|
||||
|
||||
const char* GCodeReader::axis_pos(const char *raw_str, char axis)
|
||||
{
|
||||
const char *c = raw_str;
|
||||
// Skip the whitespaces.
|
||||
c = skip_whitespaces(c);
|
||||
// Skip the command.
|
||||
c = skip_word(c);
|
||||
// Up to the end of line or comment.
|
||||
while (! is_end_of_gcode_line(*c)) {
|
||||
// Skip whitespaces.
|
||||
c = skip_whitespaces(c);
|
||||
if (is_end_of_gcode_line(*c))
|
||||
break;
|
||||
// Check the name of the axis.
|
||||
if (*c == axis)
|
||||
return c;
|
||||
// Skip the rest of the word.
|
||||
c = skip_word(c);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool GCodeReader::GCodeLine::has(char axis) const
|
||||
{
|
||||
const char *c = m_raw.c_str();
|
||||
|
|
@ -244,6 +266,29 @@ bool GCodeReader::GCodeLine::has(char axis) const
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string_view GCodeReader::GCodeLine::axis_pos(char axis) const
|
||||
{
|
||||
const std::string &s = this->raw();
|
||||
const char *c = GCodeReader::axis_pos(this->raw().c_str(), axis);
|
||||
return c ? std::string_view{ c, s.size() - (c - s.data()) } : std::string_view();
|
||||
}
|
||||
|
||||
bool GCodeReader::GCodeLine::has_value(std::string_view axis_pos, float &value)
|
||||
{
|
||||
if (const char *c = axis_pos.data(); c) {
|
||||
// Try to parse the numeric value.
|
||||
double v = 0.;
|
||||
const char *end = axis_pos.data() + axis_pos.size();
|
||||
auto [pend, ec] = fast_float::from_chars(++ c, end, v);
|
||||
if (pend != c && is_end_of_word(*pend)) {
|
||||
// The axis value has been parsed correctly.
|
||||
value = float(v);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GCodeReader::GCodeLine::has_value(char axis, float &value) const
|
||||
{
|
||||
assert(is_decimal_separator_point());
|
||||
|
|
|
|||
|
|
@ -26,11 +26,15 @@ public:
|
|||
const std::string_view comment() const
|
||||
{ size_t pos = m_raw.find(';'); return (pos == std::string::npos) ? std::string_view() : std::string_view(m_raw).substr(pos + 1); }
|
||||
|
||||
// Return position in this->raw() string starting with the "axis" character.
|
||||
std::string_view axis_pos(char axis) const;
|
||||
void clear() { m_raw.clear(); }
|
||||
bool has(Axis axis) const { return (m_mask & (1 << int(axis))) != 0; }
|
||||
float value(Axis axis) const { return m_axis[axis]; }
|
||||
bool has(char axis) const;
|
||||
bool has_value(char axis, float &value) const;
|
||||
// Parse value of an axis from raw string starting at axis_pos.
|
||||
static bool has_value(std::string_view axis_pos, float &value);
|
||||
float new_X(const GCodeReader &reader) const { return this->has(X) ? this->x() : reader.x(); }
|
||||
float new_Y(const GCodeReader &reader) const { return this->has(Y) ? this->y() : reader.y(); }
|
||||
float new_Z(const GCodeReader &reader) const { return this->has(Z) ? this->z() : reader.z(); }
|
||||
|
|
@ -190,6 +194,7 @@ private:
|
|||
; // silence -Wempty-body
|
||||
return c;
|
||||
}
|
||||
static const char* axis_pos(const char *raw_str, char axis);
|
||||
|
||||
GCodeConfig m_config;
|
||||
float m_position[NUM_AXES];
|
||||
|
|
|
|||
32
src/libslic3r/Geometry/ArcWelder.cpp
Normal file
32
src/libslic3r/Geometry/ArcWelder.cpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// The following code for merging circles into arches originates from https://github.com/FormerLurker/ArcWelderLib
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Arc Welder: Anti-Stutter Library
|
||||
//
|
||||
// Compresses many G0/G1 commands into G2/G3(arc) commands where possible, ensuring the tool paths stay within the specified resolution.
|
||||
// This reduces file size and the number of gcodes per second.
|
||||
//
|
||||
// Uses the 'Gcode Processor Library' for gcode parsing, position processing, logging, and other various functionality.
|
||||
//
|
||||
// Copyright(C) 2021 - Brad Hochgesang
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This program is free software : you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
//
|
||||
// You can contact the author at the following email address:
|
||||
// FormerLurker@pm.me
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "ArcWelder.hpp"
|
||||
|
||||
namespace Slic3r { namespace Geometry { namespace ArcWelder {
|
||||
|
||||
} } } // namespace Slic3r::Geometry::ArcWelder
|
||||
71
src/libslic3r/Geometry/ArcWelder.hpp
Normal file
71
src/libslic3r/Geometry/ArcWelder.hpp
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef slic3r_Geometry_ArcWelder_hpp_
|
||||
#define slic3r_Geometry_ArcWelder_hpp_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <Eigen/Geometry>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
|
||||
namespace Slic3r { namespace Geometry { namespace ArcWelder {
|
||||
|
||||
// Calculate center point (center of a circle) of an arc given two points and a radius.
|
||||
// positive radius: take shorter arc
|
||||
// negative radius: take longer arc
|
||||
// radius must NOT be zero!
|
||||
template<typename Derived, typename Derived2, typename Float>
|
||||
inline Eigen::Matrix<Float, 2, 1, Eigen::DontAlign> arc_center(
|
||||
const Eigen::MatrixBase<Derived> &start_pos,
|
||||
const Eigen::MatrixBase<Derived2> &end_pos,
|
||||
const Float radius,
|
||||
const bool is_ccw)
|
||||
{
|
||||
static_assert(Derived::IsVectorAtCompileTime && int(Derived::SizeAtCompileTime) == 2, "arc_center(): first parameter is not a 2D vector");
|
||||
static_assert(Derived2::IsVectorAtCompileTime && int(Derived2::SizeAtCompileTime) == 2, "arc_center(): second parameter is not a 2D vector");
|
||||
static_assert(std::is_same<typename Derived::Scalar, typename Derived2::Scalar>::value, "arc_center(): Both vectors must be of the same type.");
|
||||
static_assert(std::is_same<typename Derived::Scalar, Float>::value, "arc_center(): Radius must be of the same type as the vectors.");
|
||||
assert(radius != 0);
|
||||
using Vector = Eigen::Matrix<Float, 2, 1, Eigen::DontAlign>;
|
||||
auto v = end_pos - start_pos;
|
||||
Float q2 = v.squaredNorm();
|
||||
assert(q2 > 0);
|
||||
Float t2 = sqr(radius) / q2 - Float(.25f);
|
||||
// If the start_pos and end_pos are nearly antipodal, t2 may become slightly negative.
|
||||
// In that case return a centroid of start_point & end_point.
|
||||
Float t = t2 > 0 ? sqrt(t2) : Float(0);
|
||||
auto mid = Float(0.5) * (start_pos + end_pos);
|
||||
Vector vp{ -v.y() * t, v.x() * t };
|
||||
return (radius > Float(0)) == is_ccw ? (mid + vp).eval() : (mid - vp).eval();
|
||||
}
|
||||
|
||||
|
||||
// Return number of linear segments necessary to interpolate arc of a given positive radius and positive angle to satisfy
|
||||
// maximum deviation of an interpolating polyline from an analytic arc.
|
||||
template<typename FloatType>
|
||||
size_t arc_discretization_steps(const FloatType radius, const FloatType angle, const FloatType deviation)
|
||||
{
|
||||
assert(radius > 0);
|
||||
assert(angle > 0);
|
||||
assert(angle <= FloatType(2. * M_PI));
|
||||
assert(deviation > 0);
|
||||
|
||||
FloatType d = radius - deviation;
|
||||
return d < EPSILON ?
|
||||
// Radius smaller than deviation.
|
||||
( // Acute angle: a single segment interpolates the arc with sufficient accuracy.
|
||||
angle < M_PI ||
|
||||
// Obtuse angle: Test whether the furthest point (center) of an arc is closer than deviation to the center of a line segment.
|
||||
radius * (FloatType(1.) + cos(M_PI - FloatType(.5) * angle)) < deviation ?
|
||||
// Single segment is sufficient
|
||||
1 :
|
||||
// Two segments are necessary, the middle point is at the center of the arc.
|
||||
2) :
|
||||
size_t(ceil(angle / (2. * acos(d / radius))));
|
||||
}
|
||||
|
||||
} } } // namespace Slic3r::Geometry::ArcWelder
|
||||
|
||||
#endif // slic3r_Geometry_ArcWelder_hpp_
|
||||
|
|
@ -18,10 +18,6 @@
|
|||
#define DISABLE_INSTANCES_SYNCH 0
|
||||
// Use wxDataViewRender instead of wxDataViewCustomRenderer
|
||||
#define ENABLE_NONCUSTOM_DATA_VIEW_RENDERING 0
|
||||
// Enable G-Code viewer statistics imgui dialog
|
||||
#define ENABLE_GCODE_VIEWER_STATISTICS 0
|
||||
// Enable G-Code viewer comparison between toolpaths height and width detected from gcode and calculated at gcode generation
|
||||
#define ENABLE_GCODE_VIEWER_DATA_CHECKING 0
|
||||
// Enable project dirty state manager debug window
|
||||
#define ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW 0
|
||||
|
||||
|
|
@ -39,28 +35,21 @@
|
|||
// Enable rework of Reload from disk command
|
||||
#define ENABLE_RELOAD_FROM_DISK_REWORK 1
|
||||
|
||||
//====================
|
||||
// 2.4.0.beta1 techs
|
||||
//====================
|
||||
#define ENABLE_2_4_0_BETA1 1
|
||||
|
||||
// Enable rendering modifiers and similar objects always as transparent
|
||||
#define ENABLE_MODIFIERS_ALWAYS_TRANSPARENT (1 && ENABLE_2_4_0_BETA1)
|
||||
|
||||
|
||||
//====================
|
||||
// 2.4.0.beta2 techs
|
||||
//====================
|
||||
#define ENABLE_2_4_0_BETA2 1
|
||||
#define ENABLE_MODIFIERS_ALWAYS_TRANSPARENT 1
|
||||
|
||||
// Enable modified ImGuiWrapper::slider_float() to create a compound widget where
|
||||
// an additional button can be used to set the keyboard focus into the slider
|
||||
// to allow the user to type in the desired value
|
||||
#define ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT (1 && ENABLE_2_4_0_BETA2)
|
||||
#define ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT 1
|
||||
// Enable fit print volume command for circular printbeds
|
||||
#define ENABLE_ENHANCED_PRINT_VOLUME_FIT (1 && ENABLE_2_4_0_BETA2)
|
||||
#define ENABLE_ENHANCED_PRINT_VOLUME_FIT 1
|
||||
// Enable picking using raytracing
|
||||
#define ENABLE_RAYCAST_PICKING_DEBUG 0
|
||||
|
||||
// Enable imgui debug dialog for new gcode viewer (using libvgcode)
|
||||
#define ENABLE_NEW_GCODE_VIEWER_DEBUG 0
|
||||
// Enable extension of tool position imgui dialog to show actual speed profile
|
||||
#define ENABLE_ACTUAL_SPEED_DEBUG 1
|
||||
|
||||
#endif // _prusaslicer_technologies_h_
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ extern unsigned get_logging_level();
|
|||
extern void trace(unsigned int level, const char *message);
|
||||
// Format memory allocated, separate thousands by comma.
|
||||
extern std::string format_memsize_MB(size_t n);
|
||||
extern std::string format_memsize(size_t bytes, unsigned int decimals = 1);
|
||||
// Return string to be added to the boost::log output to inform about the current process memory allocation.
|
||||
// The string is non-empty if the loglevel >= info (3) or ignore_loglevel==true.
|
||||
// Latter is used to get the memory info from SysInfoDialog.
|
||||
|
|
|
|||
|
|
@ -1378,6 +1378,42 @@ std::string format_memsize_MB(size_t n)
|
|||
return out + "MB";
|
||||
}
|
||||
|
||||
std::string format_memsize(size_t bytes, unsigned int decimals)
|
||||
{
|
||||
static constexpr const float kb = 1024.0f;
|
||||
static constexpr const float mb = 1024.0f * kb;
|
||||
static constexpr const float gb = 1024.0f * mb;
|
||||
static constexpr const float tb = 1024.0f * gb;
|
||||
|
||||
const float f_bytes = static_cast<float>(bytes);
|
||||
if (f_bytes < kb)
|
||||
return std::to_string(bytes) + " bytes";
|
||||
else if (f_bytes < mb) {
|
||||
const float f_kb = f_bytes / kb;
|
||||
char buf[64];
|
||||
sprintf(buf, "%.*f", decimals, f_kb);
|
||||
return std::to_string(bytes) + " bytes (" + std::string(buf) + "KB)";
|
||||
}
|
||||
else if (f_bytes < gb) {
|
||||
const float f_mb = f_bytes / mb;
|
||||
char buf[64];
|
||||
sprintf(buf, "%.*f", decimals, f_mb);
|
||||
return std::to_string(bytes) + " bytes (" + std::string(buf) + "MB)";
|
||||
}
|
||||
else if (f_bytes < tb) {
|
||||
const float f_gb = f_bytes / gb;
|
||||
char buf[64];
|
||||
sprintf(buf, "%.*f", decimals, f_gb);
|
||||
return std::to_string(bytes) + " bytes (" + std::string(buf) + "GB)";
|
||||
}
|
||||
else {
|
||||
const float f_tb = f_bytes / tb;
|
||||
char buf[64];
|
||||
sprintf(buf, "%.*f", decimals, f_tb);
|
||||
return std::to_string(bytes) + " bytes (" + std::string(buf) + "TB)";
|
||||
}
|
||||
}
|
||||
|
||||
// Returns platform-specific string to be used as log output or parsed in SysInfoDialog.
|
||||
// The latter parses the string with (semi)colons as separators, it should look about as
|
||||
// "desc1: value1; desc2: value2" or similar (spaces should not matter).
|
||||
|
|
|
|||
80
src/libvgcode/CMakeLists.txt
Normal file
80
src/libvgcode/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
cmake_minimum_required(VERSION 3.13)
|
||||
project(libvgcode)
|
||||
|
||||
# glad library
|
||||
if (EMSCRIPTEN OR SLIC3R_OPENGL_ES)
|
||||
set(GLAD_SOURCES
|
||||
glad/include/glad/gles2.h
|
||||
glad/include/KHR/khrplatform.h
|
||||
glad/src/gles2.c
|
||||
)
|
||||
else ()
|
||||
set(GLAD_SOURCES
|
||||
glad/include/glad/gl.h
|
||||
glad/include/KHR/khrplatform.h
|
||||
glad/src/gl.c
|
||||
)
|
||||
endif ()
|
||||
|
||||
set(LIBVGCODE_SOURCES
|
||||
# API
|
||||
include/ColorPrint.hpp
|
||||
include/ColorRange.hpp
|
||||
include/GCodeInputData.hpp
|
||||
include/PathVertex.hpp
|
||||
include/Types.hpp
|
||||
include/Viewer.hpp
|
||||
# source
|
||||
src/Bitset.hpp
|
||||
src/Bitset.cpp
|
||||
src/CogMarker.hpp
|
||||
src/CogMarker.cpp
|
||||
src/ColorPrint.cpp
|
||||
src/ColorRange.cpp
|
||||
src/ExtrusionRoles.hpp
|
||||
src/ExtrusionRoles.cpp
|
||||
src/GCodeInputData.cpp
|
||||
src/Layers.hpp
|
||||
src/Layers.cpp
|
||||
src/OpenGLUtils.hpp
|
||||
src/OpenGLUtils.cpp
|
||||
src/OptionTemplate.hpp
|
||||
src/OptionTemplate.cpp
|
||||
src/PathVertex.cpp
|
||||
src/Range.hpp
|
||||
src/Range.cpp
|
||||
src/SegmentTemplate.hpp
|
||||
src/SegmentTemplate.cpp
|
||||
src/Settings.hpp
|
||||
src/Settings.cpp
|
||||
src/Shaders.hpp
|
||||
src/ShadersES.hpp
|
||||
src/ToolMarker.hpp
|
||||
src/ToolMarker.cpp
|
||||
src/Types.cpp
|
||||
src/Utils.hpp
|
||||
src/Utils.cpp
|
||||
src/Viewer.cpp
|
||||
src/ViewerImpl.hpp
|
||||
src/ViewerImpl.cpp
|
||||
src/ViewRange.hpp
|
||||
src/ViewRange.cpp
|
||||
${GLAD_SOURCES}
|
||||
)
|
||||
|
||||
add_library(libvgcode STATIC ${LIBVGCODE_SOURCES})
|
||||
|
||||
if (EMSCRIPTEN OR SLIC3R_OPENGL_ES)
|
||||
add_compile_definitions(ENABLE_OPENGL_ES)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
foreach(_source IN ITEMS ${LIBVGCODE_SOURCES})
|
||||
get_filename_component(_source_path "${_source}" PATH)
|
||||
string(REPLACE "/" "\\" _group_path "${_source_path}")
|
||||
source_group("${_group_path}" FILES "${_source}")
|
||||
endforeach()
|
||||
endif ()
|
||||
|
||||
# glad includes
|
||||
include_directories(glad/include)
|
||||
311
src/libvgcode/glad/include/KHR/khrplatform.h
Normal file
311
src/libvgcode/glad/include/KHR/khrplatform.h
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID:
|
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by filing pull requests or issues on
|
||||
* the EGL Registry repository linked above.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
# define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
# define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
/*
|
||||
* To support platform where unsigned long cannot be used interchangeably with
|
||||
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||
* unsigned long long or similar (this results in different C++ name mangling).
|
||||
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||
* platforms where the size of a pointer is larger than the size of long.
|
||||
*/
|
||||
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||
#define KHRONOS_USE_INTPTR_T
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef KHRONOS_USE_INTPTR_T
|
||||
typedef intptr_t khronos_intptr_t;
|
||||
typedef uintptr_t khronos_uintptr_t;
|
||||
#elif defined(_WIN64)
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
||||
3644
src/libvgcode/glad/include/glad/gl.h
Normal file
3644
src/libvgcode/glad/include/glad/gl.h
Normal file
File diff suppressed because it is too large
Load diff
1637
src/libvgcode/glad/include/glad/gles2.h
Normal file
1637
src/libvgcode/glad/include/glad/gles2.h
Normal file
File diff suppressed because it is too large
Load diff
1786
src/libvgcode/glad/src/gl.c
Normal file
1786
src/libvgcode/glad/src/gl.c
Normal file
File diff suppressed because it is too large
Load diff
877
src/libvgcode/glad/src/gles2.c
Normal file
877
src/libvgcode/glad/src/gles2.c
Normal file
|
|
@ -0,0 +1,877 @@
|
|||
/**
|
||||
* SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <glad/gles2.h>
|
||||
|
||||
#ifndef GLAD_IMPL_UTIL_C_
|
||||
#define GLAD_IMPL_UTIL_C_
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define GLAD_IMPL_UTIL_SSCANF sscanf_s
|
||||
#else
|
||||
#define GLAD_IMPL_UTIL_SSCANF sscanf
|
||||
#endif
|
||||
|
||||
#endif /* GLAD_IMPL_UTIL_C_ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int GLAD_GL_ES_VERSION_2_0 = 0;
|
||||
int GLAD_GL_ES_VERSION_3_0 = 0;
|
||||
|
||||
|
||||
|
||||
PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL;
|
||||
PFNGLATTACHSHADERPROC glad_glAttachShader = NULL;
|
||||
PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL;
|
||||
PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL;
|
||||
PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL;
|
||||
PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL;
|
||||
PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL;
|
||||
PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL;
|
||||
PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL;
|
||||
PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL;
|
||||
PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL;
|
||||
PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL;
|
||||
PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL;
|
||||
PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL;
|
||||
PFNGLBLENDCOLORPROC glad_glBlendColor = NULL;
|
||||
PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL;
|
||||
PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL;
|
||||
PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL;
|
||||
PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL;
|
||||
PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL;
|
||||
PFNGLBUFFERDATAPROC glad_glBufferData = NULL;
|
||||
PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL;
|
||||
PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL;
|
||||
PFNGLCLEARPROC glad_glClear = NULL;
|
||||
PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL;
|
||||
PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL;
|
||||
PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL;
|
||||
PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL;
|
||||
PFNGLCLEARCOLORPROC glad_glClearColor = NULL;
|
||||
PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL;
|
||||
PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL;
|
||||
PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL;
|
||||
PFNGLCOLORMASKPROC glad_glColorMask = NULL;
|
||||
PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL;
|
||||
PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL;
|
||||
PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL;
|
||||
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL;
|
||||
PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL;
|
||||
PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL;
|
||||
PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL;
|
||||
PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL;
|
||||
PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL;
|
||||
PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL;
|
||||
PFNGLCREATESHADERPROC glad_glCreateShader = NULL;
|
||||
PFNGLCULLFACEPROC glad_glCullFace = NULL;
|
||||
PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL;
|
||||
PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL;
|
||||
PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL;
|
||||
PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL;
|
||||
PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL;
|
||||
PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL;
|
||||
PFNGLDELETESHADERPROC glad_glDeleteShader = NULL;
|
||||
PFNGLDELETESYNCPROC glad_glDeleteSync = NULL;
|
||||
PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL;
|
||||
PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL;
|
||||
PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL;
|
||||
PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL;
|
||||
PFNGLDEPTHMASKPROC glad_glDepthMask = NULL;
|
||||
PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL;
|
||||
PFNGLDETACHSHADERPROC glad_glDetachShader = NULL;
|
||||
PFNGLDISABLEPROC glad_glDisable = NULL;
|
||||
PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL;
|
||||
PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL;
|
||||
PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL;
|
||||
PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL;
|
||||
PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL;
|
||||
PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL;
|
||||
PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL;
|
||||
PFNGLENABLEPROC glad_glEnable = NULL;
|
||||
PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL;
|
||||
PFNGLENDQUERYPROC glad_glEndQuery = NULL;
|
||||
PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL;
|
||||
PFNGLFENCESYNCPROC glad_glFenceSync = NULL;
|
||||
PFNGLFINISHPROC glad_glFinish = NULL;
|
||||
PFNGLFLUSHPROC glad_glFlush = NULL;
|
||||
PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL;
|
||||
PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL;
|
||||
PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL;
|
||||
PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL;
|
||||
PFNGLFRONTFACEPROC glad_glFrontFace = NULL;
|
||||
PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL;
|
||||
PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL;
|
||||
PFNGLGENQUERIESPROC glad_glGenQueries = NULL;
|
||||
PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL;
|
||||
PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL;
|
||||
PFNGLGENTEXTURESPROC glad_glGenTextures = NULL;
|
||||
PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL;
|
||||
PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL;
|
||||
PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL;
|
||||
PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL;
|
||||
PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL;
|
||||
PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL;
|
||||
PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL;
|
||||
PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL;
|
||||
PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL;
|
||||
PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL;
|
||||
PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL;
|
||||
PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL;
|
||||
PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL;
|
||||
PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL;
|
||||
PFNGLGETERRORPROC glad_glGetError = NULL;
|
||||
PFNGLGETFLOATVPROC glad_glGetFloatv = NULL;
|
||||
PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL;
|
||||
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL;
|
||||
PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL;
|
||||
PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL;
|
||||
PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL;
|
||||
PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL;
|
||||
PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL;
|
||||
PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL;
|
||||
PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL;
|
||||
PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL;
|
||||
PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL;
|
||||
PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL;
|
||||
PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL;
|
||||
PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL;
|
||||
PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL;
|
||||
PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL;
|
||||
PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL;
|
||||
PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL;
|
||||
PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL;
|
||||
PFNGLGETSTRINGPROC glad_glGetString = NULL;
|
||||
PFNGLGETSTRINGIPROC glad_glGetStringi = NULL;
|
||||
PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL;
|
||||
PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL;
|
||||
PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL;
|
||||
PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL;
|
||||
PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL;
|
||||
PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL;
|
||||
PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL;
|
||||
PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL;
|
||||
PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL;
|
||||
PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL;
|
||||
PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL;
|
||||
PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL;
|
||||
PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL;
|
||||
PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL;
|
||||
PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL;
|
||||
PFNGLHINTPROC glad_glHint = NULL;
|
||||
PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL;
|
||||
PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL;
|
||||
PFNGLISBUFFERPROC glad_glIsBuffer = NULL;
|
||||
PFNGLISENABLEDPROC glad_glIsEnabled = NULL;
|
||||
PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL;
|
||||
PFNGLISPROGRAMPROC glad_glIsProgram = NULL;
|
||||
PFNGLISQUERYPROC glad_glIsQuery = NULL;
|
||||
PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL;
|
||||
PFNGLISSAMPLERPROC glad_glIsSampler = NULL;
|
||||
PFNGLISSHADERPROC glad_glIsShader = NULL;
|
||||
PFNGLISSYNCPROC glad_glIsSync = NULL;
|
||||
PFNGLISTEXTUREPROC glad_glIsTexture = NULL;
|
||||
PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL;
|
||||
PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL;
|
||||
PFNGLLINEWIDTHPROC glad_glLineWidth = NULL;
|
||||
PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL;
|
||||
PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL;
|
||||
PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL;
|
||||
PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL;
|
||||
PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL;
|
||||
PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL;
|
||||
PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL;
|
||||
PFNGLREADBUFFERPROC glad_glReadBuffer = NULL;
|
||||
PFNGLREADPIXELSPROC glad_glReadPixels = NULL;
|
||||
PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL;
|
||||
PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL;
|
||||
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL;
|
||||
PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL;
|
||||
PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL;
|
||||
PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL;
|
||||
PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL;
|
||||
PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL;
|
||||
PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL;
|
||||
PFNGLSCISSORPROC glad_glScissor = NULL;
|
||||
PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL;
|
||||
PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL;
|
||||
PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL;
|
||||
PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL;
|
||||
PFNGLSTENCILMASKPROC glad_glStencilMask = NULL;
|
||||
PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL;
|
||||
PFNGLSTENCILOPPROC glad_glStencilOp = NULL;
|
||||
PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL;
|
||||
PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL;
|
||||
PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL;
|
||||
PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL;
|
||||
PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL;
|
||||
PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL;
|
||||
PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL;
|
||||
PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL;
|
||||
PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL;
|
||||
PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL;
|
||||
PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL;
|
||||
PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL;
|
||||
PFNGLUNIFORM1FPROC glad_glUniform1f = NULL;
|
||||
PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL;
|
||||
PFNGLUNIFORM1IPROC glad_glUniform1i = NULL;
|
||||
PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL;
|
||||
PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL;
|
||||
PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL;
|
||||
PFNGLUNIFORM2FPROC glad_glUniform2f = NULL;
|
||||
PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL;
|
||||
PFNGLUNIFORM2IPROC glad_glUniform2i = NULL;
|
||||
PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL;
|
||||
PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL;
|
||||
PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL;
|
||||
PFNGLUNIFORM3FPROC glad_glUniform3f = NULL;
|
||||
PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL;
|
||||
PFNGLUNIFORM3IPROC glad_glUniform3i = NULL;
|
||||
PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL;
|
||||
PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL;
|
||||
PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL;
|
||||
PFNGLUNIFORM4FPROC glad_glUniform4f = NULL;
|
||||
PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL;
|
||||
PFNGLUNIFORM4IPROC glad_glUniform4i = NULL;
|
||||
PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL;
|
||||
PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL;
|
||||
PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL;
|
||||
PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL;
|
||||
PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL;
|
||||
PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL;
|
||||
PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL;
|
||||
PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL;
|
||||
PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL;
|
||||
PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL;
|
||||
PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL;
|
||||
PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL;
|
||||
PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL;
|
||||
PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL;
|
||||
PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL;
|
||||
PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL;
|
||||
PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL;
|
||||
PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL;
|
||||
PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL;
|
||||
PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL;
|
||||
PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL;
|
||||
PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL;
|
||||
PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL;
|
||||
PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL;
|
||||
PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL;
|
||||
PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL;
|
||||
PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL;
|
||||
PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL;
|
||||
PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL;
|
||||
PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL;
|
||||
PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL;
|
||||
PFNGLVIEWPORTPROC glad_glViewport = NULL;
|
||||
PFNGLWAITSYNCPROC glad_glWaitSync = NULL;
|
||||
|
||||
|
||||
static void glad_gl_load_GL_ES_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_GL_ES_VERSION_2_0) return;
|
||||
glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture");
|
||||
glad_glAttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader");
|
||||
glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation");
|
||||
glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer");
|
||||
glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer");
|
||||
glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer");
|
||||
glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture");
|
||||
glad_glBlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor");
|
||||
glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation");
|
||||
glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate");
|
||||
glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc");
|
||||
glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate");
|
||||
glad_glBufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData");
|
||||
glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData");
|
||||
glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus");
|
||||
glad_glClear = (PFNGLCLEARPROC) load(userptr, "glClear");
|
||||
glad_glClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor");
|
||||
glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf");
|
||||
glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil");
|
||||
glad_glColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask");
|
||||
glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader");
|
||||
glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D");
|
||||
glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D");
|
||||
glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D");
|
||||
glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D");
|
||||
glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram");
|
||||
glad_glCreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader");
|
||||
glad_glCullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace");
|
||||
glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers");
|
||||
glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers");
|
||||
glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram");
|
||||
glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers");
|
||||
glad_glDeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader");
|
||||
glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures");
|
||||
glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc");
|
||||
glad_glDepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask");
|
||||
glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef");
|
||||
glad_glDetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader");
|
||||
glad_glDisable = (PFNGLDISABLEPROC) load(userptr, "glDisable");
|
||||
glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray");
|
||||
glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays");
|
||||
glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements");
|
||||
glad_glEnable = (PFNGLENABLEPROC) load(userptr, "glEnable");
|
||||
glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray");
|
||||
glad_glFinish = (PFNGLFINISHPROC) load(userptr, "glFinish");
|
||||
glad_glFlush = (PFNGLFLUSHPROC) load(userptr, "glFlush");
|
||||
glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer");
|
||||
glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D");
|
||||
glad_glFrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace");
|
||||
glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers");
|
||||
glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers");
|
||||
glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers");
|
||||
glad_glGenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures");
|
||||
glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap");
|
||||
glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib");
|
||||
glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform");
|
||||
glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders");
|
||||
glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation");
|
||||
glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv");
|
||||
glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv");
|
||||
glad_glGetError = (PFNGLGETERRORPROC) load(userptr, "glGetError");
|
||||
glad_glGetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv");
|
||||
glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv");
|
||||
glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv");
|
||||
glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog");
|
||||
glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv");
|
||||
glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv");
|
||||
glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog");
|
||||
glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load(userptr, "glGetShaderPrecisionFormat");
|
||||
glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource");
|
||||
glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv");
|
||||
glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString");
|
||||
glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv");
|
||||
glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv");
|
||||
glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation");
|
||||
glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv");
|
||||
glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv");
|
||||
glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv");
|
||||
glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv");
|
||||
glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv");
|
||||
glad_glHint = (PFNGLHINTPROC) load(userptr, "glHint");
|
||||
glad_glIsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer");
|
||||
glad_glIsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled");
|
||||
glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer");
|
||||
glad_glIsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram");
|
||||
glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer");
|
||||
glad_glIsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader");
|
||||
glad_glIsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture");
|
||||
glad_glLineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth");
|
||||
glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram");
|
||||
glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei");
|
||||
glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset");
|
||||
glad_glReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels");
|
||||
glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load(userptr, "glReleaseShaderCompiler");
|
||||
glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage");
|
||||
glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage");
|
||||
glad_glScissor = (PFNGLSCISSORPROC) load(userptr, "glScissor");
|
||||
glad_glShaderBinary = (PFNGLSHADERBINARYPROC) load(userptr, "glShaderBinary");
|
||||
glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource");
|
||||
glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc");
|
||||
glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate");
|
||||
glad_glStencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask");
|
||||
glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate");
|
||||
glad_glStencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp");
|
||||
glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate");
|
||||
glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D");
|
||||
glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf");
|
||||
glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv");
|
||||
glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri");
|
||||
glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv");
|
||||
glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D");
|
||||
glad_glUniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f");
|
||||
glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv");
|
||||
glad_glUniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i");
|
||||
glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv");
|
||||
glad_glUniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f");
|
||||
glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv");
|
||||
glad_glUniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i");
|
||||
glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv");
|
||||
glad_glUniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f");
|
||||
glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv");
|
||||
glad_glUniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i");
|
||||
glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv");
|
||||
glad_glUniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f");
|
||||
glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv");
|
||||
glad_glUniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i");
|
||||
glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv");
|
||||
glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv");
|
||||
glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv");
|
||||
glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv");
|
||||
glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram");
|
||||
glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram");
|
||||
glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f");
|
||||
glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv");
|
||||
glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f");
|
||||
glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv");
|
||||
glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f");
|
||||
glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv");
|
||||
glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f");
|
||||
glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv");
|
||||
glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer");
|
||||
glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport");
|
||||
}
|
||||
static void glad_gl_load_GL_ES_VERSION_3_0( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_GL_ES_VERSION_3_0) return;
|
||||
glad_glBeginQuery = (PFNGLBEGINQUERYPROC) load(userptr, "glBeginQuery");
|
||||
glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load(userptr, "glBeginTransformFeedback");
|
||||
glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase");
|
||||
glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange");
|
||||
glad_glBindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler");
|
||||
glad_glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) load(userptr, "glBindTransformFeedback");
|
||||
glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray");
|
||||
glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer");
|
||||
glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load(userptr, "glClearBufferfi");
|
||||
glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load(userptr, "glClearBufferfv");
|
||||
glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load(userptr, "glClearBufferiv");
|
||||
glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load(userptr, "glClearBufferuiv");
|
||||
glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync");
|
||||
glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load(userptr, "glCompressedTexImage3D");
|
||||
glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load(userptr, "glCompressedTexSubImage3D");
|
||||
glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData");
|
||||
glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load(userptr, "glCopyTexSubImage3D");
|
||||
glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC) load(userptr, "glDeleteQueries");
|
||||
glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers");
|
||||
glad_glDeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync");
|
||||
glad_glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) load(userptr, "glDeleteTransformFeedbacks");
|
||||
glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays");
|
||||
glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load(userptr, "glDrawArraysInstanced");
|
||||
glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load(userptr, "glDrawBuffers");
|
||||
glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load(userptr, "glDrawElementsInstanced");
|
||||
glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load(userptr, "glDrawRangeElements");
|
||||
glad_glEndQuery = (PFNGLENDQUERYPROC) load(userptr, "glEndQuery");
|
||||
glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load(userptr, "glEndTransformFeedback");
|
||||
glad_glFenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync");
|
||||
glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange");
|
||||
glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer");
|
||||
glad_glGenQueries = (PFNGLGENQUERIESPROC) load(userptr, "glGenQueries");
|
||||
glad_glGenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers");
|
||||
glad_glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) load(userptr, "glGenTransformFeedbacks");
|
||||
glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays");
|
||||
glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName");
|
||||
glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv");
|
||||
glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv");
|
||||
glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load(userptr, "glGetBufferParameteri64v");
|
||||
glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load(userptr, "glGetBufferPointerv");
|
||||
glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load(userptr, "glGetFragDataLocation");
|
||||
glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load(userptr, "glGetInteger64i_v");
|
||||
glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v");
|
||||
glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v");
|
||||
glad_glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) load(userptr, "glGetInternalformativ");
|
||||
glad_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) load(userptr, "glGetProgramBinary");
|
||||
glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load(userptr, "glGetQueryObjectuiv");
|
||||
glad_glGetQueryiv = (PFNGLGETQUERYIVPROC) load(userptr, "glGetQueryiv");
|
||||
glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv");
|
||||
glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv");
|
||||
glad_glGetStringi = (PFNGLGETSTRINGIPROC) load(userptr, "glGetStringi");
|
||||
glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv");
|
||||
glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load(userptr, "glGetTransformFeedbackVarying");
|
||||
glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex");
|
||||
glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices");
|
||||
glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load(userptr, "glGetUniformuiv");
|
||||
glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load(userptr, "glGetVertexAttribIiv");
|
||||
glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load(userptr, "glGetVertexAttribIuiv");
|
||||
glad_glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load(userptr, "glInvalidateFramebuffer");
|
||||
glad_glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load(userptr, "glInvalidateSubFramebuffer");
|
||||
glad_glIsQuery = (PFNGLISQUERYPROC) load(userptr, "glIsQuery");
|
||||
glad_glIsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler");
|
||||
glad_glIsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync");
|
||||
glad_glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) load(userptr, "glIsTransformFeedback");
|
||||
glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray");
|
||||
glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange");
|
||||
glad_glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) load(userptr, "glPauseTransformFeedback");
|
||||
glad_glProgramBinary = (PFNGLPROGRAMBINARYPROC) load(userptr, "glProgramBinary");
|
||||
glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load(userptr, "glProgramParameteri");
|
||||
glad_glReadBuffer = (PFNGLREADBUFFERPROC) load(userptr, "glReadBuffer");
|
||||
glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample");
|
||||
glad_glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) load(userptr, "glResumeTransformFeedback");
|
||||
glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf");
|
||||
glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv");
|
||||
glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri");
|
||||
glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv");
|
||||
glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC) load(userptr, "glTexImage3D");
|
||||
glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) load(userptr, "glTexStorage2D");
|
||||
glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) load(userptr, "glTexStorage3D");
|
||||
glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load(userptr, "glTexSubImage3D");
|
||||
glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load(userptr, "glTransformFeedbackVaryings");
|
||||
glad_glUniform1ui = (PFNGLUNIFORM1UIPROC) load(userptr, "glUniform1ui");
|
||||
glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load(userptr, "glUniform1uiv");
|
||||
glad_glUniform2ui = (PFNGLUNIFORM2UIPROC) load(userptr, "glUniform2ui");
|
||||
glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load(userptr, "glUniform2uiv");
|
||||
glad_glUniform3ui = (PFNGLUNIFORM3UIPROC) load(userptr, "glUniform3ui");
|
||||
glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load(userptr, "glUniform3uiv");
|
||||
glad_glUniform4ui = (PFNGLUNIFORM4UIPROC) load(userptr, "glUniform4ui");
|
||||
glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load(userptr, "glUniform4uiv");
|
||||
glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding");
|
||||
glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load(userptr, "glUniformMatrix2x3fv");
|
||||
glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load(userptr, "glUniformMatrix2x4fv");
|
||||
glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load(userptr, "glUniformMatrix3x2fv");
|
||||
glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load(userptr, "glUniformMatrix3x4fv");
|
||||
glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load(userptr, "glUniformMatrix4x2fv");
|
||||
glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load(userptr, "glUniformMatrix4x3fv");
|
||||
glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load(userptr, "glUnmapBuffer");
|
||||
glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load(userptr, "glVertexAttribDivisor");
|
||||
glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load(userptr, "glVertexAttribI4i");
|
||||
glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load(userptr, "glVertexAttribI4iv");
|
||||
glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load(userptr, "glVertexAttribI4ui");
|
||||
glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load(userptr, "glVertexAttribI4uiv");
|
||||
glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load(userptr, "glVertexAttribIPointer");
|
||||
glad_glWaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void glad_gl_free_extensions(char **exts_i) {
|
||||
if (exts_i != NULL) {
|
||||
unsigned int index;
|
||||
for(index = 0; exts_i[index]; index++) {
|
||||
free((void *) (exts_i[index]));
|
||||
}
|
||||
free((void *)exts_i);
|
||||
exts_i = NULL;
|
||||
}
|
||||
}
|
||||
static int glad_gl_get_extensions( const char **out_exts, char ***out_exts_i) {
|
||||
#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0)
|
||||
if (glad_glGetStringi != NULL && glad_glGetIntegerv != NULL) {
|
||||
unsigned int index = 0;
|
||||
unsigned int num_exts_i = 0;
|
||||
char **exts_i = NULL;
|
||||
glad_glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i);
|
||||
exts_i = (char **) malloc((num_exts_i + 1) * (sizeof *exts_i));
|
||||
if (exts_i == NULL) {
|
||||
return 0;
|
||||
}
|
||||
for(index = 0; index < num_exts_i; index++) {
|
||||
const char *gl_str_tmp = (const char*) glad_glGetStringi(GL_EXTENSIONS, index);
|
||||
size_t len = strlen(gl_str_tmp) + 1;
|
||||
|
||||
char *local_str = (char*) malloc(len * sizeof(char));
|
||||
if(local_str == NULL) {
|
||||
exts_i[index] = NULL;
|
||||
glad_gl_free_extensions(exts_i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(local_str, gl_str_tmp, len * sizeof(char));
|
||||
exts_i[index] = local_str;
|
||||
}
|
||||
exts_i[index] = NULL;
|
||||
|
||||
*out_exts_i = exts_i;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
GLAD_UNUSED(out_exts_i);
|
||||
#endif
|
||||
if (glad_glGetString == NULL) {
|
||||
return 0;
|
||||
}
|
||||
*out_exts = (const char *)glad_glGetString(GL_EXTENSIONS);
|
||||
return 1;
|
||||
}
|
||||
static int glad_gl_has_extension(const char *exts, char **exts_i, const char *ext) {
|
||||
if(exts_i) {
|
||||
unsigned int index;
|
||||
for(index = 0; exts_i[index]; index++) {
|
||||
const char *e = exts_i[index];
|
||||
if(strcmp(e, ext) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const char *extensions;
|
||||
const char *loc;
|
||||
const char *terminator;
|
||||
extensions = exts;
|
||||
if(extensions == NULL || ext == NULL) {
|
||||
return 0;
|
||||
}
|
||||
while(1) {
|
||||
loc = strstr(extensions, ext);
|
||||
if(loc == NULL) {
|
||||
return 0;
|
||||
}
|
||||
terminator = loc + strlen(ext);
|
||||
if((loc == extensions || *(loc - 1) == ' ') &&
|
||||
(*terminator == ' ' || *terminator == '\0')) {
|
||||
return 1;
|
||||
}
|
||||
extensions = terminator;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static GLADapiproc glad_gl_get_proc_from_userptr(void *userptr, const char* name) {
|
||||
return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name);
|
||||
}
|
||||
|
||||
static int glad_gl_find_extensions_gles2(void) {
|
||||
const char *exts = NULL;
|
||||
char **exts_i = NULL;
|
||||
if (!glad_gl_get_extensions(&exts, &exts_i)) return 0;
|
||||
|
||||
GLAD_UNUSED(glad_gl_has_extension);
|
||||
|
||||
glad_gl_free_extensions(exts_i);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int glad_gl_find_core_gles2(void) {
|
||||
int i;
|
||||
const char* version;
|
||||
const char* prefixes[] = {
|
||||
"OpenGL ES-CM ",
|
||||
"OpenGL ES-CL ",
|
||||
"OpenGL ES ",
|
||||
"OpenGL SC ",
|
||||
NULL
|
||||
};
|
||||
int major = 0;
|
||||
int minor = 0;
|
||||
version = (const char*) glad_glGetString(GL_VERSION);
|
||||
if (!version) return 0;
|
||||
for (i = 0; prefixes[i]; i++) {
|
||||
const size_t length = strlen(prefixes[i]);
|
||||
if (strncmp(version, prefixes[i], length) == 0) {
|
||||
version += length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor);
|
||||
|
||||
GLAD_GL_ES_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2;
|
||||
GLAD_GL_ES_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3;
|
||||
|
||||
return GLAD_MAKE_VERSION(major, minor);
|
||||
}
|
||||
|
||||
int gladLoadGLES2UserPtr( GLADuserptrloadfunc load, void *userptr) {
|
||||
int version;
|
||||
|
||||
glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString");
|
||||
if(glad_glGetString == NULL) return 0;
|
||||
version = glad_gl_find_core_gles2();
|
||||
|
||||
glad_gl_load_GL_ES_VERSION_2_0(load, userptr);
|
||||
glad_gl_load_GL_ES_VERSION_3_0(load, userptr);
|
||||
|
||||
if (!glad_gl_find_extensions_gles2()) return 0;
|
||||
|
||||
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
int gladLoadGLES2( GLADloadfunc load) {
|
||||
return gladLoadGLES2UserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef GLAD_GLES2
|
||||
|
||||
#ifndef GLAD_LOADER_LIBRARY_C_
|
||||
#define GLAD_LOADER_LIBRARY_C_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if GLAD_PLATFORM_WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
|
||||
static void* glad_get_dlopen_handle(const char *lib_names[], int length) {
|
||||
void *handle = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
#if GLAD_PLATFORM_WIN32
|
||||
#if GLAD_PLATFORM_UWP
|
||||
size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR);
|
||||
LPWSTR buffer = (LPWSTR) malloc(buffer_size);
|
||||
if (buffer != NULL) {
|
||||
int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size);
|
||||
if (ret != 0) {
|
||||
handle = (void*) LoadPackagedLibrary(buffer, 0);
|
||||
}
|
||||
free((void*) buffer);
|
||||
}
|
||||
#else
|
||||
handle = (void*) LoadLibraryA(lib_names[i]);
|
||||
#endif
|
||||
#else
|
||||
handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL);
|
||||
#endif
|
||||
if (handle != NULL) {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void glad_close_dlopen_handle(void* handle) {
|
||||
if (handle != NULL) {
|
||||
#if GLAD_PLATFORM_WIN32
|
||||
FreeLibrary((HMODULE) handle);
|
||||
#else
|
||||
dlclose(handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static GLADapiproc glad_dlsym_handle(void* handle, const char *name) {
|
||||
if (handle == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if GLAD_PLATFORM_WIN32
|
||||
return (GLADapiproc) GetProcAddress((HMODULE) handle, name);
|
||||
#else
|
||||
return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* GLAD_LOADER_LIBRARY_C_ */
|
||||
|
||||
#if GLAD_PLATFORM_EMSCRIPTEN
|
||||
#ifndef GLAD_EGL_H_
|
||||
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
|
||||
typedef __eglMustCastToProperFunctionPointerType (GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char *name);
|
||||
#endif
|
||||
extern __eglMustCastToProperFunctionPointerType emscripten_GetProcAddress(const char *name);
|
||||
#elif GLAD_GLES2_USE_SYSTEM_EGL
|
||||
#include <EGL/egl.h>
|
||||
typedef __eglMustCastToProperFunctionPointerType (GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char *name);
|
||||
#else
|
||||
#include <glad/egl.h>
|
||||
#endif
|
||||
|
||||
|
||||
struct _glad_gles2_userptr {
|
||||
void *handle;
|
||||
PFNEGLGETPROCADDRESSPROC get_proc_address_ptr;
|
||||
};
|
||||
|
||||
|
||||
static GLADapiproc glad_gles2_get_proc(void *vuserptr, const char* name) {
|
||||
struct _glad_gles2_userptr userptr = *(struct _glad_gles2_userptr*) vuserptr;
|
||||
GLADapiproc result = NULL;
|
||||
|
||||
#if GLAD_PLATFORM_EMSCRIPTEN
|
||||
GLAD_UNUSED(glad_dlsym_handle);
|
||||
#else
|
||||
result = glad_dlsym_handle(userptr.handle, name);
|
||||
#endif
|
||||
if (result == NULL) {
|
||||
result = userptr.get_proc_address_ptr(name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void* _glad_GLES2_loader_handle = NULL;
|
||||
|
||||
static void* glad_gles2_dlopen_handle(void) {
|
||||
#if GLAD_PLATFORM_EMSCRIPTEN
|
||||
#elif GLAD_PLATFORM_APPLE
|
||||
static const char *NAMES[] = {"libGLESv2.dylib"};
|
||||
#elif GLAD_PLATFORM_WIN32
|
||||
static const char *NAMES[] = {"GLESv2.dll", "libGLESv2.dll"};
|
||||
#else
|
||||
static const char *NAMES[] = {"libGLESv2.so.2", "libGLESv2.so"};
|
||||
#endif
|
||||
|
||||
#if GLAD_PLATFORM_EMSCRIPTEN
|
||||
GLAD_UNUSED(glad_get_dlopen_handle);
|
||||
return NULL;
|
||||
#else
|
||||
if (_glad_GLES2_loader_handle == NULL) {
|
||||
_glad_GLES2_loader_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0]));
|
||||
}
|
||||
|
||||
return _glad_GLES2_loader_handle;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct _glad_gles2_userptr glad_gles2_build_userptr(void *handle) {
|
||||
struct _glad_gles2_userptr userptr;
|
||||
#if GLAD_PLATFORM_EMSCRIPTEN
|
||||
GLAD_UNUSED(handle);
|
||||
userptr.get_proc_address_ptr = emscripten_GetProcAddress;
|
||||
#else
|
||||
userptr.handle = handle;
|
||||
userptr.get_proc_address_ptr = eglGetProcAddress;
|
||||
#endif
|
||||
return userptr;
|
||||
}
|
||||
|
||||
int gladLoaderLoadGLES2(void) {
|
||||
int version = 0;
|
||||
void *handle = NULL;
|
||||
int did_load = 0;
|
||||
struct _glad_gles2_userptr userptr;
|
||||
|
||||
#if GLAD_PLATFORM_EMSCRIPTEN
|
||||
GLAD_UNUSED(handle);
|
||||
GLAD_UNUSED(did_load);
|
||||
GLAD_UNUSED(glad_gles2_dlopen_handle);
|
||||
GLAD_UNUSED(glad_gles2_build_userptr);
|
||||
userptr.get_proc_address_ptr = emscripten_GetProcAddress;
|
||||
version = gladLoadGLES2UserPtr(glad_gles2_get_proc, &userptr);
|
||||
#else
|
||||
if (eglGetProcAddress == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
did_load = _glad_GLES2_loader_handle == NULL;
|
||||
handle = glad_gles2_dlopen_handle();
|
||||
if (handle != NULL) {
|
||||
userptr = glad_gles2_build_userptr(handle);
|
||||
|
||||
version = gladLoadGLES2UserPtr(glad_gles2_get_proc, &userptr);
|
||||
|
||||
if (!version && did_load) {
|
||||
gladLoaderUnloadGLES2();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void gladLoaderUnloadGLES2(void) {
|
||||
if (_glad_GLES2_loader_handle != NULL) {
|
||||
glad_close_dlopen_handle(_glad_GLES2_loader_handle);
|
||||
_glad_GLES2_loader_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GLAD_GLES2 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
22
src/libvgcode/include/ColorPrint.hpp
Normal file
22
src/libvgcode/include/ColorPrint.hpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_COLORPRINT_HPP
|
||||
#define VGCODE_COLORPRINT_HPP
|
||||
|
||||
#include "../include/Types.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
struct ColorPrint
|
||||
{
|
||||
uint8_t extruder_id{ 0 };
|
||||
uint8_t color_id{ 0 };
|
||||
uint32_t layer_id{ 0 };
|
||||
std::array<float, TIME_MODES_COUNT> times{ 0.0f, 0.0f };
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_COLORPRINT_HPP
|
||||
107
src/libvgcode/include/ColorRange.hpp
Normal file
107
src/libvgcode/include/ColorRange.hpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_COLORRANGE_HPP
|
||||
#define VGCODE_COLORRANGE_HPP
|
||||
|
||||
#include "../include/Types.hpp"
|
||||
|
||||
#include <cfloat>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
static const Palette DEFAULT_RANGES_COLORS{ {
|
||||
{ 11, 44, 122 }, // bluish
|
||||
{ 19, 89, 133 },
|
||||
{ 28, 136, 145 },
|
||||
{ 4, 214, 15 },
|
||||
{ 170, 242, 0 },
|
||||
{ 252, 249, 3 },
|
||||
{ 245, 206, 10 },
|
||||
{ 227, 136, 32 },
|
||||
{ 209, 104, 48 },
|
||||
{ 194, 82, 60 },
|
||||
{ 148, 38, 22 } // reddish
|
||||
} };
|
||||
|
||||
class ColorRange
|
||||
{
|
||||
public:
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
explicit ColorRange(EColorRangeType type = EColorRangeType::Linear);
|
||||
//
|
||||
// Return the type of this ColorRange.
|
||||
//
|
||||
EColorRangeType get_type() const;
|
||||
//
|
||||
// Return the palette used by this ColorRange.
|
||||
// Default is DEFAULT_RANGES_COLORS
|
||||
//
|
||||
const Palette& get_palette() const;
|
||||
//
|
||||
// Set the palette to be used by this ColorRange.
|
||||
// The given palette must contain at least two colors.
|
||||
//
|
||||
void set_palette(const Palette& palette);
|
||||
//
|
||||
// Return the interpolated color at the given value.
|
||||
// Value is clamped to [get_range()[0]..get_range()[1]].
|
||||
//
|
||||
Color get_color_at(float value) const;
|
||||
//
|
||||
// Return the range of this ColorRange.
|
||||
// The range is detected during the call to Viewer::load().
|
||||
// [0] -> min
|
||||
// [1] -> max
|
||||
//
|
||||
const std::array<float, 2>& get_range() const;
|
||||
//
|
||||
// Return the values corresponding to the detected color bins of this ColorRange.
|
||||
// The size of the returned vector can be:
|
||||
// 1 - If only one value was detected while setting up this ColorRange.
|
||||
// 2 - If only two values were detected while setting up this ColorRange.
|
||||
// get_palette().size() - If more than two distinct values were detected while setting up this ColorRange.
|
||||
//
|
||||
std::vector<float> get_values() const;
|
||||
//
|
||||
// Return the size of the palette, in bytes
|
||||
//
|
||||
std::size_t size_in_bytes_cpu() const;
|
||||
|
||||
static const ColorRange DUMMY_COLOR_RANGE;
|
||||
|
||||
private:
|
||||
EColorRangeType m_type{ EColorRangeType::Linear };
|
||||
//
|
||||
// The palette used by this ColorRange
|
||||
//
|
||||
Palette m_palette;
|
||||
//
|
||||
// [0] = min
|
||||
// [1] = max
|
||||
//
|
||||
std::array<float, 2> m_range{ FLT_MAX, -FLT_MAX };
|
||||
//
|
||||
// Count of different values passed to update()
|
||||
//
|
||||
std::size_t m_count{ 0 };
|
||||
|
||||
//
|
||||
// Use the passed value to update the range.
|
||||
//
|
||||
void update(float value);
|
||||
//
|
||||
// Reset the range
|
||||
// Call this method before reuse an instance of ColorRange.
|
||||
//
|
||||
void reset();
|
||||
|
||||
friend class ViewerImpl;
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_COLORRANGE_HPP
|
||||
36
src/libvgcode/include/GCodeInputData.hpp
Normal file
36
src/libvgcode/include/GCodeInputData.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_GCODEINPUTDATA_HPP
|
||||
#define VGCODE_GCODEINPUTDATA_HPP
|
||||
|
||||
#include "PathVertex.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
struct GCodeInputData
|
||||
{
|
||||
//
|
||||
// Whether or not the gcode was generated with spiral vase mode enabled.
|
||||
// Required to properly detect fictitious layer changes when spiral vase mode is enabled.
|
||||
//
|
||||
bool spiral_vase_mode{ false };
|
||||
//
|
||||
// List of path vertices (gcode moves)
|
||||
// See: PathVertex
|
||||
//
|
||||
std::vector<PathVertex> vertices;
|
||||
//
|
||||
// Palette for extruders colors
|
||||
//
|
||||
Palette tools_colors;
|
||||
//
|
||||
// Palette for color print colors
|
||||
//
|
||||
Palette color_print_colors;
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_BITSET_HPP
|
||||
121
src/libvgcode/include/PathVertex.hpp
Normal file
121
src/libvgcode/include/PathVertex.hpp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_PATHVERTEX_HPP
|
||||
#define VGCODE_PATHVERTEX_HPP
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
#include <cfloat>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
//
|
||||
// Struct representating a gcode move (toolpath segment)
|
||||
//
|
||||
struct PathVertex
|
||||
{
|
||||
//
|
||||
// Segment end position
|
||||
//
|
||||
Vec3 position{ FLT_MAX, FLT_MAX, FLT_MAX };
|
||||
//
|
||||
// Segment height
|
||||
//
|
||||
float height{ 0.0f };
|
||||
//
|
||||
// Segment width
|
||||
//
|
||||
float width{ 0.0f };
|
||||
//
|
||||
// Segment speed
|
||||
//
|
||||
float feedrate{ 0.0f };
|
||||
//
|
||||
// Segment actual speed
|
||||
//
|
||||
float actual_feedrate{ 0.0f };
|
||||
//
|
||||
// Segment mm3_per_mm
|
||||
//
|
||||
float mm3_per_mm{ 0.0f };
|
||||
//
|
||||
// Segment fan speed
|
||||
//
|
||||
float fan_speed{ 0.0f };
|
||||
//
|
||||
// Segment temperature
|
||||
//
|
||||
float temperature{ 0.0f };
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
//
|
||||
// Segment weight
|
||||
//
|
||||
float weight{ 0.0f };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
//
|
||||
// Segment extrusion role
|
||||
//
|
||||
EGCodeExtrusionRole role{ EGCodeExtrusionRole::None };
|
||||
//
|
||||
// Segment move type
|
||||
//
|
||||
EMoveType type{ EMoveType::Noop };
|
||||
//
|
||||
// Segment gcode line id
|
||||
//
|
||||
uint32_t gcode_id{ 0 };
|
||||
//
|
||||
// Segment layer id
|
||||
//
|
||||
uint32_t layer_id{ 0 };
|
||||
//
|
||||
// Segment extruder id
|
||||
//
|
||||
uint8_t extruder_id{ 0 };
|
||||
//
|
||||
// Segment color id
|
||||
//
|
||||
uint8_t color_id{ 0 };
|
||||
//
|
||||
// Segment estimated times
|
||||
//
|
||||
std::array<float, TIME_MODES_COUNT> times{ 0.0f, 0.0f };
|
||||
|
||||
//
|
||||
// Return true if the segment is an extrusion move
|
||||
//
|
||||
bool is_extrusion() const;
|
||||
//
|
||||
// Return true if the segment is an travel move
|
||||
//
|
||||
bool is_travel() const;
|
||||
//
|
||||
// Return true if the segment is an option
|
||||
// See: EOptionType
|
||||
//
|
||||
bool is_option() const;
|
||||
//
|
||||
// Return true if the segment is a wipe move
|
||||
//
|
||||
bool is_wipe() const;
|
||||
//
|
||||
// Return true if the segment was generated by custom gcode
|
||||
//
|
||||
bool is_custom_gcode() const;
|
||||
//
|
||||
// Return the volumetric flow rate of the segment
|
||||
//
|
||||
float volumetric_rate() const { return feedrate * mm3_per_mm; }
|
||||
//
|
||||
// Return the acutal volumetric flow rate of the segment
|
||||
//
|
||||
float actual_volumetric_rate() const { return actual_feedrate * mm3_per_mm; }
|
||||
|
||||
static const PathVertex DUMMY_PATH_VERTEX;
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_PATHVERTEX_HPP
|
||||
225
src/libvgcode/include/Types.hpp
Normal file
225
src/libvgcode/include/Types.hpp
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_TYPES_HPP
|
||||
#define VGCODE_TYPES_HPP
|
||||
|
||||
#define VGCODE_ENABLE_COG_AND_TOOL_MARKERS 0
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
static constexpr float PI = 3.141592f;
|
||||
|
||||
//
|
||||
// Predefined values for the radius, in mm, of the cylinders used to render the travel moves.
|
||||
//
|
||||
static constexpr float DEFAULT_TRAVELS_RADIUS_MM = 0.1f;
|
||||
static constexpr float MIN_TRAVELS_RADIUS_MM = 0.05f;
|
||||
static constexpr float MAX_TRAVELS_RADIUS_MM = 1.0f;
|
||||
|
||||
//
|
||||
// Predefined values for the radius, in mm, of the cylinders used to render the wipe moves.
|
||||
//
|
||||
static constexpr float DEFAULT_WIPES_RADIUS_MM = 0.1f;
|
||||
static constexpr float MIN_WIPES_RADIUS_MM = 0.05f;
|
||||
static constexpr float MAX_WIPES_RADIUS_MM = 1.0f;
|
||||
|
||||
//
|
||||
// Vector in 3 dimensions
|
||||
// [0] -> x
|
||||
// [1] -> y
|
||||
// [2] -> z
|
||||
// Used for positions, displacements and so on.
|
||||
//
|
||||
using Vec3 = std::array<float, 3>;
|
||||
|
||||
//
|
||||
// 4x4 square matrix with elements in column-major order:
|
||||
// | a[0] a[4] a[8] a[12] |
|
||||
// | a[1] a[5] a[9] a[13] |
|
||||
// | a[2] a[6] a[10] a[14] |
|
||||
// | a[3] a[7] a[11] a[15] |
|
||||
//
|
||||
using Mat4x4 = std::array<float, 16>;
|
||||
|
||||
//
|
||||
// RGB color
|
||||
// [0] -> red
|
||||
// [1] -> green
|
||||
// [2] -> blue
|
||||
//
|
||||
using Color = std::array<uint8_t, 3>;
|
||||
|
||||
//
|
||||
// Color palette
|
||||
//
|
||||
using Palette = std::vector<Color>;
|
||||
|
||||
//
|
||||
// Axis aligned box in 3 dimensions
|
||||
// [0] -> { min_x, min_y, min_z }
|
||||
// [1] -> { max_x, max_y, max_z }
|
||||
//
|
||||
using AABox = std::array<Vec3, 2>;
|
||||
|
||||
//
|
||||
// One dimensional natural numbers interval
|
||||
// [0] -> min
|
||||
// [1] -> max
|
||||
//
|
||||
using Interval = std::array<std::size_t, 2>;
|
||||
|
||||
//
|
||||
// View types
|
||||
//
|
||||
enum class EViewType : uint8_t
|
||||
{
|
||||
Summary, // ORCA
|
||||
FeatureType,
|
||||
ColorPrint,
|
||||
Speed,
|
||||
ActualSpeed,
|
||||
Height,
|
||||
Width,
|
||||
VolumetricFlowRate,
|
||||
ActualVolumetricFlowRate,
|
||||
LayerTimeLinear,
|
||||
LayerTimeLogarithmic,
|
||||
FanSpeed,
|
||||
Temperature,
|
||||
Tool,
|
||||
COUNT
|
||||
};
|
||||
|
||||
static constexpr std::size_t VIEW_TYPES_COUNT = static_cast<std::size_t>(EViewType::COUNT);
|
||||
|
||||
//
|
||||
// Move types
|
||||
//
|
||||
enum class EMoveType : uint8_t
|
||||
{
|
||||
Noop,
|
||||
Retract,
|
||||
Unretract,
|
||||
Seam,
|
||||
ToolChange,
|
||||
ColorChange,
|
||||
PausePrint,
|
||||
CustomGCode,
|
||||
Travel,
|
||||
Wipe,
|
||||
Extrude,
|
||||
COUNT
|
||||
};
|
||||
|
||||
static constexpr std::size_t MOVE_TYPES_COUNT = static_cast<std::size_t>(EMoveType::COUNT);
|
||||
|
||||
//
|
||||
// Extrusion roles
|
||||
//
|
||||
enum class EGCodeExtrusionRole : uint8_t
|
||||
{
|
||||
// This enum is used as in index into extrusion_roles_visibility.
|
||||
// Better only add things to the end.
|
||||
None,
|
||||
Perimeter,
|
||||
ExternalPerimeter,
|
||||
OverhangPerimeter,
|
||||
InternalInfill,
|
||||
SolidInfill,
|
||||
TopSolidInfill,
|
||||
Ironing,
|
||||
BridgeInfill,
|
||||
GapFill,
|
||||
Skirt,
|
||||
SupportMaterial,
|
||||
SupportMaterialInterface,
|
||||
WipeTower,
|
||||
Custom,
|
||||
// ORCA
|
||||
BottomSurface,
|
||||
InternalBridgeInfill,
|
||||
Brim,
|
||||
SupportTransition,
|
||||
Mixed,
|
||||
COUNT
|
||||
};
|
||||
|
||||
static constexpr std::size_t GCODE_EXTRUSION_ROLES_COUNT = static_cast<std::size_t>(EGCodeExtrusionRole::COUNT);
|
||||
|
||||
//
|
||||
// Option types
|
||||
//
|
||||
enum class EOptionType : uint8_t
|
||||
{
|
||||
// This enum is used as in index into options_visibility.
|
||||
// Better only add things to the end.
|
||||
Travels,
|
||||
Wipes,
|
||||
Retractions,
|
||||
Unretractions,
|
||||
Seams,
|
||||
ToolChanges,
|
||||
ColorChanges,
|
||||
PausePrints,
|
||||
CustomGCodes,
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
CenterOfGravity,
|
||||
ToolMarker,
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
COUNT
|
||||
};
|
||||
|
||||
static constexpr std::size_t OPTION_TYPES_COUNT = static_cast<std::size_t>(EOptionType::COUNT);
|
||||
|
||||
//
|
||||
// Time modes
|
||||
//
|
||||
enum class ETimeMode : uint8_t
|
||||
{
|
||||
Normal,
|
||||
Stealth,
|
||||
COUNT
|
||||
};
|
||||
|
||||
static constexpr std::size_t TIME_MODES_COUNT = static_cast<std::size_t>(ETimeMode::COUNT);
|
||||
|
||||
//
|
||||
// Color range types
|
||||
//
|
||||
enum class EColorRangeType : uint8_t
|
||||
{
|
||||
Linear,
|
||||
Logarithmic,
|
||||
COUNT
|
||||
};
|
||||
|
||||
static constexpr std::size_t COLOR_RANGE_TYPES_COUNT = static_cast<std::size_t>(EColorRangeType::COUNT);
|
||||
|
||||
//
|
||||
// Predefined colors
|
||||
//
|
||||
static const Color DUMMY_COLOR{ 64, 64, 64 };
|
||||
|
||||
//
|
||||
// Mapping from EMoveType to EOptionType
|
||||
// Returns EOptionType::COUNT if the given move type does not correspond
|
||||
// to any option type.
|
||||
//
|
||||
extern EOptionType move_type_to_option(EMoveType type);
|
||||
|
||||
//
|
||||
// Returns the linear interpolation between the two given colors
|
||||
// at the given t.
|
||||
// t is clamped in the range [0..1]
|
||||
//
|
||||
extern Color lerp(const Color& c1, const Color& c2, float t);
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_TYPES_HPP
|
||||
423
src/libvgcode/include/Viewer.hpp
Normal file
423
src/libvgcode/include/Viewer.hpp
Normal file
|
|
@ -0,0 +1,423 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_VIEWER_HPP
|
||||
#define VGCODE_VIEWER_HPP
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
class ViewerImpl;
|
||||
struct GCodeInputData;
|
||||
struct PathVertex;
|
||||
class ColorRange;
|
||||
struct ColorPrint;
|
||||
|
||||
class Viewer
|
||||
{
|
||||
public:
|
||||
Viewer();
|
||||
~Viewer();
|
||||
Viewer(const Viewer& other) = delete;
|
||||
Viewer(Viewer&& other) = delete;
|
||||
Viewer& operator = (const Viewer& other) = delete;
|
||||
Viewer& operator = (Viewer&& other) = delete;
|
||||
|
||||
//
|
||||
// Initialize the viewer.
|
||||
// Param opengl_context_version must be the string returned by glGetString(GL_VERSION).
|
||||
// This method must be called after a valid OpenGL context has been already created
|
||||
// and before calling any other method of the viewer.
|
||||
// Throws an std::runtime_error exception if:
|
||||
// * the method is called before creating an OpenGL context
|
||||
// * the created OpenGL context does not support OpenGL 3.2 or greater
|
||||
// * when using OpenGL ES, the created OpenGL ES context does not support OpenGL ES 2.0 or greater
|
||||
// * any of the shaders fails to compile
|
||||
//
|
||||
void init(const std::string& opengl_context_version);
|
||||
//
|
||||
// Release the resources used by the viewer.
|
||||
// This method must be called before releasing the OpenGL context if the viewer
|
||||
// goes out of scope after releasing it.
|
||||
//
|
||||
void shutdown();
|
||||
//
|
||||
// Reset the contents of the viewer.
|
||||
// Automatically called by load() method.
|
||||
//
|
||||
void reset();
|
||||
//
|
||||
// Setup the viewer content from the given data.
|
||||
// See: GCodeInputData
|
||||
//
|
||||
void load(GCodeInputData&& gcode_data);
|
||||
//
|
||||
// Render the toolpaths according to the current settings and
|
||||
// using the given camera matrices.
|
||||
//
|
||||
void render(const Mat4x4& view_matrix, const Mat4x4& projection_matrix);
|
||||
|
||||
//
|
||||
// ************************************************************************
|
||||
// Settings
|
||||
// The following methods can be used to query/customize the parameters
|
||||
// used to render the toolpaths.
|
||||
// ************************************************************************
|
||||
//
|
||||
|
||||
//
|
||||
// View type
|
||||
// See: EViewType
|
||||
//
|
||||
EViewType get_view_type() const;
|
||||
void set_view_type(EViewType type);
|
||||
//
|
||||
// Time mode
|
||||
// See: ETimeMode
|
||||
//
|
||||
ETimeMode get_time_mode() const;
|
||||
void set_time_mode(ETimeMode mode);
|
||||
//
|
||||
// Top layer only
|
||||
// Whether or not the visible range is limited to the current top layer only.
|
||||
//
|
||||
bool is_top_layer_only_view_range() const;
|
||||
//
|
||||
// Toggle the top layer only state.
|
||||
//
|
||||
void toggle_top_layer_only_view_range();
|
||||
//
|
||||
// Returns true if the given option is visible.
|
||||
//
|
||||
bool is_option_visible(EOptionType type) const;
|
||||
//
|
||||
// Toggle the visibility state of the given option.
|
||||
//
|
||||
void toggle_option_visibility(EOptionType type);
|
||||
//
|
||||
// Returns true if the given extrusion role is visible.
|
||||
//
|
||||
bool is_extrusion_role_visible(EGCodeExtrusionRole role) const;
|
||||
//
|
||||
// Toggle the visibility state of the given extrusion role.
|
||||
//
|
||||
void toggle_extrusion_role_visibility(EGCodeExtrusionRole role);
|
||||
//
|
||||
// Return the color used to render the given extrusion rols.
|
||||
//
|
||||
const Color& get_extrusion_role_color(EGCodeExtrusionRole role) const;
|
||||
//
|
||||
// Set the color used to render the given extrusion role.
|
||||
//
|
||||
void set_extrusion_role_color(EGCodeExtrusionRole role, const Color& color);
|
||||
//
|
||||
// Reset the colors used to render the extrusion roles to the default value.
|
||||
//
|
||||
void reset_default_extrusion_roles_colors();
|
||||
//
|
||||
// Return the color used to render the given option.
|
||||
//
|
||||
const Color& get_option_color(EOptionType type) const;
|
||||
//
|
||||
// Set the color used to render the given option.
|
||||
//
|
||||
void set_option_color(EOptionType type, const Color& color);
|
||||
//
|
||||
// Reset the colors used to render the options to the default value.
|
||||
//
|
||||
void reset_default_options_colors();
|
||||
//
|
||||
// Return the count of colors in the palette used to render
|
||||
// the toolpaths when the view type is EViewType::Tool.
|
||||
//
|
||||
size_t get_tool_colors_count() const;
|
||||
//
|
||||
// Return the palette used to render the toolpaths when
|
||||
// the view type is EViewType::Tool.
|
||||
//
|
||||
const Palette& get_tool_colors() const;
|
||||
//
|
||||
// Set the palette used to render the toolpaths when
|
||||
// the view type is EViewType::Tool with the given one.
|
||||
//
|
||||
void set_tool_colors(const Palette& colors);
|
||||
//
|
||||
// Return the count of colors in the palette used to render
|
||||
// the toolpaths when the view type is EViewType::ColorPrint.
|
||||
//
|
||||
size_t get_color_print_colors_count() const;
|
||||
//
|
||||
// Return the palette used to render the toolpaths when
|
||||
// the view type is EViewType::ColorPrint.
|
||||
//
|
||||
const Palette& get_color_print_colors() const;
|
||||
//
|
||||
// Set the palette used to render the toolpaths when
|
||||
// the view type is EViewType::ColorPrint with the given one.
|
||||
//
|
||||
void set_color_print_colors(const Palette& colors);
|
||||
//
|
||||
// Get the color range for the given view type.
|
||||
// Valid view types are:
|
||||
// EViewType::Height
|
||||
// EViewType::Width
|
||||
// EViewType::Speed
|
||||
// EViewType::ActualSpeed
|
||||
// EViewType::FanSpeed
|
||||
// EViewType::Temperature
|
||||
// EViewType::VolumetricFlowRate
|
||||
// EViewType::ActualVolumetricFlowRate
|
||||
// EViewType::LayerTimeLinear
|
||||
// EViewType::LayerTimeLogarithmic
|
||||
//
|
||||
const ColorRange& get_color_range(EViewType type) const;
|
||||
//
|
||||
// Set the palette for the color range corresponding to the given view type
|
||||
// with the given value.
|
||||
// Valid view types are:
|
||||
// EViewType::Height
|
||||
// EViewType::Width
|
||||
// EViewType::Speed
|
||||
// EViewType::ActualSpeed
|
||||
// EViewType::FanSpeed
|
||||
// EViewType::Temperature
|
||||
// EViewType::VolumetricFlowRate
|
||||
// EViewType::ActualVolumetricFlowRate
|
||||
// EViewType::LayerTimeLinear
|
||||
// EViewType::LayerTimeLogarithmic
|
||||
//
|
||||
void set_color_range_palette(EViewType type, const Palette& palette);
|
||||
//
|
||||
// Get the radius, in mm, of the cylinders used to render the travel moves.
|
||||
//
|
||||
float get_travels_radius() const;
|
||||
//
|
||||
// Set the radius, in mm, of the cylinders used to render the travel moves.
|
||||
// Radius is clamped to [MIN_TRAVELS_RADIUS_MM..MAX_TRAVELS_RADIUS_MM]
|
||||
//
|
||||
void set_travels_radius(float radius);
|
||||
//
|
||||
// Get the radius, in mm, of the cylinders used to render the wipe moves.
|
||||
//
|
||||
float get_wipes_radius() const;
|
||||
//
|
||||
// Set the radius, in mm, of the cylinders used to render the wipe moves.
|
||||
// Radius is clamped to [MIN_WIPES_RADIUS_MM..MAX_WIPES_RADIUS_MM]
|
||||
//
|
||||
void set_wipes_radius(float radius);
|
||||
//
|
||||
// Return the count of detected layers.
|
||||
//
|
||||
size_t get_layers_count() const;
|
||||
//
|
||||
// Return the current visible layers range.
|
||||
//
|
||||
const Interval& get_layers_view_range() const;
|
||||
//
|
||||
// Set the current visible layers range with the given interval.
|
||||
// Values are clamped to [0..get_layers_count() - 1].
|
||||
//
|
||||
void set_layers_view_range(const Interval& range);
|
||||
//
|
||||
// Set the current visible layers range with the given min and max values.
|
||||
// Values are clamped to [0..get_layers_count() - 1].
|
||||
//
|
||||
void set_layers_view_range(Interval::value_type min, Interval::value_type max);
|
||||
//
|
||||
// Return the current visible range.
|
||||
// Three ranges are defined: full, enabled and visible.
|
||||
// For all of them the range endpoints represent:
|
||||
// [0] -> min vertex id
|
||||
// [1] -> max vertex id
|
||||
// Full is the range of vertices that could potentially be visualized accordingly to the current settings.
|
||||
// Enabled is the part of the full range that is selected for visualization accordingly to the current settings.
|
||||
// Visible is the part of the enabled range that is actually visualized accordingly to the current settings.
|
||||
//
|
||||
const Interval& get_view_visible_range() const;
|
||||
//
|
||||
// Set the current visible range.
|
||||
// Values are clamped to the current view enabled range;
|
||||
//
|
||||
void set_view_visible_range(Interval::value_type min, Interval::value_type max);
|
||||
//
|
||||
// Return the current full range.
|
||||
//
|
||||
const Interval& get_view_full_range() const;
|
||||
//
|
||||
// Return the current enabled range.
|
||||
//
|
||||
const Interval& get_view_enabled_range() const;
|
||||
|
||||
//
|
||||
// ************************************************************************
|
||||
// Property getters
|
||||
// The following methods can be used to query detected properties.
|
||||
// ************************************************************************
|
||||
//
|
||||
|
||||
//
|
||||
// Spiral vase mode
|
||||
// Whether or not the gcode was generated with spiral vase mode enabled.
|
||||
// See: GCodeInputData
|
||||
//
|
||||
bool is_spiral_vase_mode() const;
|
||||
//
|
||||
// Return the z of the layer with the given id
|
||||
// or 0.0f if the id does not belong to [0..get_layers_count() - 1].
|
||||
//
|
||||
float get_layer_z(size_t layer_id) const;
|
||||
//
|
||||
// Return the list of zs of the detected layers.
|
||||
//
|
||||
std::vector<float> get_layers_zs() const;
|
||||
//
|
||||
// Return the id of the layer closest to the given z.
|
||||
//
|
||||
size_t get_layer_id_at(float z) const;
|
||||
//
|
||||
// Return the count of detected used extruders.
|
||||
//
|
||||
size_t get_used_extruders_count() const;
|
||||
//
|
||||
// Return the list of ids of the detected used extruders.
|
||||
//
|
||||
std::vector<uint8_t> get_used_extruders_ids() const;
|
||||
//
|
||||
// Return the list of detected time modes.
|
||||
//
|
||||
std::vector<ETimeMode> get_time_modes() const;
|
||||
//
|
||||
// Return the count of vertices used to render the toolpaths
|
||||
//
|
||||
size_t get_vertices_count() const;
|
||||
//
|
||||
// Return the vertex pointed by the max value of the view visible range
|
||||
//
|
||||
const PathVertex& get_current_vertex() const;
|
||||
//
|
||||
// Return the index of vertex pointed by the max value of the view visible range
|
||||
//
|
||||
size_t get_current_vertex_id() const;
|
||||
//
|
||||
// Return the vertex at the given index
|
||||
//
|
||||
const PathVertex& get_vertex_at(size_t id) const;
|
||||
//
|
||||
// Return the total estimated time, in seconds, using the current time mode.
|
||||
//
|
||||
float get_estimated_time() const;
|
||||
//
|
||||
// Return the estimated time, in seconds, at the vertex with the given index
|
||||
// using the current time mode.
|
||||
//
|
||||
float get_estimated_time_at(size_t id) const;
|
||||
//
|
||||
// Return the color used to render the given vertex with the current settings.
|
||||
//
|
||||
Color get_vertex_color(const PathVertex& vertex) const;
|
||||
//
|
||||
// Return the count of detected extrusion roles
|
||||
//
|
||||
size_t get_extrusion_roles_count() const;
|
||||
//
|
||||
// Return the list of detected extrusion roles
|
||||
//
|
||||
std::vector<EGCodeExtrusionRole> get_extrusion_roles() const;
|
||||
//
|
||||
// Return the count of detected options.
|
||||
//
|
||||
size_t get_options_count() const;
|
||||
//
|
||||
// Return the list of detected options.
|
||||
//
|
||||
const std::vector<EOptionType>& get_options() const;
|
||||
//
|
||||
// Return the count of detected color prints.
|
||||
//
|
||||
size_t get_color_prints_count(uint8_t extruder_id) const;
|
||||
//
|
||||
// Return the list of detected color prints.
|
||||
//
|
||||
std::vector<ColorPrint> get_color_prints(uint8_t extruder_id) const;
|
||||
//
|
||||
// Return the estimated time for the given role and the current time mode.
|
||||
//
|
||||
float get_extrusion_role_estimated_time(EGCodeExtrusionRole role) const;
|
||||
//
|
||||
// Return the estimated time for the travel moves and the current time mode.
|
||||
//
|
||||
float get_travels_estimated_time() const;
|
||||
//
|
||||
// Return the list of layers time for the current time mode.
|
||||
//
|
||||
std::vector<float> get_layers_estimated_times() const;
|
||||
//
|
||||
// Return the axes aligned bounding box containing all the given types.
|
||||
//
|
||||
AABox get_bounding_box(const std::vector<EMoveType>& types = {
|
||||
EMoveType::Retract, EMoveType::Unretract, EMoveType::Seam, EMoveType::ToolChange,
|
||||
EMoveType::ColorChange, EMoveType::PausePrint, EMoveType::CustomGCode, EMoveType::Travel,
|
||||
EMoveType::Wipe, EMoveType::Extrude }) const;
|
||||
//
|
||||
// Return the axes aligned bounding box containing all the extrusions with the given roles.
|
||||
//
|
||||
AABox get_extrusion_bounding_box(const std::vector<EGCodeExtrusionRole>& roles = {
|
||||
EGCodeExtrusionRole::Perimeter, EGCodeExtrusionRole::ExternalPerimeter, EGCodeExtrusionRole::OverhangPerimeter,
|
||||
EGCodeExtrusionRole::InternalInfill, EGCodeExtrusionRole::SolidInfill, EGCodeExtrusionRole::TopSolidInfill,
|
||||
EGCodeExtrusionRole::Ironing, EGCodeExtrusionRole::BridgeInfill, EGCodeExtrusionRole::GapFill,
|
||||
EGCodeExtrusionRole::Skirt, EGCodeExtrusionRole::SupportMaterial, EGCodeExtrusionRole::SupportMaterialInterface,
|
||||
EGCodeExtrusionRole::WipeTower, EGCodeExtrusionRole::Custom,
|
||||
// ORCA
|
||||
EGCodeExtrusionRole::BottomSurface, EGCodeExtrusionRole::InternalBridgeInfill, EGCodeExtrusionRole::Brim,
|
||||
EGCodeExtrusionRole::SupportTransition, EGCodeExtrusionRole::Mixed
|
||||
}) const;
|
||||
//
|
||||
// Return the size of the used cpu memory, in bytes
|
||||
//
|
||||
size_t get_used_cpu_memory() const;
|
||||
//
|
||||
// Return the size of the used gpu memory, in bytes
|
||||
//
|
||||
size_t get_used_gpu_memory() const;
|
||||
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
//
|
||||
// Returns the position of the center of gravity of the toolpaths.
|
||||
// It does not take in account extrusions of type:
|
||||
// Skirt
|
||||
// Support Material
|
||||
// Support Material Interface
|
||||
// WipeTower
|
||||
// Custom
|
||||
//
|
||||
Vec3 get_cog_position() const;
|
||||
|
||||
float get_cog_marker_scale_factor() const;
|
||||
void set_cog_marker_scale_factor(float factor);
|
||||
|
||||
const Vec3& get_tool_marker_position() const;
|
||||
|
||||
float get_tool_marker_offset_z() const;
|
||||
void set_tool_marker_offset_z(float offset_z);
|
||||
|
||||
float get_tool_marker_scale_factor() const;
|
||||
void set_tool_marker_scale_factor(float factor);
|
||||
|
||||
const Color& get_tool_marker_color() const;
|
||||
void set_tool_marker_color(const Color& color);
|
||||
|
||||
float get_tool_marker_alpha() const;
|
||||
void set_tool_marker_alpha(float alpha);
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
private:
|
||||
ViewerImpl* m_impl{ nullptr };
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_VIEWER_HPP
|
||||
8
src/libvgcode/src/Bitset.cpp
Normal file
8
src/libvgcode/src/Bitset.cpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "Bitset.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
} // namespace libvgcode
|
||||
103
src/libvgcode/src/Bitset.hpp
Normal file
103
src/libvgcode/src/Bitset.hpp
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_BITSET_HPP
|
||||
#define VGCODE_BITSET_HPP
|
||||
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
// By default, types are not atomic,
|
||||
template<typename T> auto constexpr is_atomic = false;
|
||||
|
||||
// but std::atomic<T> types are,
|
||||
template<typename T> auto constexpr is_atomic<std::atomic<T>> = true;
|
||||
|
||||
template<typename T = unsigned long long>
|
||||
struct BitSet
|
||||
{
|
||||
BitSet() = default;
|
||||
BitSet(std::size_t size) : size(size), blocks(1 + (size / (sizeof(T) * 8))) { clear(); }
|
||||
|
||||
void clear() {
|
||||
for (std::size_t i = 0; i < blocks.size(); ++i) {
|
||||
blocks[i] &= T(0);
|
||||
}
|
||||
}
|
||||
|
||||
void setAll() {
|
||||
for (std::size_t i = 0; i < blocks.size(); ++i) {
|
||||
blocks[i] |= ~T(0);
|
||||
}
|
||||
}
|
||||
|
||||
//return true if bit changed
|
||||
bool set(std::size_t index) {
|
||||
const auto [block_idx, bit_idx] = get_coords(index);
|
||||
const T mask = (T(1) << bit_idx);
|
||||
bool flip = mask ^ blocks[block_idx];
|
||||
blocks[block_idx] |= mask;
|
||||
return flip;
|
||||
}
|
||||
|
||||
//return true if bit changed
|
||||
bool reset(std::size_t index) {
|
||||
const auto [block_idx, bit_idx] = get_coords(index);
|
||||
const T mask = (T(1) << bit_idx);
|
||||
const bool flip = mask ^ blocks[block_idx];
|
||||
blocks[block_idx] &= (~mask);
|
||||
return flip;
|
||||
}
|
||||
|
||||
bool operator [] (std::size_t index) const {
|
||||
const auto [block_idx, bit_idx] = get_coords(index);
|
||||
return ((blocks[block_idx] >> bit_idx) & 1) != 0;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
BitSet& operator &= (const BitSet<U>& other) {
|
||||
static_assert(sizeof(T) == sizeof(U), "Type1 and Type2 must be of the same size.");
|
||||
for (std::size_t i = 0; i < blocks.size(); ++i) {
|
||||
blocks[i] &= other.blocks[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Atomic set operation (enabled only for atomic types), return true if bit changed
|
||||
template<typename U = T>
|
||||
inline typename std::enable_if<is_atomic<U>, bool>::type set_atomic(std::size_t index) {
|
||||
const auto [block_idx, bit_idx] = get_coords(index);
|
||||
const T mask = static_cast<T>(1) << bit_idx;
|
||||
const T oldval = blocks[block_idx].fetch_or(mask, std::memory_order_relaxed);
|
||||
return oldval ^ (oldval or mask);
|
||||
}
|
||||
|
||||
// Atomic reset operation (enabled only for atomic types), return true if bit changed
|
||||
template<typename U = T>
|
||||
inline typename std::enable_if<is_atomic<U>, bool>::type reset_atomic(std::size_t index) {
|
||||
const auto [block_idx, bit_idx] = get_coords(index);
|
||||
const T mask = ~(static_cast<T>(1) << bit_idx);
|
||||
const T oldval = blocks[block_idx].fetch_and(mask, std::memory_order_relaxed);
|
||||
return oldval ^ (oldval and mask);
|
||||
}
|
||||
|
||||
std::pair<std::size_t, std::size_t> get_coords(std::size_t index) const {
|
||||
const std::size_t block_idx = index / (sizeof(T) * 8);
|
||||
const std::size_t bit_idx = index % (sizeof(T) * 8);
|
||||
return { block_idx, bit_idx };
|
||||
}
|
||||
|
||||
std::size_t size_in_bytes_cpu() const {
|
||||
return blocks.size() * sizeof(T);
|
||||
}
|
||||
|
||||
std::size_t size{ 0 };
|
||||
std::vector<T> blocks{ 0 };
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_BITSET_HPP
|
||||
173
src/libvgcode/src/CogMarker.cpp
Normal file
173
src/libvgcode/src/CogMarker.cpp
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
// needed for tech VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#include "../include/Types.hpp"
|
||||
#include "CogMarker.hpp"
|
||||
#include "OpenGLUtils.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
// Geometry:
|
||||
// sphere with 'resolution' sides, centered at (0.0, 0.0, 0.0) and radius equal to 'radius'
|
||||
void CogMarker::init(uint8_t resolution, float radius)
|
||||
{
|
||||
if (m_vao_id != 0)
|
||||
return;
|
||||
|
||||
// ensure vertices count does not exceed 65536
|
||||
resolution = std::clamp<uint8_t>(resolution, 4, 105);
|
||||
|
||||
const uint16_t sector_count = (uint16_t)resolution;
|
||||
const uint16_t stack_count = (uint16_t)resolution;
|
||||
|
||||
const float sector_step = 2.0f * PI / float(sector_count);
|
||||
const float stack_step = PI / float(stack_count);
|
||||
|
||||
std::vector<float> vertices;
|
||||
const uint16_t vertices_count = (stack_count - 1) * sector_count + 2;
|
||||
vertices.reserve(6 * vertices_count);
|
||||
|
||||
m_indices_count = 3 * (2 * (stack_count - 1) * sector_count);
|
||||
std::vector<uint16_t> indices;
|
||||
indices.reserve(m_indices_count);
|
||||
|
||||
// vertices
|
||||
for (uint16_t i = 0; i <= stack_count; ++i) {
|
||||
// from pi/2 to -pi/2
|
||||
const float stack_angle = 0.5f * PI - stack_step * float(i);
|
||||
const float xy = radius * std::cos(stack_angle);
|
||||
const float z = radius * std::sin(stack_angle);
|
||||
if (i == 0 || i == stack_count) {
|
||||
const Vec3 pos = { xy, 0.0f, z };
|
||||
const Vec3 norm = normalize(pos);
|
||||
add_vertex(pos, norm, vertices);
|
||||
}
|
||||
else {
|
||||
for (uint16_t j = 0; j < sector_count; ++j) {
|
||||
// from 0 to 2pi
|
||||
const float sector_angle = sector_step * float(j);
|
||||
const Vec3 pos = { xy * std::cos(sector_angle), xy * std::sin(sector_angle), z };
|
||||
const Vec3 norm = normalize(pos);
|
||||
add_vertex(pos, norm, vertices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// indices
|
||||
for (uint16_t i = 0; i < stack_count; ++i) {
|
||||
// Beginning of current stack.
|
||||
uint16_t k1 = (i == 0) ? 0 : (1 + (i - 1) * sector_count);
|
||||
const uint16_t k1_first = k1;
|
||||
// Beginning of next stack.
|
||||
uint16_t k2 = (i == 0) ? 1 : (k1 + sector_count);
|
||||
const uint16_t k2_first = k2;
|
||||
for (uint16_t j = 0; j < sector_count; ++j) {
|
||||
// 2 triangles per sector excluding first and last stacks
|
||||
uint16_t k1_next = k1;
|
||||
uint16_t k2_next = k2;
|
||||
if (i != 0) {
|
||||
k1_next = (j + 1 == sector_count) ? k1_first : (k1 + 1);
|
||||
add_triangle(k1, k2, k1_next, indices);
|
||||
}
|
||||
if (i + 1 != stack_count) {
|
||||
k2_next = (j + 1 == sector_count) ? k2_first : (k2 + 1);
|
||||
add_triangle(k1_next, k2, k2_next, indices);
|
||||
}
|
||||
k1 = k1_next;
|
||||
k2 = k2_next;
|
||||
}
|
||||
}
|
||||
|
||||
m_size_in_bytes_gpu += vertices.size() * sizeof(float);
|
||||
m_size_in_bytes_gpu += indices.size() * sizeof(uint16_t);
|
||||
|
||||
const size_t vertex_stride = 6 * sizeof(float);
|
||||
const size_t position_offset = 0;
|
||||
const size_t normal_offset = 3 * sizeof(float);
|
||||
|
||||
int curr_vertex_array;
|
||||
glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array));
|
||||
int curr_array_buffer;
|
||||
glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer));
|
||||
|
||||
glsafe(glGenVertexArrays(1, &m_vao_id));
|
||||
glsafe(glBindVertexArray(m_vao_id));
|
||||
glsafe(glGenBuffers(1, &m_vbo_id));
|
||||
glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
|
||||
glsafe(glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW));
|
||||
glsafe(glEnableVertexAttribArray(0));
|
||||
glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset));
|
||||
glsafe(glEnableVertexAttribArray(1));
|
||||
glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset));
|
||||
|
||||
glsafe(glGenBuffers(1, &m_ibo_id));
|
||||
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id));
|
||||
glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW));
|
||||
|
||||
glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer));
|
||||
glsafe(glBindVertexArray(curr_vertex_array));
|
||||
}
|
||||
|
||||
void CogMarker::shutdown()
|
||||
{
|
||||
if (m_ibo_id != 0) {
|
||||
glsafe(glDeleteBuffers(1, &m_ibo_id));
|
||||
m_ibo_id = 0;
|
||||
}
|
||||
if (m_vbo_id != 0) {
|
||||
glsafe(glDeleteBuffers(1, &m_vbo_id));
|
||||
m_vbo_id = 0;
|
||||
}
|
||||
if (m_vao_id != 0) {
|
||||
glsafe(glDeleteVertexArrays(1, &m_vao_id));
|
||||
m_vao_id = 0;
|
||||
}
|
||||
|
||||
m_size_in_bytes_gpu = 0;
|
||||
}
|
||||
|
||||
void CogMarker::render()
|
||||
{
|
||||
if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0 || m_indices_count == 0)
|
||||
return;
|
||||
|
||||
int curr_vertex_array;
|
||||
glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array));
|
||||
glcheck();
|
||||
|
||||
glsafe(glBindVertexArray(m_vao_id));
|
||||
glsafe(glDrawElements(GL_TRIANGLES, m_indices_count, GL_UNSIGNED_SHORT, (const void*)0));
|
||||
glsafe(glBindVertexArray(curr_vertex_array));
|
||||
}
|
||||
|
||||
void CogMarker::update(const Vec3& position, float mass)
|
||||
{
|
||||
m_total_position = m_total_position + mass * position;
|
||||
m_total_mass += mass;
|
||||
}
|
||||
|
||||
void CogMarker::reset()
|
||||
{
|
||||
m_total_position = { 0.0f, 0.0f, 0.0f };
|
||||
m_total_mass = 0.0f;
|
||||
}
|
||||
|
||||
Vec3 CogMarker::get_position() const
|
||||
{
|
||||
assert(m_total_mass > 0.0f);
|
||||
const float inv_total_mass = 1.0f / m_total_mass;
|
||||
return inv_total_mass * m_total_position;
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
77
src/libvgcode/src/CogMarker.hpp
Normal file
77
src/libvgcode/src/CogMarker.hpp
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_COGMARKER_HPP
|
||||
#define VGCODE_COGMARKER_HPP
|
||||
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
class CogMarker
|
||||
{
|
||||
public:
|
||||
CogMarker() = default;
|
||||
~CogMarker() { shutdown(); }
|
||||
CogMarker(const CogMarker& other) = delete;
|
||||
CogMarker(CogMarker&& other) = delete;
|
||||
CogMarker& operator = (const CogMarker& other) = delete;
|
||||
CogMarker& operator = (CogMarker&& other) = delete;
|
||||
|
||||
//
|
||||
// Initialize gpu buffers
|
||||
//
|
||||
void init(uint8_t resolution, float radius);
|
||||
//
|
||||
// Release gpu buffers
|
||||
//
|
||||
void shutdown();
|
||||
//
|
||||
// Render the marker
|
||||
//
|
||||
void render();
|
||||
//
|
||||
// Update values used to calculate the center of gravity
|
||||
//
|
||||
void update(const Vec3& position, float mass);
|
||||
//
|
||||
// Reset values used to calculate the center of gravity
|
||||
//
|
||||
void reset();
|
||||
//
|
||||
// Return the calculated center of gravity position
|
||||
//
|
||||
Vec3 get_position() const;
|
||||
//
|
||||
// Return the size of the data sent to gpu, in bytes.
|
||||
//
|
||||
size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; }
|
||||
|
||||
private:
|
||||
//
|
||||
// Values used to calculate the center of gravity
|
||||
//
|
||||
float m_total_mass{ 0.0f };
|
||||
Vec3 m_total_position{ 0.0f, 0.0f, 0.0f };
|
||||
//
|
||||
// The count of indices stored into the ibo buffer.
|
||||
//
|
||||
uint16_t m_indices_count{ 0 };
|
||||
//
|
||||
// gpu buffers ids.
|
||||
//
|
||||
unsigned int m_vao_id{ 0 };
|
||||
unsigned int m_vbo_id{ 0 };
|
||||
unsigned int m_ibo_id{ 0 };
|
||||
//
|
||||
// Size of the data sent to gpu, in bytes.
|
||||
//
|
||||
size_t m_size_in_bytes_gpu{ 0 };
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
#endif // VGCODE_COGMARKER_HPP
|
||||
8
src/libvgcode/src/ColorPrint.cpp
Normal file
8
src/libvgcode/src/ColorPrint.cpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "../include/ColorPrint.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
} // namespace libvgcode
|
||||
139
src/libvgcode/src/ColorRange.cpp
Normal file
139
src/libvgcode/src/ColorRange.cpp
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "../include/ColorRange.hpp"
|
||||
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
const ColorRange ColorRange::DUMMY_COLOR_RANGE = ColorRange();
|
||||
|
||||
static float get_step_size(const ColorRange& color_range)
|
||||
{
|
||||
const std::array<float, 2>& range = color_range.get_range();
|
||||
const Palette& palette = color_range.get_palette();
|
||||
switch (color_range.get_type())
|
||||
{
|
||||
default:
|
||||
case EColorRangeType::Linear:
|
||||
{
|
||||
return (range[1] - range[0]) / (static_cast<float>(palette.size()) - 1.0f);
|
||||
}
|
||||
case EColorRangeType::Logarithmic:
|
||||
{
|
||||
return (range[0] != 0.0f) ? std::log(range[1] / range[0]) / (static_cast<float>(palette.size()) - 1.0f) : 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColorRange::ColorRange(EColorRangeType type)
|
||||
: m_type(type)
|
||||
, m_palette(DEFAULT_RANGES_COLORS)
|
||||
{
|
||||
}
|
||||
|
||||
EColorRangeType ColorRange::get_type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
const Palette& ColorRange::get_palette() const
|
||||
{
|
||||
return m_palette;
|
||||
}
|
||||
|
||||
void ColorRange::set_palette(const Palette& palette)
|
||||
{
|
||||
if (palette.size() > 1)
|
||||
m_palette = palette;
|
||||
}
|
||||
|
||||
Color ColorRange::get_color_at(float value) const
|
||||
{
|
||||
// Input value scaled to the colors range
|
||||
float global_t = 0.0f;
|
||||
value = std::clamp(value, m_range[0], m_range[1]);
|
||||
const float step = get_step_size(*this);
|
||||
if (step > 0.0f) {
|
||||
if (m_type == EColorRangeType::Logarithmic) {
|
||||
if (m_range[0] != 0.0f)
|
||||
global_t = std::log(value / m_range[0]) / step;
|
||||
}
|
||||
else
|
||||
global_t = (value - m_range[0]) / step;
|
||||
}
|
||||
|
||||
const size_t color_max_idx = m_palette.size() - 1;
|
||||
|
||||
// Compute the two colors just below (low) and above (high) the input value
|
||||
const size_t color_low_idx = std::clamp<size_t>(static_cast<size_t>(global_t), 0, color_max_idx);
|
||||
const size_t color_high_idx = std::clamp<size_t>(color_low_idx + 1, 0, color_max_idx);
|
||||
|
||||
// Interpolate between the low and high colors to find exactly which color the input value should get
|
||||
return lerp(m_palette[color_low_idx], m_palette[color_high_idx], global_t - static_cast<float>(color_low_idx));
|
||||
}
|
||||
|
||||
const std::array<float, 2>& ColorRange::get_range() const
|
||||
{
|
||||
return m_range;
|
||||
}
|
||||
|
||||
std::vector<float> ColorRange::get_values() const
|
||||
{
|
||||
std::vector<float> ret;
|
||||
|
||||
if (m_count == 1) {
|
||||
// single item use case
|
||||
ret.emplace_back(m_range[0]);
|
||||
}
|
||||
else if (m_count == 2) {
|
||||
// two items use case
|
||||
ret.emplace_back(m_range[0]);
|
||||
ret.emplace_back(m_range[1]);
|
||||
}
|
||||
else {
|
||||
const float step_size = get_step_size(*this);
|
||||
for (size_t i = 0; i < m_palette.size(); ++i) {
|
||||
float value = 0.0f;
|
||||
switch (m_type)
|
||||
{
|
||||
default:
|
||||
case EColorRangeType::Linear: { value = m_range[0] + static_cast<float>(i) * step_size; break; }
|
||||
case EColorRangeType::Logarithmic: { value = ::exp(::log(m_range[0]) + static_cast<float>(i) * step_size); break; }
|
||||
}
|
||||
ret.emplace_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ColorRange::size_in_bytes_cpu() const
|
||||
{
|
||||
size_t ret = STDVEC_MEMSIZE(m_palette, Color);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ColorRange::update(float value)
|
||||
{
|
||||
if (value != m_range[0] && value != m_range[1])
|
||||
++m_count;
|
||||
|
||||
m_range[0] = std::min(m_range[0], value);
|
||||
m_range[1] = std::max(m_range[1], value);
|
||||
}
|
||||
|
||||
void ColorRange::reset()
|
||||
{
|
||||
m_range = { FLT_MAX, -FLT_MAX };
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
39
src/libvgcode/src/ExtrusionRoles.cpp
Normal file
39
src/libvgcode/src/ExtrusionRoles.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "ExtrusionRoles.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
void ExtrusionRoles::add(EGCodeExtrusionRole role, const std::array<float, TIME_MODES_COUNT>& times)
|
||||
{
|
||||
auto role_it = m_items.find(role);
|
||||
if (role_it == m_items.end())
|
||||
role_it = m_items.insert(std::make_pair(role, Item())).first;
|
||||
|
||||
for (std::size_t i = 0; i < TIME_MODES_COUNT; ++i) {
|
||||
role_it->second.times[i] += times[i];
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<EGCodeExtrusionRole> ExtrusionRoles::get_roles() const
|
||||
{
|
||||
std::vector<EGCodeExtrusionRole> ret;
|
||||
ret.reserve(m_items.size());
|
||||
for (const auto& [role, item] : m_items) {
|
||||
ret.emplace_back(role);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
float ExtrusionRoles::get_time(EGCodeExtrusionRole role, ETimeMode mode) const
|
||||
{
|
||||
const auto role_it = m_items.find(role);
|
||||
if (role_it == m_items.end())
|
||||
return 0.0f;
|
||||
|
||||
return (mode < ETimeMode::COUNT) ? role_it->second.times[static_cast<std::size_t>(mode)] : 0.0f;
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
36
src/libvgcode/src/ExtrusionRoles.hpp
Normal file
36
src/libvgcode/src/ExtrusionRoles.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_EXTRUSION_ROLES_HPP
|
||||
#define VGCODE_EXTRUSION_ROLES_HPP
|
||||
|
||||
#include "../include/Types.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
class ExtrusionRoles
|
||||
{
|
||||
public:
|
||||
struct Item
|
||||
{
|
||||
std::array<float, TIME_MODES_COUNT> times;
|
||||
};
|
||||
|
||||
void add(EGCodeExtrusionRole role, const std::array<float, TIME_MODES_COUNT>& times);
|
||||
|
||||
std::size_t get_roles_count() const { return m_items.size(); }
|
||||
std::vector<EGCodeExtrusionRole> get_roles() const;
|
||||
float get_time(EGCodeExtrusionRole role, ETimeMode mode) const;
|
||||
|
||||
void reset() { m_items.clear(); }
|
||||
|
||||
private:
|
||||
std::map<EGCodeExtrusionRole, Item> m_items;
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_EXTRUSION_ROLES_HPP
|
||||
8
src/libvgcode/src/GCodeInputData.cpp
Normal file
8
src/libvgcode/src/GCodeInputData.cpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "../include/GCodeInputData.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
} // namespace libvgcode
|
||||
83
src/libvgcode/src/Layers.cpp
Normal file
83
src/libvgcode/src/Layers.cpp
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "Layers.hpp"
|
||||
|
||||
#include "../include/PathVertex.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
static bool is_colorprint_option(const PathVertex& v)
|
||||
{
|
||||
return v.type == EMoveType::PausePrint || v.type == EMoveType::CustomGCode;
|
||||
}
|
||||
|
||||
void Layers::update(const PathVertex& vertex, uint32_t vertex_id)
|
||||
{
|
||||
if (m_items.empty() || vertex.layer_id == m_items.size()) {
|
||||
// this code assumes that gcode paths are sent sequentially, one layer after the other
|
||||
assert(vertex.layer_id == static_cast<uint32_t>(m_items.size()));
|
||||
Item& item = m_items.emplace_back(Item());
|
||||
if (vertex.type == EMoveType::Extrude && vertex.role != EGCodeExtrusionRole::Custom)
|
||||
item.z = vertex.position[2];
|
||||
item.range.set(vertex_id, vertex_id);
|
||||
item.times = vertex.times;
|
||||
item.contains_colorprint_options |= is_colorprint_option(vertex);
|
||||
}
|
||||
else {
|
||||
Item& item = m_items.back();
|
||||
if (vertex.type == EMoveType::Extrude && vertex.role != EGCodeExtrusionRole::Custom && item.z != vertex.position[2])
|
||||
item.z = vertex.position[2];
|
||||
item.range.set_max(vertex_id);
|
||||
for (size_t i = 0; i < TIME_MODES_COUNT; ++i) {
|
||||
item.times[i] += vertex.times[i];
|
||||
}
|
||||
item.contains_colorprint_options |= is_colorprint_option(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
void Layers::reset()
|
||||
{
|
||||
m_items.clear();
|
||||
m_view_range.reset();
|
||||
}
|
||||
|
||||
std::vector<float> Layers::get_times(ETimeMode mode) const
|
||||
{
|
||||
std::vector<float> ret;
|
||||
if (mode < ETimeMode::COUNT) {
|
||||
for (const Item& item : m_items) {
|
||||
ret.emplace_back(item.times[static_cast<size_t>(mode)]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<float> Layers::get_zs() const
|
||||
{
|
||||
std::vector<float> ret;
|
||||
ret.reserve(m_items.size());
|
||||
for (const Item& item : m_items) {
|
||||
ret.emplace_back(item.z);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t Layers::get_layer_id_at(float z) const
|
||||
{
|
||||
auto iter = std::upper_bound(m_items.begin(), m_items.end(), z, [](float z, const Item& item) { return item.z < z; });
|
||||
return std::distance(m_items.begin(), iter);
|
||||
}
|
||||
|
||||
size_t Layers::size_in_bytes_cpu() const
|
||||
{
|
||||
size_t ret = STDVEC_MEMSIZE(m_items, Item);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
60
src/libvgcode/src/Layers.hpp
Normal file
60
src/libvgcode/src/Layers.hpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_LAYERS_HPP
|
||||
#define VGCODE_LAYERS_HPP
|
||||
|
||||
#include "Range.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
struct PathVertex;
|
||||
|
||||
class Layers
|
||||
{
|
||||
public:
|
||||
void update(const PathVertex& vertex, uint32_t vertex_id);
|
||||
void reset();
|
||||
|
||||
bool empty() const { return m_items.empty(); }
|
||||
std::size_t count() const { return m_items.size(); }
|
||||
|
||||
std::vector<float> get_times(ETimeMode mode) const;
|
||||
std::vector<float> get_zs() const;
|
||||
|
||||
float get_layer_time(ETimeMode mode, std::size_t layer_id) const {
|
||||
return (mode < ETimeMode::COUNT&& layer_id < m_items.size()) ?
|
||||
m_items[layer_id].times[static_cast<std::size_t>(mode)] : 0.0f;
|
||||
}
|
||||
float get_layer_z(std::size_t layer_id) const {
|
||||
return (layer_id < m_items.size()) ? m_items[layer_id].z : 0.0f;
|
||||
}
|
||||
std::size_t get_layer_id_at(float z) const;
|
||||
|
||||
const Interval& get_view_range() const { return m_view_range.get(); }
|
||||
void set_view_range(const Interval& range) { set_view_range(range[0], range[1]); }
|
||||
void set_view_range(Interval::value_type min, Interval::value_type max) { m_view_range.set(min, max); }
|
||||
|
||||
bool layer_contains_colorprint_options(std::size_t layer_id) const {
|
||||
return (layer_id < m_items.size()) ? m_items[layer_id].contains_colorprint_options : false;
|
||||
}
|
||||
|
||||
std::size_t size_in_bytes_cpu() const;
|
||||
|
||||
private:
|
||||
struct Item
|
||||
{
|
||||
float z{ 0.0f };
|
||||
Range range;
|
||||
std::array<float, TIME_MODES_COUNT> times{ 0.0f, 0.0f };
|
||||
bool contains_colorprint_options{ false };
|
||||
};
|
||||
|
||||
std::vector<Item> m_items;
|
||||
Range m_view_range;
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_LAYERS_HPP
|
||||
98
src/libvgcode/src/OpenGLUtils.cpp
Normal file
98
src/libvgcode/src/OpenGLUtils.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak, Vojtěch Bubník @bubnikv
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
|
||||
#include "OpenGLUtils.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include <cctype>
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
#ifdef HAS_GLSAFE
|
||||
void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char* function_name)
|
||||
{
|
||||
const GLenum err = glGetError();
|
||||
if (err == GL_NO_ERROR)
|
||||
return;
|
||||
const char* sErr = 0;
|
||||
switch (err) {
|
||||
case GL_INVALID_ENUM: { sErr = "Invalid Enum"; break; }
|
||||
case GL_INVALID_VALUE: { sErr = "Invalid Value"; break; }
|
||||
// be aware that GL_INVALID_OPERATION is generated if glGetError is executed between the execution of glBegin / glEnd
|
||||
case GL_INVALID_OPERATION: { sErr = "Invalid Operation"; break; }
|
||||
case GL_OUT_OF_MEMORY: { sErr = "Out Of Memory"; break; }
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION: { sErr = "Invalid framebuffer operation"; break; }
|
||||
#if !defined(ENABLE_OPENGL_ES)
|
||||
case GL_STACK_OVERFLOW: { sErr = "Stack Overflow"; break; }
|
||||
case GL_STACK_UNDERFLOW: { sErr = "Stack Underflow"; break; }
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
default: { sErr = "Unknown"; break; }
|
||||
}
|
||||
std::cout << "OpenGL error in " << file_name << ":" << line << ", function " << function_name << "() : " << (int)err << " - " << sErr << "\n";
|
||||
assert(false);
|
||||
}
|
||||
#endif // HAS_GLSAFE
|
||||
|
||||
static const char* OPENGL_ES_PREFIXES[] = { "OpenGL ES-CM ", "OpenGL ES-CL ", "OpenGL ES ", nullptr };
|
||||
|
||||
bool OpenGLWrapper::s_valid_context = false;
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
int OpenGLWrapper::s_max_texture_size = 0;
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
bool OpenGLWrapper::load_opengl(const std::string& context_version)
|
||||
{
|
||||
s_valid_context = false;
|
||||
|
||||
const char* version = context_version.c_str();
|
||||
for (int i = 0; OPENGL_ES_PREFIXES[i] != nullptr; ++i) {
|
||||
const size_t length = strlen(OPENGL_ES_PREFIXES[i]);
|
||||
if (strncmp(version, OPENGL_ES_PREFIXES[i], length) == 0) {
|
||||
version += length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GLint major = 0;
|
||||
GLint minor = 0;
|
||||
#ifdef _MSC_VER
|
||||
const int res = sscanf_s(version, "%d.%d", &major, &minor);
|
||||
#else
|
||||
const int res = sscanf(version, "%d.%d", &major, &minor);
|
||||
#endif // _MSC_VER
|
||||
if (res != 2)
|
||||
return false;
|
||||
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
s_valid_context = major > 3 || (major == 3 && minor >= 0);
|
||||
const int glad_res = gladLoaderLoadGLES2();
|
||||
#else
|
||||
s_valid_context = major > 3 || (major == 3 && minor >= 2);
|
||||
const int glad_res = gladLoaderLoadGL();
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
if (glad_res == 0)
|
||||
return false;
|
||||
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
glsafe(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &s_max_texture_size));
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
return s_valid_context;
|
||||
}
|
||||
|
||||
void OpenGLWrapper::unload_opengl()
|
||||
{
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
gladLoaderUnloadGLES2();
|
||||
#else
|
||||
gladLoaderUnloadGL();
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
52
src/libvgcode/src/OpenGLUtils.hpp
Normal file
52
src/libvgcode/src/OpenGLUtils.hpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak, Vojtěch Bubník @bubnikv
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_OPENGLUTILS_HPP
|
||||
#define VGCODE_OPENGLUTILS_HPP
|
||||
|
||||
// OpenGL loader
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
#include "../glad/include/glad/gles2.h"
|
||||
#else
|
||||
#include "../glad/include/glad/gl.h"
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace libvgcode {
|
||||
#ifndef NDEBUG
|
||||
#define HAS_GLSAFE
|
||||
#endif // NDEBUG
|
||||
|
||||
#ifdef HAS_GLSAFE
|
||||
extern void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char* function_name);
|
||||
inline void glAssertRecentCall() { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); }
|
||||
#define glsafe(cmd) do { cmd; glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } while (false)
|
||||
#define glcheck() do { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } while (false)
|
||||
#else
|
||||
inline void glAssertRecentCall() { }
|
||||
#define glsafe(cmd) cmd
|
||||
#define glcheck()
|
||||
#endif // HAS_GLSAFE
|
||||
|
||||
class OpenGLWrapper
|
||||
{
|
||||
public:
|
||||
static bool load_opengl(const std::string& context_version);
|
||||
static void unload_opengl();
|
||||
static bool is_valid_context() { return s_valid_context; }
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
static size_t max_texture_size() { return static_cast<size_t>(s_max_texture_size); }
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
private:
|
||||
static bool s_valid_context;
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
static int s_max_texture_size;
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_OPENGLUTILS_HPP
|
||||
126
src/libvgcode/src/OptionTemplate.cpp
Normal file
126
src/libvgcode/src/OptionTemplate.cpp
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "OptionTemplate.hpp"
|
||||
#include "OpenGLUtils.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
// Geometry:
|
||||
// diamond with 'resolution' sides, centered at (0.0, 0.0, 0.0)
|
||||
// height and width of the diamond are equal to 1.0
|
||||
void OptionTemplate::init(uint8_t resolution)
|
||||
{
|
||||
if (m_top_vao_id != 0)
|
||||
return;
|
||||
|
||||
m_resolution = std::max<uint8_t>(resolution, 3);
|
||||
m_vertices_count = 2 + resolution;
|
||||
const float step = 2.0f * PI / float(m_resolution);
|
||||
|
||||
//
|
||||
// top fan
|
||||
//
|
||||
std::vector<float> top_vertices;
|
||||
top_vertices.reserve(6 * m_vertices_count);
|
||||
add_vertex({ 0.0f, 0.0f, 0.5f }, { 0.0f, 0.0f, 1.0f }, top_vertices);
|
||||
for (uint8_t i = 0; i <= m_resolution; ++i) {
|
||||
const float ii = float(i) * step;
|
||||
const Vec3 pos = { 0.5f * std::cos(ii), 0.5f * std::sin(ii), 0.0f };
|
||||
const Vec3 norm = normalize(pos);
|
||||
add_vertex(pos, norm, top_vertices);
|
||||
}
|
||||
|
||||
//
|
||||
// bottom fan
|
||||
//
|
||||
std::vector<float> bottom_vertices;
|
||||
bottom_vertices.reserve(6 * m_vertices_count);
|
||||
add_vertex({ 0.0f, 0.0f, -0.5f }, { 0.0f, 0.0f, -1.0f }, bottom_vertices);
|
||||
for (uint8_t i = 0; i <= m_resolution; ++i) {
|
||||
const float ii = -float(i) * step;
|
||||
const Vec3 pos = { 0.5f * std::cos(ii), 0.5f * std::sin(ii), 0.0f };
|
||||
const Vec3 norm = normalize(pos);
|
||||
add_vertex(pos, norm, bottom_vertices);
|
||||
}
|
||||
|
||||
m_size_in_bytes_gpu += top_vertices.size() * sizeof(float);
|
||||
m_size_in_bytes_gpu += bottom_vertices.size() * sizeof(float);
|
||||
|
||||
const size_t vertex_stride = 6 * sizeof(float);
|
||||
const size_t position_offset = 0;
|
||||
const size_t normal_offset = 3 * sizeof(float);
|
||||
|
||||
int curr_vertex_array;
|
||||
glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array));
|
||||
int curr_array_buffer;
|
||||
glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer));
|
||||
|
||||
glsafe(glGenVertexArrays(1, &m_top_vao_id));
|
||||
glsafe(glBindVertexArray(m_top_vao_id));
|
||||
glsafe(glGenBuffers(1, &m_top_vbo_id));
|
||||
glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_top_vbo_id));
|
||||
glsafe(glBufferData(GL_ARRAY_BUFFER, top_vertices.size() * sizeof(float), top_vertices.data(), GL_STATIC_DRAW));
|
||||
glsafe(glEnableVertexAttribArray(0));
|
||||
glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset));
|
||||
glsafe(glEnableVertexAttribArray(1));
|
||||
glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset));
|
||||
|
||||
glsafe(glGenVertexArrays(1, &m_bottom_vao_id));
|
||||
glsafe(glBindVertexArray(m_bottom_vao_id));
|
||||
glsafe(glGenBuffers(1, &m_bottom_vbo_id));
|
||||
glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_bottom_vbo_id));
|
||||
glsafe(glBufferData(GL_ARRAY_BUFFER, bottom_vertices.size() * sizeof(float), bottom_vertices.data(), GL_STATIC_DRAW));
|
||||
glsafe(glEnableVertexAttribArray(0));
|
||||
glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset));
|
||||
glsafe(glEnableVertexAttribArray(1));
|
||||
glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset));
|
||||
|
||||
glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer));
|
||||
glsafe(glBindVertexArray(curr_vertex_array));
|
||||
}
|
||||
|
||||
void OptionTemplate::shutdown()
|
||||
{
|
||||
if (m_bottom_vbo_id != 0) {
|
||||
glsafe(glDeleteBuffers(1, &m_bottom_vbo_id));
|
||||
m_bottom_vbo_id = 0;
|
||||
}
|
||||
if (m_bottom_vao_id != 0) {
|
||||
glsafe(glDeleteVertexArrays(1, &m_bottom_vao_id));
|
||||
m_bottom_vao_id = 0;
|
||||
}
|
||||
if (m_top_vbo_id != 0) {
|
||||
glsafe(glDeleteBuffers(1, &m_top_vbo_id));
|
||||
m_top_vbo_id = 0;
|
||||
}
|
||||
if (m_top_vao_id != 0) {
|
||||
glsafe(glDeleteVertexArrays(1, &m_top_vao_id));
|
||||
m_top_vao_id = 0;
|
||||
}
|
||||
|
||||
m_size_in_bytes_gpu = 0;
|
||||
}
|
||||
|
||||
void OptionTemplate::render(size_t count)
|
||||
{
|
||||
if (m_top_vao_id == 0 || m_top_vbo_id == 0 || m_bottom_vao_id == 0 || m_bottom_vbo_id == 0 || count == 0)
|
||||
return;
|
||||
|
||||
int curr_vertex_array;
|
||||
glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array));
|
||||
|
||||
glsafe(glBindVertexArray(m_top_vao_id));
|
||||
glsafe(glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, static_cast<GLsizei>(m_vertices_count), static_cast<GLsizei>(count)));
|
||||
glsafe(glBindVertexArray(m_bottom_vao_id));
|
||||
glsafe(glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, static_cast<GLsizei>(m_vertices_count), static_cast<GLsizei>(count)));
|
||||
glsafe(glBindVertexArray(curr_vertex_array));
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
56
src/libvgcode/src/OptionTemplate.hpp
Normal file
56
src/libvgcode/src/OptionTemplate.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_OPTIONTEMPLATE_HPP
|
||||
#define VGCODE_OPTIONTEMPLATE_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
class OptionTemplate
|
||||
{
|
||||
public:
|
||||
OptionTemplate() = default;
|
||||
~OptionTemplate() { shutdown(); }
|
||||
OptionTemplate(const OptionTemplate& other) = delete;
|
||||
OptionTemplate(OptionTemplate&& other) = delete;
|
||||
OptionTemplate& operator = (const OptionTemplate& other) = delete;
|
||||
OptionTemplate& operator = (OptionTemplate&& other) = delete;
|
||||
|
||||
//
|
||||
// Initialize gpu buffers.
|
||||
//
|
||||
void init(uint8_t resolution);
|
||||
//
|
||||
// Release gpu buffers.
|
||||
//
|
||||
void shutdown();
|
||||
void render(size_t count);
|
||||
|
||||
//
|
||||
// Return the size of the data sent to gpu, in bytes.
|
||||
//
|
||||
size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; }
|
||||
|
||||
private:
|
||||
uint8_t m_resolution{ 0 };
|
||||
uint8_t m_vertices_count{ 0 };
|
||||
//
|
||||
// gpu buffers ids.
|
||||
//
|
||||
unsigned int m_top_vao_id{ 0 };
|
||||
unsigned int m_top_vbo_id{ 0 };
|
||||
unsigned int m_bottom_vao_id{ 0 };
|
||||
unsigned int m_bottom_vbo_id{ 0 };
|
||||
//
|
||||
// Size of the data sent to gpu, in bytes.
|
||||
//
|
||||
size_t m_size_in_bytes_gpu{ 0 };
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_OPTIONTEMPLATE_HPP
|
||||
52
src/libvgcode/src/PathVertex.cpp
Normal file
52
src/libvgcode/src/PathVertex.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "../include/PathVertex.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
const PathVertex PathVertex::DUMMY_PATH_VERTEX = PathVertex();
|
||||
|
||||
bool PathVertex::is_extrusion() const
|
||||
{
|
||||
return type == EMoveType::Extrude;
|
||||
}
|
||||
|
||||
bool PathVertex::is_travel() const
|
||||
{
|
||||
return type == EMoveType::Travel;
|
||||
}
|
||||
|
||||
bool PathVertex::is_wipe() const
|
||||
{
|
||||
return type == EMoveType::Wipe;
|
||||
}
|
||||
|
||||
bool PathVertex::is_option() const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EMoveType::Retract:
|
||||
case EMoveType::Unretract:
|
||||
case EMoveType::Seam:
|
||||
case EMoveType::ToolChange:
|
||||
case EMoveType::ColorChange:
|
||||
case EMoveType::PausePrint:
|
||||
case EMoveType::CustomGCode:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PathVertex::is_custom_gcode() const
|
||||
{
|
||||
return type == EMoveType::Extrude && role == EGCodeExtrusionRole::Custom;
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
25
src/libvgcode/src/Range.cpp
Normal file
25
src/libvgcode/src/Range.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "Range.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
void Range::set(Interval::value_type min, Interval::value_type max)
|
||||
{
|
||||
if (max < min)
|
||||
std::swap(min, max);
|
||||
m_range[0] = min;
|
||||
m_range[1] = max;
|
||||
}
|
||||
|
||||
void Range::clamp(Range& other)
|
||||
{
|
||||
other.m_range[0] = std::clamp(other.m_range[0], m_range[0], m_range[1]);
|
||||
other.m_range[1] = std::clamp(other.m_range[1], m_range[0], m_range[1]);
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
39
src/libvgcode/src/Range.hpp
Normal file
39
src/libvgcode/src/Range.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_RANGE_HPP
|
||||
#define VGCODE_RANGE_HPP
|
||||
|
||||
#include "../include/Types.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
class Range
|
||||
{
|
||||
public:
|
||||
const Interval& get() const { return m_range; }
|
||||
void set(const Range& other) { m_range = other.m_range; }
|
||||
void set(const Interval& range) { set(range[0], range[1]); }
|
||||
void set(Interval::value_type min, Interval::value_type max);
|
||||
|
||||
Interval::value_type get_min() const { return m_range[0]; }
|
||||
void set_min(Interval::value_type min) { set(min, m_range[1]); }
|
||||
|
||||
Interval::value_type get_max() const { return m_range[1]; }
|
||||
void set_max(Interval::value_type max) { set(m_range[0], max); }
|
||||
|
||||
// clamp the given range to stay inside this range
|
||||
void clamp(Range& other);
|
||||
void reset() { m_range = { 0, 0 }; }
|
||||
|
||||
bool operator == (const Range& other) const { return m_range == other.m_range; }
|
||||
bool operator != (const Range& other) const { return m_range != other.m_range; }
|
||||
|
||||
private:
|
||||
Interval m_range{ 0, 0 };
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_RANGE_HPP
|
||||
85
src/libvgcode/src/SegmentTemplate.cpp
Normal file
85
src/libvgcode/src/SegmentTemplate.cpp
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "SegmentTemplate.hpp"
|
||||
#include "OpenGLUtils.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
//| /1-------6\ |
|
||||
//| / | | \ |
|
||||
//| 2--0-------5--7 |
|
||||
//| \ | | / |
|
||||
//| 3-------4 |
|
||||
static constexpr const std::array<uint8_t, 24> VERTEX_DATA = {
|
||||
0, 1, 2, // front spike
|
||||
0, 2, 3, // front spike
|
||||
0, 3, 4, // right/bottom body
|
||||
0, 4, 5, // right/bottom body
|
||||
0, 5, 6, // left/top body
|
||||
0, 6, 1, // left/top body
|
||||
5, 4, 7, // back spike
|
||||
5, 7, 6, // back spike
|
||||
};
|
||||
|
||||
void SegmentTemplate::init()
|
||||
{
|
||||
if (m_vao_id != 0)
|
||||
return;
|
||||
|
||||
m_size_in_bytes_gpu += VERTEX_DATA.size() * sizeof(uint8_t);
|
||||
|
||||
int curr_vertex_array;
|
||||
glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array));
|
||||
int curr_array_buffer;
|
||||
glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer));
|
||||
|
||||
glsafe(glGenVertexArrays(1, &m_vao_id));
|
||||
glsafe(glBindVertexArray(m_vao_id));
|
||||
|
||||
glsafe(glGenBuffers(1, &m_vbo_id));
|
||||
glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
|
||||
glsafe(glBufferData(GL_ARRAY_BUFFER, VERTEX_DATA.size() * sizeof(uint8_t), VERTEX_DATA.data(), GL_STATIC_DRAW));
|
||||
glsafe(glEnableVertexAttribArray(0));
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
glsafe(glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, (const void*)0));
|
||||
#else
|
||||
glsafe(glVertexAttribIPointer(0, 1, GL_UNSIGNED_BYTE, 0, (const void*)0));
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer));
|
||||
glsafe(glBindVertexArray(curr_vertex_array));
|
||||
}
|
||||
|
||||
void SegmentTemplate::shutdown()
|
||||
{
|
||||
if (m_vbo_id != 0) {
|
||||
glsafe(glDeleteBuffers(1, &m_vbo_id));
|
||||
m_vbo_id = 0;
|
||||
}
|
||||
if (m_vao_id != 0) {
|
||||
glsafe(glDeleteVertexArrays(1, &m_vao_id));
|
||||
m_vao_id = 0;
|
||||
}
|
||||
|
||||
m_size_in_bytes_gpu = 0;
|
||||
}
|
||||
|
||||
void SegmentTemplate::render(size_t count)
|
||||
{
|
||||
if (m_vao_id == 0 || m_vbo_id == 0 || count == 0)
|
||||
return;
|
||||
|
||||
int curr_vertex_array;
|
||||
glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array));
|
||||
|
||||
glsafe(glBindVertexArray(m_vao_id));
|
||||
glsafe(glDrawArraysInstanced(GL_TRIANGLES, 0, static_cast<GLsizei>(VERTEX_DATA.size()), static_cast<GLsizei>(count)));
|
||||
glsafe(glBindVertexArray(curr_vertex_array));
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
51
src/libvgcode/src/SegmentTemplate.hpp
Normal file
51
src/libvgcode/src/SegmentTemplate.hpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_SEGMENTTEMPLATE_HPP
|
||||
#define VGCODE_SEGMENTTEMPLATE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
class SegmentTemplate
|
||||
{
|
||||
public:
|
||||
SegmentTemplate() = default;
|
||||
~SegmentTemplate() { shutdown(); }
|
||||
SegmentTemplate(const SegmentTemplate& other) = delete;
|
||||
SegmentTemplate(SegmentTemplate&& other) = delete;
|
||||
SegmentTemplate& operator = (const SegmentTemplate& other) = delete;
|
||||
SegmentTemplate& operator = (SegmentTemplate&& other) = delete;
|
||||
|
||||
//
|
||||
// Initialize gpu buffers.
|
||||
//
|
||||
void init();
|
||||
//
|
||||
// Release gpu buffers.
|
||||
//
|
||||
void shutdown();
|
||||
void render(size_t count);
|
||||
|
||||
//
|
||||
// Return the size of the data sent to gpu, in bytes.
|
||||
//
|
||||
size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; }
|
||||
|
||||
private:
|
||||
//
|
||||
// gpu buffers ids.
|
||||
//
|
||||
unsigned int m_vao_id{ 0 };
|
||||
unsigned int m_vbo_id{ 0 };
|
||||
//
|
||||
// Size of the data sent to gpu, in bytes.
|
||||
//
|
||||
size_t m_size_in_bytes_gpu{ 0 };
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_SEGMENTTEMPLATE_HPP
|
||||
9
src/libvgcode/src/Settings.cpp
Normal file
9
src/libvgcode/src/Settings.cpp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "Settings.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
} // namespace libvgcode
|
||||
|
||||
76
src/libvgcode/src/Settings.hpp
Normal file
76
src/libvgcode/src/Settings.hpp
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_SETTINGS_HPP
|
||||
#define VGCODE_SETTINGS_HPP
|
||||
|
||||
#include "../include/Types.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
struct Settings
|
||||
{
|
||||
//
|
||||
// Visualization parameters
|
||||
//
|
||||
EViewType view_type{ EViewType::FeatureType };
|
||||
ETimeMode time_mode{ ETimeMode::Normal };
|
||||
bool top_layer_only_view_range{ false };
|
||||
bool spiral_vase_mode{ false };
|
||||
//
|
||||
// Required update flags
|
||||
//
|
||||
bool update_view_full_range{ true };
|
||||
bool update_enabled_entities{ true };
|
||||
bool update_colors{ true };
|
||||
|
||||
//
|
||||
// Visibility maps
|
||||
//
|
||||
std::array<bool, std::size_t(EOptionType::COUNT)> options_visibility{
|
||||
false, // Travels
|
||||
false, // Wipes
|
||||
false, // Retractions
|
||||
false, // Unretractions
|
||||
true, // Seams
|
||||
false, // ToolChanges
|
||||
false, // ColorChanges
|
||||
false, // PausePrints
|
||||
false, // CustomGCodes
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
false, // CenterOfGravity
|
||||
true // ToolMarker
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
};
|
||||
|
||||
std::array<bool, std::size_t(EGCodeExtrusionRole::COUNT)> extrusion_roles_visibility{
|
||||
true, // None
|
||||
true, // Perimeter
|
||||
true, // ExternalPerimeter
|
||||
true, // OverhangPerimeter
|
||||
true, // InternalInfill
|
||||
true, // SolidInfill
|
||||
true, // TopSolidInfill
|
||||
true, // Ironing
|
||||
true, // BridgeInfill
|
||||
true, // GapFill
|
||||
true, // Skirt
|
||||
true, // SupportMaterial
|
||||
true, // SupportMaterialInterface
|
||||
true, // WipeTower
|
||||
true, // Custom
|
||||
// ORCA
|
||||
true, // BottomSurface
|
||||
true, // InternalBridgeInfill
|
||||
true, // Brim
|
||||
true, // SupportTransition
|
||||
true, // Mixed
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_SETTINGS_HPP
|
||||
303
src/libvgcode/src/Shaders.hpp
Normal file
303
src/libvgcode/src/Shaders.hpp
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_SHADERS_HPP
|
||||
#define VGCODE_SHADERS_HPP
|
||||
|
||||
// needed for tech VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#include "../include/Types.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
static const char* Segments_Vertex_Shader =
|
||||
"#version 150\n"
|
||||
"#define POINTY_CAPS\n"
|
||||
"#define FIX_TWISTING\n"
|
||||
"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"const float light_top_diffuse = 0.6 * 0.8;\n"
|
||||
"const float light_top_specular = 0.6 * 0.125;\n"
|
||||
"const float light_top_shininess = 20.0;\n"
|
||||
"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n"
|
||||
"const float light_front_diffuse = 0.6 * 0.2;\n"
|
||||
"const float ambient = 0.2;\n"
|
||||
"const float emission = 0.15;\n"
|
||||
"const vec3 UP = vec3(0, 0, 1);\n"
|
||||
"uniform mat4 view_matrix;\n"
|
||||
"uniform mat4 projection_matrix;\n"
|
||||
"uniform vec3 camera_position;\n"
|
||||
"uniform samplerBuffer position_tex;\n"
|
||||
"uniform samplerBuffer height_width_angle_tex;\n"
|
||||
"uniform samplerBuffer color_tex;\n"
|
||||
"uniform usamplerBuffer segment_index_tex;\n"
|
||||
"in int vertex_id;\n"
|
||||
"out vec3 color;\n"
|
||||
"vec3 decode_color(float color) {\n"
|
||||
" int c = int(round(color));\n"
|
||||
" int r = (c >> 16) & 0xFF;\n"
|
||||
" int g = (c >> 8) & 0xFF;\n"
|
||||
" int b = (c >> 0) & 0xFF;\n"
|
||||
" float f = 1.0 / 255.0f;\n"
|
||||
" return f * vec3(r, g, b);\n"
|
||||
"}\n"
|
||||
"float lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n"
|
||||
" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n"
|
||||
" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n"
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" int id_a = int(texelFetch(segment_index_tex, gl_InstanceID).r);\n"
|
||||
" int id_b = id_a + 1;\n"
|
||||
" vec3 pos_a = texelFetch(position_tex, id_a).xyz;\n"
|
||||
" vec3 pos_b = texelFetch(position_tex, id_b).xyz;\n"
|
||||
" vec3 line = pos_b - pos_a;\n"
|
||||
" // directions of the line box in world space\n"
|
||||
" float line_len = length(line);\n"
|
||||
" vec3 line_dir;\n"
|
||||
" if (line_len < 1e-4)\n"
|
||||
" line_dir = vec3(1.0, 0.0, 0.0);\n"
|
||||
" else\n"
|
||||
" line_dir = line / line_len;\n"
|
||||
" vec3 line_right_dir;\n"
|
||||
" if (abs(dot(line_dir, UP)) > 0.9) {\n"
|
||||
" // For vertical lines, the width and height should be same, there is no concept of up and down.\n"
|
||||
" // For simplicity, the code will expand width in the x axis, and height in the y axis\n"
|
||||
" line_right_dir = normalize(cross(vec3(1, 0, 0), line_dir));\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" line_right_dir = normalize(cross(line_dir, UP));\n"
|
||||
" vec3 line_up_dir = normalize(cross(line_right_dir, line_dir));\n"
|
||||
" const vec2 horizontal_vertical_view_signs_array[16] = vec2[](\n"
|
||||
" //horizontal view (from right)\n"
|
||||
" vec2(1.0, 0.0),\n"
|
||||
" vec2(0.0, 1.0),\n"
|
||||
" vec2(0.0, 0.0),\n"
|
||||
" vec2(0.0, -1.0),\n"
|
||||
" vec2(0.0, -1.0),\n"
|
||||
" vec2(1.0, 0.0),\n"
|
||||
" vec2(0.0, 1.0),\n"
|
||||
" vec2(0.0, 0.0),\n"
|
||||
" // vertical view (from top)\n"
|
||||
" vec2(0.0, 1.0),\n"
|
||||
" vec2(-1.0, 0.0),\n"
|
||||
" vec2(0.0, 0.0),\n"
|
||||
" vec2(1.0, 0.0),\n"
|
||||
" vec2(1.0, 0.0),\n"
|
||||
" vec2(0.0, 1.0),\n"
|
||||
" vec2(-1.0, 0.0),\n"
|
||||
" vec2(0.0, 0.0)\n"
|
||||
" );\n"
|
||||
" int id = vertex_id < 4 ? id_a : id_b;\n"
|
||||
" vec3 endpoint_pos = vertex_id < 4 ? pos_a : pos_b;\n"
|
||||
" vec3 height_width_angle = texelFetch(height_width_angle_tex, id).xyz;\n"
|
||||
"#ifdef FIX_TWISTING\n"
|
||||
" int closer_id = (dot(camera_position - pos_a, camera_position - pos_a) < dot(camera_position - pos_b, camera_position - pos_b)) ? id_a : id_b;\n"
|
||||
" vec3 closer_pos = (closer_id == id_a) ? pos_a : pos_b;\n"
|
||||
" vec3 camera_view_dir = normalize(closer_pos - camera_position);\n"
|
||||
" vec3 closer_height_width_angle = texelFetch(height_width_angle_tex, closer_id).xyz;\n"
|
||||
" vec3 diagonal_dir_border = normalize(closer_height_width_angle.x * line_up_dir + closer_height_width_angle.y * line_right_dir);\n"
|
||||
"#else\n"
|
||||
" vec3 camera_view_dir = normalize(endpoint_pos - camera_position);\n"
|
||||
" vec3 diagonal_dir_border = normalize(height_width_angle.x * line_up_dir + height_width_angle.y * line_right_dir);\n"
|
||||
"#endif\n"
|
||||
" bool is_vertical_view = abs(dot(camera_view_dir, line_up_dir)) / abs(dot(diagonal_dir_border, line_up_dir)) >\n"
|
||||
" abs(dot(camera_view_dir, line_right_dir)) / abs(dot(diagonal_dir_border, line_right_dir));\n"
|
||||
" vec2 signs = horizontal_vertical_view_signs_array[vertex_id + 8 * int(is_vertical_view)];\n"
|
||||
"#ifndef POINTY_CAPS\n"
|
||||
" if (vertex_id == 2 || vertex_id == 7) signs = -horizontal_vertical_view_signs_array[(vertex_id - 2) + 8 * int(is_vertical_view)];\n"
|
||||
"#endif\n"
|
||||
" float view_right_sign = sign(dot(-camera_view_dir, line_right_dir));\n"
|
||||
" float view_top_sign = sign(dot(-camera_view_dir, line_up_dir));\n"
|
||||
" float half_height = 0.5 * height_width_angle.x;\n"
|
||||
" float half_width = 0.5 * height_width_angle.y;\n"
|
||||
" vec3 horizontal_dir = half_width * line_right_dir;\n"
|
||||
" vec3 vertical_dir = half_height * line_up_dir;\n"
|
||||
" float horizontal_sign = signs.x * view_right_sign;\n"
|
||||
" float vertical_sign = signs.y * view_top_sign;\n"
|
||||
" vec3 pos = endpoint_pos + horizontal_sign * horizontal_dir + vertical_sign * vertical_dir;\n"
|
||||
" if (vertex_id == 2 || vertex_id == 7) {\n"
|
||||
" float line_dir_sign = (vertex_id == 2) ? -1.0 : 1.0;\n"
|
||||
" if (height_width_angle.z == 0) {\n"
|
||||
"#ifdef POINTY_CAPS\n"
|
||||
" // There I add a cap to lines that do not have a following line\n"
|
||||
" // (or they have one, but perfectly aligned, so the cap is hidden inside the next line).\n"
|
||||
" pos += line_dir_sign * line_dir * half_width;\n"
|
||||
"#endif\n"
|
||||
" }\n"
|
||||
" else {\n"
|
||||
" pos += line_dir_sign * line_dir * half_width * sin(abs(height_width_angle.z) * 0.5);\n"
|
||||
" pos += sign(height_width_angle.z) * horizontal_dir * cos(abs(height_width_angle.z) * 0.5);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" vec3 eye_position = (view_matrix * vec4(pos, 1.0)).xyz;\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(normalize(pos - endpoint_pos), 0.0)).xyz;\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, id).r);\n"
|
||||
" color = color_base * lighting(eye_position, eye_normal);\n"
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Segments_Fragment_Shader =
|
||||
"#version 150\n"
|
||||
"in vec3 color;\n"
|
||||
"out vec4 fragment_color;\n"
|
||||
"void main() {\n"
|
||||
" fragment_color = vec4(color, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Options_Vertex_Shader =
|
||||
"#version 150\n"
|
||||
"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"const float light_top_diffuse = 0.6 * 0.8;\n"
|
||||
"const float light_top_specular = 0.6 * 0.125;\n"
|
||||
"const float light_top_shininess = 20.0;\n"
|
||||
"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n"
|
||||
"const float light_front_diffuse = 0.6 * 0.3;\n"
|
||||
"const float ambient = 0.3;\n"
|
||||
"const float emission = 0.25;\n"
|
||||
#ifndef _WIN32
|
||||
"const float scaling_factor = 0.75;\n"
|
||||
#else
|
||||
"const float scaling_factor = 1.5;\n"
|
||||
#endif
|
||||
"uniform mat4 view_matrix;\n"
|
||||
"uniform mat4 projection_matrix;\n"
|
||||
"uniform samplerBuffer position_tex;\n"
|
||||
"uniform samplerBuffer height_width_angle_tex;\n"
|
||||
"uniform samplerBuffer color_tex;\n"
|
||||
"uniform usamplerBuffer segment_index_tex;\n"
|
||||
"in vec3 in_position;\n"
|
||||
"in vec3 in_normal;\n"
|
||||
"out vec3 color;\n"
|
||||
"vec3 decode_color(float color) {\n"
|
||||
" int c = int(round(color));\n"
|
||||
" int r = (c >> 16) & 0xFF;\n"
|
||||
" int g = (c >> 8) & 0xFF;\n"
|
||||
" int b = (c >> 0) & 0xFF;\n"
|
||||
" float f = 1.0 / 255.0f;\n"
|
||||
" return f * vec3(r, g, b);\n"
|
||||
"}\n"
|
||||
"float lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n"
|
||||
" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n"
|
||||
" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n"
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" int id = int(texelFetch(segment_index_tex, gl_InstanceID).r);\n"
|
||||
" vec2 height_width = texelFetch(height_width_angle_tex, id).xy;\n"
|
||||
" vec3 offset = texelFetch(position_tex, id).xyz - vec3(0.0, 0.0, 0.5 * height_width.x);\n"
|
||||
" height_width *= scaling_factor;\n"
|
||||
" mat3 scale_matrix = mat3(\n"
|
||||
" height_width.y, 0.0, 0.0,\n"
|
||||
" 0.0, height_width.y, 0.0,\n"
|
||||
" 0.0, 0.0, height_width.x);\n"
|
||||
" vec3 eye_position = (view_matrix * vec4(scale_matrix * in_position + offset, 1.0)).xyz;\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, id).r);\n"
|
||||
" color = color_base * lighting(eye_position, eye_normal);\n"
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Options_Fragment_Shader =
|
||||
"#version 150\n"
|
||||
"in vec3 color;\n"
|
||||
"out vec4 fragment_color;\n"
|
||||
"void main() {\n"
|
||||
" fragment_color = vec4(color, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
static const char* Cog_Marker_Vertex_Shader =
|
||||
"#version 150\n"
|
||||
"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"const float light_top_diffuse = 0.6 * 0.8;\n"
|
||||
"const float light_top_specular = 0.6 * 0.125;\n"
|
||||
"const float light_top_shininess = 20.0;\n"
|
||||
"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n"
|
||||
"const float light_front_diffuse = 0.6 * 0.3;\n"
|
||||
"const float ambient = 0.3;\n"
|
||||
"const float emission = 0.25;\n"
|
||||
"uniform vec3 world_center_position;\n"
|
||||
"uniform float scale_factor;\n"
|
||||
"uniform mat4 view_matrix;\n"
|
||||
"uniform mat4 projection_matrix;\n"
|
||||
"in vec3 in_position;\n"
|
||||
"in vec3 in_normal;\n"
|
||||
"out float intensity;\n"
|
||||
"out vec3 world_position;\n"
|
||||
"float lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n"
|
||||
" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n"
|
||||
" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n"
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" world_position = scale_factor * in_position + world_center_position;\n"
|
||||
" vec3 eye_position = (view_matrix * vec4(world_position, 1.0)).xyz;\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n"
|
||||
" intensity = lighting(eye_position, eye_normal);\n"
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Cog_Marker_Fragment_Shader =
|
||||
"#version 150\n"
|
||||
"const vec3 BLACK = vec3(0.05);\n"
|
||||
"const vec3 WHITE = vec3(0.95);\n"
|
||||
"uniform vec3 world_center_position;\n"
|
||||
"in float intensity;\n"
|
||||
"in vec3 world_position;\n"
|
||||
"out vec4 out_color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec3 delta = world_position - world_center_position;\n"
|
||||
" vec3 color = delta.x * delta.y * delta.z > 0.0 ? BLACK : WHITE;\n"
|
||||
" out_color = intensity * vec4(color, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Tool_Marker_Vertex_Shader =
|
||||
"#version 150\n"
|
||||
"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"const float light_top_diffuse = 0.6 * 0.8;\n"
|
||||
"const float light_top_specular = 0.6 * 0.125;\n"
|
||||
"const float light_top_shininess = 20.0;\n"
|
||||
"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n"
|
||||
"const float light_front_diffuse = 0.6 * 0.3;\n"
|
||||
"const float ambient = 0.3;\n"
|
||||
"const float emission = 0.25;\n"
|
||||
"uniform vec3 world_origin;\n"
|
||||
"uniform float scale_factor;\n"
|
||||
"uniform mat4 view_matrix;\n"
|
||||
"uniform mat4 projection_matrix;\n"
|
||||
"uniform vec4 color_base;\n"
|
||||
"in vec3 in_position;\n"
|
||||
"in vec3 in_normal;\n"
|
||||
"out vec4 color;\n"
|
||||
"float lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n"
|
||||
" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n"
|
||||
" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n"
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" vec3 world_position = scale_factor * in_position + world_origin;\n"
|
||||
" vec3 eye_position = (view_matrix * vec4(world_position, 1.0)).xyz;\n"
|
||||
" // no need of normal matrix as the scaling is uniform\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n"
|
||||
" color = vec4(color_base.rgb * lighting(eye_position, eye_normal), color_base.a);\n"
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Tool_Marker_Fragment_Shader =
|
||||
"#version 150\n"
|
||||
"in vec4 color;\n"
|
||||
"out vec4 fragment_color;\n"
|
||||
"void main() {\n"
|
||||
" fragment_color = color;\n"
|
||||
"}\n";
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_SHADERS_HPP
|
||||
|
||||
322
src/libvgcode/src/ShadersES.hpp
Normal file
322
src/libvgcode/src/ShadersES.hpp
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_SHADERSES_HPP
|
||||
#define VGCODE_SHADERSES_HPP
|
||||
|
||||
// needed for tech VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#include "../include/Types.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
static const char* Segments_Vertex_Shader_ES =
|
||||
"#version 300 es\n"
|
||||
"precision lowp usampler2D;\n"
|
||||
"#define POINTY_CAPS\n"
|
||||
"#define FIX_TWISTING\n"
|
||||
"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"const float light_top_diffuse = 0.6 * 0.8;\n"
|
||||
"const float light_top_specular = 0.6 * 0.125;\n"
|
||||
"const float light_top_shininess = 20.0;\n"
|
||||
"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n"
|
||||
"const float light_front_diffuse = 0.6 * 0.3;\n"
|
||||
"const float ambient = 0.3;\n"
|
||||
"const float emission = 0.15;\n"
|
||||
"const vec3 UP = vec3(0, 0, 1);\n"
|
||||
"uniform mat4 view_matrix;\n"
|
||||
"uniform mat4 projection_matrix;\n"
|
||||
"uniform vec3 camera_position;\n"
|
||||
"uniform sampler2D position_tex;\n"
|
||||
"uniform sampler2D height_width_angle_tex;\n"
|
||||
"uniform sampler2D color_tex;\n"
|
||||
"uniform usampler2D segment_index_tex;\n"
|
||||
"in float vertex_id_float;\n"
|
||||
"out vec3 color;\n"
|
||||
"vec3 decode_color(float color) {\n"
|
||||
" int c = int(round(color));\n"
|
||||
" int r = (c >> 16) & 0xFF;\n"
|
||||
" int g = (c >> 8) & 0xFF;\n"
|
||||
" int b = (c >> 0) & 0xFF;\n"
|
||||
" float f = 1.0 / 255.0f;\n"
|
||||
" return f * vec3(r, g, b);\n"
|
||||
"}\n"
|
||||
"float lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n"
|
||||
" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n"
|
||||
" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n"
|
||||
"}\n"
|
||||
"ivec2 tex_coord(sampler2D sampler, int id) {\n"
|
||||
" ivec2 tex_size = textureSize(sampler, 0);\n"
|
||||
" return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);\n"
|
||||
"}\n"
|
||||
"ivec2 tex_coord_u(usampler2D sampler, int id) {\n"
|
||||
" ivec2 tex_size = textureSize(sampler, 0);\n"
|
||||
" return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);\n"
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" int vertex_id = int(vertex_id_float);\n"
|
||||
" int id_a = int(texelFetch(segment_index_tex, tex_coord_u(segment_index_tex, gl_InstanceID), 0).r);\n"
|
||||
" int id_b = id_a + 1;\n"
|
||||
" vec3 pos_a = texelFetch(position_tex, tex_coord(position_tex, id_a), 0).xyz;\n"
|
||||
" vec3 pos_b = texelFetch(position_tex, tex_coord(position_tex, id_b), 0).xyz;\n"
|
||||
" vec3 line = pos_b - pos_a;\n"
|
||||
" // directions of the line box in world space\n"
|
||||
" float line_len = length(line);\n"
|
||||
" vec3 line_dir;\n"
|
||||
" if (line_len < 1e-4)\n"
|
||||
" line_dir = vec3(1.0, 0.0, 0.0);\n"
|
||||
" else\n"
|
||||
" line_dir = line / line_len;\n"
|
||||
" vec3 line_right_dir;\n"
|
||||
" if (abs(dot(line_dir, UP)) > 0.9) {\n"
|
||||
" // For vertical lines, the width and height should be same, there is no concept of up and down.\n"
|
||||
" // For simplicity, the code will expand width in the x axis, and height in the y axis\n"
|
||||
" line_right_dir = normalize(cross(vec3(1, 0, 0), line_dir));\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" line_right_dir = normalize(cross(line_dir, UP));\n"
|
||||
" vec3 line_up_dir = normalize(cross(line_right_dir, line_dir));\n"
|
||||
" const vec2 horizontal_vertical_view_signs_array[16] = vec2[](\n"
|
||||
" //horizontal view (from right)\n"
|
||||
" vec2(1.0, 0.0),\n"
|
||||
" vec2(0.0, 1.0),\n"
|
||||
" vec2(0.0, 0.0),\n"
|
||||
" vec2(0.0, -1.0),\n"
|
||||
" vec2(0.0, -1.0),\n"
|
||||
" vec2(1.0, 0.0),\n"
|
||||
" vec2(0.0, 1.0),\n"
|
||||
" vec2(0.0, 0.0),\n"
|
||||
" // vertical view (from top)\n"
|
||||
" vec2(0.0, 1.0),\n"
|
||||
" vec2(-1.0, 0.0),\n"
|
||||
" vec2(0.0, 0.0),\n"
|
||||
" vec2(1.0, 0.0),\n"
|
||||
" vec2(1.0, 0.0),\n"
|
||||
" vec2(0.0, 1.0),\n"
|
||||
" vec2(-1.0, 0.0),\n"
|
||||
" vec2(0.0, 0.0)\n"
|
||||
" );\n"
|
||||
" int id = vertex_id < 4 ? id_a : id_b;\n"
|
||||
" vec3 endpoint_pos = vertex_id < 4 ? pos_a : pos_b;\n"
|
||||
" vec3 height_width_angle = texelFetch(height_width_angle_tex, tex_coord(height_width_angle_tex, id), 0).xyz;\n"
|
||||
"#ifdef FIX_TWISTING\n"
|
||||
" int closer_id = (dot(camera_position - pos_a, camera_position - pos_a) < dot(camera_position - pos_b, camera_position - pos_b)) ? id_a : id_b;\n"
|
||||
" vec3 closer_pos = (closer_id == id_a) ? pos_a : pos_b;\n"
|
||||
" vec3 camera_view_dir = normalize(closer_pos - camera_position);\n"
|
||||
" vec3 closer_height_width_angle = texelFetch(height_width_angle_tex, tex_coord(height_width_angle_tex, closer_id), 0).xyz;\n"
|
||||
" vec3 diagonal_dir_border = normalize(closer_height_width_angle.x * line_up_dir + closer_height_width_angle.y * line_right_dir);\n"
|
||||
"#else\n"
|
||||
" vec3 camera_view_dir = normalize(endpoint_pos - camera_position);\n"
|
||||
" vec3 diagonal_dir_border = normalize(height_width_angle.x * line_up_dir + height_width_angle.y * line_right_dir);\n"
|
||||
"#endif\n"
|
||||
" bool is_vertical_view = abs(dot(camera_view_dir, line_up_dir)) / abs(dot(diagonal_dir_border, line_up_dir)) >\n"
|
||||
" abs(dot(camera_view_dir, line_right_dir)) / abs(dot(diagonal_dir_border, line_right_dir));\n"
|
||||
" vec2 signs = horizontal_vertical_view_signs_array[vertex_id + 8 * int(is_vertical_view)];\n"
|
||||
"#ifndef POINTY_CAPS\n"
|
||||
" if (vertex_id == 2 || vertex_id == 7) signs = -horizontal_vertical_view_signs_array[(vertex_id - 2) + 8 * int(is_vertical_view)];\n"
|
||||
"#endif\n"
|
||||
" float view_right_sign = sign(dot(-camera_view_dir, line_right_dir));\n"
|
||||
" float view_top_sign = sign(dot(-camera_view_dir, line_up_dir));\n"
|
||||
" float half_height = 0.5 * height_width_angle.x;\n"
|
||||
" float half_width = 0.5 * height_width_angle.y;\n"
|
||||
" vec3 horizontal_dir = half_width * line_right_dir;\n"
|
||||
" vec3 vertical_dir = half_height * line_up_dir;\n"
|
||||
" float horizontal_sign = signs.x * view_right_sign;\n"
|
||||
" float vertical_sign = signs.y * view_top_sign;\n"
|
||||
" vec3 pos = endpoint_pos + horizontal_sign * horizontal_dir + vertical_sign * vertical_dir;\n"
|
||||
" if (vertex_id == 2 || vertex_id == 7) {\n"
|
||||
" float line_dir_sign = (vertex_id == 2) ? -1.0 : 1.0;\n"
|
||||
" if (height_width_angle.z == 0.0) {\n"
|
||||
"#ifdef POINTY_CAPS\n"
|
||||
" // There I add a cap to lines that do not have a following line\n"
|
||||
" // (or they have one, but perfectly aligned, so the cap is hidden inside the next line).\n"
|
||||
" pos += line_dir_sign * line_dir * half_width;\n"
|
||||
"#endif\n"
|
||||
" }\n"
|
||||
" else {\n"
|
||||
" pos += line_dir_sign * line_dir * half_width * sin(abs(height_width_angle.z) * 0.5);\n"
|
||||
" pos += sign(height_width_angle.z) * horizontal_dir * cos(abs(height_width_angle.z) * 0.5);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" vec3 eye_position = (view_matrix * vec4(pos, 1.0)).xyz;\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(normalize(pos - endpoint_pos), 0.0)).xyz;\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, tex_coord(color_tex, id), 0).r);\n"
|
||||
" color = color_base * lighting(eye_position, eye_normal);\n"
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Segments_Fragment_Shader_ES =
|
||||
"#version 300 es\n"
|
||||
"precision highp float;\n"
|
||||
"in vec3 color;\n"
|
||||
"out vec4 fragment_color;\n"
|
||||
"void main() {\n"
|
||||
" fragment_color = vec4(color, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Options_Vertex_Shader_ES =
|
||||
"#version 300 es\n"
|
||||
"precision lowp usampler2D;\n"
|
||||
"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"const float light_top_diffuse = 0.6 * 0.8;\n"
|
||||
"const float light_top_specular = 0.6 * 0.125;\n"
|
||||
"const float light_top_shininess = 20.0;\n"
|
||||
"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n"
|
||||
"const float light_front_diffuse = 0.6 * 0.3;\n"
|
||||
"const float ambient = 0.3;\n"
|
||||
"const float emission = 0.25;\n"
|
||||
"const float scaling_factor = 1.5;\n"
|
||||
"uniform mat4 view_matrix;\n"
|
||||
"uniform mat4 projection_matrix;\n"
|
||||
"uniform sampler2D position_tex;\n"
|
||||
"uniform sampler2D height_width_angle_tex;\n"
|
||||
"uniform sampler2D color_tex;\n"
|
||||
"uniform usampler2D segment_index_tex;\n"
|
||||
"in vec3 in_position;\n"
|
||||
"in vec3 in_normal;\n"
|
||||
"out vec3 color;\n"
|
||||
"vec3 decode_color(float color) {\n"
|
||||
" int c = int(round(color));\n"
|
||||
" int r = (c >> 16) & 0xFF;\n"
|
||||
" int g = (c >> 8) & 0xFF;\n"
|
||||
" int b = (c >> 0) & 0xFF;\n"
|
||||
" float f = 1.0 / 255.0f;\n"
|
||||
" return f * vec3(r, g, b);\n"
|
||||
"}\n"
|
||||
"float lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n"
|
||||
" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n"
|
||||
" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n"
|
||||
"}\n"
|
||||
"ivec2 tex_coord(sampler2D sampler, int id) {\n"
|
||||
" ivec2 tex_size = textureSize(sampler, 0);\n"
|
||||
" return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);\n"
|
||||
"}\n"
|
||||
"ivec2 tex_coord_u(usampler2D sampler, int id) {\n"
|
||||
" ivec2 tex_size = textureSize(sampler, 0);\n"
|
||||
" return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);\n"
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" int id = int(texelFetch(segment_index_tex, tex_coord_u(segment_index_tex, gl_InstanceID), 0).r);\n"
|
||||
" vec2 height_width = texelFetch(height_width_angle_tex, tex_coord(height_width_angle_tex, id), 0).xy;\n"
|
||||
" vec3 offset = texelFetch(position_tex, tex_coord(position_tex, id), 0).xyz - vec3(0.0, 0.0, 0.5 * height_width.x);\n"
|
||||
" height_width *= scaling_factor;\n"
|
||||
" mat3 scale_matrix = mat3(\n"
|
||||
" height_width.y, 0.0, 0.0,\n"
|
||||
" 0.0, height_width.y, 0.0,\n"
|
||||
" 0.0, 0.0, height_width.x);\n"
|
||||
" vec3 eye_position = (view_matrix * vec4(scale_matrix * in_position + offset, 1.0)).xyz;\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, tex_coord(color_tex, id), 0).r);\n"
|
||||
" color = color_base * lighting(eye_position, eye_normal);\n"
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Options_Fragment_Shader_ES =
|
||||
"#version 300 es\n"
|
||||
"precision highp float;\n"
|
||||
"in vec3 color;\n"
|
||||
"out vec4 fragment_color;\n"
|
||||
"void main() {\n"
|
||||
" fragment_color = vec4(color, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
static const char* Cog_Marker_Vertex_Shader_ES =
|
||||
"#version 300 es\n"
|
||||
"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"const float light_top_diffuse = 0.6 * 0.8;\n"
|
||||
"const float light_top_specular = 0.6 * 0.125;\n"
|
||||
"const float light_top_shininess = 20.0;\n"
|
||||
"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n"
|
||||
"const float light_front_diffuse = 0.6 * 0.3;\n"
|
||||
"const float ambient = 0.3;\n"
|
||||
"const float emission = 0.25;\n"
|
||||
"uniform vec3 world_center_position;\n"
|
||||
"uniform float scale_factor;\n"
|
||||
"uniform mat4 view_matrix;\n"
|
||||
"uniform mat4 projection_matrix;\n"
|
||||
"in vec3 in_position;\n"
|
||||
"in vec3 in_normal;\n"
|
||||
"out float intensity;\n"
|
||||
"out vec3 world_position;\n"
|
||||
"float lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n"
|
||||
" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n"
|
||||
" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n"
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" world_position = scale_factor * in_position + world_center_position;\n"
|
||||
" vec3 eye_position = (view_matrix * vec4(world_position, 1.0)).xyz;\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n"
|
||||
" intensity = lighting(eye_position, eye_normal);\n"
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Cog_Marker_Fragment_Shader_ES =
|
||||
"#version 300 es\n"
|
||||
"precision highp float;\n"
|
||||
"const vec3 BLACK = vec3(0.05);\n"
|
||||
"const vec3 WHITE = vec3(0.95);\n"
|
||||
"uniform vec3 world_center_position;\n"
|
||||
"in float intensity;\n"
|
||||
"in vec3 world_position;\n"
|
||||
"out vec4 out_color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec3 delta = world_position - world_center_position;\n"
|
||||
" vec3 color = delta.x * delta.y * delta.z > 0.0 ? BLACK : WHITE;\n"
|
||||
" out_color = intensity * vec4(color, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Tool_Marker_Vertex_Shader_ES =
|
||||
"#version 300 es\n"
|
||||
"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"const float light_top_diffuse = 0.6 * 0.8;\n"
|
||||
"const float light_top_specular = 0.6 * 0.125;\n"
|
||||
"const float light_top_shininess = 20.0;\n"
|
||||
"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n"
|
||||
"const float light_front_diffuse = 0.6 * 0.3;\n"
|
||||
"const float ambient = 0.3;\n"
|
||||
"const float emission = 0.25;\n"
|
||||
"uniform vec3 world_origin;\n"
|
||||
"uniform float scale_factor;\n"
|
||||
"uniform mat4 view_matrix;\n"
|
||||
"uniform mat4 projection_matrix;\n"
|
||||
"uniform vec4 color_base;\n"
|
||||
"in vec3 in_position;\n"
|
||||
"in vec3 in_normal;\n"
|
||||
"out vec4 color;\n"
|
||||
"float lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n"
|
||||
" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n"
|
||||
" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n"
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" vec3 world_position = scale_factor * in_position + world_origin;\n"
|
||||
" vec3 eye_position = (view_matrix * vec4(world_position, 1.0)).xyz;\n"
|
||||
" // no need of normal matrix as the scaling is uniform\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n"
|
||||
" color = vec4(color_base.rgb * lighting(eye_position, eye_normal), color_base.a);\n"
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Tool_Marker_Fragment_Shader_ES =
|
||||
"#version 300 es\n"
|
||||
"precision highp float;\n"
|
||||
"in vec4 color;\n"
|
||||
"out vec4 fragment_color;\n"
|
||||
"void main() {\n"
|
||||
" fragment_color = color;\n"
|
||||
"}\n";
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_SHADERSES_HPP
|
||||
|
||||
172
src/libvgcode/src/ToolMarker.cpp
Normal file
172
src/libvgcode/src/ToolMarker.cpp
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "ToolMarker.hpp"
|
||||
#include "OpenGLUtils.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
// Geometry:
|
||||
// Arrow with cylindrical stem and conical tip, with the given dimensions and resolution
|
||||
// The origin of the arrow is at the tip of the conical section
|
||||
// The axis of symmetry is along the Z axis
|
||||
// The arrow is pointing downward
|
||||
void ToolMarker::init(uint16_t resolution, float tip_radius, float tip_height, float stem_radius, float stem_height)
|
||||
{
|
||||
if (m_vao_id != 0)
|
||||
return;
|
||||
|
||||
// ensure vertices count does not exceed 65536
|
||||
resolution = std::clamp<uint16_t>(resolution, 4, 10922);
|
||||
|
||||
std::vector<float> vertices;
|
||||
const uint16_t vertices_count = 6 * resolution + 2;
|
||||
vertices.reserve(6 * vertices_count);
|
||||
|
||||
m_indices_count = 6 * resolution * 3;
|
||||
std::vector<uint16_t> indices;
|
||||
indices.reserve(m_indices_count);
|
||||
|
||||
const float angle_step = 2.0f * PI / float(resolution);
|
||||
std::vector<float> cosines(resolution);
|
||||
std::vector<float> sines(resolution);
|
||||
|
||||
for (uint16_t i = 0; i < resolution; ++i) {
|
||||
const float angle = angle_step * float(i);
|
||||
cosines[i] = std::cos(angle);
|
||||
sines[i] = -std::sin(angle);
|
||||
}
|
||||
|
||||
const float total_height = tip_height + stem_height;
|
||||
|
||||
// tip vertices
|
||||
add_vertex({ 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, -1.0f }, vertices);
|
||||
for (uint16_t i = 0; i < resolution; ++i) {
|
||||
add_vertex({ tip_radius * sines[i], tip_radius * cosines[i], tip_height }, { sines[i], cosines[i], 0.0f }, vertices);
|
||||
}
|
||||
|
||||
// tip triangles
|
||||
for (uint16_t i = 0; i < resolution; ++i) {
|
||||
const uint16_t v3 = (i < resolution - 1) ? i + 2 : 1;
|
||||
add_triangle(0, i + 1, v3, indices);
|
||||
}
|
||||
|
||||
// tip cap outer perimeter vertices
|
||||
for (uint16_t i = 0; i < resolution; ++i) {
|
||||
add_vertex({ tip_radius * sines[i], tip_radius * cosines[i], tip_height }, { 0.0f, 0.0f, 1.0f }, vertices);
|
||||
}
|
||||
|
||||
// tip cap inner perimeter vertices
|
||||
for (uint16_t i = 0; i < resolution; ++i) {
|
||||
add_vertex({ stem_radius * sines[i], stem_radius * cosines[i], tip_height }, { 0.0f, 0.0f, 1.0f }, vertices);
|
||||
}
|
||||
|
||||
// tip cap triangles
|
||||
for (uint16_t i = 0; i < resolution; ++i) {
|
||||
const uint16_t v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1;
|
||||
const uint16_t v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1;
|
||||
add_triangle(i + resolution + 1, v3, v2, indices);
|
||||
add_triangle(i + resolution + 1, i + 2 * resolution + 1, v3, indices);
|
||||
}
|
||||
|
||||
// stem bottom vertices
|
||||
for (uint16_t i = 0; i < resolution; ++i) {
|
||||
add_vertex({ stem_radius * sines[i], stem_radius * cosines[i], tip_height }, { sines[i], cosines[i], 0.0f }, vertices);
|
||||
}
|
||||
|
||||
// stem top vertices
|
||||
for (uint16_t i = 0; i < resolution; ++i) {
|
||||
add_vertex({ stem_radius * sines[i], stem_radius * cosines[i], total_height }, { sines[i], cosines[i], 0.0f }, vertices);
|
||||
}
|
||||
|
||||
// stem triangles
|
||||
for (uint16_t i = 0; i < resolution; ++i) {
|
||||
const uint16_t v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1;
|
||||
const uint16_t v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1;
|
||||
add_triangle(i + 3 * resolution + 1, v3, v2, indices);
|
||||
add_triangle(i + 3 * resolution + 1, i + 4 * resolution + 1, v3, indices);
|
||||
}
|
||||
|
||||
// stem cap vertices
|
||||
add_vertex({ 0.0f, 0.0f, total_height }, { 0.0f, 0.0f, 1.0f }, vertices);
|
||||
for (uint16_t i = 0; i < resolution; ++i) {
|
||||
add_vertex({ stem_radius * sines[i], stem_radius * cosines[i], total_height }, { 0.0f, 0.0f, 1.0f }, vertices);
|
||||
}
|
||||
|
||||
// stem cap triangles
|
||||
for (uint16_t i = 0; i < resolution; ++i) {
|
||||
const uint16_t v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2;
|
||||
add_triangle(5 * resolution + 1, v3, i + 5 * resolution + 2, indices);
|
||||
}
|
||||
|
||||
m_size_in_bytes_gpu += vertices.size() * sizeof(float);
|
||||
m_size_in_bytes_gpu += indices.size() * sizeof(uint16_t);
|
||||
|
||||
const size_t vertex_stride = 6 * sizeof(float);
|
||||
const size_t position_offset = 0;
|
||||
const size_t normal_offset = 3 * sizeof(float);
|
||||
|
||||
int curr_vertex_array;
|
||||
glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array));
|
||||
int curr_array_buffer;
|
||||
glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer));
|
||||
|
||||
glsafe(glGenVertexArrays(1, &m_vao_id));
|
||||
glsafe(glBindVertexArray(m_vao_id));
|
||||
glsafe(glGenBuffers(1, &m_vbo_id));
|
||||
glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
|
||||
glsafe(glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW));
|
||||
glsafe(glEnableVertexAttribArray(0));
|
||||
glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset));
|
||||
glsafe(glEnableVertexAttribArray(1));
|
||||
glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset));
|
||||
|
||||
glsafe(glGenBuffers(1, &m_ibo_id));
|
||||
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id));
|
||||
glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW));
|
||||
|
||||
glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer));
|
||||
glsafe(glBindVertexArray(curr_vertex_array));
|
||||
}
|
||||
|
||||
void ToolMarker::shutdown()
|
||||
{
|
||||
if (m_ibo_id != 0) {
|
||||
glsafe(glDeleteBuffers(1, &m_ibo_id));
|
||||
m_ibo_id = 0;
|
||||
}
|
||||
if (m_vbo_id != 0) {
|
||||
glsafe(glDeleteBuffers(1, &m_vbo_id));
|
||||
m_vbo_id = 0;
|
||||
}
|
||||
if (m_vao_id != 0) {
|
||||
glsafe(glDeleteVertexArrays(1, &m_vao_id));
|
||||
m_vao_id = 0;
|
||||
}
|
||||
|
||||
m_size_in_bytes_gpu = 0;
|
||||
}
|
||||
|
||||
void ToolMarker::render()
|
||||
{
|
||||
if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0)
|
||||
return;
|
||||
|
||||
int curr_vertex_array;
|
||||
glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array));
|
||||
glcheck();
|
||||
|
||||
glsafe(glBindVertexArray(m_vao_id));
|
||||
glsafe(glDrawElements(GL_TRIANGLES, m_indices_count, GL_UNSIGNED_SHORT, (const void*)0));
|
||||
glsafe(glBindVertexArray(curr_vertex_array));
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
75
src/libvgcode/src/ToolMarker.hpp
Normal file
75
src/libvgcode/src/ToolMarker.hpp
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_TOOLMARKER_HPP
|
||||
#define VGCODE_TOOLMARKER_HPP
|
||||
|
||||
#include "../include/Types.hpp"
|
||||
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#include <algorithm>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
class ToolMarker
|
||||
{
|
||||
public:
|
||||
ToolMarker() = default;
|
||||
~ToolMarker() { shutdown(); }
|
||||
ToolMarker(const ToolMarker& other) = delete;
|
||||
ToolMarker(ToolMarker&& other) = delete;
|
||||
ToolMarker& operator = (const ToolMarker& other) = delete;
|
||||
ToolMarker& operator = (ToolMarker&& other) = delete;
|
||||
|
||||
//
|
||||
// Initialize gpu buffers.
|
||||
//
|
||||
void init(uint16_t resolution, float tip_radius, float tip_height, float stem_radius, float stem_height);
|
||||
//
|
||||
// Release gpu buffers.
|
||||
//
|
||||
void shutdown();
|
||||
void render();
|
||||
|
||||
const Vec3& get_position() const { return m_position; }
|
||||
void set_position(const Vec3& position) { m_position = position; }
|
||||
|
||||
float get_offset_z() const { return m_offset_z; }
|
||||
void set_offset_z(float offset_z) { m_offset_z = std::max(offset_z, 0.0f); }
|
||||
|
||||
const Color& get_color() const { return m_color; }
|
||||
void set_color(const Color& color) { m_color = color; }
|
||||
|
||||
float get_alpha() const { return m_alpha; }
|
||||
void set_alpha(float alpha) { m_alpha = std::clamp(alpha, 0.25f, 0.75f); }
|
||||
|
||||
//
|
||||
// Return the size of the data sent to gpu, in bytes.
|
||||
//
|
||||
size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; }
|
||||
|
||||
private:
|
||||
Vec3 m_position{ 0.0f, 0.0f, 0.0f };
|
||||
float m_offset_z{ 0.5f };
|
||||
Color m_color{ 255, 255, 255 };
|
||||
float m_alpha{ 0.5f };
|
||||
|
||||
uint16_t m_indices_count{ 0 };
|
||||
//
|
||||
// gpu buffers ids.
|
||||
//
|
||||
unsigned int m_vao_id{ 0 };
|
||||
unsigned int m_vbo_id{ 0 };
|
||||
unsigned int m_ibo_id{ 0 };
|
||||
//
|
||||
// Size of the data sent to gpu, in bytes.
|
||||
//
|
||||
size_t m_size_in_bytes_gpu{ 0 };
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
#endif // VGCODE_TOOLMARKER_HPP
|
||||
42
src/libvgcode/src/Types.cpp
Normal file
42
src/libvgcode/src/Types.cpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "../include/Types.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
// mapping from EMoveType to EOptionType
|
||||
EOptionType move_type_to_option(EMoveType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EMoveType::Travel: { return EOptionType::Travels; }
|
||||
case EMoveType::Wipe: { return EOptionType::Wipes; }
|
||||
case EMoveType::Retract: { return EOptionType::Retractions; }
|
||||
case EMoveType::Unretract: { return EOptionType::Unretractions; }
|
||||
case EMoveType::Seam: { return EOptionType::Seams; }
|
||||
case EMoveType::ToolChange: { return EOptionType::ToolChanges; }
|
||||
case EMoveType::ColorChange: { return EOptionType::ColorChanges; }
|
||||
case EMoveType::PausePrint: { return EOptionType::PausePrints; }
|
||||
case EMoveType::CustomGCode: { return EOptionType::CustomGCodes; }
|
||||
default: { return EOptionType::COUNT; }
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t lerp(uint8_t f1, uint8_t f2, float t)
|
||||
{
|
||||
const float one_minus_t = 1.0f - t;
|
||||
return static_cast<uint8_t>(one_minus_t * static_cast<float>(f1) + t * static_cast<float>(f2));
|
||||
}
|
||||
|
||||
// It will be possible to replace this with std::lerp when using c++20
|
||||
Color lerp(const Color& c1, const Color& c2, float t)
|
||||
{
|
||||
t = std::clamp(t, 0.0f, 1.0f);
|
||||
return { lerp(c1[0], c2[0], t), lerp(c1[1], c2[1], t), lerp(c1[2], c2[2], t) };
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
68
src/libvgcode/src/Utils.cpp
Normal file
68
src/libvgcode/src/Utils.cpp
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
void add_vertex(const Vec3& position, const Vec3& normal, std::vector<float>& vertices)
|
||||
{
|
||||
vertices.emplace_back(position[0]);
|
||||
vertices.emplace_back(position[1]);
|
||||
vertices.emplace_back(position[2]);
|
||||
vertices.emplace_back(normal[0]);
|
||||
vertices.emplace_back(normal[1]);
|
||||
vertices.emplace_back(normal[2]);
|
||||
}
|
||||
|
||||
void add_triangle(uint16_t v1, uint16_t v2, uint16_t v3, std::vector<uint16_t>& indices)
|
||||
{
|
||||
indices.emplace_back(v1);
|
||||
indices.emplace_back(v2);
|
||||
indices.emplace_back(v3);
|
||||
}
|
||||
|
||||
Vec3 normalize(const Vec3& v)
|
||||
{
|
||||
const float length = std::sqrt(dot(v, v));
|
||||
assert(length > 0.0f);
|
||||
const float inv_length = 1.0f / length;
|
||||
return { v[0] * inv_length, v[1] * inv_length, v[2] * inv_length };
|
||||
}
|
||||
|
||||
float dot(const Vec3& v1, const Vec3& v2)
|
||||
{
|
||||
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
|
||||
}
|
||||
|
||||
float length(const Vec3& v)
|
||||
{
|
||||
return std::sqrt(dot(v, v));
|
||||
}
|
||||
|
||||
bool operator == (const Vec3& v1, const Vec3& v2) {
|
||||
return v1[0] == v2[0] && v1[1] == v2[1] && v1[2] == v2[2];
|
||||
}
|
||||
|
||||
bool operator != (const Vec3& v1, const Vec3& v2) {
|
||||
return v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2];
|
||||
}
|
||||
|
||||
Vec3 operator + (const Vec3& v1, const Vec3& v2) {
|
||||
return { v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2] };
|
||||
}
|
||||
|
||||
Vec3 operator - (const Vec3& v1, const Vec3& v2) {
|
||||
return { v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2] };
|
||||
}
|
||||
|
||||
Vec3 operator * (float f, const Vec3& v) {
|
||||
return { f * v[0], f * v[1], f * v[2] };
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
31
src/libvgcode/src/Utils.hpp
Normal file
31
src/libvgcode/src/Utils.hpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_UTILS_HPP
|
||||
#define VGCODE_UTILS_HPP
|
||||
|
||||
#include "../include/Types.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + __alignof(TYPE) - 1) / __alignof(TYPE)) * __alignof(TYPE)
|
||||
#else
|
||||
#define STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + alignof(TYPE) - 1) / alignof(TYPE)) * alignof(TYPE)
|
||||
#endif // _WIN32
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
extern void add_vertex(const Vec3& position, const Vec3& normal, std::vector<float>& vertices);
|
||||
extern void add_triangle(uint16_t v1, uint16_t v2, uint16_t v3, std::vector<uint16_t>& indices);
|
||||
extern Vec3 normalize(const Vec3& v);
|
||||
extern float dot(const Vec3& v1, const Vec3& v2);
|
||||
extern float length(const Vec3& v);
|
||||
extern bool operator == (const Vec3& v1, const Vec3& v2);
|
||||
extern bool operator != (const Vec3& v1, const Vec3& v2);
|
||||
extern Vec3 operator + (const Vec3& v1, const Vec3& v2);
|
||||
extern Vec3 operator - (const Vec3& v1, const Vec3& v2);
|
||||
extern Vec3 operator * (float f, const Vec3& v);
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_UTILS_HPP
|
||||
39
src/libvgcode/src/ViewRange.cpp
Normal file
39
src/libvgcode/src/ViewRange.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "ViewRange.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
void ViewRange::set_full(Interval::value_type min, Interval::value_type max)
|
||||
{
|
||||
m_full.set(min, max);
|
||||
// force the enabled range to stay inside the modified full range
|
||||
m_full.clamp(m_enabled);
|
||||
// force the visible range to stay inside the modified enabled range
|
||||
m_enabled.clamp(m_visible);
|
||||
}
|
||||
|
||||
void ViewRange::set_enabled(Interval::value_type min, Interval::value_type max)
|
||||
{
|
||||
m_enabled.set(min, max);
|
||||
// force the visible range to stay inside the modified enabled range
|
||||
m_enabled.clamp(m_visible);
|
||||
}
|
||||
|
||||
void ViewRange::set_visible(Interval::value_type min, Interval::value_type max)
|
||||
{
|
||||
m_visible.set(min, max);
|
||||
// force the visible range to stay inside the enabled range
|
||||
m_enabled.clamp(m_visible);
|
||||
}
|
||||
|
||||
void ViewRange::reset()
|
||||
{
|
||||
m_full.reset();
|
||||
m_enabled.reset();
|
||||
m_visible.reset();
|
||||
}
|
||||
|
||||
} // namespace libvgcode
|
||||
56
src/libvgcode/src/ViewRange.hpp
Normal file
56
src/libvgcode/src/ViewRange.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_VIEWRANGE_HPP
|
||||
#define VGCODE_VIEWRANGE_HPP
|
||||
|
||||
#include "Range.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
class ViewRange
|
||||
{
|
||||
public:
|
||||
const Interval& get_full() const { return m_full.get(); }
|
||||
void set_full(const Range& other) { set_full(other.get()); }
|
||||
void set_full(const Interval& range) { set_full(range[0], range[1]); }
|
||||
void set_full(Interval::value_type min, Interval::value_type max);
|
||||
|
||||
const Interval& get_enabled() const { return m_enabled.get(); }
|
||||
void set_enabled(const Range& other) { set_enabled(other.get()); }
|
||||
void set_enabled(const Interval& range) { set_enabled(range[0], range[1]); }
|
||||
void set_enabled(Interval::value_type min, Interval::value_type max);
|
||||
|
||||
const Interval& get_visible() const { return m_visible.get(); }
|
||||
void set_visible(const Range& other) { set_visible(other.get()); }
|
||||
void set_visible(const Interval& range) { set_visible(range[0], range[1]); }
|
||||
void set_visible(Interval::value_type min, Interval::value_type max);
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
//
|
||||
// Full range
|
||||
// The range of moves that could potentially be visible.
|
||||
// It is usually equal to the enabled range, unless Settings::top_layer_only_view_range is set to true.
|
||||
//
|
||||
Range m_full;
|
||||
|
||||
//
|
||||
// Enabled range
|
||||
// The range of moves that are enabled for visualization.
|
||||
// It is usually equal to the full range, unless Settings::top_layer_only_view_range is set to true.
|
||||
//
|
||||
Range m_enabled;
|
||||
|
||||
//
|
||||
// Visible range
|
||||
// The range of moves that are currently rendered.
|
||||
//
|
||||
Range m_visible;
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_VIEWRANGE_HPP
|
||||
422
src/libvgcode/src/Viewer.cpp
Normal file
422
src/libvgcode/src/Viewer.cpp
Normal file
|
|
@ -0,0 +1,422 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "../include/Viewer.hpp"
|
||||
#include "ViewerImpl.hpp"
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
Viewer::Viewer()
|
||||
{
|
||||
m_impl = new ViewerImpl();
|
||||
}
|
||||
|
||||
Viewer::~Viewer()
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
void Viewer::init(const std::string& opengl_context_version)
|
||||
{
|
||||
m_impl->init(opengl_context_version);
|
||||
}
|
||||
|
||||
void Viewer::shutdown()
|
||||
{
|
||||
m_impl->shutdown();
|
||||
}
|
||||
|
||||
void Viewer::reset()
|
||||
{
|
||||
m_impl->reset();
|
||||
}
|
||||
|
||||
void Viewer::load(GCodeInputData&& gcode_data)
|
||||
{
|
||||
m_impl->load(std::move(gcode_data));
|
||||
}
|
||||
|
||||
void Viewer::render(const Mat4x4& view_matrix, const Mat4x4& projection_matrix)
|
||||
{
|
||||
m_impl->render(view_matrix, projection_matrix);
|
||||
}
|
||||
|
||||
EViewType Viewer::get_view_type() const
|
||||
{
|
||||
return m_impl->get_view_type();
|
||||
}
|
||||
|
||||
void Viewer::set_view_type(EViewType type)
|
||||
{
|
||||
m_impl->set_view_type(type);
|
||||
}
|
||||
|
||||
ETimeMode Viewer::get_time_mode() const
|
||||
{
|
||||
return m_impl->get_time_mode();
|
||||
}
|
||||
|
||||
void Viewer::set_time_mode(ETimeMode mode)
|
||||
{
|
||||
m_impl->set_time_mode(mode);
|
||||
}
|
||||
|
||||
bool Viewer::is_top_layer_only_view_range() const
|
||||
{
|
||||
return m_impl->is_top_layer_only_view_range();
|
||||
}
|
||||
|
||||
void Viewer::toggle_top_layer_only_view_range()
|
||||
{
|
||||
m_impl->toggle_top_layer_only_view_range();
|
||||
}
|
||||
|
||||
bool Viewer::is_option_visible(EOptionType type) const
|
||||
{
|
||||
return m_impl->is_option_visible(type);
|
||||
}
|
||||
|
||||
void Viewer::toggle_option_visibility(EOptionType type)
|
||||
{
|
||||
m_impl->toggle_option_visibility(type);
|
||||
}
|
||||
|
||||
bool Viewer::is_extrusion_role_visible(EGCodeExtrusionRole role) const
|
||||
{
|
||||
return m_impl->is_extrusion_role_visible(role);
|
||||
}
|
||||
|
||||
void Viewer::toggle_extrusion_role_visibility(EGCodeExtrusionRole role)
|
||||
{
|
||||
m_impl->toggle_extrusion_role_visibility(role);
|
||||
}
|
||||
|
||||
const Color& Viewer::get_extrusion_role_color(EGCodeExtrusionRole role) const
|
||||
{
|
||||
return m_impl->get_extrusion_role_color(role);
|
||||
}
|
||||
|
||||
void Viewer::set_extrusion_role_color(EGCodeExtrusionRole role, const Color& color)
|
||||
{
|
||||
m_impl->set_extrusion_role_color(role, color);
|
||||
}
|
||||
|
||||
void Viewer::reset_default_extrusion_roles_colors()
|
||||
{
|
||||
m_impl->reset_default_extrusion_roles_colors();
|
||||
}
|
||||
|
||||
const Color& Viewer::get_option_color(EOptionType type) const
|
||||
{
|
||||
return m_impl->get_option_color(type);
|
||||
}
|
||||
|
||||
void Viewer::set_option_color(EOptionType type, const Color& color)
|
||||
{
|
||||
m_impl->set_option_color(type, color);
|
||||
}
|
||||
|
||||
void Viewer::reset_default_options_colors()
|
||||
{
|
||||
m_impl->reset_default_options_colors();
|
||||
}
|
||||
|
||||
size_t Viewer::get_tool_colors_count() const
|
||||
{
|
||||
return m_impl->get_tool_colors_count();
|
||||
}
|
||||
|
||||
const Palette& Viewer::get_tool_colors() const
|
||||
{
|
||||
return m_impl->get_tool_colors();
|
||||
}
|
||||
|
||||
void Viewer::set_tool_colors(const Palette& colors)
|
||||
{
|
||||
m_impl->set_tool_colors(colors);
|
||||
}
|
||||
|
||||
size_t Viewer::get_color_print_colors_count() const
|
||||
{
|
||||
return m_impl->get_color_print_colors_count();
|
||||
}
|
||||
|
||||
const Palette& Viewer::get_color_print_colors() const
|
||||
{
|
||||
return m_impl->get_color_print_colors();
|
||||
}
|
||||
|
||||
void Viewer::set_color_print_colors(const Palette& colors)
|
||||
{
|
||||
m_impl->set_color_print_colors(colors);
|
||||
}
|
||||
|
||||
const ColorRange& Viewer::get_color_range(EViewType type) const
|
||||
{
|
||||
return m_impl->get_color_range(type);
|
||||
}
|
||||
|
||||
void Viewer::set_color_range_palette(EViewType type, const Palette& palette)
|
||||
{
|
||||
m_impl->set_color_range_palette(type, palette);
|
||||
}
|
||||
|
||||
float Viewer::get_travels_radius() const
|
||||
{
|
||||
return m_impl->get_travels_radius();
|
||||
}
|
||||
|
||||
void Viewer::set_travels_radius(float radius)
|
||||
{
|
||||
m_impl->set_travels_radius(radius);
|
||||
}
|
||||
|
||||
float Viewer::get_wipes_radius() const
|
||||
{
|
||||
return m_impl->get_wipes_radius();
|
||||
}
|
||||
|
||||
void Viewer::set_wipes_radius(float radius)
|
||||
{
|
||||
m_impl->set_wipes_radius(radius);
|
||||
}
|
||||
|
||||
size_t Viewer::get_layers_count() const
|
||||
{
|
||||
return m_impl->get_layers_count();
|
||||
}
|
||||
|
||||
const Interval& Viewer::get_layers_view_range() const
|
||||
{
|
||||
return m_impl->get_layers_view_range();
|
||||
}
|
||||
|
||||
void Viewer::set_layers_view_range(const Interval& range)
|
||||
{
|
||||
m_impl->set_layers_view_range(range);
|
||||
}
|
||||
|
||||
void Viewer::set_layers_view_range(Interval::value_type min, Interval::value_type max)
|
||||
{
|
||||
m_impl->set_layers_view_range(min, max);
|
||||
}
|
||||
|
||||
const Interval& Viewer::get_view_visible_range() const
|
||||
{
|
||||
return m_impl->get_view_visible_range();
|
||||
}
|
||||
|
||||
void Viewer::set_view_visible_range(Interval::value_type min, Interval::value_type max)
|
||||
{
|
||||
m_impl->set_view_visible_range(min, max);
|
||||
}
|
||||
|
||||
const Interval& Viewer::get_view_full_range() const
|
||||
{
|
||||
return m_impl->get_view_full_range();
|
||||
}
|
||||
|
||||
const Interval& Viewer::get_view_enabled_range() const
|
||||
{
|
||||
return m_impl->get_view_enabled_range();
|
||||
}
|
||||
|
||||
bool Viewer::is_spiral_vase_mode() const
|
||||
{
|
||||
return m_impl->is_spiral_vase_mode();
|
||||
}
|
||||
|
||||
float Viewer::get_layer_z(size_t layer_id) const
|
||||
{
|
||||
return m_impl->get_layer_z(layer_id);
|
||||
}
|
||||
|
||||
std::vector<float> Viewer::get_layers_zs() const
|
||||
{
|
||||
return m_impl->get_layers_zs();
|
||||
}
|
||||
|
||||
size_t Viewer::get_layer_id_at(float z) const
|
||||
{
|
||||
return m_impl->get_layer_id_at(z);
|
||||
}
|
||||
|
||||
size_t Viewer::get_used_extruders_count() const
|
||||
{
|
||||
return m_impl->get_used_extruders_count();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Viewer::get_used_extruders_ids() const
|
||||
{
|
||||
return m_impl->get_used_extruders_ids();
|
||||
}
|
||||
|
||||
std::vector<ETimeMode> Viewer::get_time_modes() const
|
||||
{
|
||||
return m_impl->get_time_modes();
|
||||
}
|
||||
|
||||
size_t Viewer::get_vertices_count() const
|
||||
{
|
||||
return m_impl->get_vertices_count();
|
||||
}
|
||||
|
||||
const PathVertex& Viewer::get_current_vertex() const
|
||||
{
|
||||
return m_impl->get_current_vertex();
|
||||
}
|
||||
|
||||
size_t Viewer::get_current_vertex_id() const
|
||||
{
|
||||
return m_impl->get_current_vertex_id();
|
||||
}
|
||||
|
||||
const PathVertex& Viewer::get_vertex_at(size_t id) const
|
||||
{
|
||||
return m_impl->get_vertex_at(id);
|
||||
}
|
||||
|
||||
float Viewer::get_estimated_time() const
|
||||
{
|
||||
return m_impl->get_estimated_time();
|
||||
}
|
||||
|
||||
float Viewer::get_estimated_time_at(size_t id) const
|
||||
{
|
||||
return m_impl->get_estimated_time_at(id);
|
||||
}
|
||||
|
||||
Color Viewer::get_vertex_color(const PathVertex& vertex) const
|
||||
{
|
||||
return m_impl->get_vertex_color(vertex);
|
||||
}
|
||||
|
||||
size_t Viewer::get_extrusion_roles_count() const
|
||||
{
|
||||
return m_impl->get_extrusion_roles_count();
|
||||
}
|
||||
|
||||
std::vector<EGCodeExtrusionRole> Viewer::get_extrusion_roles() const
|
||||
{
|
||||
return m_impl->get_extrusion_roles();
|
||||
}
|
||||
|
||||
size_t Viewer::get_options_count() const
|
||||
{
|
||||
return m_impl->get_options_count();
|
||||
}
|
||||
|
||||
const std::vector<EOptionType>& Viewer::get_options() const
|
||||
{
|
||||
return m_impl->get_options();
|
||||
}
|
||||
|
||||
size_t Viewer::get_color_prints_count(uint8_t extruder_id) const
|
||||
{
|
||||
return m_impl->get_color_prints_count(extruder_id);
|
||||
}
|
||||
|
||||
std::vector<ColorPrint> Viewer::get_color_prints(uint8_t extruder_id) const
|
||||
{
|
||||
return m_impl->get_color_prints(extruder_id);
|
||||
}
|
||||
|
||||
float Viewer::get_extrusion_role_estimated_time(EGCodeExtrusionRole role) const
|
||||
{
|
||||
return m_impl->get_extrusion_role_estimated_time(role);
|
||||
}
|
||||
|
||||
float Viewer::get_travels_estimated_time() const
|
||||
{
|
||||
return m_impl->get_travels_estimated_time();
|
||||
}
|
||||
|
||||
std::vector<float> Viewer::get_layers_estimated_times() const
|
||||
{
|
||||
return m_impl->get_layers_estimated_times();
|
||||
}
|
||||
|
||||
AABox Viewer::get_bounding_box(const std::vector<EMoveType>& types) const
|
||||
{
|
||||
return m_impl->get_bounding_box(types);
|
||||
}
|
||||
|
||||
AABox Viewer::get_extrusion_bounding_box(const std::vector<EGCodeExtrusionRole>& roles) const
|
||||
{
|
||||
return m_impl->get_extrusion_bounding_box(roles);
|
||||
}
|
||||
|
||||
size_t Viewer::get_used_cpu_memory() const
|
||||
{
|
||||
return m_impl->get_used_cpu_memory();
|
||||
}
|
||||
|
||||
size_t Viewer::get_used_gpu_memory() const
|
||||
{
|
||||
return m_impl->get_used_gpu_memory();
|
||||
}
|
||||
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
Vec3 Viewer::get_cog_position() const
|
||||
{
|
||||
return m_impl->get_cog_marker_position();
|
||||
}
|
||||
|
||||
float Viewer::get_cog_marker_scale_factor() const
|
||||
{
|
||||
return m_impl->get_cog_marker_scale_factor();
|
||||
}
|
||||
|
||||
void Viewer::set_cog_marker_scale_factor(float factor)
|
||||
{
|
||||
m_impl->set_cog_marker_scale_factor(factor);
|
||||
}
|
||||
|
||||
const Vec3& Viewer::get_tool_marker_position() const
|
||||
{
|
||||
return m_impl->get_tool_marker_position();
|
||||
}
|
||||
|
||||
float Viewer::get_tool_marker_offset_z() const
|
||||
{
|
||||
return m_impl->get_tool_marker_offset_z();
|
||||
}
|
||||
|
||||
void Viewer::set_tool_marker_offset_z(float offset_z)
|
||||
{
|
||||
m_impl->set_tool_marker_offset_z(offset_z);
|
||||
}
|
||||
|
||||
float Viewer::get_tool_marker_scale_factor() const
|
||||
{
|
||||
return m_impl->get_tool_marker_scale_factor();
|
||||
}
|
||||
|
||||
void Viewer::set_tool_marker_scale_factor(float factor)
|
||||
{
|
||||
m_impl->set_tool_marker_scale_factor(factor);
|
||||
}
|
||||
|
||||
const Color& Viewer::get_tool_marker_color() const
|
||||
{
|
||||
return m_impl->get_tool_marker_color();
|
||||
}
|
||||
|
||||
void Viewer::set_tool_marker_color(const Color& color)
|
||||
{
|
||||
m_impl->set_tool_marker_color(color);
|
||||
}
|
||||
|
||||
float Viewer::get_tool_marker_alpha() const
|
||||
{
|
||||
return m_impl->get_tool_marker_alpha();
|
||||
}
|
||||
|
||||
void Viewer::set_tool_marker_alpha(float alpha)
|
||||
{
|
||||
m_impl->set_tool_marker_alpha(alpha);
|
||||
}
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
} // namespace libvgcode
|
||||
2107
src/libvgcode/src/ViewerImpl.cpp
Normal file
2107
src/libvgcode/src/ViewerImpl.cpp
Normal file
File diff suppressed because it is too large
Load diff
470
src/libvgcode/src/ViewerImpl.hpp
Normal file
470
src/libvgcode/src/ViewerImpl.hpp
Normal file
|
|
@ -0,0 +1,470 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak
|
||||
///|/
|
||||
///|/ libvgcode is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef VGCODE_VIEWERIMPL_HPP
|
||||
#define VGCODE_VIEWERIMPL_HPP
|
||||
|
||||
#include "Settings.hpp"
|
||||
#include "SegmentTemplate.hpp"
|
||||
#include "OptionTemplate.hpp"
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#include "CogMarker.hpp"
|
||||
#include "ToolMarker.hpp"
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#include "../include/PathVertex.hpp"
|
||||
#include "../include/ColorRange.hpp"
|
||||
#include "../include/ColorPrint.hpp"
|
||||
#include "Bitset.hpp"
|
||||
#include "ViewRange.hpp"
|
||||
#include "Layers.hpp"
|
||||
#include "ExtrusionRoles.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
namespace libvgcode {
|
||||
|
||||
struct GCodeInputData;
|
||||
|
||||
class ViewerImpl
|
||||
{
|
||||
public:
|
||||
ViewerImpl();
|
||||
~ViewerImpl() { shutdown(); }
|
||||
ViewerImpl(const ViewerImpl& other) = delete;
|
||||
ViewerImpl(ViewerImpl&& other) = delete;
|
||||
ViewerImpl& operator = (const ViewerImpl& other) = delete;
|
||||
ViewerImpl& operator = (ViewerImpl&& other) = delete;
|
||||
|
||||
//
|
||||
// Initialize shaders, uniform indices and segment geometry.
|
||||
//
|
||||
void init(const std::string& opengl_context_version);
|
||||
//
|
||||
// Release the resources used by the viewer.
|
||||
//
|
||||
void shutdown();
|
||||
//
|
||||
// Reset all caches and free gpu memory.
|
||||
//
|
||||
void reset();
|
||||
//
|
||||
// Setup all the variables used for visualization of the toolpaths
|
||||
// from the given gcode data.
|
||||
//
|
||||
void load(GCodeInputData&& gcode_data);
|
||||
|
||||
//
|
||||
// Update the visibility property of toolpaths in dependence
|
||||
// of the current settings
|
||||
//
|
||||
void update_enabled_entities();
|
||||
//
|
||||
// Update the color of toolpaths in dependence of the current
|
||||
// view type and settings
|
||||
//
|
||||
void update_colors();
|
||||
void update_colors_texture();
|
||||
|
||||
//
|
||||
// Render the toolpaths
|
||||
//
|
||||
void render(const Mat4x4& view_matrix, const Mat4x4& projection_matrix);
|
||||
|
||||
EViewType get_view_type() const { return m_settings.view_type; }
|
||||
void set_view_type(EViewType type);
|
||||
|
||||
ETimeMode get_time_mode() const { return m_settings.time_mode; }
|
||||
void set_time_mode(ETimeMode mode);
|
||||
|
||||
const Interval& get_layers_view_range() const { return m_layers.get_view_range(); }
|
||||
void set_layers_view_range(const Interval& range) { set_layers_view_range(range[0], range[1]); }
|
||||
void set_layers_view_range(Interval::value_type min, Interval::value_type max);
|
||||
|
||||
bool is_top_layer_only_view_range() const { return m_settings.top_layer_only_view_range; }
|
||||
void toggle_top_layer_only_view_range();
|
||||
|
||||
bool is_spiral_vase_mode() const { return m_settings.spiral_vase_mode; }
|
||||
|
||||
std::vector<ETimeMode> get_time_modes() const;
|
||||
|
||||
size_t get_layers_count() const { return m_layers.count(); }
|
||||
float get_layer_z(size_t layer_id) const { return m_layers.get_layer_z(layer_id); }
|
||||
std::vector<float> get_layers_zs() const { return m_layers.get_zs(); }
|
||||
|
||||
size_t get_layer_id_at(float z) const { return m_layers.get_layer_id_at(z); }
|
||||
|
||||
size_t get_used_extruders_count() const { return m_used_extruders.size(); }
|
||||
std::vector<uint8_t> get_used_extruders_ids() const;
|
||||
|
||||
size_t get_color_prints_count(uint8_t extruder_id) const;
|
||||
std::vector<ColorPrint> get_color_prints(uint8_t extruder_id) const;
|
||||
|
||||
AABox get_bounding_box(const std::vector<EMoveType>& types = {
|
||||
EMoveType::Retract, EMoveType::Unretract, EMoveType::Seam, EMoveType::ToolChange,
|
||||
EMoveType::ColorChange, EMoveType::PausePrint, EMoveType::CustomGCode, EMoveType::Travel,
|
||||
EMoveType::Wipe, EMoveType::Extrude }) const;
|
||||
AABox get_extrusion_bounding_box(const std::vector<EGCodeExtrusionRole>& roles = {
|
||||
EGCodeExtrusionRole::Perimeter, EGCodeExtrusionRole::ExternalPerimeter, EGCodeExtrusionRole::OverhangPerimeter,
|
||||
EGCodeExtrusionRole::InternalInfill, EGCodeExtrusionRole::SolidInfill, EGCodeExtrusionRole::TopSolidInfill,
|
||||
EGCodeExtrusionRole::Ironing, EGCodeExtrusionRole::BridgeInfill, EGCodeExtrusionRole::GapFill,
|
||||
EGCodeExtrusionRole::Skirt, EGCodeExtrusionRole::SupportMaterial, EGCodeExtrusionRole::SupportMaterialInterface,
|
||||
EGCodeExtrusionRole::WipeTower, EGCodeExtrusionRole::Custom,
|
||||
// ORCA
|
||||
EGCodeExtrusionRole::BottomSurface, EGCodeExtrusionRole::InternalBridgeInfill, EGCodeExtrusionRole::Brim,
|
||||
EGCodeExtrusionRole::SupportTransition, EGCodeExtrusionRole::Mixed
|
||||
}) const;
|
||||
|
||||
bool is_option_visible(EOptionType type) const;
|
||||
void toggle_option_visibility(EOptionType type);
|
||||
|
||||
bool is_extrusion_role_visible(EGCodeExtrusionRole role) const;
|
||||
void toggle_extrusion_role_visibility(EGCodeExtrusionRole role);
|
||||
|
||||
const Interval& get_view_full_range() const { return m_view_range.get_full(); }
|
||||
const Interval& get_view_enabled_range() const { return m_view_range.get_enabled(); }
|
||||
const Interval& get_view_visible_range() const { return m_view_range.get_visible(); }
|
||||
void set_view_visible_range(Interval::value_type min, Interval::value_type max);
|
||||
|
||||
size_t get_vertices_count() const { return m_vertices.size(); }
|
||||
const PathVertex& get_current_vertex() const { return get_vertex_at(get_current_vertex_id()); }
|
||||
size_t get_current_vertex_id() const { return static_cast<size_t>(m_view_range.get_visible()[1]); }
|
||||
const PathVertex& get_vertex_at(size_t id) const {
|
||||
return (id < m_vertices.size()) ? m_vertices[id] : PathVertex::DUMMY_PATH_VERTEX;
|
||||
}
|
||||
float get_estimated_time() const { return m_total_time[static_cast<size_t>(m_settings.time_mode)]; }
|
||||
float get_estimated_time_at(size_t id) const;
|
||||
Color get_vertex_color(const PathVertex& vertex) const;
|
||||
|
||||
size_t get_extrusion_roles_count() const { return m_extrusion_roles.get_roles_count(); }
|
||||
std::vector<EGCodeExtrusionRole> get_extrusion_roles() const { return m_extrusion_roles.get_roles(); }
|
||||
float get_extrusion_role_estimated_time(EGCodeExtrusionRole role) const { return m_extrusion_roles.get_time(role, m_settings.time_mode); }
|
||||
|
||||
size_t get_options_count() const { return m_options.size(); }
|
||||
const std::vector<EOptionType>& get_options() const { return m_options; }
|
||||
|
||||
float get_travels_estimated_time() const { return m_travels_time[static_cast<size_t>(m_settings.time_mode)]; }
|
||||
std::vector<float> get_layers_estimated_times() const { return m_layers.get_times(m_settings.time_mode); }
|
||||
|
||||
size_t get_tool_colors_count() const { return m_tool_colors.size(); }
|
||||
const Palette& get_tool_colors() const { return m_tool_colors; }
|
||||
void set_tool_colors(const Palette& colors);
|
||||
|
||||
size_t get_color_print_colors_count() const { return m_color_print_colors.size(); }
|
||||
const Palette& get_color_print_colors() const { return m_color_print_colors; }
|
||||
void set_color_print_colors(const Palette& colors);
|
||||
|
||||
const Color& get_extrusion_role_color(EGCodeExtrusionRole role) const;
|
||||
void set_extrusion_role_color(EGCodeExtrusionRole role, const Color& color);
|
||||
void reset_default_extrusion_roles_colors();
|
||||
|
||||
const Color& get_option_color(EOptionType type) const;
|
||||
void set_option_color(EOptionType type, const Color& color);
|
||||
void reset_default_options_colors();
|
||||
|
||||
const ColorRange& get_color_range(EViewType type) const;
|
||||
void set_color_range_palette(EViewType type, const Palette& palette);
|
||||
|
||||
float get_travels_radius() const { return m_travels_radius; }
|
||||
void set_travels_radius(float radius);
|
||||
float get_wipes_radius() const { return m_wipes_radius; }
|
||||
void set_wipes_radius(float radius);
|
||||
|
||||
size_t get_used_cpu_memory() const;
|
||||
size_t get_used_gpu_memory() const;
|
||||
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
Vec3 get_cog_marker_position() const { return m_cog_marker.get_position(); }
|
||||
|
||||
float get_cog_marker_scale_factor() const { return m_cog_marker_scale_factor; }
|
||||
void set_cog_marker_scale_factor(float factor) { m_cog_marker_scale_factor = std::max(factor, 0.001f); }
|
||||
|
||||
const Vec3& get_tool_marker_position() const { return m_tool_marker.get_position(); }
|
||||
|
||||
float get_tool_marker_offset_z() const { return m_tool_marker.get_offset_z(); }
|
||||
void set_tool_marker_offset_z(float offset_z) { m_tool_marker.set_offset_z(offset_z); }
|
||||
|
||||
float get_tool_marker_scale_factor() const { return m_tool_marker_scale_factor; }
|
||||
void set_tool_marker_scale_factor(float factor) { m_tool_marker_scale_factor = std::max(factor, 0.001f); }
|
||||
|
||||
const Color& get_tool_marker_color() const { return m_tool_marker.get_color(); }
|
||||
void set_tool_marker_color(const Color& color) { m_tool_marker.set_color(color); }
|
||||
|
||||
float get_tool_marker_alpha() const { return m_tool_marker.get_alpha(); }
|
||||
void set_tool_marker_alpha(float alpha) { m_tool_marker.set_alpha(alpha); }
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
private:
|
||||
//
|
||||
// Settings used to render the toolpaths
|
||||
//
|
||||
Settings m_settings;
|
||||
//
|
||||
// Detected layers
|
||||
//
|
||||
Layers m_layers;
|
||||
//
|
||||
// Detected extrusion roles
|
||||
//
|
||||
ExtrusionRoles m_extrusion_roles;
|
||||
//
|
||||
// Detected options
|
||||
//
|
||||
std::vector<EOptionType> m_options;
|
||||
//
|
||||
// Detected used extruders ids
|
||||
//
|
||||
std::map<uint8_t, std::vector<ColorPrint>> m_used_extruders;
|
||||
//
|
||||
// Vertices ranges for visualization
|
||||
//
|
||||
ViewRange m_view_range;
|
||||
//
|
||||
// Detected total moves times
|
||||
//
|
||||
std::array<float, TIME_MODES_COUNT> m_total_time{ 0.0f, 0.0f };
|
||||
//
|
||||
// Detected travel moves times
|
||||
//
|
||||
std::array<float, TIME_MODES_COUNT> m_travels_time{ 0.0f, 0.0f };
|
||||
//
|
||||
// Radius of cylinders used to render travel moves segments
|
||||
//
|
||||
float m_travels_radius{ DEFAULT_TRAVELS_RADIUS_MM };
|
||||
//
|
||||
// Radius of cylinders used to render wipe moves segments
|
||||
//
|
||||
float m_wipes_radius{ DEFAULT_WIPES_RADIUS_MM };
|
||||
//
|
||||
// Palette used to render extrusion roles
|
||||
//
|
||||
std::array<Color, size_t(EGCodeExtrusionRole::COUNT)> m_extrusion_roles_colors;
|
||||
//
|
||||
// Palette used to render options
|
||||
//
|
||||
std::array<Color, size_t(EOptionType::COUNT)> m_options_colors;
|
||||
|
||||
bool m_initialized{ false };
|
||||
|
||||
//
|
||||
// The OpenGL element used to represent all toolpath segments
|
||||
//
|
||||
SegmentTemplate m_segment_template;
|
||||
//
|
||||
// The OpenGL element used to represent all option markers
|
||||
//
|
||||
OptionTemplate m_option_template;
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
//
|
||||
// The OpenGL element used to represent the center of gravity
|
||||
//
|
||||
CogMarker m_cog_marker;
|
||||
float m_cog_marker_scale_factor{ 1.0f };
|
||||
//
|
||||
// The OpenGL element used to represent the tool nozzle
|
||||
//
|
||||
ToolMarker m_tool_marker;
|
||||
float m_tool_marker_scale_factor{ 1.0f };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
//
|
||||
// cpu buffer to store vertices
|
||||
//
|
||||
std::vector<PathVertex> m_vertices;
|
||||
|
||||
// Cache for the colors to reduce the need to recalculate colors of all the vertices.
|
||||
std::vector<float> m_vertices_colors;
|
||||
|
||||
//
|
||||
// Variables used for toolpaths visibiliity
|
||||
//
|
||||
BitSet<> m_valid_lines_bitset;
|
||||
//
|
||||
// Variables used for toolpaths coloring
|
||||
//
|
||||
std::optional<Settings> m_settings_used_for_ranges;
|
||||
ColorRange m_height_range;
|
||||
ColorRange m_width_range;
|
||||
ColorRange m_speed_range;
|
||||
ColorRange m_actual_speed_range;
|
||||
ColorRange m_fan_speed_range;
|
||||
ColorRange m_temperature_range;
|
||||
ColorRange m_volumetric_rate_range;
|
||||
ColorRange m_actual_volumetric_rate_range;
|
||||
std::array<ColorRange, COLOR_RANGE_TYPES_COUNT> m_layer_time_range{
|
||||
ColorRange(EColorRangeType::Linear), ColorRange(EColorRangeType::Logarithmic)
|
||||
};
|
||||
Palette m_tool_colors;
|
||||
Palette m_color_print_colors;
|
||||
//
|
||||
// OpenGL shaders ids
|
||||
//
|
||||
unsigned int m_segments_shader_id{ 0 };
|
||||
unsigned int m_options_shader_id{ 0 };
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
unsigned int m_cog_marker_shader_id{ 0 };
|
||||
unsigned int m_tool_marker_shader_id{ 0 };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
//
|
||||
// Caches for OpenGL uniforms id for segments shader
|
||||
//
|
||||
int m_uni_segments_view_matrix_id{ -1 };
|
||||
int m_uni_segments_projection_matrix_id{ -1 };
|
||||
int m_uni_segments_camera_position_id{ -1 };
|
||||
int m_uni_segments_positions_tex_id{ -1 };
|
||||
int m_uni_segments_height_width_angle_tex_id{ -1 };
|
||||
int m_uni_segments_colors_tex_id{ -1 };
|
||||
int m_uni_segments_segment_index_tex_id{ -1 };
|
||||
//
|
||||
// Caches for OpenGL uniforms id for options shader
|
||||
//
|
||||
int m_uni_options_view_matrix_id{ -1 };
|
||||
int m_uni_options_projection_matrix_id{ -1 };
|
||||
int m_uni_options_positions_tex_id{ -1 };
|
||||
int m_uni_options_height_width_angle_tex_id{ -1 };
|
||||
int m_uni_options_colors_tex_id{ -1 };
|
||||
int m_uni_options_segment_index_tex_id{ -1 };
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
//
|
||||
// Caches for OpenGL uniforms id for cog marker shader
|
||||
//
|
||||
int m_uni_cog_marker_world_center_position{ -1 };
|
||||
int m_uni_cog_marker_scale_factor{ -1 };
|
||||
int m_uni_cog_marker_view_matrix{ -1 };
|
||||
int m_uni_cog_marker_projection_matrix{ -1 };
|
||||
//
|
||||
// Caches for OpenGL uniforms id for tool marker shader
|
||||
//
|
||||
int m_uni_tool_marker_world_origin{ -1 };
|
||||
int m_uni_tool_marker_scale_factor{ -1 };
|
||||
int m_uni_tool_marker_view_matrix{ -1 };
|
||||
int m_uni_tool_marker_projection_matrix{ -1 };
|
||||
int m_uni_tool_marker_color_base{ -1 };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
class TextureData
|
||||
{
|
||||
public:
|
||||
void init(size_t vertices_count);
|
||||
void set_positions(const std::vector<Vec3>& positions);
|
||||
void set_heights_widths_angles(const std::vector<Vec3>& heights_widths_angles);
|
||||
void set_colors(const std::vector<float>& colors);
|
||||
void set_enabled_segments(const std::vector<uint32_t>& enabled_segments);
|
||||
void set_enabled_options(const std::vector<uint32_t>& enabled_options);
|
||||
void reset();
|
||||
size_t get_count() const { return m_count; }
|
||||
std::pair<unsigned int, size_t> get_positions_tex_id(size_t id) const;
|
||||
std::pair<unsigned int, size_t> get_heights_widths_angles_tex_id(size_t id) const;
|
||||
std::pair<unsigned int, size_t> get_colors_tex_id(size_t id) const;
|
||||
std::pair<unsigned int, size_t> get_enabled_segments_tex_id(size_t id) const;
|
||||
std::pair<unsigned int, size_t> get_enabled_options_tex_id(size_t id) const;
|
||||
|
||||
size_t get_enabled_segments_count() const;
|
||||
size_t get_enabled_options_count() const;
|
||||
|
||||
size_t max_texture_capacity() const { return m_width * m_height; }
|
||||
size_t get_used_gpu_memory() const;
|
||||
|
||||
private:
|
||||
//
|
||||
// Texture width
|
||||
//
|
||||
size_t m_width{ 0 };
|
||||
//
|
||||
// Texture height
|
||||
//
|
||||
size_t m_height{ 0 };
|
||||
//
|
||||
// Count of textures
|
||||
//
|
||||
size_t m_count{ 0 };
|
||||
//
|
||||
// Caches for size of data sent to gpu, in bytes
|
||||
//
|
||||
size_t m_positions_size{ 0 };
|
||||
size_t m_height_width_angle_size{ 0 };
|
||||
size_t m_colors_size{ 0 };
|
||||
size_t m_enabled_segments_size{ 0 };
|
||||
size_t m_enabled_options_size{ 0 };
|
||||
|
||||
struct TexIds
|
||||
{
|
||||
//
|
||||
// OpenGL texture to store positions
|
||||
//
|
||||
std::pair<unsigned int, size_t> positions{ 0, 0 };
|
||||
//
|
||||
// OpenGL texture to store heights, widths and angles
|
||||
//
|
||||
std::pair<unsigned int, size_t> heights_widths_angles{ 0, 0 };
|
||||
//
|
||||
// OpenGL texture to store colors
|
||||
//
|
||||
std::pair<unsigned int, size_t> colors{ 0, 0 };
|
||||
//
|
||||
// OpenGL texture to store enabled segments
|
||||
//
|
||||
std::pair<unsigned int, size_t> enabled_segments{ 0, 0 };
|
||||
//
|
||||
// OpenGL texture to store enabled options
|
||||
//
|
||||
std::pair<unsigned int, size_t> enabled_options{ 0, 0 };
|
||||
};
|
||||
|
||||
std::vector<TexIds> m_tex_ids;
|
||||
};
|
||||
|
||||
TextureData m_texture_data;
|
||||
#else
|
||||
//
|
||||
// OpenGL buffers to store positions
|
||||
//
|
||||
unsigned int m_positions_buf_id{ 0 };
|
||||
unsigned int m_positions_tex_id{ 0 };
|
||||
//
|
||||
// OpenGL buffers to store heights, widths and angles
|
||||
//
|
||||
unsigned int m_heights_widths_angles_buf_id{ 0 };
|
||||
unsigned int m_heights_widths_angles_tex_id{ 0 };
|
||||
//
|
||||
// OpenGL buffers to store colors
|
||||
//
|
||||
unsigned int m_colors_buf_id{ 0 };
|
||||
unsigned int m_colors_tex_id{ 0 };
|
||||
//
|
||||
// OpenGL buffers to store enabled segments
|
||||
//
|
||||
unsigned int m_enabled_segments_buf_id{ 0 };
|
||||
unsigned int m_enabled_segments_tex_id{ 0 };
|
||||
size_t m_enabled_segments_count{ 0 };
|
||||
//
|
||||
// OpenGL buffers to store enabled options
|
||||
//
|
||||
unsigned int m_enabled_options_buf_id{ 0 };
|
||||
unsigned int m_enabled_options_tex_id{ 0 };
|
||||
size_t m_enabled_options_count{ 0 };
|
||||
//
|
||||
// Caches for size of data sent to gpu, in bytes
|
||||
//
|
||||
size_t m_positions_tex_size{ 0 };
|
||||
size_t m_height_width_angle_tex_size{ 0 };
|
||||
size_t m_colors_tex_size{ 0 };
|
||||
size_t m_enabled_segments_tex_size{ 0 };
|
||||
size_t m_enabled_options_tex_size{ 0 };
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
void update_view_full_range();
|
||||
void update_color_ranges();
|
||||
void update_heights_widths();
|
||||
void render_segments(const Mat4x4& view_matrix, const Mat4x4& projection_matrix, const Vec3& camera_position);
|
||||
void render_options(const Mat4x4& view_matrix, const Mat4x4& projection_matrix);
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
void render_cog_marker(const Mat4x4& view_matrix, const Mat4x4& projection_matrix);
|
||||
void render_tool_marker(const Mat4x4& view_matrix, const Mat4x4& projection_matrix);
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
};
|
||||
|
||||
} // namespace libvgcode
|
||||
|
||||
#endif // VGCODE_VIEWERIMPL_HPP
|
||||
|
|
@ -299,6 +299,8 @@ set(SLIC3R_GUI_SOURCES
|
|||
GUI/Jobs/Worker.hpp
|
||||
GUI/KBShortcutsDialog.cpp
|
||||
GUI/KBShortcutsDialog.hpp
|
||||
GUI/LibVGCode/LibVGCodeWrapper.hpp
|
||||
GUI/LibVGCode/LibVGCodeWrapper.cpp
|
||||
GUI/MainFrame.cpp
|
||||
GUI/MainFrame.hpp
|
||||
GUI/MarkdownTip.cpp
|
||||
|
|
@ -707,13 +709,15 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SLIC3R_GUI_SOURCES})
|
|||
|
||||
encoding_check(libslic3r_gui)
|
||||
|
||||
|
||||
if(APPLE AND CMAKE_VERSION VERSION_GREATER_EQUAL "4.0")
|
||||
set(_opengl_link_lib "")
|
||||
else()
|
||||
set(_opengl_link_lib OpenGL::GL)
|
||||
endif()
|
||||
|
||||
target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo GLEW::GLEW ${_opengl_link_lib} hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise)
|
||||
target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo libvgcode GLEW::GLEW OpenGL::GL hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise)
|
||||
|
||||
|
||||
if (MSVC)
|
||||
target_link_libraries(libslic3r_gui Setupapi.lib)
|
||||
|
|
|
|||
|
|
@ -936,7 +936,11 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
|
|||
return;
|
||||
|
||||
GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat");
|
||||
GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat");
|
||||
#if SLIC3R_OPENGL_ES
|
||||
GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("dashed_lines");
|
||||
#else
|
||||
GLShaderProgram* edges_shader = GUI::OpenGLManager::get_gl_info().is_core_profile() ? GUI::wxGetApp().get_shader("dashed_thick_lines") : GUI::wxGetApp().get_shader("flat");
|
||||
#endif // SLIC3R_OPENGL_ES
|
||||
|
||||
if (type == ERenderType::Transparent) {
|
||||
glsafe(::glEnable(GL_BLEND));
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -10,6 +10,10 @@
|
|||
|
||||
#include <boost/iostreams/device/mapped_file.hpp>
|
||||
|
||||
#include "LibVGCode/LibVGCodeWrapper.hpp"
|
||||
// needed for tech VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#include <libvgcode/include/Types.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <float.h>
|
||||
#include <set>
|
||||
|
|
@ -33,584 +37,44 @@ static const float SLIDER_RIGHT_MARGIN = 124.0f;
|
|||
static const float SLIDER_BOTTOM_MARGIN = 64.0f;
|
||||
class GCodeViewer
|
||||
{
|
||||
using IBufferType = unsigned short;
|
||||
using VertexBuffer = std::vector<float>;
|
||||
using MultiVertexBuffer = std::vector<VertexBuffer>;
|
||||
using IndexBuffer = std::vector<IBufferType>;
|
||||
using MultiIndexBuffer = std::vector<IndexBuffer>;
|
||||
using InstanceBuffer = std::vector<float>;
|
||||
using InstanceIdBuffer = std::vector<size_t>;
|
||||
using InstancesOffsets = std::vector<Vec3f>;
|
||||
|
||||
static const std::vector<ColorRGBA> Extrusion_Role_Colors;
|
||||
static const std::vector<ColorRGBA> Options_Colors;
|
||||
static const std::vector<ColorRGBA> Travel_Colors;
|
||||
static const std::vector<ColorRGBA> Range_Colors;
|
||||
static const ColorRGBA Wipe_Color;
|
||||
static const ColorRGBA Neutral_Color;
|
||||
|
||||
enum class EOptionsColors : unsigned char
|
||||
{
|
||||
Retractions,
|
||||
Unretractions,
|
||||
Seams,
|
||||
ToolChanges,
|
||||
ColorChanges,
|
||||
PausePrints,
|
||||
CustomGCodes
|
||||
};
|
||||
|
||||
// vbo buffer containing vertices data used to render a specific toolpath type
|
||||
struct VBuffer
|
||||
{
|
||||
enum class EFormat : unsigned char
|
||||
{
|
||||
// vertex format: 3 floats -> position.x|position.y|position.z
|
||||
Position,
|
||||
// vertex format: 4 floats -> position.x|position.y|position.z|normal.x
|
||||
PositionNormal1,
|
||||
// vertex format: 6 floats -> position.x|position.y|position.z|normal.x|normal.y|normal.z
|
||||
PositionNormal3
|
||||
};
|
||||
|
||||
EFormat format{ EFormat::Position };
|
||||
// vbos id
|
||||
std::vector<unsigned int> vbos;
|
||||
// sizes of the buffers, in bytes, used in export to obj
|
||||
std::vector<size_t> sizes;
|
||||
// count of vertices, updated after data are sent to gpu
|
||||
size_t count{ 0 };
|
||||
|
||||
size_t data_size_bytes() const { return count * vertex_size_bytes(); }
|
||||
// We set 65536 as max count of vertices inside a vertex buffer to allow
|
||||
// to use unsigned short in place of unsigned int for indices in the index buffer, to save memory
|
||||
size_t max_size_bytes() const { return 65536 * vertex_size_bytes(); }
|
||||
|
||||
size_t vertex_size_floats() const { return position_size_floats() + normal_size_floats(); }
|
||||
size_t vertex_size_bytes() const { return vertex_size_floats() * sizeof(float); }
|
||||
|
||||
size_t position_offset_floats() const { return 0; }
|
||||
size_t position_offset_bytes() const { return position_offset_floats() * sizeof(float); }
|
||||
|
||||
size_t position_size_floats() const { return 3; }
|
||||
size_t position_size_bytes() const { return position_size_floats() * sizeof(float); }
|
||||
|
||||
size_t normal_offset_floats() const {
|
||||
assert(format == EFormat::PositionNormal1 || format == EFormat::PositionNormal3);
|
||||
return position_size_floats();
|
||||
}
|
||||
size_t normal_offset_bytes() const { return normal_offset_floats() * sizeof(float); }
|
||||
|
||||
size_t normal_size_floats() const {
|
||||
switch (format)
|
||||
{
|
||||
case EFormat::PositionNormal1: { return 1; }
|
||||
case EFormat::PositionNormal3: { return 3; }
|
||||
default: { return 0; }
|
||||
}
|
||||
}
|
||||
size_t normal_size_bytes() const { return normal_size_floats() * sizeof(float); }
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
// buffer containing instances data used to render a toolpaths using instanced or batched models
|
||||
// instance record format:
|
||||
// instanced models: 5 floats -> position.x|position.y|position.z|width|height (which are sent to the shader as -> vec3 (offset) + vec2 (scales) in GLModel::render_instanced())
|
||||
// batched models: 3 floats -> position.x|position.y|position.z
|
||||
struct InstanceVBuffer
|
||||
{
|
||||
// ranges used to render only subparts of the intances
|
||||
struct Ranges
|
||||
{
|
||||
struct Range
|
||||
{
|
||||
// offset in bytes of the 1st instance to render
|
||||
unsigned int offset;
|
||||
// count of instances to render
|
||||
unsigned int count;
|
||||
// vbo id
|
||||
unsigned int vbo{ 0 };
|
||||
// Color to apply to the instances
|
||||
ColorRGBA color;
|
||||
};
|
||||
|
||||
std::vector<Range> ranges;
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
enum class EFormat : unsigned char
|
||||
{
|
||||
InstancedModel,
|
||||
BatchedModel
|
||||
};
|
||||
|
||||
EFormat format;
|
||||
|
||||
// cpu-side buffer containing all instances data
|
||||
InstanceBuffer buffer;
|
||||
// indices of the moves for all instances
|
||||
std::vector<size_t> s_ids;
|
||||
// position offsets, used to show the correct value of the tool position
|
||||
InstancesOffsets offsets;
|
||||
Ranges render_ranges;
|
||||
|
||||
size_t data_size_bytes() const { return s_ids.size() * instance_size_bytes(); }
|
||||
|
||||
size_t instance_size_floats() const {
|
||||
switch (format)
|
||||
{
|
||||
case EFormat::InstancedModel: { return 5; }
|
||||
case EFormat::BatchedModel: { return 3; }
|
||||
default: { return 0; }
|
||||
}
|
||||
}
|
||||
size_t instance_size_bytes() const { return instance_size_floats() * sizeof(float); }
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
// ibo buffer containing indices data (for lines/triangles) used to render a specific toolpath type
|
||||
struct IBuffer
|
||||
{
|
||||
// id of the associated vertex buffer
|
||||
unsigned int vbo{ 0 };
|
||||
// ibo id
|
||||
unsigned int ibo{ 0 };
|
||||
// count of indices, updated after data are sent to gpu
|
||||
size_t count{ 0 };
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
// Used to identify different toolpath sub-types inside a IBuffer
|
||||
struct Path
|
||||
{
|
||||
struct Endpoint
|
||||
{
|
||||
// index of the buffer in the multibuffer vector
|
||||
// the buffer type may change:
|
||||
// it is the vertex buffer while extracting vertices data,
|
||||
// the index buffer while extracting indices data
|
||||
unsigned int b_id{ 0 };
|
||||
// index into the buffer
|
||||
size_t i_id{ 0 };
|
||||
// move id
|
||||
size_t s_id{ 0 };
|
||||
Vec3f position{ Vec3f::Zero() };
|
||||
};
|
||||
|
||||
struct Sub_Path
|
||||
{
|
||||
Endpoint first;
|
||||
Endpoint last;
|
||||
|
||||
bool contains(size_t s_id) const {
|
||||
return first.s_id <= s_id && s_id <= last.s_id;
|
||||
}
|
||||
};
|
||||
|
||||
EMoveType type{ EMoveType::Noop };
|
||||
ExtrusionRole role{ erNone };
|
||||
float delta_extruder{ 0.0f };
|
||||
float height{ 0.0f };
|
||||
float width{ 0.0f };
|
||||
float feedrate{ 0.0f };
|
||||
float fan_speed{ 0.0f };
|
||||
float temperature{ 0.0f };
|
||||
float volumetric_rate{ 0.0f };
|
||||
float layer_time{ 0.0f };
|
||||
unsigned char extruder_id{ 0 };
|
||||
unsigned char cp_color_id{ 0 };
|
||||
std::vector<Sub_Path> sub_paths;
|
||||
|
||||
bool matches(const GCodeProcessorResult::MoveVertex& move) const;
|
||||
size_t vertices_count() const {
|
||||
return sub_paths.empty() ? 0 : sub_paths.back().last.s_id - sub_paths.front().first.s_id + 1;
|
||||
}
|
||||
bool contains(size_t s_id) const {
|
||||
return sub_paths.empty() ? false : sub_paths.front().first.s_id <= s_id && s_id <= sub_paths.back().last.s_id;
|
||||
}
|
||||
int get_id_of_sub_path_containing(size_t s_id) const {
|
||||
if (sub_paths.empty())
|
||||
return -1;
|
||||
else {
|
||||
for (int i = 0; i < static_cast<int>(sub_paths.size()); ++i) {
|
||||
if (sub_paths[i].contains(s_id))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
void add_sub_path(const GCodeProcessorResult::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id) {
|
||||
Endpoint endpoint = { b_id, i_id, s_id, move.position };
|
||||
sub_paths.push_back({ endpoint , endpoint });
|
||||
}
|
||||
};
|
||||
|
||||
// Used to batch the indices needed to render the paths
|
||||
struct RenderPath
|
||||
{
|
||||
// Index of the parent tbuffer
|
||||
unsigned char tbuffer_id;
|
||||
// Render path property
|
||||
ColorRGBA color;
|
||||
// Index of the buffer in TBuffer::indices
|
||||
unsigned int ibuffer_id;
|
||||
// Render path content
|
||||
// Index of the path in TBuffer::paths
|
||||
unsigned int path_id;
|
||||
std::vector<unsigned int> sizes;
|
||||
std::vector<size_t> offsets; // use size_t because we need an unsigned integer whose size matches pointer's size (used in the call glMultiDrawElements())
|
||||
bool contains(size_t offset) const {
|
||||
for (size_t i = 0; i < offsets.size(); ++i) {
|
||||
if (offsets[i] <= offset && offset <= offsets[i] + static_cast<size_t>(sizes[i] * sizeof(IBufferType)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
struct RenderPathPropertyLower {
|
||||
bool operator() (const RenderPath &l, const RenderPath &r) const {
|
||||
if (l.tbuffer_id < r.tbuffer_id)
|
||||
return true;
|
||||
if (l.color < r.color)
|
||||
return true;
|
||||
else if (l.color > r.color)
|
||||
return false;
|
||||
return l.ibuffer_id < r.ibuffer_id;
|
||||
}
|
||||
};
|
||||
struct RenderPathPropertyEqual {
|
||||
bool operator() (const RenderPath &l, const RenderPath &r) const {
|
||||
return l.tbuffer_id == r.tbuffer_id && l.ibuffer_id == r.ibuffer_id && l.color == r.color;
|
||||
}
|
||||
};
|
||||
|
||||
// buffer containing data for rendering a specific toolpath type
|
||||
struct TBuffer
|
||||
{
|
||||
enum class ERenderPrimitiveType : unsigned char
|
||||
{
|
||||
Line,
|
||||
Triangle,
|
||||
InstancedModel,
|
||||
BatchedModel
|
||||
};
|
||||
|
||||
ERenderPrimitiveType render_primitive_type;
|
||||
|
||||
// buffers for point, line and triangle primitive types
|
||||
VBuffer vertices;
|
||||
std::vector<IBuffer> indices;
|
||||
|
||||
struct Model
|
||||
{
|
||||
GLModel model;
|
||||
ColorRGBA color;
|
||||
InstanceVBuffer instances;
|
||||
GLModel::Geometry data;
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
// contain the buffer for model primitive types
|
||||
Model model;
|
||||
|
||||
std::string shader;
|
||||
std::vector<Path> paths;
|
||||
std::vector<RenderPath> render_paths;
|
||||
bool visible{ false };
|
||||
|
||||
void reset();
|
||||
|
||||
// b_id index of buffer contained in this->indices
|
||||
// i_id index of first index contained in this->indices[b_id]
|
||||
// s_id index of first vertex contained in this->vertices
|
||||
void add_path(const GCodeProcessorResult::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id);
|
||||
|
||||
unsigned int max_vertices_per_segment() const {
|
||||
switch (render_primitive_type)
|
||||
{
|
||||
case ERenderPrimitiveType::Line: { return 2; }
|
||||
case ERenderPrimitiveType::Triangle: { return 8; }
|
||||
default: { return 0; }
|
||||
}
|
||||
}
|
||||
|
||||
size_t max_vertices_per_segment_size_floats() const { return vertices.vertex_size_floats() * static_cast<size_t>(max_vertices_per_segment()); }
|
||||
size_t max_vertices_per_segment_size_bytes() const { return max_vertices_per_segment_size_floats() * sizeof(float); }
|
||||
unsigned int indices_per_segment() const {
|
||||
switch (render_primitive_type)
|
||||
{
|
||||
case ERenderPrimitiveType::Line: { return 2; }
|
||||
case ERenderPrimitiveType::Triangle: { return 30; } // 3 indices x 10 triangles
|
||||
default: { return 0; }
|
||||
}
|
||||
}
|
||||
size_t indices_per_segment_size_bytes() const { return static_cast<size_t>(indices_per_segment() * sizeof(IBufferType)); }
|
||||
unsigned int max_indices_per_segment() const {
|
||||
switch (render_primitive_type)
|
||||
{
|
||||
case ERenderPrimitiveType::Line: { return 2; }
|
||||
case ERenderPrimitiveType::Triangle: { return 36; } // 3 indices x 12 triangles
|
||||
default: { return 0; }
|
||||
}
|
||||
}
|
||||
size_t max_indices_per_segment_size_bytes() const { return max_indices_per_segment() * sizeof(IBufferType); }
|
||||
|
||||
bool has_data() const {
|
||||
switch (render_primitive_type)
|
||||
{
|
||||
case ERenderPrimitiveType::Line:
|
||||
case ERenderPrimitiveType::Triangle: {
|
||||
return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0;
|
||||
}
|
||||
case ERenderPrimitiveType::InstancedModel: { return model.model.is_initialized() && !model.instances.buffer.empty(); }
|
||||
case ERenderPrimitiveType::BatchedModel: {
|
||||
return !model.data.vertices.empty() && !model.data.indices.empty() &&
|
||||
!vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0;
|
||||
}
|
||||
default: { return false; }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// helper to render extrusion paths
|
||||
struct Extrusions
|
||||
{
|
||||
struct Range
|
||||
{
|
||||
float min;
|
||||
float max;
|
||||
unsigned int count;
|
||||
bool log_scale;
|
||||
|
||||
Range() { reset(); }
|
||||
void update_from(const float value) {
|
||||
if (value != max && value != min)
|
||||
++count;
|
||||
min = std::min(min, value);
|
||||
max = std::max(max, value);
|
||||
}
|
||||
void reset(bool log = false) { min = FLT_MAX; max = -FLT_MAX; count = 0; log_scale = log; }
|
||||
|
||||
float step_size() const;
|
||||
ColorRGBA get_color_at(float value) const;
|
||||
float get_value_at_step(int step) const;
|
||||
|
||||
};
|
||||
|
||||
struct Ranges
|
||||
{
|
||||
// Color mapping by layer height.
|
||||
Range height;
|
||||
// Color mapping by extrusion width.
|
||||
Range width;
|
||||
// Color mapping by feedrate.
|
||||
Range feedrate;
|
||||
// Color mapping by fan speed.
|
||||
Range fan_speed;
|
||||
// Color mapping by volumetric extrusion rate.
|
||||
Range volumetric_rate;
|
||||
// Color mapping by extrusion temperature.
|
||||
Range temperature;
|
||||
// Color mapping by layer time.
|
||||
Range layer_duration;
|
||||
Range layer_duration_log;
|
||||
void reset() {
|
||||
height.reset();
|
||||
width.reset();
|
||||
feedrate.reset();
|
||||
fan_speed.reset();
|
||||
volumetric_rate.reset();
|
||||
temperature.reset();
|
||||
layer_duration.reset();
|
||||
layer_duration_log.reset(true);
|
||||
}
|
||||
};
|
||||
|
||||
unsigned int role_visibility_flags{ 0 };
|
||||
Ranges ranges;
|
||||
|
||||
void reset_role_visibility_flags() {
|
||||
role_visibility_flags = 0;
|
||||
for (unsigned int i = 0; i < erCount; ++i) {
|
||||
role_visibility_flags |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
void reset_ranges() { ranges.reset(); }
|
||||
};
|
||||
|
||||
class Layers
|
||||
{
|
||||
public:
|
||||
struct Endpoints
|
||||
{
|
||||
size_t first{ 0 };
|
||||
size_t last{ 0 };
|
||||
|
||||
bool operator == (const Endpoints& other) const { return first == other.first && last == other.last; }
|
||||
bool operator != (const Endpoints& other) const { return !operator==(other); }
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<double> m_zs;
|
||||
std::vector<Endpoints> m_endpoints;
|
||||
|
||||
public:
|
||||
void append(double z, Endpoints endpoints) {
|
||||
m_zs.emplace_back(z);
|
||||
m_endpoints.emplace_back(endpoints);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
m_zs = std::vector<double>();
|
||||
m_endpoints = std::vector<Endpoints>();
|
||||
}
|
||||
|
||||
size_t size() const { return m_zs.size(); }
|
||||
bool empty() const { return m_zs.empty(); }
|
||||
const std::vector<double>& get_zs() const { return m_zs; }
|
||||
const std::vector<Endpoints>& get_endpoints() const { return m_endpoints; }
|
||||
std::vector<Endpoints>& get_endpoints() { return m_endpoints; }
|
||||
double get_z_at(unsigned int id) const { return (id < m_zs.size()) ? m_zs[id] : 0.0; }
|
||||
Endpoints get_endpoints_at(unsigned int id) const { return (id < m_endpoints.size()) ? m_endpoints[id] : Endpoints(); }
|
||||
int get_l_at(float z) const
|
||||
{
|
||||
auto iter = std::upper_bound(m_zs.begin(), m_zs.end(), z);
|
||||
return std::distance(m_zs.begin(), iter);
|
||||
}
|
||||
|
||||
bool operator != (const Layers& other) const {
|
||||
if (m_zs != other.m_zs)
|
||||
return true;
|
||||
if (m_endpoints != other.m_endpoints)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// used to render the toolpath caps of the current sequential range
|
||||
// (i.e. when sliding on the horizontal slider)
|
||||
struct SequentialRangeCap
|
||||
{
|
||||
TBuffer* buffer{ nullptr };
|
||||
unsigned int ibo{ 0 };
|
||||
unsigned int vbo{ 0 };
|
||||
ColorRGBA color;
|
||||
|
||||
~SequentialRangeCap();
|
||||
bool is_renderable() const { return buffer != nullptr; }
|
||||
void reset();
|
||||
size_t indices_count() const { return 6; }
|
||||
};
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
struct Statistics
|
||||
{
|
||||
// time
|
||||
int64_t results_time{ 0 };
|
||||
int64_t load_time{ 0 };
|
||||
int64_t load_vertices{ 0 };
|
||||
int64_t smooth_vertices{ 0 };
|
||||
int64_t load_indices{ 0 };
|
||||
int64_t refresh_time{ 0 };
|
||||
int64_t refresh_paths_time{ 0 };
|
||||
// opengl calls
|
||||
int64_t gl_multi_lines_calls_count{ 0 };
|
||||
int64_t gl_multi_triangles_calls_count{ 0 };
|
||||
int64_t gl_triangles_calls_count{ 0 };
|
||||
int64_t gl_instanced_models_calls_count{ 0 };
|
||||
int64_t gl_batched_models_calls_count{ 0 };
|
||||
// memory
|
||||
int64_t results_size{ 0 };
|
||||
int64_t total_vertices_gpu_size{ 0 };
|
||||
int64_t total_indices_gpu_size{ 0 };
|
||||
int64_t total_instances_gpu_size{ 0 };
|
||||
int64_t max_vbuffer_gpu_size{ 0 };
|
||||
int64_t max_ibuffer_gpu_size{ 0 };
|
||||
int64_t paths_size{ 0 };
|
||||
int64_t render_paths_size{ 0 };
|
||||
int64_t models_instances_size{ 0 };
|
||||
// other
|
||||
int64_t travel_segments_count{ 0 };
|
||||
int64_t wipe_segments_count{ 0 };
|
||||
int64_t extrude_segments_count{ 0 };
|
||||
int64_t instances_count{ 0 };
|
||||
int64_t batched_count{ 0 };
|
||||
int64_t vbuffers_count{ 0 };
|
||||
int64_t ibuffers_count{ 0 };
|
||||
|
||||
void reset_all() {
|
||||
reset_times();
|
||||
reset_opengl();
|
||||
reset_sizes();
|
||||
reset_others();
|
||||
}
|
||||
|
||||
void reset_times() {
|
||||
results_time = 0;
|
||||
load_time = 0;
|
||||
load_vertices = 0;
|
||||
smooth_vertices = 0;
|
||||
load_indices = 0;
|
||||
refresh_time = 0;
|
||||
refresh_paths_time = 0;
|
||||
}
|
||||
|
||||
void reset_opengl() {
|
||||
gl_multi_lines_calls_count = 0;
|
||||
gl_multi_triangles_calls_count = 0;
|
||||
gl_triangles_calls_count = 0;
|
||||
gl_instanced_models_calls_count = 0;
|
||||
gl_batched_models_calls_count = 0;
|
||||
}
|
||||
|
||||
void reset_sizes() {
|
||||
results_size = 0;
|
||||
total_vertices_gpu_size = 0;
|
||||
total_indices_gpu_size = 0;
|
||||
total_instances_gpu_size = 0;
|
||||
max_vbuffer_gpu_size = 0;
|
||||
max_ibuffer_gpu_size = 0;
|
||||
paths_size = 0;
|
||||
render_paths_size = 0;
|
||||
models_instances_size = 0;
|
||||
}
|
||||
|
||||
void reset_others() {
|
||||
travel_segments_count = 0;
|
||||
wipe_segments_count = 0;
|
||||
extrude_segments_count = 0;
|
||||
instances_count = 0;
|
||||
batched_count = 0;
|
||||
vbuffers_count = 0;
|
||||
ibuffers_count = 0;
|
||||
}
|
||||
};
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
||||
public:
|
||||
enum class EViewType : unsigned char;
|
||||
struct SequentialView
|
||||
{
|
||||
#if ENABLE_ACTUAL_SPEED_DEBUG
|
||||
struct ActualSpeedImguiWidget
|
||||
{
|
||||
std::pair<float, float> y_range = { 0.0f, 0.0f };
|
||||
std::vector<std::pair<float, ColorRGBA>> levels;
|
||||
struct Item
|
||||
{
|
||||
float pos{ 0.0f };
|
||||
float speed{ 0.0f };
|
||||
bool internal{ false };
|
||||
};
|
||||
std::vector<Item> data;
|
||||
int plot(const char* label, const std::array<float, 2>& frame_size = { 0.0f, 0.0f });
|
||||
};
|
||||
#endif // ENABLE_ACTUAL_SPEED_DEBUG
|
||||
|
||||
class Marker
|
||||
{
|
||||
GLModel m_model;
|
||||
Vec3f m_world_position;
|
||||
Transform3f m_world_transform;
|
||||
// for seams, the position of the marker is on the last endpoint of the toolpath containing it
|
||||
// the offset is used to show the correct value of tool position in the "ToolPosition" window
|
||||
// see implementation of render() method
|
||||
Vec3f m_world_offset;
|
||||
float m_z_offset{ 0.5f };
|
||||
GCodeProcessorResult::MoveVertex m_curr_move;
|
||||
float m_z_offset{ 0.0f };
|
||||
// z offset of the model
|
||||
float m_model_z_offset{ 0.5f };
|
||||
bool m_visible{ true };
|
||||
bool m_is_dark = false;
|
||||
bool m_fixed_screen_size{ false };
|
||||
float m_scale_factor{ 1.0f };
|
||||
#if ENABLE_ACTUAL_SPEED_DEBUG
|
||||
ActualSpeedImguiWidget m_actual_speed_imgui_widget;
|
||||
#endif // ENABLE_ACTUAL_SPEED_DEBUG
|
||||
|
||||
public:
|
||||
float m_scale = 1.0f;
|
||||
|
|
@ -619,16 +83,28 @@ public:
|
|||
|
||||
const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); }
|
||||
|
||||
void set_world_position(const Vec3f& position);
|
||||
void set_world_position(const Vec3f& position) { m_world_position = position; }
|
||||
void set_world_offset(const Vec3f& offset) { m_world_offset = offset; }
|
||||
void set_z_offset(float z_offset) { m_z_offset = z_offset; }
|
||||
|
||||
#if ENABLE_ACTUAL_SPEED_DEBUG
|
||||
void set_actual_speed_y_range(const std::pair<float, float>& y_range) {
|
||||
m_actual_speed_imgui_widget.y_range = y_range;
|
||||
}
|
||||
void set_actual_speed_levels(const std::vector<std::pair<float, ColorRGBA>>& levels) {
|
||||
m_actual_speed_imgui_widget.levels = levels;
|
||||
}
|
||||
void set_actual_speed_data(const std::vector<ActualSpeedImguiWidget::Item>& data) {
|
||||
m_actual_speed_imgui_widget.data = data;
|
||||
}
|
||||
#endif // ENABLE_ACTUAL_SPEED_DEBUG
|
||||
|
||||
bool is_visible() const { return m_visible; }
|
||||
void set_visible(bool visible) { m_visible = visible; }
|
||||
|
||||
void render(int canvas_width, int canvas_height, const EViewType& view_type);
|
||||
void render(int canvas_width, int canvas_height, const libvgcode::EViewType& view_type);
|
||||
void render_position_window(const libvgcode::Viewer* viewer, int canvas_width, int canvas_height);
|
||||
void on_change_color_mode(bool is_dark) { m_is_dark = is_dark; }
|
||||
|
||||
void update_curr_move(const GCodeProcessorResult::MoveVertex move);
|
||||
};
|
||||
|
||||
class GCodeWindow
|
||||
|
|
@ -672,33 +148,12 @@ public:
|
|||
void stop_mapping_file();
|
||||
};
|
||||
|
||||
struct Endpoints
|
||||
{
|
||||
size_t first{ 0 };
|
||||
size_t last{ 0 };
|
||||
};
|
||||
|
||||
bool skip_invisible_moves{ false };
|
||||
Endpoints endpoints;
|
||||
Endpoints current;
|
||||
Endpoints last_current;
|
||||
Endpoints global;
|
||||
Vec3f current_position{ Vec3f::Zero() };
|
||||
Vec3f current_offset{ Vec3f::Zero() };
|
||||
Marker marker;
|
||||
GCodeWindow gcode_window;
|
||||
std::vector<unsigned int> gcode_ids;
|
||||
float m_scale = 1.0;
|
||||
bool m_show_marker = false;
|
||||
void render(const bool has_render_path, float legend_height, int canvas_width, int canvas_height, int right_margin, const EViewType& view_type);
|
||||
void render(const bool has_render_path, float legend_height, const libvgcode::Viewer* viewer, uint32_t gcode_id, int canvas_width, int canvas_height, int right_margin, const libvgcode::EViewType& view_type);
|
||||
};
|
||||
|
||||
struct ETools
|
||||
{
|
||||
std::vector<ColorRGBA> m_tool_colors;
|
||||
std::vector<bool> m_tool_visibles;
|
||||
};
|
||||
|
||||
struct ExtruderFilament
|
||||
{
|
||||
std::string type;
|
||||
|
|
@ -706,24 +161,6 @@ public:
|
|||
unsigned char filament_id;
|
||||
bool is_support_filament;
|
||||
};
|
||||
|
||||
enum class EViewType : unsigned char
|
||||
{
|
||||
Summary = 0,
|
||||
FeatureType,
|
||||
Height,
|
||||
Width,
|
||||
Feedrate,
|
||||
FanSpeed,
|
||||
Temperature,
|
||||
VolumetricRate,
|
||||
Tool,
|
||||
ColorPrint,
|
||||
FilamentId,
|
||||
LayerTime,
|
||||
LayerTimeLog,
|
||||
Count
|
||||
};
|
||||
// helper to render shells
|
||||
struct Shells
|
||||
{
|
||||
|
|
@ -744,19 +181,16 @@ private:
|
|||
std::vector<int> m_plater_extruder;
|
||||
bool m_gl_data_initialized{ false };
|
||||
unsigned int m_last_result_id{ 0 };
|
||||
size_t m_moves_count{ 0 };
|
||||
//BBS: save m_gcode_result as well
|
||||
const GCodeProcessorResult* m_gcode_result;
|
||||
//BBS: add only gcode mode
|
||||
bool m_only_gcode_in_preview {false};
|
||||
std::vector<size_t> m_ssid_to_moveid_map;
|
||||
|
||||
//BBS: extruder dispensing filament
|
||||
std::vector<ExtruderFilament> m_left_extruder_filament;
|
||||
std::vector<ExtruderFilament> m_right_extruder_filament;
|
||||
size_t m_nozzle_nums;
|
||||
|
||||
std::vector<TBuffer> m_buffers{ static_cast<size_t>(EMoveType::Extrude) };
|
||||
// bounding box of toolpaths
|
||||
BoundingBoxf3 m_paths_bounding_box;
|
||||
// bounding box of toolpaths + marker tools
|
||||
|
|
@ -764,41 +198,38 @@ private:
|
|||
//BBS: add shell bounding box
|
||||
BoundingBoxf3 m_shell_bounding_box;
|
||||
float m_max_print_height{ 0.0f };
|
||||
float m_z_offset{ 0.0f };
|
||||
|
||||
//BBS save m_tools_color and m_tools_visible
|
||||
ETools m_tools;
|
||||
ConfigOptionMode m_user_mode;
|
||||
bool m_fold = {false};
|
||||
|
||||
Layers m_layers;
|
||||
std::array<unsigned int, 2> m_layers_z_range;
|
||||
std::vector<ExtrusionRole> m_roles;
|
||||
size_t m_extruders_count;
|
||||
std::vector<unsigned char> m_extruder_ids;
|
||||
std::vector<float> m_filament_diameters;
|
||||
std::vector<float> m_filament_densities;
|
||||
Extrusions m_extrusions;
|
||||
SequentialView m_sequential_view;
|
||||
IMSlider* m_moves_slider;
|
||||
IMSlider* m_layers_slider;
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
// whether or not to render the cog model with fixed screen size
|
||||
bool m_cog_marker_fixed_screen_size{ true };
|
||||
float m_cog_marker_size{ 1.0f };
|
||||
bool m_tool_marker_fixed_screen_size{ false };
|
||||
float m_tool_marker_size{ 1.0f };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
/*BBS GUI refactor, store displayed items in color scheme combobox */
|
||||
std::vector<EViewType> view_type_items;
|
||||
std::vector<libvgcode::EViewType> view_type_items;
|
||||
std::vector<std::string> view_type_items_str;
|
||||
int m_view_type_sel = 0;
|
||||
EViewType m_view_type{ EViewType::FeatureType };
|
||||
std::vector<EMoveType> options_items;
|
||||
|
||||
bool m_legend_visible{ true };
|
||||
bool m_legend_enabled{ true };
|
||||
|
||||
float m_legend_height;
|
||||
PrintEstimatedStatistics m_print_statistics;
|
||||
PrintEstimatedStatistics::ETimeMode m_time_estimate_mode{ PrintEstimatedStatistics::ETimeMode::Normal };
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
Statistics m_statistics;
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
std::array<float, 2> m_detected_point_sizes = { 0.0f, 0.0f };
|
||||
GCodeProcessorResult::SettingsIds m_settings_ids;
|
||||
std::array<SequentialRangeCap, 2> m_sequential_range_caps;
|
||||
|
||||
std::vector<CustomGCode::Item> m_custom_gcode_per_print_z;
|
||||
|
||||
|
|
@ -806,6 +237,9 @@ private:
|
|||
mutable bool m_no_render_path { false };
|
||||
bool m_is_dark = false;
|
||||
|
||||
libvgcode::Viewer m_viewer;
|
||||
bool m_loaded_as_preview{ false };
|
||||
|
||||
public:
|
||||
GCodeViewer();
|
||||
~GCodeViewer();
|
||||
|
|
@ -818,11 +252,10 @@ public:
|
|||
|
||||
// extract rendering data from the given parameters
|
||||
//BBS: add only gcode mode
|
||||
void load(const GCodeProcessorResult& gcode_result, const Print& print, const BuildVolume& build_volume,
|
||||
const std::vector<BoundingBoxf3>& exclude_bounding_box, ConfigOptionMode mode, bool only_gcode = false);
|
||||
// recalculate ranges in dependence of what is visible and sets tool/print colors
|
||||
void refresh(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors);
|
||||
void refresh_render_paths();
|
||||
void load_as_gcode(const GCodeProcessorResult& gcode_result, const Print& print, const std::vector<std::string>& str_tool_colors,
|
||||
const std::vector<std::string>& str_color_print_colors, const BuildVolume& build_volume,
|
||||
const std::vector<BoundingBoxf3>& exclude_bounding_box, ConfigOptionMode mode, bool only_gcode = false);
|
||||
void load_as_preview(libvgcode::GCodeInputData&& data);
|
||||
void update_shells_color_by_extruder(const DynamicPrintConfig* config);
|
||||
void set_shell_transparency(float alpha = 0.15f);
|
||||
|
||||
|
|
@ -836,11 +269,11 @@ public:
|
|||
//BBS: GUI refactor: add canvas width and height
|
||||
void render(int canvas_width, int canvas_height, int right_margin);
|
||||
//BBS
|
||||
void _render_calibration_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager);
|
||||
void _render_calibration_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager);
|
||||
void render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager);
|
||||
// void _render_calibration_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager);
|
||||
// void _render_calibration_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager);
|
||||
// void render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager);
|
||||
bool has_data() const { return !m_viewer.get_extrusion_roles().empty(); }
|
||||
|
||||
bool has_data() const { return !m_roles.empty(); }
|
||||
bool can_export_toolpaths() const;
|
||||
std::vector<int> get_plater_extruder();
|
||||
|
||||
|
|
@ -848,8 +281,15 @@ public:
|
|||
const BoundingBoxf3& get_paths_bounding_box() const { return m_paths_bounding_box; }
|
||||
const BoundingBoxf3& get_max_bounding_box() const { return m_max_bounding_box; }
|
||||
const BoundingBoxf3& get_shell_bounding_box() const { return m_shell_bounding_box; }
|
||||
const std::vector<double>& get_layers_zs() const { return m_layers.get_zs(); }
|
||||
const std::array<unsigned int,2> &get_layers_z_range() const { return m_layers_z_range; }
|
||||
std::vector<double> get_layers_zs() const {
|
||||
const std::vector<float> zs = m_viewer.get_layers_zs();
|
||||
std::vector<double> ret;
|
||||
std::transform(zs.begin(), zs.end(), std::back_inserter(ret), [](float z) { return static_cast<double>(z); });
|
||||
return ret;
|
||||
}
|
||||
std::vector<float> get_layers_times() const { return m_viewer.get_layers_estimated_times(); }
|
||||
|
||||
const std::array<size_t,2> &get_layers_z_range() const { return m_viewer.get_layers_view_range(); }
|
||||
|
||||
const SequentialView& get_sequential_view() const { return m_sequential_view; }
|
||||
void update_sequential_view_current(unsigned int first, unsigned int last);
|
||||
|
|
@ -860,56 +300,56 @@ public:
|
|||
void enable_moves_slider(bool enable) const;
|
||||
void update_moves_slider(bool set_to_max = false);
|
||||
void update_layers_slider_mode();
|
||||
void update_marker_curr_move();
|
||||
|
||||
const libvgcode::Interval& get_gcode_view_full_range() const { return m_viewer.get_view_full_range(); }
|
||||
const libvgcode::Interval& get_gcode_view_enabled_range() const { return m_viewer.get_view_enabled_range(); }
|
||||
const libvgcode::Interval& get_gcode_view_visible_range() const { return m_viewer.get_view_visible_range(); }
|
||||
const libvgcode::PathVertex& get_gcode_vertex_at(size_t id) const { return m_viewer.get_vertex_at(id); }
|
||||
|
||||
bool is_contained_in_bed() const { return m_contained_in_bed; }
|
||||
//BBS: add only gcode mode
|
||||
bool is_only_gcode_in_preview() const { return m_only_gcode_in_preview; }
|
||||
|
||||
EViewType get_view_type() const { return m_view_type; }
|
||||
void set_view_type(EViewType type, bool reset_feature_type_visible = true) {
|
||||
if (type == EViewType::Count)
|
||||
type = EViewType::FeatureType;
|
||||
m_view_type = (EViewType)type;
|
||||
if (reset_feature_type_visible && type == EViewType::ColorPrint) {
|
||||
reset_visible(EViewType::FeatureType);
|
||||
}
|
||||
void set_view_type(libvgcode::EViewType type) {
|
||||
m_viewer.set_view_type(type);
|
||||
}
|
||||
void reset_visible(EViewType type) {
|
||||
if (type == EViewType::FeatureType) {
|
||||
for (size_t i = 0; i < m_roles.size(); ++i) {
|
||||
ExtrusionRole role = m_roles[i];
|
||||
m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags | (1 << role);
|
||||
void reset_visible(libvgcode::EViewType type) {
|
||||
if (type == libvgcode::EViewType::FeatureType) {
|
||||
auto roles = m_viewer.get_extrusion_roles();
|
||||
for (size_t i = 0; i < roles.size(); ++i) {
|
||||
auto role = roles[i];
|
||||
if (!m_viewer.is_extrusion_role_visible(role)) {
|
||||
m_viewer.toggle_extrusion_role_visibility(role);
|
||||
}
|
||||
}
|
||||
} else if (type == EViewType::ColorPrint){
|
||||
for(auto item: m_tools.m_tool_visibles) item = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_toolpath_move_type_visible(EMoveType type) const;
|
||||
void set_toolpath_move_type_visible(EMoveType type, bool visible);
|
||||
unsigned int get_toolpath_role_visibility_flags() const { return m_extrusions.role_visibility_flags; }
|
||||
void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; }
|
||||
unsigned int get_options_visibility_flags() const;
|
||||
void set_options_visibility_from_flags(unsigned int flags);
|
||||
libvgcode::EViewType get_view_type() const { return m_viewer.get_view_type(); }
|
||||
|
||||
void set_layers_z_range(const std::array<unsigned int, 2>& layers_z_range);
|
||||
|
||||
bool is_legend_enabled() const { return m_legend_enabled; }
|
||||
bool is_legend_shown() const { return m_legend_visible && m_legend_enabled; }
|
||||
void show_legend(bool show) { m_legend_visible = show; }
|
||||
void enable_legend(bool enable) { m_legend_enabled = enable; }
|
||||
float get_legend_height() { return m_legend_height; }
|
||||
|
||||
void export_toolpaths_to_obj(const char* filename) const;
|
||||
|
||||
std::vector<CustomGCode::Item>& get_custom_gcode_per_print_z() { return m_custom_gcode_per_print_z; }
|
||||
size_t get_extruders_count() { return m_extruders_count; }
|
||||
void push_combo_style();
|
||||
void pop_combo_style();
|
||||
|
||||
void invalidate_legend() { /*TODO: m_legend_resizer.reset();*/ }
|
||||
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
float get_cog_marker_scale_factor() const { return m_viewer.get_cog_marker_scale_factor(); }
|
||||
void set_cog_marker_scale_factor(float factor) { return m_viewer.set_cog_marker_scale_factor(factor); }
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
|
||||
private:
|
||||
void load_toolpaths(const GCodeProcessorResult& gcode_result, const BuildVolume& build_volume, const std::vector<BoundingBoxf3>& exclude_bounding_box);
|
||||
//BBS: always load shell at preview
|
||||
//void load_shells(const Print& print);
|
||||
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
|
||||
void render_toolpaths();
|
||||
void render_shells(int canvas_width, int canvas_height);
|
||||
|
||||
|
|
@ -917,16 +357,6 @@ private:
|
|||
void render_legend(float &legend_height, int canvas_width, int canvas_height, int right_margin);
|
||||
void render_legend_color_arr_recommen(float window_padding);
|
||||
void render_slider(int canvas_width, int canvas_height);
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
void render_statistics();
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
bool is_visible(ExtrusionRole role) const {
|
||||
return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0;
|
||||
}
|
||||
bool is_visible(const Path& path) const { return is_visible(path.role); }
|
||||
void log_memory_used(const std::string& label, int64_t additional = 0) const;
|
||||
ColorRGBA option_color(EMoveType move_type) const;
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -286,8 +286,8 @@ class GLCanvas3D
|
|||
|
||||
bool is_allowed() const;
|
||||
|
||||
bool is_enabled() const;
|
||||
void set_enabled(bool enabled);
|
||||
bool is_enabled() const { return m_enabled; }
|
||||
void set_enabled(bool enabled) { m_enabled = is_allowed() && enabled; }
|
||||
|
||||
void show_tooltip_information(const GLCanvas3D& canvas, std::map<wxString, wxString> captions_texts, float x, float y);
|
||||
void render_variable_layer_height_dialog(const GLCanvas3D& canvas);
|
||||
|
|
@ -327,25 +327,20 @@ class GLCanvas3D
|
|||
static const Vec3d Invalid_3D_Point;
|
||||
static const int MoveThresholdPx;
|
||||
|
||||
Point start_position_2D;
|
||||
Vec3d start_position_3D;
|
||||
int move_volume_idx;
|
||||
bool move_requires_threshold;
|
||||
Point move_start_threshold_position_2D;
|
||||
|
||||
public:
|
||||
Drag();
|
||||
Point start_position_2D{ Invalid_2D_Point };
|
||||
Vec3d start_position_3D{ Invalid_3D_Point };
|
||||
int move_volume_idx{ -1 };
|
||||
bool move_requires_threshold{ false };
|
||||
Point move_start_threshold_position_2D{ Invalid_2D_Point };
|
||||
};
|
||||
|
||||
bool dragging;
|
||||
Vec2d position;
|
||||
Vec3d scene_position;
|
||||
bool dragging{ false };
|
||||
Vec2d position{ DBL_MAX, DBL_MAX };
|
||||
Vec3d scene_position{ DBL_MAX, DBL_MAX, DBL_MAX };
|
||||
bool ignore_left_up{ false };
|
||||
Drag drag;
|
||||
bool ignore_left_up;
|
||||
bool ignore_right_up;
|
||||
|
||||
Mouse();
|
||||
|
||||
void set_start_position_2D_as_invalid() { drag.start_position_2D = Drag::Invalid_2D_Point; }
|
||||
void set_start_position_3D_as_invalid() { drag.start_position_3D = Drag::Invalid_3D_Point; }
|
||||
void set_move_start_threshold_position_2D_as_invalid() { drag.move_start_threshold_position_2D = Drag::Invalid_2D_Point; }
|
||||
|
|
@ -638,6 +633,9 @@ private:
|
|||
int custom_height_count = 0;
|
||||
int assembly_view_count = 0;
|
||||
|
||||
// used to show layers times on the layers slider when pre-gcode view is active
|
||||
std::vector<float> m_gcode_layers_times_cache;
|
||||
|
||||
public:
|
||||
OrientSettings& get_orient_settings()
|
||||
{
|
||||
|
|
@ -685,7 +683,7 @@ public:
|
|||
|
||||
struct ToolbarHighlighter
|
||||
{
|
||||
void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY);
|
||||
void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY) { m_timer.SetOwner(owner, timerid); }
|
||||
void init(GLToolbarItem* toolbar_item, GLCanvas3D* canvas);
|
||||
void blink();
|
||||
void invalidate();
|
||||
|
|
@ -700,7 +698,7 @@ public:
|
|||
|
||||
struct GizmoHighlighter
|
||||
{
|
||||
void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY);
|
||||
void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY) { m_timer.SetOwner(owner, timerid); }
|
||||
void init(GLGizmosManager* manager, GLGizmosManager::EType gizmo, GLCanvas3D* canvas);
|
||||
void blink();
|
||||
void invalidate();
|
||||
|
|
@ -764,22 +762,33 @@ public:
|
|||
void reset_explosion_ratio() { m_explosion_ratio = 1.0; }
|
||||
void on_change_color_mode(bool is_dark, bool reinit = true);
|
||||
const bool get_dark_mode_status() { return m_is_dark; }
|
||||
void set_as_dirty();
|
||||
void set_as_dirty() { m_dirty = true; }
|
||||
void requires_check_outside_state() { m_requires_check_outside_state = true; }
|
||||
|
||||
unsigned int get_volumes_count() const;
|
||||
unsigned int get_volumes_count() const { return (unsigned int)m_volumes.volumes.size(); }
|
||||
const GLVolumeCollection& get_volumes() const { return m_volumes; }
|
||||
void reset_volumes();
|
||||
ModelInstanceEPrintVolumeState check_volumes_outside_state(ObjectFilamentResults* object_results = nullptr) const;
|
||||
void check_volumes_outside_state(GLVolumeCollection& volumes) const { check_volumes_outside_state(volumes, nullptr, false); }
|
||||
bool is_all_plates_selected() { return m_sel_plate_toolbar.m_all_plates_stats_item && m_sel_plate_toolbar.m_all_plates_stats_item->selected; }
|
||||
const float get_scale() const;
|
||||
|
||||
private:
|
||||
// returns true if all the volumes are completely contained in the print volume
|
||||
// returns the containment state in the given out_state, if non-null
|
||||
bool check_volumes_outside_state(GLVolumeCollection& volumes, ModelInstanceEPrintVolumeState* out_state, bool selection_only = true) const;
|
||||
|
||||
public:
|
||||
//BBS
|
||||
GCodeViewer& get_gcode_viewer() { return m_gcode_viewer; }
|
||||
void init_gcode_viewer(ConfigOptionMode mode, Slic3r::PresetBundle* preset_bundle) { m_gcode_viewer.init(mode, preset_bundle); }
|
||||
void reset_gcode_toolpaths() { m_gcode_viewer.reset(); }
|
||||
const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); }
|
||||
void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { m_gcode_viewer.update_sequential_view_current(first, last); }
|
||||
const libvgcode::Interval& get_gcode_view_full_range() const { return m_gcode_viewer.get_gcode_view_full_range(); }
|
||||
const libvgcode::Interval& get_gcode_view_enabled_range() const { return m_gcode_viewer.get_gcode_view_enabled_range(); }
|
||||
const libvgcode::Interval& get_gcode_view_visible_range() const { return m_gcode_viewer.get_gcode_view_visible_range(); }
|
||||
const libvgcode::PathVertex& get_gcode_vertex_at(size_t id) const { return m_gcode_viewer.get_gcode_vertex_at(id); }
|
||||
|
||||
void toggle_selected_volume_visibility(bool selected_visible);
|
||||
void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1);
|
||||
|
|
@ -788,7 +797,7 @@ public:
|
|||
void update_instance_printable_state_for_objects(const std::vector<size_t>& object_idxs);
|
||||
|
||||
void set_config(const DynamicPrintConfig* config);
|
||||
void set_process(BackgroundSlicingProcess* process);
|
||||
void set_process(BackgroundSlicingProcess* process) { m_process = process; }
|
||||
void set_model(Model* model);
|
||||
const Model* get_model() const { return m_model; }
|
||||
|
||||
|
|
@ -832,22 +841,28 @@ public:
|
|||
BoundingBoxf3 scene_bounding_box() const;
|
||||
BoundingBoxf3 plate_scene_bounding_box(int plate_idx) const;
|
||||
|
||||
bool is_layers_editing_enabled() const;
|
||||
bool is_layers_editing_allowed() const;
|
||||
bool is_layers_editing_enabled() const { return m_layers_editing.is_enabled(); }
|
||||
bool is_layers_editing_allowed() const { return m_layers_editing.is_allowed(); }
|
||||
|
||||
void reset_layer_height_profile();
|
||||
void adaptive_layer_height_profile(float quality_factor);
|
||||
void smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params);
|
||||
|
||||
bool is_reload_delayed() const;
|
||||
bool is_reload_delayed() const { return m_reload_delayed; }
|
||||
|
||||
void enable_layers_editing(bool enable);
|
||||
void enable_legend_texture(bool enable);
|
||||
void enable_picking(bool enable);
|
||||
void enable_moving(bool enable);
|
||||
void enable_gizmos(bool enable);
|
||||
void enable_selection(bool enable);
|
||||
void enable_main_toolbar(bool enable);
|
||||
void enable_picking(bool enable)
|
||||
{
|
||||
m_picking_enabled = enable;
|
||||
// Orca: invalidate hover state when dragging is toggled, otherwise if we turned off dragging
|
||||
// while hovering above a volume, the hovering state won't update even if mouse has moved away.
|
||||
// Fixes https://github.com/OrcaSlicer/OrcaSlicer/pull/9979#issuecomment-3065575889
|
||||
m_hover_volume_idxs.clear();
|
||||
}
|
||||
void enable_moving(bool enable) { m_moving_enabled = enable; }
|
||||
void enable_gizmos(bool enable) { m_gizmos.set_enabled(enable); }
|
||||
void enable_selection(bool enable) { m_selection.set_enabled(enable); }
|
||||
void enable_main_toolbar(bool enable) { m_main_toolbar.set_enabled(enable); }
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
void _update_select_plate_toolbar_stats_item(bool force_selected = false);
|
||||
void reset_select_plate_toolbar_selection();
|
||||
|
|
@ -855,10 +870,10 @@ public:
|
|||
void enable_assemble_view_toolbar(bool enable);
|
||||
void enable_return_toolbar(bool enable);
|
||||
void enable_separator_toolbar(bool enable);
|
||||
void enable_dynamic_background(bool enable);
|
||||
void enable_dynamic_background(bool enable) { m_dynamic_background_enabled = enable; }
|
||||
void enable_labels(bool enable) { m_labels.enable(enable); }
|
||||
void enable_slope(bool enable) { m_slope.enable(enable); }
|
||||
void allow_multisample(bool allow);
|
||||
void allow_multisample(bool allow) { m_multisample_allowed = allow; }
|
||||
|
||||
void zoom_to_bed();
|
||||
void zoom_to_volumes();
|
||||
|
|
@ -963,9 +978,6 @@ public:
|
|||
bool for_picking = false,
|
||||
bool ban_light = false);
|
||||
|
||||
//BBS use gcoder viewer render calibration thumbnails
|
||||
void render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params);
|
||||
|
||||
//BBS
|
||||
void select_curr_plate_all();
|
||||
void select_object_from_idx(std::vector<int>& object_idxs);
|
||||
|
|
@ -976,18 +988,14 @@ public:
|
|||
void deselect_all();
|
||||
void exit_gizmo();
|
||||
void set_selected_visible(bool visible);
|
||||
void delete_selected();
|
||||
void delete_selected() { m_selection.erase(); }
|
||||
void ensure_on_bed(unsigned int object_idx, bool allow_negative_z);
|
||||
|
||||
bool is_gcode_legend_enabled() const { return m_gcode_viewer.is_legend_enabled(); }
|
||||
GCodeViewer::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); }
|
||||
const std::vector<double>& get_gcode_layers_zs() const;
|
||||
std::vector<double> get_volumes_print_zs(bool active_only) const;
|
||||
unsigned int get_gcode_options_visibility_flags() const { return m_gcode_viewer.get_options_visibility_flags(); }
|
||||
void set_gcode_options_visibility_from_flags(unsigned int flags);
|
||||
unsigned int get_toolpath_role_visibility_flags() const { return m_gcode_viewer.get_toolpath_role_visibility_flags(); }
|
||||
void set_volumes_z_range(const std::array<double, 2>& range);
|
||||
std::vector<CustomGCode::Item>& get_custom_gcode_per_print_z() { return m_gcode_viewer.get_custom_gcode_per_print_z(); }
|
||||
std::vector<double> get_gcode_layers_zs() const { return m_gcode_viewer.get_layers_zs(); }
|
||||
std::vector<float> get_gcode_layers_times() const { return m_gcode_viewer.get_layers_times(); }
|
||||
const std::vector<float>& get_gcode_layers_times_cache() const { return m_gcode_layers_times_cache; }
|
||||
void reset_gcode_layers_times_cache() { m_gcode_layers_times_cache.clear(); }
|
||||
void set_volumes_z_range(const std::array<double, 2>& range) { m_volumes.set_range(range[0] - 1e-6, range[1] + 1e-6); }
|
||||
size_t get_gcode_extruders_count() { return m_gcode_viewer.get_extruders_count(); }
|
||||
|
||||
std::vector<int> load_object(const ModelObject& model_object, int obj_idx, std::vector<int> instance_idxs);
|
||||
|
|
@ -1003,16 +1011,16 @@ public:
|
|||
void set_shells_on_previewing(bool is_preview) { m_gcode_viewer.set_shells_on_preview(is_preview); }
|
||||
|
||||
//BBS: add only gcode mode
|
||||
void load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors, bool only_gcode);
|
||||
void refresh_gcode_preview_render_paths();
|
||||
void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); }
|
||||
GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); }
|
||||
void load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors,
|
||||
const std::vector<std::string>& str_color_print_colors, bool only_gcode);
|
||||
void set_gcode_view_type(libvgcode::EViewType type) { return m_gcode_viewer.set_view_type(type); }
|
||||
libvgcode::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); }
|
||||
|
||||
void load_sla_preview();
|
||||
//void load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values);
|
||||
void bind_event_handlers();
|
||||
void unbind_event_handlers();
|
||||
|
||||
void on_size(wxSizeEvent& evt);
|
||||
void on_size(wxSizeEvent& evt) { m_dirty = true; }
|
||||
void on_idle(wxIdleEvent& evt);
|
||||
void on_char(wxKeyEvent& evt);
|
||||
void on_key(wxKeyEvent& evt);
|
||||
|
|
@ -1079,7 +1087,8 @@ public:
|
|||
inline double rotation() const { return m_rotation; }
|
||||
inline const Vec2d bb_size() const { return m_bb.size(); }
|
||||
|
||||
void apply_wipe_tower() const;
|
||||
void apply_wipe_tower() const { apply_wipe_tower(m_pos, m_rotation); }
|
||||
void apply_wipe_tower(Vec2d pos, double rot) const;
|
||||
};
|
||||
|
||||
// BBS: add partplate logic
|
||||
|
|
@ -1101,7 +1110,7 @@ public:
|
|||
Vec2f get_nearest_empty_cell(const Vec2f start_point, const Vec2f step = {10, 10});
|
||||
|
||||
void set_cursor(ECursorType type);
|
||||
void msw_rescale();
|
||||
void msw_rescale() { m_gcode_viewer.invalidate_legend(); }
|
||||
|
||||
void request_extra_frame() { m_extra_frame_requested = true; }
|
||||
|
||||
|
|
@ -1111,8 +1120,8 @@ public:
|
|||
void force_main_toolbar_left_action(int item_id) { m_main_toolbar.force_left_action(item_id, *this); }
|
||||
void force_main_toolbar_right_action(int item_id) { m_main_toolbar.force_right_action(item_id, *this); }
|
||||
|
||||
bool has_toolpaths_to_export() const;
|
||||
void export_toolpaths_to_obj(const char* filename) const;
|
||||
bool has_toolpaths_to_export() const { return m_gcode_viewer.can_export_toolpaths(); }
|
||||
void export_toolpaths_to_obj(const char* filename) const { m_gcode_viewer.export_toolpaths_to_obj(filename); }
|
||||
|
||||
void mouse_up_cleanup();
|
||||
|
||||
|
|
@ -1234,7 +1243,7 @@ private:
|
|||
void _render_selection();
|
||||
void _render_sequential_clearance();
|
||||
#if ENABLE_RENDER_SELECTION_CENTER
|
||||
void _render_selection_center();
|
||||
void _render_selection_center() { m_selection.render_center(m_gizmos.is_dragging()); }
|
||||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||
void _check_and_update_toolbar_icon_scale();
|
||||
void _render_overlays();
|
||||
|
|
@ -1260,7 +1269,7 @@ private:
|
|||
void _render_camera_target();
|
||||
#endif // ENABLE_SHOW_CAMERA_TARGET
|
||||
void _render_sla_slices();
|
||||
void _render_selection_sidebar_hints();
|
||||
void _render_selection_sidebar_hints() { m_selection.render_sidebar_hints(m_sidebar_field, m_gizmos.get_uniform_scaling()); }
|
||||
//BBS: GUI refactor: adjust main toolbar position
|
||||
bool _render_orient_menu(float left, float right, float bottom, float top);
|
||||
bool _render_arrange_menu(float left, float right, float bottom, float top);
|
||||
|
|
@ -1271,23 +1280,12 @@ private:
|
|||
// Convert the screen space coordinate to world coordinate on the bed.
|
||||
Vec3d _mouse_to_bed_3d(const Point& mouse_pos);
|
||||
|
||||
void _start_timer();
|
||||
void _stop_timer();
|
||||
|
||||
// Create 3D thick extrusion lines for a skirt and brim.
|
||||
// Adds a new Slic3r::GUI::3DScene::Volume to volumes, updates collision with the build_volume.
|
||||
void _load_print_toolpaths(const BuildVolume &build_volume);
|
||||
// Create 3D thick extrusion lines for object forming extrusions.
|
||||
// Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
|
||||
// one for perimeters, one for infill and one for supports, updates collision with the build_volume.
|
||||
void _load_print_object_toolpaths(const PrintObject& print_object, const BuildVolume &build_volume,
|
||||
const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values);
|
||||
// Create 3D thick extrusion lines for wipe tower extrusions, updates collision with the build_volume.
|
||||
void _load_wipe_tower_toolpaths(const BuildVolume &build_volume, const std::vector<std::string>& str_tool_colors);
|
||||
void _start_timer() { m_timer.Start(100, wxTIMER_CONTINUOUS); }
|
||||
void _stop_timer() { m_timer.Stop(); }
|
||||
|
||||
// Load SLA objects and support structures for objects, for which the slaposSliceSupports step has been finished.
|
||||
void _load_sla_shells();
|
||||
void _update_sla_shells_outside_state();
|
||||
void _load_sla_shells();
|
||||
void _update_sla_shells_outside_state() { check_volumes_outside_state(); }
|
||||
void _set_warning_notification_if_needed(EWarning warning);
|
||||
|
||||
//BBS: add partplate print volume get function
|
||||
|
|
|
|||
|
|
@ -551,6 +551,16 @@ void GLModel::reset()
|
|||
glsafe(::glDeleteBuffers(1, &m_render_data.vbo_id));
|
||||
m_render_data.vbo_id = 0;
|
||||
}
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
if (m_render_data.vao_id > 0) {
|
||||
glsafe(::glDeleteVertexArrays(1, &m_render_data.vao_id));
|
||||
m_render_data.vao_id = 0;
|
||||
}
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
m_render_data.vertices_count = 0;
|
||||
m_render_data.indices_count = 0;
|
||||
|
|
@ -619,6 +629,14 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
|
|||
const bool normal = Geometry::has_normal(data.format);
|
||||
const bool tex_coord = Geometry::has_tex_coord(data.format);
|
||||
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
glsafe(::glBindVertexArray(m_render_data.vao_id));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
// the following binding is needed to set the vertex attributes
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id));
|
||||
|
||||
int position_id = -1;
|
||||
|
|
@ -661,6 +679,13 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
|
|||
glsafe(::glDisableVertexAttribArray(position_id));
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
glsafe(::glBindVertexArray(0));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
}
|
||||
|
||||
void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count)
|
||||
|
|
@ -689,6 +714,14 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
|
|||
return;
|
||||
}
|
||||
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
glsafe(::glBindVertexArray(m_render_data.vao_id));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, instances_vbo));
|
||||
const size_t instance_stride = 5 * sizeof(float);
|
||||
glsafe(::glVertexAttribPointer(offset_id, 3, GL_FLOAT, GL_FALSE, instance_stride, (const void*)0));
|
||||
|
|
@ -735,6 +768,13 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
|
|||
glsafe(::glDisableVertexAttribArray(offset_id));
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
glsafe(::glBindVertexArray(0));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
}
|
||||
|
||||
bool GLModel::send_to_gpu()
|
||||
|
|
@ -750,6 +790,15 @@ bool GLModel::send_to_gpu()
|
|||
return false;
|
||||
}
|
||||
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
glsafe(::glGenVertexArrays(1, &m_render_data.vao_id));
|
||||
glsafe(::glBindVertexArray(m_render_data.vao_id));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
// vertices
|
||||
glsafe(::glGenBuffers(1, &m_render_data.vbo_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id));
|
||||
|
|
@ -790,6 +839,14 @@ bool GLModel::send_to_gpu()
|
|||
m_render_data.indices_count = indices_count;
|
||||
data.indices = std::vector<unsigned int>();
|
||||
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
glsafe(::glBindVertexArray(0));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ namespace GUI {
|
|||
struct RenderData
|
||||
{
|
||||
Geometry geometry;
|
||||
unsigned int vao_id{ 0 };
|
||||
unsigned int vbo_id{ 0 };
|
||||
unsigned int ibo_id{ 0 };
|
||||
size_t vertices_count{ 0 };
|
||||
|
|
|
|||
|
|
@ -72,15 +72,26 @@ namespace GUI {
|
|||
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));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (!OpenGLManager::get_gl_info().is_core_profile())
|
||||
glsafe(::glLineWidth(1.5f));
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
glsafe(::glPushAttrib(GL_ENABLE_BIT));
|
||||
glsafe(::glLineStipple(4, 0xAAAA));
|
||||
glsafe(::glEnable(GL_LINE_STIPPLE));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (!OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
glsafe(::glPushAttrib(GL_ENABLE_BIT));
|
||||
glsafe(::glLineStipple(4, 0xAAAA));
|
||||
glsafe(::glEnable(GL_LINE_STIPPLE));
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
#if SLIC3R_OPENGL_ES
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("dashed_lines");
|
||||
#else
|
||||
GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
|
||||
#endif // SLIC3R_OPENGL_ES
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
|
|
@ -90,34 +101,86 @@ namespace GUI {
|
|||
m_rectangle.reset();
|
||||
|
||||
GLModel::Geometry init_data;
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 };
|
||||
init_data.reserve_vertices(4);
|
||||
init_data.reserve_indices(4);
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P4 };
|
||||
init_data.reserve_vertices(5);
|
||||
init_data.reserve_indices(8);
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
else {
|
||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 };
|
||||
init_data.reserve_vertices(4);
|
||||
init_data.reserve_indices(4);
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
// vertices
|
||||
init_data.add_vertex(Vec2f(left, bottom));
|
||||
init_data.add_vertex(Vec2f(right, bottom));
|
||||
init_data.add_vertex(Vec2f(right, top));
|
||||
init_data.add_vertex(Vec2f(left, top));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
const float width = right - left;
|
||||
const float height = top - bottom;
|
||||
float perimeter = 0.0f;
|
||||
|
||||
// indices
|
||||
init_data.add_index(0);
|
||||
init_data.add_index(1);
|
||||
init_data.add_index(2);
|
||||
init_data.add_index(3);
|
||||
init_data.add_vertex(Vec4f(left, bottom, 0.0f, perimeter));
|
||||
perimeter += width;
|
||||
init_data.add_vertex(Vec4f(right, bottom, 0.0f, perimeter));
|
||||
perimeter += height;
|
||||
init_data.add_vertex(Vec4f(right, top, 0.0f, perimeter));
|
||||
perimeter += width;
|
||||
init_data.add_vertex(Vec4f(left, top, 0.0f, perimeter));
|
||||
perimeter += height;
|
||||
init_data.add_vertex(Vec4f(left, bottom, 0.0f, perimeter));
|
||||
|
||||
// indices
|
||||
init_data.add_line(0, 1);
|
||||
init_data.add_line(1, 2);
|
||||
init_data.add_line(2, 3);
|
||||
init_data.add_line(3, 4);
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
else {
|
||||
init_data.add_vertex(Vec2f(left, bottom));
|
||||
init_data.add_vertex(Vec2f(right, bottom));
|
||||
init_data.add_vertex(Vec2f(right, top));
|
||||
init_data.add_vertex(Vec2f(left, top));
|
||||
|
||||
// indices
|
||||
init_data.add_index(0);
|
||||
init_data.add_index(1);
|
||||
init_data.add_index(2);
|
||||
init_data.add_index(3);
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
m_rectangle.init_from(std::move(init_data));
|
||||
}
|
||||
|
||||
shader->set_uniform("view_model_matrix", Transform3d::Identity());
|
||||
shader->set_uniform("projection_matrix", Transform3d::Identity());
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
const std::array<int, 4>& viewport = wxGetApp().plater()->get_camera().get_viewport();
|
||||
shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3])));
|
||||
shader->set_uniform("width", 0.25f);
|
||||
shader->set_uniform("dash_size", 0.01f);
|
||||
shader->set_uniform("gap_size", 0.0075f);
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
m_rectangle.set_color(ColorRGBA::ORCA()); // ORCA: use orca color for selection rectangle
|
||||
m_rectangle.render();
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
glsafe(::glPopAttrib());
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (!OpenGLManager::get_gl_info().is_core_profile())
|
||||
glsafe(::glPopAttrib());
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
|
|
|
|||
|
|
@ -33,7 +33,13 @@ std::pair<bool, std::string> GLShadersManager::init()
|
|||
|
||||
bool valid = true;
|
||||
|
||||
#if SLIC3R_OPENGL_ES
|
||||
const std::string prefix = "ES/";
|
||||
// used to render wireframed triangles
|
||||
valid &= append_shader("wireframe", { prefix + "wireframe.vs", prefix + "wireframe.fs" });
|
||||
#else
|
||||
const std::string prefix = GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 1) ? "140/" : "110/";
|
||||
#endif // SLIC3R_OPENGL_ES
|
||||
// imgui shader
|
||||
valid &= append_shader("imgui", { prefix + "imgui.vs", prefix + "imgui.fs" });
|
||||
// basic shader, used to render all what was previously rendered using the immediate mode
|
||||
|
|
@ -44,13 +50,21 @@ std::pair<bool, std::string> GLShadersManager::init()
|
|||
valid &= append_shader("flat_texture", { prefix + "flat_texture.vs", prefix + "flat_texture.fs" });
|
||||
// used to render 3D scene background
|
||||
valid &= append_shader("background", { prefix + "background.vs", prefix + "background.fs" });
|
||||
#if SLIC3R_OPENGL_ES
|
||||
// used to render dashed lines
|
||||
valid &= append_shader("dashed_lines", { prefix + "dashed_lines.vs", prefix + "dashed_lines.fs" });
|
||||
#else
|
||||
if (GUI::OpenGLManager::get_gl_info().is_core_profile())
|
||||
// used to render thick and/or dashed lines
|
||||
valid &= append_shader("dashed_thick_lines", { prefix + "dashed_thick_lines.vs", prefix + "dashed_thick_lines.fs", prefix + "dashed_thick_lines.gs" });
|
||||
#endif // SLIC3R_OPENGL_ES
|
||||
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview
|
||||
valid &= append_shader("gouraud_light", { prefix + "gouraud_light.vs", prefix + "gouraud_light.fs" });
|
||||
//used to render thumbnail
|
||||
valid &= append_shader("thumbnail", { prefix + "thumbnail.vs", prefix + "thumbnail.fs"});
|
||||
// used to render printbed
|
||||
valid &= append_shader("printbed", { prefix + "printbed.vs", prefix + "printbed.fs" });
|
||||
valid &= append_shader("hotbed", {"110/hotbed.vs", "110/hotbed.fs"});
|
||||
valid &= append_shader("hotbed", {prefix + "hotbed.vs", prefix + "hotbed.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", { prefix + "gouraud_light_instanced.vs", prefix + "gouraud_light_instanced.fs" });
|
||||
|
|
|
|||
|
|
@ -2278,7 +2278,8 @@ std::string GUI_App::get_gl_info(bool for_github)
|
|||
|
||||
wxGLContext* GUI_App::init_glcontext(wxGLCanvas& canvas)
|
||||
{
|
||||
return m_opengl_mgr.init_glcontext(canvas);
|
||||
return m_opengl_mgr.init_glcontext(canvas, init_params != nullptr ? init_params->opengl_version : std::make_pair(0, 0),
|
||||
init_params != nullptr ? init_params->opengl_compatibility_profile : false, init_params != nullptr ? init_params->opengl_debug : false);
|
||||
}
|
||||
|
||||
bool GUI_App::init_opengl()
|
||||
|
|
@ -6567,7 +6568,7 @@ void GUI_App::open_preferences(size_t open_on_tab, const std::string& highlight_
|
|||
#else
|
||||
if (dlg.seq_top_layer_only_changed())
|
||||
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||
this->plater_->refresh_print();
|
||||
this->plater_->reload_print();
|
||||
#ifdef _WIN32
|
||||
if (is_editor()) {
|
||||
if (app_config->get("associate_3mf") == "true")
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
const std::vector<std::pair<int, int>> OpenGLVersions::core = { {3,2}, {3,3}, {4,0}, {4,1}, {4,2}, {4,3}, {4,4}, {4,5}, {4,6} };
|
||||
|
||||
int GUI_Run(GUI_InitParams ¶ms)
|
||||
{
|
||||
#if __APPLE__
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ namespace Slic3r {
|
|||
|
||||
namespace GUI {
|
||||
|
||||
struct OpenGLVersions
|
||||
{
|
||||
static const std::vector<std::pair<int, int>> core;
|
||||
};
|
||||
|
||||
struct GUI_InitParams
|
||||
{
|
||||
int argc;
|
||||
|
|
@ -20,6 +25,10 @@ struct GUI_InitParams
|
|||
DynamicPrintConfig extra_config;
|
||||
std::vector<std::string> input_files;
|
||||
|
||||
std::pair<int, int> opengl_version { 0, 0 };
|
||||
bool opengl_debug { false };
|
||||
bool opengl_compatibility_profile { false };
|
||||
|
||||
//BBS: remove start_as_gcodeviewer logic
|
||||
//bool start_as_gcodeviewer;
|
||||
bool input_gcode { false };
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@
|
|||
#include "GUI_Preview.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI.hpp"
|
||||
#if ENABLE_OPENGL_AUTO_AA_SAMPLES
|
||||
#include "GUI_Init.hpp"
|
||||
#endif // ENABLE_OPENGL_AUTO_AA_SAMPLES
|
||||
#include "I18N.hpp"
|
||||
#include "3DScene.hpp"
|
||||
#include "BackgroundSlicingProcess.hpp"
|
||||
|
|
@ -55,6 +58,10 @@ bool View3D::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig
|
|||
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
|
||||
return false;
|
||||
|
||||
#if ENABLE_OPENGL_AUTO_AA_SAMPLES
|
||||
const GUI_InitParams* const init_params = wxGetApp().init_params;
|
||||
m_canvas_widget = OpenGLManager::create_wxglcanvas(*this, (init_params != nullptr) ? init_params->opengl_aa : false);
|
||||
#else
|
||||
m_canvas_widget = OpenGLManager::create_wxglcanvas(*this);
|
||||
if (m_canvas_widget == nullptr)
|
||||
return false;
|
||||
|
|
@ -254,6 +261,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model)
|
|||
#endif // _WIN32
|
||||
|
||||
m_canvas_widget = OpenGLManager::create_wxglcanvas(*this);
|
||||
#endif // ENABLE_OPENGL_AUTO_AA_SAMPLES
|
||||
if (m_canvas_widget == nullptr)
|
||||
return false;
|
||||
|
||||
|
|
@ -264,8 +272,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model)
|
|||
m_canvas->set_model(model);
|
||||
m_canvas->set_process(m_process);
|
||||
m_canvas->set_type(GLCanvas3D::ECanvasType::CanvasPreview);
|
||||
m_canvas->enable_legend_texture(true);
|
||||
|
||||
m_canvas->get_gcode_viewer().enable_legend(true);
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
if (wxGetApp().is_editor()) {
|
||||
m_canvas->enable_select_plate_toolbar(true);
|
||||
|
|
@ -332,50 +339,16 @@ void Preview::load_print(bool keep_z_range, bool only_gcode)
|
|||
}
|
||||
|
||||
//BBS: add only gcode mode
|
||||
void Preview::reload_print(bool keep_volumes, bool only_gcode)
|
||||
void Preview::reload_print(bool only_gcode)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" %1%: enter, keep_volumes %2%")%__LINE__ %keep_volumes;
|
||||
#ifdef __linux__
|
||||
// We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955.
|
||||
// So we are applying a workaround here: a delayed release of OpenGL vertex buffers.
|
||||
if (!IsShown())
|
||||
{
|
||||
m_volumes_cleanup_required = !keep_volumes;
|
||||
return;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
if (
|
||||
#ifdef __linux__
|
||||
m_volumes_cleanup_required ||
|
||||
#endif /* __linux__ */
|
||||
!keep_volumes)
|
||||
{
|
||||
m_canvas->reset_volumes();
|
||||
//BBS: add m_loaded_print logic
|
||||
//m_loaded = false;
|
||||
m_loaded_print = nullptr;
|
||||
#ifdef __linux__
|
||||
m_volumes_cleanup_required = false;
|
||||
#endif /* __linux__ */
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" %1%: enter")%__LINE__;
|
||||
|
||||
load_print(false, only_gcode);
|
||||
m_only_gcode = only_gcode;
|
||||
}
|
||||
|
||||
//BBS: add only gcode mode
|
||||
void Preview::refresh_print()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" %1%: enter, current m_loaded_print %2%")%__LINE__ %m_loaded_print;
|
||||
//BBS: add m_loaded_print logic
|
||||
//m_loaded = false;
|
||||
m_loaded_print = nullptr;
|
||||
|
||||
if (!IsShown())
|
||||
return;
|
||||
|
||||
load_print(true, m_only_gcode);
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" %1%: exit")%__LINE__;
|
||||
load_print(false, only_gcode);
|
||||
m_only_gcode = only_gcode;
|
||||
}
|
||||
|
||||
//BBS: always load shell at preview
|
||||
|
|
@ -396,7 +369,7 @@ void Preview::msw_rescale()
|
|||
get_canvas3d()->msw_rescale();
|
||||
|
||||
// rescale legend
|
||||
refresh_print();
|
||||
reload_print(m_only_gcode);
|
||||
}
|
||||
|
||||
void Preview::sys_color_changed()
|
||||
|
|
@ -580,7 +553,7 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
|
|||
ticks_info_from_curr_plate = plater->model().get_curr_plate_custom_gcodes();
|
||||
else {
|
||||
ticks_info_from_curr_plate.mode = CustomGCode::Mode::SingleExtruder;
|
||||
ticks_info_from_curr_plate.gcodes = m_canvas->get_custom_gcode_per_print_z();
|
||||
ticks_info_from_curr_plate.gcodes = m_gcode_result->custom_gcode_per_print_z;
|
||||
}
|
||||
check_layers_slider_values(ticks_info_from_curr_plate.gcodes, layers_z);
|
||||
|
||||
|
|
@ -612,7 +585,7 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
|
|||
m_layers_slider->SetTicksValues(ticks_info_from_curr_plate);
|
||||
|
||||
auto print_mode_stat = m_gcode_result->print_statistics.modes.front();
|
||||
m_layers_slider->SetLayersTimes(print_mode_stat.layers_times, print_mode_stat.time);
|
||||
m_layers_slider->SetLayersTimes(m_canvas->get_gcode_layers_times_cache(), print_mode_stat.time);
|
||||
|
||||
// Suggest the auto color change, if model looks like sign
|
||||
if (m_layers_slider->IsNewPrint()) {
|
||||
|
|
@ -701,28 +674,17 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode)
|
|||
else if (directly_preview && !has_layers)
|
||||
keep_z_range = false;
|
||||
|
||||
GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type();
|
||||
bool gcode_preview_data_valid = !m_gcode_result->moves.empty();
|
||||
libvgcode::EViewType gcode_view_type = m_canvas->get_gcode_view_type();
|
||||
const bool gcode_preview_data_valid = !m_gcode_result->moves.empty();
|
||||
const bool is_pregcode_preview = !gcode_preview_data_valid && wxGetApp().is_editor();
|
||||
|
||||
// Collect colors per extruder.
|
||||
std::vector<std::string> colors;
|
||||
std::vector<CustomGCode::Item> color_print_values = {};
|
||||
// set color print values, if it si selected "ColorPrint" view type
|
||||
if (gcode_view_type == GCodeViewer::EViewType::ColorPrint) {
|
||||
colors = wxGetApp().plater()->get_colors_for_color_print(m_gcode_result);
|
||||
|
||||
if (!gcode_preview_data_valid) {
|
||||
if (wxGetApp().is_editor())
|
||||
//BBS
|
||||
color_print_values = wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes;
|
||||
else
|
||||
color_print_values = m_canvas->get_custom_gcode_per_print_z();
|
||||
colors.push_back("#808080"); // gray color for pause print or custom G-code
|
||||
}
|
||||
}
|
||||
else if (gcode_preview_data_valid || gcode_view_type == GCodeViewer::EViewType::Tool) {
|
||||
colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(m_gcode_result);
|
||||
color_print_values.clear();
|
||||
const std::vector<std::string> tool_colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(m_gcode_result);
|
||||
const std::vector<CustomGCode::Item>& color_print_values = wxGetApp().is_editor() ?
|
||||
wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_gcode_result->custom_gcode_per_print_z;
|
||||
std::vector<std::string> color_print_colors;
|
||||
if (!color_print_values.empty()) {
|
||||
color_print_colors = wxGetApp().plater()->get_colors_for_color_print(m_gcode_result);
|
||||
color_print_colors.push_back("#808080"); // gray color for pause print or custom G-code
|
||||
}
|
||||
|
||||
std::vector<double> zs;
|
||||
|
|
@ -735,7 +697,9 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode)
|
|||
//BBS: add more log
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": will load gcode_preview from result, moves count %1%") % m_gcode_result->moves.size();
|
||||
//BBS: add only gcode mode
|
||||
m_canvas->load_gcode_preview(*m_gcode_result, colors, only_gcode);
|
||||
m_canvas->load_gcode_preview(*m_gcode_result, tool_colors, color_print_colors, only_gcode);
|
||||
// the view type may have been changed by the call m_canvas->load_gcode_preview()
|
||||
gcode_view_type = m_canvas->get_gcode_view_type();
|
||||
//BBS show sliders
|
||||
show_moves_sliders();
|
||||
|
||||
|
|
@ -748,7 +712,7 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode)
|
|||
//m_loaded = true;
|
||||
m_loaded_print = print;
|
||||
}
|
||||
else if (wxGetApp().is_editor()) {
|
||||
else if (is_pregcode_preview) {
|
||||
// Load the initial preview based on slices, not the final G-code.
|
||||
//BBS: only display shell before slicing result out
|
||||
//m_canvas->load_preview(colors, color_print_values);
|
||||
|
|
@ -764,7 +728,7 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode)
|
|||
std::vector<CustomGCode::Item> gcodes = wxGetApp().is_editor() ?
|
||||
//BBS
|
||||
wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes :
|
||||
m_canvas->get_custom_gcode_per_print_z();
|
||||
m_gcode_result->custom_gcode_per_print_z;
|
||||
const wxString choice = !gcodes.empty() ?
|
||||
_L("Multicolor Print") :
|
||||
(number_extruders > 1) ? _L("Filaments") : _L("Line Type");
|
||||
|
|
@ -775,7 +739,8 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode)
|
|||
//BBS
|
||||
show_layers_sliders(false);
|
||||
m_canvas_widget->Refresh();
|
||||
} else
|
||||
}
|
||||
else
|
||||
update_layers_slider(zs, keep_z_range);
|
||||
}
|
||||
}
|
||||
|
|
@ -798,7 +763,12 @@ bool AssembleView::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrint
|
|||
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
|
||||
return false;
|
||||
|
||||
#if ENABLE_OPENGL_AUTO_AA_SAMPLES
|
||||
const GUI_InitParams* const init_params = wxGetApp().init_params;
|
||||
m_canvas_widget = OpenGLManager::create_wxglcanvas(*this, (init_params != nullptr) ? init_params->opengl_aa : false);
|
||||
#else
|
||||
m_canvas_widget = OpenGLManager::create_wxglcanvas(*this);
|
||||
#endif // ENABLE_OPENGL_AUTO_AA_SAMPLES
|
||||
if (m_canvas_widget == nullptr)
|
||||
return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -92,12 +92,6 @@ class Preview : public wxPanel
|
|||
BackgroundSlicingProcess* m_process;
|
||||
GCodeProcessorResult* m_gcode_result;
|
||||
|
||||
#ifdef __linux__
|
||||
// We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955.
|
||||
// So we are applying a workaround here.
|
||||
bool m_volumes_cleanup_required { false };
|
||||
#endif /* __linux__ */
|
||||
|
||||
// Calling this function object forces Plater::schedule_background_process.
|
||||
std::function<void()> m_schedule_background_process;
|
||||
|
||||
|
|
@ -146,8 +140,7 @@ public:
|
|||
|
||||
//BBS: add only gcode mode
|
||||
void load_print(bool keep_z_range = false, bool only_gcode = false);
|
||||
void reload_print(bool keep_volumes = false, bool only_gcode = false);
|
||||
void refresh_print();
|
||||
void reload_print(bool only_gcode = false);
|
||||
//BBS: always load shell at preview
|
||||
void load_shells(const Print& print, bool force_previewing = false);
|
||||
void reset_shells();
|
||||
|
|
|
|||
|
|
@ -989,11 +989,19 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers()
|
|||
}
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f));
|
||||
glLineStipple(1, 0x0FFF);
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
// ORCA: OpenGL Core Profile
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (!OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f));
|
||||
glLineStipple(1, 0x0FFF);
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
m_grabber_connection.render();
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (!OpenGLManager::get_gl_info().is_core_profile())
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
|
|
@ -1147,10 +1155,18 @@ void GLGizmoAdvancedCut::render_cut_line()
|
|||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
glLineStipple(1, 0x0FFF);
|
||||
// ORCA: OpenGL Core Profile
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (!OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
glLineStipple(1, 0x0FFF);
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
m_cut_line.render();
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (!OpenGLManager::get_gl_info().is_core_profile())
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,7 +231,11 @@ void GLGizmoBase::render_cross_mark(const Vec3f &target, bool is_single)
|
|||
{
|
||||
const float half_length = 4.0f;
|
||||
|
||||
glsafe(::glLineWidth(2.0f));
|
||||
// ORCA: OpenGL Core Profile
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (!OpenGLManager::get_gl_info().is_core_profile())
|
||||
glsafe(::glLineWidth(2.0f));
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
auto render_line = [](const Vec3f& p1, const Vec3f& p2, const ColorRGBA& color) {
|
||||
GLModel::Geometry init_data;
|
||||
|
|
|
|||
|
|
@ -1184,24 +1184,30 @@ void GLGizmoMeasure::render_dimensioning()
|
|||
|
||||
const Transform3d ss_to_ndc_matrix = TransformHelper::ndc_to_ss_matrix_inverse(viewport);
|
||||
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
shader->stop_using();
|
||||
|
||||
shader = wxGetApp().get_shader("dashed_thick_lines");
|
||||
#if SLIC3R_OPENGL_ES
|
||||
shader = wxGetApp().get_shader("dashed_lines");
|
||||
#else
|
||||
shader = wxGetApp().get_shader("dashed_thick_lines");
|
||||
#endif // SLIC3R_OPENGL_ES
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
shader->start_using();
|
||||
shader->set_uniform("projection_matrix", Transform3d::Identity());
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3])));
|
||||
shader->set_uniform("width", 1.0f);
|
||||
shader->set_uniform("gap_size", 0.0f);
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
else
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
glsafe(::glLineWidth(2.0f));
|
||||
glsafe(::glLineWidth(2.0f));
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
// stem
|
||||
shader->set_uniform("view_model_matrix", overlap ?
|
||||
ss_to_ndc_matrix * Geometry::translation_transform(v1ss_3) * q12ss * Geometry::translation_transform(-2.0 * TRIANGLE_HEIGHT * Vec3d::UnitX()) * Geometry::scale_transform({ v12ss_len + 4.0 * TRIANGLE_HEIGHT, 1.0f, 1.0f }) :
|
||||
|
|
@ -1209,8 +1215,9 @@ void GLGizmoMeasure::render_dimensioning()
|
|||
m_dimensioning.line.set_color(color);
|
||||
m_dimensioning.line.render();
|
||||
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
shader->stop_using();
|
||||
|
||||
shader = wxGetApp().get_shader("flat");
|
||||
|
|
@ -1218,10 +1225,11 @@ void GLGizmoMeasure::render_dimensioning()
|
|||
return;
|
||||
|
||||
shader->start_using();
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
else
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
glsafe(::glLineWidth(1.0f));
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
// arrow 1
|
||||
if (show_first_tri) {
|
||||
|
|
@ -1441,11 +1449,16 @@ void GLGizmoMeasure::render_dimensioning()
|
|||
}
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
shader->stop_using();
|
||||
|
||||
#if SLIC3R_OPENGL_ES
|
||||
shader = wxGetApp().get_shader("dashed_lines");
|
||||
#else
|
||||
shader = wxGetApp().get_shader("dashed_thick_lines");
|
||||
#endif // SLIC3R_OPENGL_ES
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
|
|
@ -1455,18 +1468,20 @@ void GLGizmoMeasure::render_dimensioning()
|
|||
shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3])));
|
||||
shader->set_uniform("width", 1.0f);
|
||||
shader->set_uniform("gap_size", 0.0f);
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
else
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
glsafe(::glLineWidth(2.0f));
|
||||
glsafe(::glLineWidth(2.0f));
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
// arc
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * Geometry::translation_transform(center));
|
||||
m_dimensioning.arc.render();
|
||||
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
shader->stop_using();
|
||||
|
||||
shader = wxGetApp().get_shader("flat");
|
||||
|
|
@ -1474,10 +1489,11 @@ void GLGizmoMeasure::render_dimensioning()
|
|||
return;
|
||||
|
||||
shader->start_using();
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
else
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
glsafe(::glLineWidth(1.0f));
|
||||
glsafe(::glLineWidth(1.0f));
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
// arrows
|
||||
auto render_arrow = [this, shader, &camera, &normal, ¢er, &e1_unit, draw_radius, step, resolution](unsigned int endpoint_id) {
|
||||
|
|
|
|||
|
|
@ -887,6 +887,16 @@ void GLMmSegmentationGizmo3DScene::release_geometry() {
|
|||
glsafe(::glDeleteBuffers(1, &triangle_indices_VBO_id));
|
||||
triangle_indices_VBO_id = 0;
|
||||
}
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
if (this->vertices_VAO_id > 0) {
|
||||
glsafe(::glDeleteVertexArrays(1, &this->vertices_VAO_id));
|
||||
this->vertices_VAO_id = 0;
|
||||
}
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
this->clear();
|
||||
}
|
||||
|
|
@ -895,6 +905,13 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const
|
|||
{
|
||||
assert(triangle_indices_idx < this->triangle_indices_VBO_ids.size());
|
||||
assert(this->triangle_patches.size() == this->triangle_indices_VBO_ids.size());
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
assert(this->vertices_VAO_id != 0);
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
assert(this->vertices_VBO_id != 0);
|
||||
assert(this->triangle_indices_VBO_ids[triangle_indices_idx] != 0);
|
||||
|
||||
|
|
@ -902,6 +919,13 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const
|
|||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
glsafe(::glBindVertexArray(this->vertices_VAO_id));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
// the following binding is needed to set the vertex attributes
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id));
|
||||
const GLint position_id = shader->get_attrib_location("v_position");
|
||||
|
|
@ -922,17 +946,48 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const
|
|||
glsafe(::glDisableVertexAttribArray(position_id));
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
glsafe(::glBindVertexArray(0));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
}
|
||||
|
||||
void GLMmSegmentationGizmo3DScene::finalize_vertices()
|
||||
{
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
assert(this->vertices_VAO_id == 0);
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
assert(this->vertices_VBO_id == 0);
|
||||
if (!this->vertices.empty()) {
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
glsafe(::glGenVertexArrays(1, &this->vertices_VAO_id));
|
||||
glsafe(::glBindVertexArray(this->vertices_VAO_id));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
|
||||
glsafe(::glGenBuffers(1, &this->vertices_VBO_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id));
|
||||
glsafe(::glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(float), this->vertices.data(), GL_STATIC_DRAW));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
this->vertices.clear();
|
||||
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
if (OpenGLManager::get_gl_info().is_core_profile()) {
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
glsafe(::glBindVertexArray(0));
|
||||
#if !SLIC3R_OPENGL_ES
|
||||
}
|
||||
#endif // !SLIC3R_OPENGL_ES
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public:
|
|||
|
||||
// IDs of the Vertex Array Objects, into which the geometry has been loaded.
|
||||
// Zero if the VBOs are not sent to GPU yet.
|
||||
unsigned int vertices_VAO_id{ 0 };
|
||||
unsigned int vertices_VBO_id{0};
|
||||
std::vector<unsigned int> triangle_indices_VBO_ids;
|
||||
};
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue