More work on heightmap probing.

This commit is contained in:
2023-05-07 23:06:12 +03:00
parent 7e9be315cf
commit 368e5621d7
4 changed files with 300 additions and 25 deletions
+6
View File
@@ -46,6 +46,12 @@ Corner finding
- need to know the bit diameter
- use G38.2 to probe X edge and set that as current X - diam/2
Render arcs
Render quadratic splines
Render bezier splines
Synchronize executing program with render (show executed paths with different colors)
Show a progress bar when executing programs.
Add aggressive buffer execution policy and make it selectable.
DONE - Show program extents
+106 -7
View File
@@ -33,6 +33,7 @@
#include "render.h"
#include "glm/gtx/quaternion.hpp"
#include "nanogui/nanogui.h"
#include "glm/gtc/matrix_inverse.hpp"
#include <glm/ext/quaternion_float.hpp>
#include <glm/ext/quaternion_trigonometric.hpp>
#include <glm/vec3.hpp> // glm::vec3
@@ -68,7 +69,7 @@ public:
float cam_zoom = 0;
glm::quat cam_src_rotation = glm::quat(1.0, 0.0, 0.0, 0.0); // identity quaternion
Widget *info_layer;
Widget *info_layer, *heightmap_layer;
TabWidget *tab_widget;
VScrollPanel *settings_vscroll;
Widget *settings_layer;
@@ -93,6 +94,7 @@ public:
window->set_layout(new BoxLayout(nanogui::Orientation::Vertical));
tab_widget = window->add<TabWidget>();
tab_widget->set_tabs_draggable(true);
tab_widget->set_callback([&](int index) {
tab_widget->set_selected_index(index);
});
@@ -107,8 +109,6 @@ public:
probe_layer->set_layout(new GroupLayout(10, 20, 30, 0));
probe_layer->add<Label>("");
tab_widget->append_tab("Probing", info_layer);
add_status_markup();
add_dro_markup();
add_program_extents();
@@ -117,10 +117,17 @@ public:
add_work_parameters_markup();
add_z_probe_markup();
heightmap_layer = tab_widget->add<Widget>();
heightmap_layer->set_layout(new GroupLayout(10, 20, 30, 0));
heightmap_layer->add<Label>("");
tab_widget->append_tab("Heightmap", heightmap_layer);
add_heightmap_markup();
perform_layout();
m_render_pass = new RenderPass({this});
m_render_pass->set_clear_color(0, Color(0.3f, 0.3f, 0.32f, 1.f));
m_render_pass->set_clear_color(0, Color(0.13f, 0.13f, 0.13f, 1.f));
m_render_pass->set_depth_test(RenderPass::DepthTest::Always, true);
m_render_pass->set_cull_mode(RenderPass::CullMode::Disabled);
}
@@ -187,6 +194,8 @@ public:
if (pgm.load_from_file(path)) {
init_program_geometry();
set_program_extents();
fill_heightmap_from_model();
update_grid();
} else {
}
});
@@ -444,6 +453,97 @@ public:
extents_max_z = extents_holder->add<TextBox>("");
}
TextBox *txt_heightmap_from_x, *txt_heightmap_from_y;
TextBox *txt_heightmap_to_x, *txt_heightmap_to_y;
TextBox *txt_grid_res;
void add_heightmap_markup() {
heightmap_layer->add<Label>("Grid definition", "sans-bold", 20);
auto heightmap_params_holder = heightmap_layer->add<Widget>();
heightmap_params_holder->set_layout(new BoxLayout(Orientation::Vertical, Alignment::Fill, 4, 4));
// grid size
auto grid_size_holder = heightmap_params_holder->add<Widget>();
grid_size_holder->set_layout(new GridLayout(Orientation::Horizontal, 3, Alignment::Middle, 4, 4));
grid_size_holder->add<Label>("", "sans-bold", 20);
grid_size_holder->add<Label>("X", "sans-bold", 20);
grid_size_holder->add<Label>("Y", "sans-bold", 20);
grid_size_holder->add<Label>("From", "sans-bold", 20);
txt_heightmap_from_x = grid_size_holder->add<TextBox>("");
txt_heightmap_from_x->set_editable(true);
txt_heightmap_from_x->set_fixed_width(150);
txt_heightmap_from_y = grid_size_holder->add<TextBox>("");
txt_heightmap_from_y->set_editable(true);
txt_heightmap_from_y->set_fixed_width(150);
grid_size_holder->add<Label>("To", "sans-bold", 20);
txt_heightmap_to_x = grid_size_holder->add<TextBox>("");
txt_heightmap_to_x->set_editable(true);
txt_heightmap_to_x->set_fixed_width(150);
txt_heightmap_to_y = grid_size_holder->add<TextBox>("");
txt_heightmap_to_y->set_editable(true);
txt_heightmap_to_y->set_fixed_width(150);
grid_size_holder->add<Label>("");
auto btn = grid_size_holder->add<Button>("Fetch from model");
btn->set_callback([&]() {
fill_heightmap_from_model();
});
grid_size_holder->add<Label>("");
txt_heightmap_from_x->set_callback([&](const std::string& new_value) {
update_grid();
return true;
});
txt_heightmap_from_y->set_callback([&](const std::string& new_value) {
update_grid();
return true;
});
txt_heightmap_to_x->set_callback([&](const std::string& new_value) {
update_grid();
return true;
});
txt_heightmap_to_y->set_callback([&](const std::string& new_value) {
update_grid();
return true;
});
// grid resolution
auto grid_res_holder = heightmap_params_holder->add<Widget>();
grid_res_holder->set_layout(new BoxLayout(nanogui::Orientation::Horizontal, Alignment::Middle, 4, 4));
grid_res_holder->add<Label>("Grid resolution", "sans-bold", 20);
txt_grid_res = grid_res_holder->add<TextBox>("5");
txt_grid_res->set_editable(true);
txt_grid_res->set_fixed_width(150);
txt_grid_res->set_callback([&](const std::string& new_value) {
update_grid();
return true;
});
grid_res_holder->add<Label>("mm", "sans-bold", 20);
}
void fill_heightmap_from_model() {
auto min = renderer.get_extents_min();
auto max = renderer.get_extents_max();
txt_heightmap_from_x->set_value(std::to_string(min.x));
txt_heightmap_from_y->set_value(std::to_string(min.y));
txt_heightmap_to_x->set_value(std::to_string(max.x));
txt_heightmap_to_y->set_value(std::to_string(max.y));
}
void update_grid() {
auto from_x = std::stof(txt_heightmap_from_x->value());
auto from_y = std::stof(txt_heightmap_from_y->value());
auto to_x = std::stof(txt_heightmap_to_x->value());
auto to_y = std::stof(txt_heightmap_to_y->value());
auto res = std::stoi(txt_grid_res->value());
renderer.update_grid(from_x, from_y, to_x, to_y, res);
}
void add_pins_markup() {
// Pins
info_layer->add<Label>("Pins", "sans-bold", 20);
@@ -861,9 +961,8 @@ public:
glm::translate(glm::mat4(1.0f), -cam_target);
glm::mat4 model = glm::mat4(1.0f);
auto mvp = projection * view * model;
renderer.render(mvp, glm::vec2(fb_size.x(), fb_size.y()));
glm::mat3 normal_mat = glm::inverseTranspose(glm::mat3(view * model));
renderer.render(model, view, projection, normal_mat, glm::vec2(fb_size.x(), fb_size.y()));
}
m_render_pass->end();
+179 -15
View File
@@ -53,6 +53,69 @@ static const char *ps_code = R"(
}
)";
static const char *vs_heightmap_code = R"(
#version 330
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec4 color;
uniform mat4 mmtx;
uniform mat4 vmtx;
uniform mat4 pmtx;
uniform mat3 nmtx;
out vec3 eye_space_normal;
out vec3 eye_space_position;
out vec4 diffuse_color;
void main() {
mat4 mvp = pmtx * vmtx * mmtx;
gl_Position = mvp * vec4(position, 1.0);
eye_space_position = (vmtx * mmtx * vec4(position, 1)).xyz;
eye_space_normal = normalize(nmtx * normal);
diffuse_color = color;
}
)";
static const char *ps_heightmap_code = R"(
#version 330
in vec3 eye_space_normal;
in vec3 eye_space_position;
in vec4 diffuse_color;
out vec4 color;
void main() {
vec3 normal = normalize(eye_space_normal);
vec3 light_dir = normalize(vec3(0, 0, 1));
vec4 ambient_color = vec4(0.1, 0.1, 0.1, 1);
float n_dot_l = max(dot(normal, light_dir), 0.0);
color = n_dot_l * diffuse_color + ambient_color;
}
)";
static void add_vertex(std::vector<float>& buffer_data, glm::vec3 v, glm::vec3 n, glm::vec4 col) {
buffer_data.push_back(v.x);
buffer_data.push_back(v.y);
buffer_data.push_back(v.z);
buffer_data.push_back(n.x);
buffer_data.push_back(n.y);
buffer_data.push_back(n.z);
buffer_data.push_back(col.r);
buffer_data.push_back(col.g);
buffer_data.push_back(col.b);
buffer_data.push_back(col.a);
}
static void add_vertex(std::vector<float>& buffer_data, glm::vec3 v, glm::vec4 col) {
buffer_data.push_back(v.x);
buffer_data.push_back(v.y);
@@ -74,8 +137,28 @@ static void add_line(std::vector<float>& buffer_data, glm::vec3 from, glm::vec3
add_vertex(buffer_data, to, col);
}
static void add_triangle(std::vector<float>& buffer_data, glm::vec3 p1, glm::vec3 p2, glm::vec3 p3, glm::vec3 n, glm::vec4 col) {
add_vertex(buffer_data, p1, n, col);
add_vertex(buffer_data, p2, n, col);
add_vertex(buffer_data, p3, n, col);
}
void grbl::program_renderer::render(glm::mat4 model, glm::mat4 view, glm::mat4 projection, glm::mat3 normal_mat, glm::vec2 viewport_size) {
// draw heightmap
heightmap_shader->bind();
heightmap_shader->set_mat4(glm::value_ptr(model), "mmtx");
heightmap_shader->set_mat4(glm::value_ptr(view), "vmtx");
heightmap_shader->set_mat4(glm::value_ptr(projection), "pmtx");
heightmap_shader->set_mat3(glm::value_ptr(normal_mat), "nmtx");
glBindVertexArray(heightmap_vao_id);
glDrawArrays(GL_TRIANGLES, 0, heightmap_vertices_count);
heightmap_shader->unbind();
auto mvp = projection * view * model;
void grbl::program_renderer::render(glm::mat4 mvp, glm::vec2 viewport_size) {
// draw model
shader->bind();
shader->set_mat4(glm::value_ptr(mvp), "mvp");
@@ -109,25 +192,27 @@ void grbl::program_renderer::render(glm::mat4 mvp, glm::vec2 viewport_size) {
void grbl::program_renderer::update(const grbl::program& pgm, const grbl::machine& cnc) {
if (!initialized) {
shader = new shader_program(vs_code, ps_code);
heightmap_shader = new shader_program(vs_heightmap_code, ps_heightmap_code);
initialize_spindle_buffers();
initialize_program_buffers();
initialize_extents_buffers();
initialize_heightmap_buffers();
initialized = true;
}
// update program with machine status
// build vbo and vao
vertices_count = build_vbo(pgm);
vertices_count = update_model_vbo(pgm);
auto work_pos = cnc.get_status().machine_pos;
auto offsets = cnc.get_current_work_offset_values();
for (int i = 0; i < 3; i++) {
work_pos[i] -= offsets[i];
}
spindle_pos = glm::vec3(work_pos[0], work_pos[1], work_pos[2]);
auto machine_pos = glm::vec3{cnc.get_status().machine_pos[0],
cnc.get_status().machine_pos[1],
cnc.get_status().machine_pos[2]};
auto offsets = glm::vec3{cnc.get_current_work_offset_values()[0],
cnc.get_current_work_offset_values()[1],
cnc.get_current_work_offset_values()[2]};
spindle_pos = machine_pos - offsets;
}
@@ -199,7 +284,7 @@ void grbl::program_renderer::initialize_extents_buffers() {
// or at least we'll try to.
// construct box
glm::vec4 col(1, 0, 1, 1);
glm::vec4 col(1, 0.7, 0.3, 1);
// box will range from [0,0,0] to [1,1,1] and we'll use
@@ -251,7 +336,7 @@ void grbl::program_renderer::initialize_program_buffers() {
glBindVertexArray(0);
}
GLsizei grbl::program_renderer::build_vbo(const grbl::program& pgm) {
GLsizei grbl::program_renderer::update_model_vbo(const grbl::program& pgm) {
static auto movement_re = std::regex(R"(([gG]0*1?\s+|[xXyYzZ]\s*[0-9\.\-]+))");
bool is_tool_on = false;
@@ -301,14 +386,14 @@ GLsizei grbl::program_renderer::build_vbo(const grbl::program& pgm) {
auto from_color = glm::vec4(1.0f);
auto to_color = glm::vec4(1.0f);
if (is_tool_on) {
from_color = glm::vec4(1, 0, 0, 1);
to_color = glm::vec4(1, 0, 0, 1);
from_color = glm::vec4(1, 0.6, 0.6, 1);
to_color = glm::vec4(1, 0.6, 0.6, 1);
}
if (is_plunge) {
to_color = glm::vec4(1, 0, 0, 1);
to_color = glm::vec4(1, 0.6, 0.6, 1);
} else if (is_retract) {
to_color = glm::vec4(0, 1, 0, 1);
to_color = glm::vec4(0.6, 1, 0.6, 1);
}
add_line(buffer_data, tool_pos, from_color, new_pos, to_color);
@@ -336,6 +421,83 @@ GLsizei grbl::program_renderer::build_vbo(const grbl::program& pgm) {
return number_of_vertices;
}
void grbl::program_renderer::update_grid(float from_x, float from_y, float to_x, float to_y, int resolution) {
int x_segments = ceil((to_x - from_x) / resolution);
int y_segments = ceil((to_y - from_y) / resolution);
glm::vec4 color = {0.5, 0.3, 0, 1};
std::vector<glm::vec3> vertices;
float y_pos = from_y;
for (int y = 0; y < (y_segments + 1); y++) {
float x_pos = from_x;
for (int x = 0; x < (x_segments + 1); x++) {
vertices.emplace_back(x_pos, y_pos, 0);
x_pos += resolution;
}
y_pos += resolution;
}
std::vector<float> buffer_data;
for (int y = 0; y < y_segments; y++) {
for (int x = 0; x < x_segments; x++) {
int current = x + y * (x_segments + 1);
int next = current + 1;
int bottom = next + x_segments;
int bottom_next = bottom + 1;
auto p1 = vertices[current];
auto p2 = vertices[bottom];
auto p3 = vertices[next];
glm::vec3 normal = glm::normalize(glm::cross(p1 - p2, p3 - p1));
add_triangle(buffer_data, p1, p2, p3, normal, color);
p1 = vertices[next];
p2 = vertices[bottom];
p3 = vertices[bottom_next];
normal = glm::normalize(glm::cross(p1 - p2, p3 - p1));
add_triangle(buffer_data, p1, p2, p3, normal, color);
}
}
const GLsizei size_of_vertex_in_bytes = 40;
heightmap_vertices_count = buffer_data.size() * sizeof(float) / size_of_vertex_in_bytes;
glBindBuffer(GL_ARRAY_BUFFER, heightmap_vbo_id);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * buffer_data.size(), buffer_data.data(), GL_STATIC_DRAW);
}
void grbl::program_renderer::initialize_heightmap_buffers() {
glGenBuffers(1, &heightmap_vbo_id);
glGenVertexArrays(1, &heightmap_vao_id);
// for height map we are going to use solid rendering (triangles)
// we also need to send normals so that we can better see the shape of the map through lighting
// vertex format: v.x, v.y, v.z, n.x, n.y, n.z, r, g, b, a
// stride: 10 * 4 bytes => 40 bytes
const GLsizei size_of_vertex_in_bytes = 40;
glBindVertexArray(heightmap_vao_id);
glBindBuffer(GL_ARRAY_BUFFER, heightmap_vbo_id);
glEnableVertexAttribArray(0); // vertices on stream 0
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, size_of_vertex_in_bytes, (void *) 0);
glEnableVertexAttribArray(1); // normals on stream 1
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, size_of_vertex_in_bytes, (void *) (sizeof(float) * 3));
glEnableVertexAttribArray(2); // vertex colors on stream 2
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, size_of_vertex_in_bytes, (void *) (sizeof(float) * 6));
// unbind vao
glBindVertexArray(0);
}
std::string get_shader_info_log(GLuint id) {
GLint log_length = 0;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &log_length);
@@ -365,6 +527,7 @@ bool check_compile_error(GLuint shader_id) {
std::cerr << "Shader compile error: " << "(id: " << shader_id << ") - " << get_shader_info_log(shader_id) << std::endl;
glDeleteShader(shader_id);
exit(1);
return false;
}
@@ -376,6 +539,7 @@ bool check_link_error(GLuint program_id) {
std::cerr << "Shader program link error: " << "(id: " << program_id << ") - " << get_program_info_log(program_id) << std::endl;
glDeleteProgram(program_id);
exit(1);
return false;
}
+9 -3
View File
@@ -12,14 +12,15 @@ class shader_program;
class program_renderer {
public:
void update(const program& pgm, const machine& cnc);
void render(glm::mat4 mvp, glm::vec2 viewport_size);
void render(glm::mat4 model, glm::mat4 view, glm::mat4 projection, glm::mat3 normal_mat, glm::vec2 viewport_size);
glm::vec3 get_extents_min() const { return min_pos; };
glm::vec3 get_extents_max() const { return max_pos; };
void update_grid(float from_x, float from_y, float to_x, float to_y, int resolution);
private:
GLsizei build_vbo(const grbl::program& pgm);
GLsizei update_model_vbo(const grbl::program& pgm);
GLuint spindle_vbo_id;
GLuint spindle_vao_id;
@@ -30,16 +31,21 @@ private:
GLuint extents_vbo_id;
GLuint extents_vao_id;
GLuint heightmap_vbo_id;
GLuint heightmap_vao_id;
shader_program *shader = nullptr;
shader_program *heightmap_shader = nullptr;
bool initialized = false;
glm::vec3 min_pos, max_pos, spindle_pos;
GLsizei vertices_count, spindle_vertices_count, extents_vertices_count;
GLsizei vertices_count, spindle_vertices_count, extents_vertices_count, heightmap_vertices_count;
void initialize_program_buffers();
void initialize_spindle_buffers();
void initialize_extents_buffers();
void initialize_heightmap_buffers();
};