Use multiple index buffers to render toolpaths in preview
This commit is contained in:
parent
743d6643ae
commit
7a10e23470
@ -129,16 +129,19 @@ void GCodeViewer::TBuffer::reset()
|
|||||||
{
|
{
|
||||||
// release gpu memory
|
// release gpu memory
|
||||||
vertices.reset();
|
vertices.reset();
|
||||||
indices.reset();
|
for (IBuffer& buffer : indices) {
|
||||||
|
buffer.reset();
|
||||||
|
}
|
||||||
|
|
||||||
// release cpu memory
|
// release cpu memory
|
||||||
|
indices = std::vector<IBuffer>();
|
||||||
paths = std::vector<Path>();
|
paths = std::vector<Path>();
|
||||||
render_paths = std::vector<RenderPath>();
|
render_paths = std::vector<RenderPath>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id)
|
void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id)
|
||||||
{
|
{
|
||||||
Path::Endpoint endpoint = { i_id, s_id, move.position };
|
Path::Endpoint endpoint = { b_id, i_id, s_id, move.position };
|
||||||
// use rounding to reduce the number of generated paths
|
// use rounding to reduce the number of generated paths
|
||||||
paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder,
|
paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder,
|
||||||
round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed,
|
round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed,
|
||||||
@ -561,7 +564,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
|
|||||||
|
|
||||||
// the data needed is contained into the Extrude TBuffer
|
// the data needed is contained into the Extrude TBuffer
|
||||||
const TBuffer& buffer = m_buffers[buffer_id(EMoveType::Extrude)];
|
const TBuffer& buffer = m_buffers[buffer_id(EMoveType::Extrude)];
|
||||||
if (buffer.vertices.id == 0 || buffer.indices.id == 0)
|
if (!buffer.has_data())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// collect color information to generate materials
|
// collect color information to generate materials
|
||||||
@ -611,10 +614,13 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
|
|||||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||||
|
|
||||||
// get indices data from index buffer on gpu
|
// get indices data from index buffer on gpu
|
||||||
std::vector<unsigned int> indices = std::vector<unsigned int>(buffer.indices.count);
|
MultiIndexBuffer indices;
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id));
|
for (size_t i = 0; i < buffer.indices.size(); ++i) {
|
||||||
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, static_cast<GLsizeiptr>(indices.size() * sizeof(unsigned int)), indices.data()));
|
indices.push_back(IndexBuffer(buffer.indices[i].count));
|
||||||
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices[i].id));
|
||||||
|
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, static_cast<GLsizeiptr>(indices.back().size() * sizeof(unsigned int)), indices.back().data()));
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||||
|
}
|
||||||
|
|
||||||
auto get_vertex = [&vertices, floats_per_vertex](unsigned int id) {
|
auto get_vertex = [&vertices, floats_per_vertex](unsigned int id) {
|
||||||
// extract vertex from vector of floats
|
// extract vertex from vector of floats
|
||||||
@ -672,6 +678,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
|
|||||||
for (size_t i = 0; i < buffer.render_paths.size(); ++i) {
|
for (size_t i = 0; i < buffer.render_paths.size(); ++i) {
|
||||||
// get paths segments from buffer paths
|
// get paths segments from buffer paths
|
||||||
const RenderPath& render_path = buffer.render_paths[i];
|
const RenderPath& render_path = buffer.render_paths[i];
|
||||||
|
const IndexBuffer& ibuffer = indices[render_path.index_buffer_id];
|
||||||
const Path& path = buffer.paths[render_path.path_id];
|
const Path& path = buffer.paths[render_path.path_id];
|
||||||
float half_width = 0.5f * path.width;
|
float half_width = 0.5f * path.width;
|
||||||
// clamp height to avoid artifacts due to z-fighting when importing the obj file into blender and similar
|
// clamp height to avoid artifacts due to z-fighting when importing the obj file into blender and similar
|
||||||
@ -687,7 +694,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
|
|||||||
unsigned int end = start + render_path.sizes[j];
|
unsigned int end = start + render_path.sizes[j];
|
||||||
|
|
||||||
for (size_t k = start; k < end; k += static_cast<size_t>(indices_per_segment)) {
|
for (size_t k = start; k < end; k += static_cast<size_t>(indices_per_segment)) {
|
||||||
Segment curr = generate_segment(indices[k + start_vertex_offset], indices[k + end_vertex_offset], half_width, half_height);
|
Segment curr = generate_segment(ibuffer[k + start_vertex_offset], ibuffer[k + end_vertex_offset], half_width, half_height);
|
||||||
if (k == start) {
|
if (k == start) {
|
||||||
// starting endpoint vertices/normals
|
// starting endpoint vertices/normals
|
||||||
out_vertices.push_back(curr.v1 + curr.rl_displacement); out_normals.push_back(curr.right); // right
|
out_vertices.push_back(curr.v1 + curr.rl_displacement); out_normals.push_back(curr.right); // right
|
||||||
@ -710,7 +717,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
|
|||||||
out_vertices_count += 2;
|
out_vertices_count += 2;
|
||||||
|
|
||||||
size_t first_vertex_id = k - static_cast<size_t>(indices_per_segment);
|
size_t first_vertex_id = k - static_cast<size_t>(indices_per_segment);
|
||||||
Segment prev = generate_segment(indices[first_vertex_id + start_vertex_offset], indices[first_vertex_id + end_vertex_offset], half_width, half_height);
|
Segment prev = generate_segment(ibuffer[first_vertex_id + start_vertex_offset], ibuffer[first_vertex_id + end_vertex_offset], half_width, half_height);
|
||||||
float disp = 0.0f;
|
float disp = 0.0f;
|
||||||
float cos_dir = prev.dir.dot(curr.dir);
|
float cos_dir = prev.dir.dot(curr.dir);
|
||||||
if (cos_dir > -0.9998477f) {
|
if (cos_dir > -0.9998477f) {
|
||||||
@ -895,17 +902,17 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
|
|
||||||
// format data into the buffers to be rendered as points
|
// format data into the buffers to be rendered as points
|
||||||
auto add_as_point = [](const GCodeProcessor::MoveVertex& curr, TBuffer& buffer,
|
auto add_as_point = [](const GCodeProcessor::MoveVertex& curr, TBuffer& buffer,
|
||||||
std::vector<float>& buffer_vertices, std::vector<unsigned int>& buffer_indices, size_t move_id) {
|
std::vector<float>& buffer_vertices, unsigned int index_buffer_id, IndexBuffer& buffer_indices, size_t move_id) {
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
buffer_vertices.push_back(curr.position[j]);
|
buffer_vertices.push_back(curr.position[j]);
|
||||||
}
|
}
|
||||||
buffer.add_path(curr, static_cast<unsigned int>(buffer_indices.size()), static_cast<unsigned int>(move_id));
|
buffer.add_path(curr, index_buffer_id, static_cast<size_t>(buffer_indices.size()), static_cast<size_t>(move_id));
|
||||||
buffer_indices.push_back(static_cast<unsigned int>(buffer_indices.size()));
|
buffer_indices.push_back(static_cast<unsigned int>(buffer_indices.size()));
|
||||||
};
|
};
|
||||||
|
|
||||||
// format data into the buffers to be rendered as lines
|
// format data into the buffers to be rendered as lines
|
||||||
auto add_as_line = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer,
|
auto add_as_line = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer,
|
||||||
std::vector<float>& buffer_vertices, std::vector<unsigned int>& buffer_indices, size_t move_id) {
|
std::vector<float>& buffer_vertices, unsigned int index_buffer_id, IndexBuffer& buffer_indices, size_t move_id) {
|
||||||
// x component of the normal to the current segment (the normal is parallel to the XY plane)
|
// x component of the normal to the current segment (the normal is parallel to the XY plane)
|
||||||
float normal_x = (curr.position - prev.position).normalized()[1];
|
float normal_x = (curr.position - prev.position).normalized()[1];
|
||||||
|
|
||||||
@ -918,7 +925,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
buffer_vertices.push_back(normal_x);
|
buffer_vertices.push_back(normal_x);
|
||||||
// add starting index
|
// add starting index
|
||||||
buffer_indices.push_back(static_cast<unsigned int>(buffer_indices.size()));
|
buffer_indices.push_back(static_cast<unsigned int>(buffer_indices.size()));
|
||||||
buffer.add_path(curr, static_cast<unsigned int>(buffer_indices.size() - 1), static_cast<unsigned int>(move_id - 1));
|
buffer.add_path(curr, index_buffer_id, static_cast<size_t>(buffer_indices.size() - 1), static_cast<size_t>(move_id - 1));
|
||||||
buffer.paths.back().first.position = prev.position;
|
buffer.paths.back().first.position = prev.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,12 +949,12 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
buffer_vertices.push_back(normal_x);
|
buffer_vertices.push_back(normal_x);
|
||||||
// add current index
|
// add current index
|
||||||
buffer_indices.push_back(static_cast<unsigned int>(buffer_indices.size()));
|
buffer_indices.push_back(static_cast<unsigned int>(buffer_indices.size()));
|
||||||
last_path.last = { static_cast<unsigned int>(buffer_indices.size() - 1), static_cast<unsigned int>(move_id), curr.position };
|
last_path.last = { index_buffer_id, static_cast<size_t>(buffer_indices.size() - 1), static_cast<size_t>(move_id), curr.position };
|
||||||
};
|
};
|
||||||
|
|
||||||
// format data into the buffers to be rendered as solid
|
// format data into the buffers to be rendered as solid
|
||||||
auto add_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer,
|
auto add_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer,
|
||||||
std::vector<float>& buffer_vertices, std::vector<unsigned int>& buffer_indices, size_t move_id) {
|
std::vector<float>& buffer_vertices, unsigned int index_buffer_id, IndexBuffer& buffer_indices, size_t move_id) {
|
||||||
static Vec3f prev_dir;
|
static Vec3f prev_dir;
|
||||||
static Vec3f prev_up;
|
static Vec3f prev_up;
|
||||||
static float prev_length;
|
static float prev_length;
|
||||||
@ -961,7 +968,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
buffer_vertices.push_back(normal[j]);
|
buffer_vertices.push_back(normal[j]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
auto store_triangle = [](std::vector<unsigned int>& buffer_indices, unsigned int i1, unsigned int i2, unsigned int i3) {
|
auto store_triangle = [](IndexBuffer& buffer_indices, unsigned int i1, unsigned int i2, unsigned int i3) {
|
||||||
buffer_indices.push_back(i1);
|
buffer_indices.push_back(i1);
|
||||||
buffer_indices.push_back(i2);
|
buffer_indices.push_back(i2);
|
||||||
buffer_indices.push_back(i3);
|
buffer_indices.push_back(i3);
|
||||||
@ -974,13 +981,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
vertices[id + 1] = position[1];
|
vertices[id + 1] = position[1];
|
||||||
vertices[id + 2] = position[2];
|
vertices[id + 2] = position[2];
|
||||||
};
|
};
|
||||||
auto append_dummy_cap = [store_triangle](std::vector<unsigned int>& buffer_indices, unsigned int id) {
|
auto append_dummy_cap = [store_triangle](IndexBuffer& buffer_indices, unsigned int id) {
|
||||||
store_triangle(buffer_indices, id, id, id);
|
store_triangle(buffer_indices, id, id, id);
|
||||||
store_triangle(buffer_indices, id, id, id);
|
store_triangle(buffer_indices, id, id, id);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (prev.type != curr.type || !buffer.paths.back().matches(curr)) {
|
if (prev.type != curr.type || !buffer.paths.back().matches(curr)) {
|
||||||
buffer.add_path(curr, static_cast<unsigned int>(buffer_indices.size()), static_cast<unsigned int>(move_id - 1));
|
buffer.add_path(curr, index_buffer_id, static_cast<size_t>(buffer_indices.size()), static_cast<size_t>(move_id - 1));
|
||||||
buffer.paths.back().first.position = prev.position;
|
buffer.paths.back().first.position = prev.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1154,7 +1161,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
store_triangle(buffer_indices, starting_vertices_size + 2, starting_vertices_size + 3, starting_vertices_size + 4);
|
store_triangle(buffer_indices, starting_vertices_size + 2, starting_vertices_size + 3, starting_vertices_size + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
last_path.last = { static_cast<unsigned int>(buffer_indices.size() - 1), static_cast<unsigned int>(move_id), curr.position };
|
last_path.last = { index_buffer_id, static_cast<size_t>(buffer_indices.size() - 1), static_cast<size_t>(move_id), curr.position };
|
||||||
prev_dir = dir;
|
prev_dir = dir;
|
||||||
prev_up = up;
|
prev_up = up;
|
||||||
prev_length = length;
|
prev_length = length;
|
||||||
@ -1162,7 +1169,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
|
|
||||||
// toolpaths data -> extract from result
|
// toolpaths data -> extract from result
|
||||||
std::vector<std::vector<float>> vertices(m_buffers.size());
|
std::vector<std::vector<float>> vertices(m_buffers.size());
|
||||||
std::vector<std::vector<unsigned int>> indices(m_buffers.size());
|
std::vector<MultiIndexBuffer> indices(m_buffers.size());
|
||||||
|
for (auto i : indices) {
|
||||||
|
i.push_back(IndexBuffer());
|
||||||
|
}
|
||||||
for (size_t i = 0; i < m_moves_count; ++i) {
|
for (size_t i = 0; i < m_moves_count; ++i) {
|
||||||
// skip first vertex
|
// skip first vertex
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
@ -1174,7 +1184,34 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
unsigned char id = buffer_id(curr.type);
|
unsigned char id = buffer_id(curr.type);
|
||||||
TBuffer& buffer = m_buffers[id];
|
TBuffer& buffer = m_buffers[id];
|
||||||
std::vector<float>& buffer_vertices = vertices[id];
|
std::vector<float>& buffer_vertices = vertices[id];
|
||||||
std::vector<unsigned int>& buffer_indices = indices[id];
|
MultiIndexBuffer& buffer_indices = indices[id];
|
||||||
|
if (buffer_indices.empty())
|
||||||
|
buffer_indices.push_back(IndexBuffer());
|
||||||
|
|
||||||
|
static const size_t THRESHOLD = 1024 * 1024 * 1024;
|
||||||
|
// if adding the indices for the current segment exceeds the threshold size of the current index buffer
|
||||||
|
// create another index buffer, and move the current path indices into it
|
||||||
|
if (buffer_indices.back().size() >= THRESHOLD - static_cast<size_t>(buffer.indices_per_segment())) {
|
||||||
|
buffer_indices.push_back(IndexBuffer());
|
||||||
|
if (curr.type == EMoveType::Extrude || curr.type == EMoveType::Travel) {
|
||||||
|
if (!(prev.type != curr.type || !buffer.paths.back().matches(curr))) {
|
||||||
|
Path& last_path = buffer.paths.back();
|
||||||
|
size_t delta_id = last_path.last.i_id - last_path.first.i_id;
|
||||||
|
|
||||||
|
// move indices of the last path from the previous into the new index buffer
|
||||||
|
IndexBuffer& src_buffer = buffer_indices[buffer_indices.size() - 2];
|
||||||
|
IndexBuffer& dst_buffer = buffer_indices[buffer_indices.size() - 1];
|
||||||
|
std::move(src_buffer.begin() + last_path.first.i_id, src_buffer.end(), std::back_inserter(dst_buffer));
|
||||||
|
src_buffer.erase(src_buffer.begin() + last_path.first.i_id, src_buffer.end());
|
||||||
|
|
||||||
|
// updates path indices
|
||||||
|
last_path.first.b_id = buffer_indices.size() - 1;
|
||||||
|
last_path.first.i_id = 0;
|
||||||
|
last_path.last.b_id = buffer_indices.size() - 1;
|
||||||
|
last_path.last.i_id = delta_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (curr.type)
|
switch (curr.type)
|
||||||
{
|
{
|
||||||
@ -1185,17 +1222,17 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
case EMoveType::Retract:
|
case EMoveType::Retract:
|
||||||
case EMoveType::Unretract:
|
case EMoveType::Unretract:
|
||||||
{
|
{
|
||||||
add_as_point(curr, buffer, buffer_vertices, buffer_indices, i);
|
add_as_point(curr, buffer, buffer_vertices, static_cast<unsigned int>(buffer_indices.size()) - 1, buffer_indices.back(), i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EMoveType::Extrude:
|
case EMoveType::Extrude:
|
||||||
{
|
{
|
||||||
add_as_solid(prev, curr, buffer, buffer_vertices, buffer_indices, i);
|
add_as_solid(prev, curr, buffer, buffer_vertices, static_cast<unsigned int>(buffer_indices.size()) - 1, buffer_indices.back(), i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EMoveType::Travel:
|
case EMoveType::Travel:
|
||||||
{
|
{
|
||||||
add_as_line(prev, curr, buffer, buffer_vertices, buffer_indices, i);
|
add_as_line(prev, curr, buffer, buffer_vertices, static_cast<unsigned int>(buffer_indices.size()) - 1, buffer_indices.back(), i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: { break; }
|
default: { break; }
|
||||||
@ -1220,29 +1257,39 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||||
|
|
||||||
// indices
|
// indices
|
||||||
const std::vector<unsigned int>& buffer_indices = indices[i];
|
for (size_t j = 0; j < indices[i].size(); ++j) {
|
||||||
buffer.indices.count = buffer_indices.size();
|
const IndexBuffer& buffer_indices = indices[i][j];
|
||||||
|
buffer.indices.push_back(IBuffer());
|
||||||
|
IBuffer& ibuffer = buffer.indices.back();
|
||||||
|
ibuffer.count = buffer_indices.size();
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
m_statistics.indices_gpu_size += buffer.indices.count * sizeof(unsigned int);
|
m_statistics.indices_gpu_size += ibuffer.count * sizeof(unsigned int);
|
||||||
m_statistics.max_indices_in_index_buffer = std::max(m_statistics.max_indices_in_index_buffer, static_cast<long long>(buffer.indices.count));
|
m_statistics.max_indices_in_index_buffer = std::max(m_statistics.max_indices_in_index_buffer, static_cast<long long>(ibuffer.count));
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
|
|
||||||
if (buffer.indices.count > 0) {
|
if (ibuffer.count > 0) {
|
||||||
glsafe(::glGenBuffers(1, &buffer.indices.id));
|
glsafe(::glGenBuffers(1, &ibuffer.id));
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id));
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer.id));
|
||||||
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.count * sizeof(unsigned int), buffer_indices.data(), GL_STATIC_DRAW));
|
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer_indices.size() * sizeof(unsigned int), buffer_indices.data(), GL_STATIC_DRAW));
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
for (const TBuffer& buffer : m_buffers) {
|
for (const TBuffer& buffer : m_buffers) {
|
||||||
m_statistics.paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path);
|
m_statistics.paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path);
|
||||||
}
|
}
|
||||||
unsigned int travel_buffer_id = buffer_id(EMoveType::Travel);
|
unsigned int travel_buffer_id = buffer_id(EMoveType::Travel);
|
||||||
m_statistics.travel_segments_count = indices[travel_buffer_id].size() / m_buffers[travel_buffer_id].indices_per_segment();
|
const MultiIndexBuffer& travel_buffer_indices = indices[travel_buffer_id];
|
||||||
|
for (size_t i = 0; i < travel_buffer_indices.size(); ++i) {
|
||||||
|
m_statistics.travel_segments_count = travel_buffer_indices[i].size() / m_buffers[travel_buffer_id].indices_per_segment();
|
||||||
|
}
|
||||||
unsigned int extrude_buffer_id = buffer_id(EMoveType::Extrude);
|
unsigned int extrude_buffer_id = buffer_id(EMoveType::Extrude);
|
||||||
m_statistics.extrude_segments_count = indices[extrude_buffer_id].size() / m_buffers[extrude_buffer_id].indices_per_segment();
|
const MultiIndexBuffer& extrude_buffer_indices = indices[extrude_buffer_id];
|
||||||
|
for (size_t i = 0; i < extrude_buffer_indices.size(); ++i) {
|
||||||
|
m_statistics.extrude_segments_count = extrude_buffer_indices[i].size() / m_buffers[extrude_buffer_id].indices_per_segment();
|
||||||
|
}
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
|
|
||||||
// layers zs / roles / extruder ids / cp color ids -> extract from result
|
// layers zs / roles / extruder ids / cp color ids -> extract from result
|
||||||
@ -1288,7 +1335,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||||||
}
|
}
|
||||||
long long indices_size = 0;
|
long long indices_size = 0;
|
||||||
for (size_t i = 0; i < indices.size(); ++i) {
|
for (size_t i = 0; i < indices.size(); ++i) {
|
||||||
indices_size += SLIC3R_STDVEC_MEMSIZE(indices[i], unsigned int);
|
for (size_t j = 0; j < indices[i].size(); ++j) {
|
||||||
|
indices_size += SLIC3R_STDVEC_MEMSIZE(indices[i][j], unsigned int);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
log_memory_used("Loaded G-code extrusion paths, ", vertices_size + indices_size);
|
log_memory_used("Loaded G-code extrusion paths, ", vertices_size + indices_size);
|
||||||
|
|
||||||
@ -1396,7 +1445,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
m_sequential_view.current.last = m_moves_count;
|
m_sequential_view.current.last = m_moves_count;
|
||||||
|
|
||||||
// first pass: collect visible paths and update sequential view data
|
// first pass: collect visible paths and update sequential view data
|
||||||
std::vector<std::pair<TBuffer*, size_t>> paths;
|
std::vector<std::tuple<TBuffer*, unsigned int, unsigned int>> paths;
|
||||||
for (TBuffer& buffer : m_buffers) {
|
for (TBuffer& buffer : m_buffers) {
|
||||||
// reset render paths
|
// reset render paths
|
||||||
buffer.render_paths.clear();
|
buffer.render_paths.clear();
|
||||||
@ -1417,7 +1466,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// store valid path
|
// store valid path
|
||||||
paths.push_back({ &buffer, i });
|
paths.push_back({ &buffer, path.first.b_id, static_cast<unsigned int>(i) });
|
||||||
|
|
||||||
m_sequential_view.endpoints.first = std::min(m_sequential_view.endpoints.first, path.first.s_id);
|
m_sequential_view.endpoints.first = std::min(m_sequential_view.endpoints.first, path.first.s_id);
|
||||||
m_sequential_view.endpoints.last = std::max(m_sequential_view.endpoints.last, path.last.s_id);
|
m_sequential_view.endpoints.last = std::max(m_sequential_view.endpoints.last, path.last.s_id);
|
||||||
@ -1434,7 +1483,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
// searches the path containing the current position
|
// searches the path containing the current position
|
||||||
for (const Path& path : buffer.paths) {
|
for (const Path& path : buffer.paths) {
|
||||||
if (path.contains(m_sequential_view.current.last)) {
|
if (path.contains(m_sequential_view.current.last)) {
|
||||||
unsigned int offset = m_sequential_view.current.last - path.first.s_id;
|
unsigned int offset = static_cast<unsigned int>(m_sequential_view.current.last - path.first.s_id);
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Line)
|
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Line)
|
||||||
offset = 2 * offset - 1;
|
offset = 2 * offset - 1;
|
||||||
@ -1443,11 +1492,11 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
offset = indices_count * (offset - 1) + (indices_count - 6);
|
offset = indices_count * (offset - 1) + (indices_count - 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
offset += path.first.i_id;
|
offset += static_cast<unsigned int>(path.first.i_id);
|
||||||
|
|
||||||
// gets the index from the index buffer on gpu
|
// gets the index from the index buffer on gpu
|
||||||
unsigned int index = 0;
|
unsigned int index = 0;
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id));
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices[path.first.b_id].id));
|
||||||
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLintptr>(offset * sizeof(unsigned int)), static_cast<GLsizeiptr>(sizeof(unsigned int)), static_cast<void*>(&index)));
|
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLintptr>(offset * sizeof(unsigned int)), static_cast<GLsizeiptr>(sizeof(unsigned int)), static_cast<void*>(&index)));
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||||
|
|
||||||
@ -1464,8 +1513,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
// second pass: filter paths by sequential data and collect them by color
|
// second pass: filter paths by sequential data and collect them by color
|
||||||
for (const auto& [buffer, id] : paths) {
|
for (const auto& [buffer, index_buffer_id, path_id] : paths) {
|
||||||
const Path& path = buffer->paths[id];
|
const Path& path = buffer->paths[path_id];
|
||||||
if (m_sequential_view.current.last <= path.first.s_id || path.last.s_id <= m_sequential_view.current.first)
|
if (m_sequential_view.current.last <= path.first.s_id || path.last.s_id <= m_sequential_view.current.first)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1477,11 +1526,14 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
default: { color = { 0.0f, 0.0f, 0.0f }; break; }
|
default: { color = { 0.0f, 0.0f, 0.0f }; break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = std::find_if(buffer->render_paths.begin(), buffer->render_paths.end(), [color](const RenderPath& path) { return path.color == color; });
|
unsigned int ibuffer_id = index_buffer_id;
|
||||||
|
auto it = std::find_if(buffer->render_paths.begin(), buffer->render_paths.end(),
|
||||||
|
[color, ibuffer_id](const RenderPath& path) { return path.index_buffer_id == ibuffer_id && path.color == color; });
|
||||||
if (it == buffer->render_paths.end()) {
|
if (it == buffer->render_paths.end()) {
|
||||||
it = buffer->render_paths.insert(buffer->render_paths.end(), RenderPath());
|
it = buffer->render_paths.insert(buffer->render_paths.end(), RenderPath());
|
||||||
it->color = color;
|
it->color = color;
|
||||||
it->path_id = id;
|
it->path_id = path_id;
|
||||||
|
it->index_buffer_id = index_buffer_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int segments_count = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1;
|
unsigned int segments_count = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1;
|
||||||
@ -1531,7 +1583,8 @@ void GCodeViewer::render_toolpaths() const
|
|||||||
shader.set_uniform("uniform_color", color4);
|
shader.set_uniform("uniform_color", color4);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto render_as_points = [this, zoom, point_size, near_plane_height, set_uniform_color](const TBuffer& buffer, EOptionsColors color_id, GLShaderProgram& shader) {
|
auto render_as_points = [this, zoom, point_size, near_plane_height, set_uniform_color]
|
||||||
|
(const TBuffer& buffer, unsigned int index_buffer_id, EOptionsColors color_id, GLShaderProgram& shader) {
|
||||||
set_uniform_color(Options_Colors[static_cast<unsigned int>(color_id)], shader);
|
set_uniform_color(Options_Colors[static_cast<unsigned int>(color_id)], shader);
|
||||||
shader.set_uniform("zoom", zoom);
|
shader.set_uniform("zoom", zoom);
|
||||||
shader.set_uniform("percent_outline_radius", 0.0f);
|
shader.set_uniform("percent_outline_radius", 0.0f);
|
||||||
@ -1543,35 +1596,41 @@ void GCodeViewer::render_toolpaths() const
|
|||||||
glsafe(::glEnable(GL_POINT_SPRITE));
|
glsafe(::glEnable(GL_POINT_SPRITE));
|
||||||
|
|
||||||
for (const RenderPath& path : buffer.render_paths) {
|
for (const RenderPath& path : buffer.render_paths) {
|
||||||
|
if (path.index_buffer_id == index_buffer_id) {
|
||||||
glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
++m_statistics.gl_multi_points_calls_count;
|
++m_statistics.gl_multi_points_calls_count;
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glsafe(::glDisable(GL_POINT_SPRITE));
|
glsafe(::glDisable(GL_POINT_SPRITE));
|
||||||
glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto render_as_lines = [this, light_intensity, set_uniform_color](const TBuffer& buffer, GLShaderProgram& shader) {
|
auto render_as_lines = [this, light_intensity, set_uniform_color](const TBuffer& buffer, unsigned int index_buffer_id, GLShaderProgram& shader) {
|
||||||
shader.set_uniform("light_intensity", light_intensity);
|
shader.set_uniform("light_intensity", light_intensity);
|
||||||
for (const RenderPath& path : buffer.render_paths) {
|
for (const RenderPath& path : buffer.render_paths) {
|
||||||
|
if (path.index_buffer_id == index_buffer_id) {
|
||||||
set_uniform_color(path.color, shader);
|
set_uniform_color(path.color, shader);
|
||||||
glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
++m_statistics.gl_multi_lines_calls_count;
|
++m_statistics.gl_multi_lines_calls_count;
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto render_as_triangles = [this, set_uniform_color](const TBuffer& buffer, GLShaderProgram& shader) {
|
auto render_as_triangles = [this, set_uniform_color](const TBuffer& buffer, unsigned int index_buffer_id, GLShaderProgram& shader) {
|
||||||
for (const RenderPath& path : buffer.render_paths) {
|
for (const RenderPath& path : buffer.render_paths) {
|
||||||
|
if (path.index_buffer_id == index_buffer_id) {
|
||||||
set_uniform_color(path.color, shader);
|
set_uniform_color(path.color, shader);
|
||||||
glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
++m_statistics.gl_multi_triangles_calls_count;
|
++m_statistics.gl_multi_triangles_calls_count;
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto line_width = [](double zoom) {
|
auto line_width = [](double zoom) {
|
||||||
@ -1585,10 +1644,7 @@ void GCodeViewer::render_toolpaths() const
|
|||||||
|
|
||||||
for (unsigned char i = begin_id; i < end_id; ++i) {
|
for (unsigned char i = begin_id; i < end_id; ++i) {
|
||||||
const TBuffer& buffer = m_buffers[i];
|
const TBuffer& buffer = m_buffers[i];
|
||||||
if (!buffer.visible)
|
if (!buffer.visible || !buffer.has_data())
|
||||||
continue;
|
|
||||||
|
|
||||||
if (buffer.vertices.id == 0 || buffer.indices.id == 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str());
|
GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str());
|
||||||
@ -1604,7 +1660,8 @@ void GCodeViewer::render_toolpaths() const
|
|||||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id));
|
for (size_t j = 0; j < buffer.indices.size(); ++j) {
|
||||||
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices[j].id));
|
||||||
|
|
||||||
switch (buffer.render_primitive_type)
|
switch (buffer.render_primitive_type)
|
||||||
{
|
{
|
||||||
@ -1620,22 +1677,23 @@ void GCodeViewer::render_toolpaths() const
|
|||||||
case EMoveType::Retract: { color = EOptionsColors::Retractions; break; }
|
case EMoveType::Retract: { color = EOptionsColors::Retractions; break; }
|
||||||
case EMoveType::Unretract: { color = EOptionsColors::Unretractions; break; }
|
case EMoveType::Unretract: { color = EOptionsColors::Unretractions; break; }
|
||||||
}
|
}
|
||||||
render_as_points(buffer, color, *shader);
|
render_as_points(buffer, static_cast<unsigned int>(j), color, *shader);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TBuffer::ERenderPrimitiveType::Line:
|
case TBuffer::ERenderPrimitiveType::Line:
|
||||||
{
|
{
|
||||||
render_as_lines(buffer, *shader);
|
render_as_lines(buffer, static_cast<unsigned int>(j), *shader);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TBuffer::ERenderPrimitiveType::Triangle:
|
case TBuffer::ERenderPrimitiveType::Triangle:
|
||||||
{
|
{
|
||||||
render_as_triangles(buffer, *shader);
|
render_as_triangles(buffer, static_cast<unsigned int>(j), *shader);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||||
|
}
|
||||||
|
|
||||||
if (has_normals)
|
if (has_normals)
|
||||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||||
@ -2237,7 +2295,7 @@ void GCodeViewer::render_legend() const
|
|||||||
auto any_option_available = [this]() {
|
auto any_option_available = [this]() {
|
||||||
auto available = [this](EMoveType type) {
|
auto available = [this](EMoveType type) {
|
||||||
const TBuffer& buffer = m_buffers[buffer_id(type)];
|
const TBuffer& buffer = m_buffers[buffer_id(type)];
|
||||||
return buffer.visible && buffer.indices.count > 0;
|
return buffer.visible && buffer.has_data();
|
||||||
};
|
};
|
||||||
|
|
||||||
return available(EMoveType::Color_change) ||
|
return available(EMoveType::Color_change) ||
|
||||||
@ -2250,7 +2308,7 @@ void GCodeViewer::render_legend() const
|
|||||||
|
|
||||||
auto add_option = [this, append_item](EMoveType move_type, EOptionsColors color, const std::string& text) {
|
auto add_option = [this, append_item](EMoveType move_type, EOptionsColors color, const std::string& text) {
|
||||||
const TBuffer& buffer = m_buffers[buffer_id(move_type)];
|
const TBuffer& buffer = m_buffers[buffer_id(move_type)];
|
||||||
if (buffer.visible && buffer.indices.count > 0)
|
if (buffer.visible && buffer.has_data())
|
||||||
append_item((buffer.shader == "options_110") ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast<unsigned int>(color)], text);
|
append_item((buffer.shader == "options_110") ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast<unsigned int>(color)], text);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2276,7 +2334,7 @@ void GCodeViewer::render_legend() const
|
|||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
void GCodeViewer::render_statistics() const
|
void GCodeViewer::render_statistics() const
|
||||||
{
|
{
|
||||||
static const float offset = 230.0f;
|
static const float offset = 250.0f;
|
||||||
|
|
||||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||||
|
|
||||||
|
@ -18,6 +18,9 @@ namespace GUI {
|
|||||||
class GCodeViewer
|
class GCodeViewer
|
||||||
{
|
{
|
||||||
using Color = std::array<float, 3>;
|
using Color = std::array<float, 3>;
|
||||||
|
using IndexBuffer = std::vector<unsigned int>;
|
||||||
|
using MultiIndexBuffer = std::vector<IndexBuffer>;
|
||||||
|
|
||||||
static const std::vector<Color> Extrusion_Role_Colors;
|
static const std::vector<Color> Extrusion_Role_Colors;
|
||||||
static const std::vector<Color> Options_Colors;
|
static const std::vector<Color> Options_Colors;
|
||||||
static const std::vector<Color> Travel_Colors;
|
static const std::vector<Color> Travel_Colors;
|
||||||
@ -112,10 +115,12 @@ class GCodeViewer
|
|||||||
{
|
{
|
||||||
struct Endpoint
|
struct Endpoint
|
||||||
{
|
{
|
||||||
// index into the indices buffer
|
// index of the index buffer
|
||||||
unsigned int i_id{ 0u };
|
unsigned int b_id{ 0 };
|
||||||
// sequential id
|
// index into the index buffer
|
||||||
unsigned int s_id{ 0u };
|
size_t i_id{ 0 };
|
||||||
|
// sequential id (index into the vertex buffer)
|
||||||
|
size_t s_id{ 0 };
|
||||||
Vec3f position{ Vec3f::Zero() };
|
Vec3f position{ Vec3f::Zero() };
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -134,14 +139,15 @@ class GCodeViewer
|
|||||||
|
|
||||||
bool matches(const GCodeProcessor::MoveVertex& move) const;
|
bool matches(const GCodeProcessor::MoveVertex& move) const;
|
||||||
size_t vertices_count() const { return last.s_id - first.s_id + 1; }
|
size_t vertices_count() const { return last.s_id - first.s_id + 1; }
|
||||||
bool contains(unsigned int id) const { return first.s_id <= id && id <= last.s_id; }
|
bool contains(size_t id) const { return first.s_id <= id && id <= last.s_id; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used to batch the indices needed to render paths
|
// Used to batch the indices needed to render paths
|
||||||
struct RenderPath
|
struct RenderPath
|
||||||
{
|
{
|
||||||
Color color;
|
Color color;
|
||||||
size_t path_id;
|
unsigned int path_id;
|
||||||
|
unsigned int index_buffer_id;
|
||||||
std::vector<unsigned int> sizes;
|
std::vector<unsigned int> sizes;
|
||||||
std::vector<size_t> offsets; // use size_t because we need an unsigned int whose size matches pointer's size (used in the call glMultiDrawElements())
|
std::vector<size_t> offsets; // use size_t because we need an unsigned int whose size matches pointer's size (used in the call glMultiDrawElements())
|
||||||
};
|
};
|
||||||
@ -158,7 +164,7 @@ class GCodeViewer
|
|||||||
|
|
||||||
ERenderPrimitiveType render_primitive_type;
|
ERenderPrimitiveType render_primitive_type;
|
||||||
VBuffer vertices;
|
VBuffer vertices;
|
||||||
IBuffer indices;
|
std::vector<IBuffer> indices;
|
||||||
|
|
||||||
std::string shader;
|
std::string shader;
|
||||||
std::vector<Path> paths;
|
std::vector<Path> paths;
|
||||||
@ -166,7 +172,10 @@ class GCodeViewer
|
|||||||
bool visible{ false };
|
bool visible{ false };
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
void add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id);
|
// 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 GCodeProcessor::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id);
|
||||||
unsigned int indices_per_segment() const {
|
unsigned int indices_per_segment() const {
|
||||||
switch (render_primitive_type)
|
switch (render_primitive_type)
|
||||||
{
|
{
|
||||||
@ -194,6 +203,8 @@ class GCodeViewer
|
|||||||
default: { return 0; }
|
default: { return 0; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_data() const { return vertices.id != 0 && !indices.empty() && indices.front().id != 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper to render shells
|
// helper to render shells
|
||||||
@ -350,8 +361,8 @@ public:
|
|||||||
|
|
||||||
struct Endpoints
|
struct Endpoints
|
||||||
{
|
{
|
||||||
unsigned int first{ 0 };
|
size_t first{ 0 };
|
||||||
unsigned int last{ 0 };
|
size_t last{ 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
Endpoints endpoints;
|
Endpoints endpoints;
|
||||||
|
Loading…
Reference in New Issue
Block a user