Merge remote-tracking branch 'origin/et_seams_as_batched_models'
This commit is contained in:
commit
a8a7efddc5
7 changed files with 360 additions and 16 deletions
|
@ -34,7 +34,9 @@ void main()
|
|||
float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
|
||||
|
||||
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
|
||||
vec4 world_position = vec4(v_position * vec3(vec2(i_scales.x), i_scales.y) + i_offset, 1.0);
|
||||
float width = 1.5 * i_scales.x;
|
||||
float height = 1.5 * i_scales.y;
|
||||
vec4 world_position = vec4(v_position * vec3(vec2(width), height) + i_offset - vec3(0.0, 0.0, 0.5 * i_scales.y), 1.0);
|
||||
vec3 eye_position = (gl_ModelViewMatrix * world_position).xyz;
|
||||
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
|
||||
|
||||
|
|
|
@ -37,24 +37,33 @@
|
|||
|
||||
|
||||
//====================
|
||||
// 2.4.0.alpha0 techs
|
||||
// 2.4.0.alpha1 techs
|
||||
//====================
|
||||
#define ENABLE_2_4_0_ALPHA0 1
|
||||
#define ENABLE_2_4_0_ALPHA1 1
|
||||
|
||||
// Enable delayed rendering of transparent volumes
|
||||
#define ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING (1 && ENABLE_2_4_0_ALPHA0)
|
||||
#define ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING (1 && ENABLE_2_4_0_ALPHA1)
|
||||
// Enable the fix of importing color print view from gcode files into GCodeViewer
|
||||
#define ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER (1 && ENABLE_2_4_0_ALPHA0)
|
||||
#define ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER (1 && ENABLE_2_4_0_ALPHA1)
|
||||
// Enable drawing contours, at cut level, for sinking volumes
|
||||
#define ENABLE_SINKING_CONTOURS (1 && ENABLE_2_4_0_ALPHA0)
|
||||
#define ENABLE_SINKING_CONTOURS (1 && ENABLE_2_4_0_ALPHA1)
|
||||
// Enable implementation of retract acceleration in gcode processor
|
||||
#define ENABLE_RETRACT_ACCELERATION (1 && ENABLE_2_4_0_ALPHA0)
|
||||
#define ENABLE_RETRACT_ACCELERATION (1 && ENABLE_2_4_0_ALPHA1)
|
||||
// Enable the fix for exporting and importing to/from 3mf file of mirrored volumes
|
||||
#define ENABLE_FIX_MIRRORED_VOLUMES_3MF_IMPORT_EXPORT (1 && ENABLE_2_4_0_ALPHA0)
|
||||
#define ENABLE_FIX_MIRRORED_VOLUMES_3MF_IMPORT_EXPORT (1 && ENABLE_2_4_0_ALPHA1)
|
||||
// Enable rendering seams (and other options) in preview using models
|
||||
#define ENABLE_SEAMS_USING_MODELS (1 && ENABLE_2_4_0_ALPHA0)
|
||||
#define ENABLE_SEAMS_USING_MODELS (1 && ENABLE_2_4_0_ALPHA1)
|
||||
// Enable save and save as commands to be enabled also when the plater is empty and allow to load empty projects
|
||||
#define ENABLE_SAVE_COMMANDS_ALWAYS_ENABLED (1 && ENABLE_2_4_0_ALPHA0)
|
||||
#define ENABLE_SAVE_COMMANDS_ALWAYS_ENABLED (1 && ENABLE_2_4_0_ALPHA1)
|
||||
|
||||
|
||||
//====================
|
||||
// 2.4.0.alpha2 techs
|
||||
//====================
|
||||
#define ENABLE_2_4_0_ALPHA2 1
|
||||
|
||||
// Enable rendering seams (and other options) in preview using batched models on systems not supporting OpenGL 3.3
|
||||
#define ENABLE_SEAMS_USING_BATCHED_MODELS (1 && ENABLE_SEAMS_USING_MODELS && ENABLE_2_4_0_ALPHA2)
|
||||
|
||||
|
||||
#endif // _prusaslicer_technologies_h_
|
||||
|
|
|
@ -768,6 +768,25 @@ void GCodeViewer::render()
|
|||
case EMoveType::Unretract:
|
||||
case EMoveType::Seam: {
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
if (wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) {
|
||||
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::InstancedModel;
|
||||
buffer.shader = "gouraud_light_instanced";
|
||||
buffer.model.model.init_from(diamond(16));
|
||||
buffer.model.color = option_color(type);
|
||||
buffer.model.instances.format = InstanceVBuffer::EFormat::InstancedModel;
|
||||
}
|
||||
else {
|
||||
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::BatchedModel;
|
||||
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
|
||||
buffer.shader = "gouraud_light";
|
||||
|
||||
buffer.model.data = diamond(16);
|
||||
buffer.model.color = option_color(type);
|
||||
buffer.model.instances.format = InstanceVBuffer::EFormat::BatchedModel;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
if (wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) {
|
||||
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Model;
|
||||
buffer.shader = "gouraud_light_instanced";
|
||||
|
@ -780,6 +799,7 @@ void GCodeViewer::render()
|
|||
buffer.shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110";
|
||||
}
|
||||
break;
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#else
|
||||
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Point;
|
||||
buffer.vertices.format = VBuffer::EFormat::Position;
|
||||
|
@ -1172,7 +1192,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) {
|
||||
if (prev.type != curr.type || !buffer.paths.back().matches(curr)) {
|
||||
// add starting index
|
||||
indices.push_back(static_cast<unsigned int>(indices.size()));
|
||||
indices.push_back(static_cast<IBufferType>(indices.size()));
|
||||
buffer.add_path(curr, ibuffer_id, indices.size() - 1, move_id - 1);
|
||||
buffer.paths.back().sub_paths.front().first.position = prev.position;
|
||||
}
|
||||
|
@ -1180,11 +1200,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
Path& last_path = buffer.paths.back();
|
||||
if (last_path.sub_paths.front().first.i_id != last_path.sub_paths.back().last.i_id) {
|
||||
// add previous index
|
||||
indices.push_back(static_cast<unsigned int>(indices.size()));
|
||||
indices.push_back(static_cast<IBufferType>(indices.size()));
|
||||
}
|
||||
|
||||
// add current index
|
||||
indices.push_back(static_cast<unsigned int>(indices.size()));
|
||||
indices.push_back(static_cast<IBufferType>(indices.size()));
|
||||
last_path.sub_paths.back().last = { ibuffer_id, indices.size() - 1, move_id, curr.position };
|
||||
};
|
||||
|
||||
|
@ -1387,20 +1407,63 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
};
|
||||
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
// format data into the buffers to be rendered as model
|
||||
// format data into the buffers to be rendered as instanced model
|
||||
auto add_model_instance = [](const GCodeProcessor::MoveVertex& curr, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) {
|
||||
// append position
|
||||
instances.push_back(curr.position.x());
|
||||
instances.push_back(curr.position.y());
|
||||
instances.push_back(curr.position.z());
|
||||
// append width
|
||||
instances.push_back(1.5f * curr.width);
|
||||
instances.push_back(curr.width);
|
||||
// append height
|
||||
instances.push_back(1.5f * curr.height);
|
||||
instances.push_back(curr.height);
|
||||
|
||||
// append id
|
||||
instances_ids.push_back(move_id);
|
||||
};
|
||||
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
// format data into the buffers to be rendered as batched model
|
||||
auto add_vertices_as_model_batch = [](const GCodeProcessor::MoveVertex& curr, const GLModel::InitializationData& data, VertexBuffer& vertices, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) {
|
||||
const double width = static_cast<double>(1.5f * curr.width);
|
||||
const double height = static_cast<double>(1.5f * curr.height);
|
||||
|
||||
const Transform3d trafo = Geometry::assemble_transform((curr.position - 0.5f * curr.height * Vec3f::UnitZ()).cast<double>(), Vec3d::Zero(), { width, width, height });
|
||||
const Eigen::Matrix<double, 3, 3, Eigen::DontAlign> normal_matrix = trafo.matrix().template block<3, 3>(0, 0).inverse().transpose();
|
||||
|
||||
for (const auto& entity : data.entities) {
|
||||
// append vertices
|
||||
for (size_t i = 0; i < entity.positions.size(); ++i) {
|
||||
// append position
|
||||
const Vec3d position = trafo * entity.positions[i].cast<double>();
|
||||
vertices.push_back(static_cast<float>(position.x()));
|
||||
vertices.push_back(static_cast<float>(position.y()));
|
||||
vertices.push_back(static_cast<float>(position.z()));
|
||||
|
||||
// append normal
|
||||
const Vec3d normal = normal_matrix * entity.normals[i].cast<double>();
|
||||
vertices.push_back(static_cast<float>(normal.x()));
|
||||
vertices.push_back(static_cast<float>(normal.y()));
|
||||
vertices.push_back(static_cast<float>(normal.z()));
|
||||
}
|
||||
}
|
||||
|
||||
// append instance position
|
||||
instances.push_back(curr.position.x());
|
||||
instances.push_back(curr.position.y());
|
||||
instances.push_back(curr.position.z());
|
||||
// append instance id
|
||||
instances_ids.push_back(move_id);
|
||||
};
|
||||
|
||||
auto add_indices_as_model_batch = [](const GLModel::InitializationData& data, IndexBuffer& indices, IBufferType base_index) {
|
||||
for (const auto& entity : data.entities) {
|
||||
for (size_t i = 0; i < entity.indices.size(); ++i) {
|
||||
indices.push_back(static_cast<IBufferType>(entity.indices[i] + base_index));
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
@ -1484,7 +1547,12 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
|
||||
// if adding the vertices for the current segment exceeds the threshold size of the current vertex buffer
|
||||
// add another vertex buffer
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
size_t vertices_size_to_add = (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) ? t_buffer.model.data.vertices_size_bytes() : t_buffer.max_vertices_per_segment_size_bytes();
|
||||
if (v_multibuffer.back().size() * sizeof(float) > t_buffer.vertices.max_size_bytes() - vertices_size_to_add) {
|
||||
#else
|
||||
if (v_multibuffer.back().size() * sizeof(float) > t_buffer.vertices.max_size_bytes() - t_buffer.max_vertices_per_segment_size_bytes()) {
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
v_multibuffer.push_back(VertexBuffer());
|
||||
if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) {
|
||||
Path& last_path = t_buffer.paths.back();
|
||||
|
@ -1501,6 +1569,24 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
case TBuffer::ERenderPrimitiveType::Line: { add_vertices_as_line(prev, curr, v_buffer); break; }
|
||||
case TBuffer::ERenderPrimitiveType::Triangle: { add_vertices_as_solid(prev, curr, t_buffer, static_cast<unsigned int>(v_multibuffer.size()) - 1, v_buffer, i); break; }
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
case TBuffer::ERenderPrimitiveType::InstancedModel:
|
||||
{
|
||||
add_model_instance(curr, inst_buffer, inst_id_buffer, i);
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
++m_statistics.instances_count;
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
break;
|
||||
}
|
||||
case TBuffer::ERenderPrimitiveType::BatchedModel:
|
||||
{
|
||||
add_vertices_as_model_batch(curr, t_buffer.model.data, v_buffer, inst_buffer, inst_id_buffer, i);
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
++m_statistics.batched_count;
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
break;
|
||||
}
|
||||
#else
|
||||
case TBuffer::ERenderPrimitiveType::Model:
|
||||
{
|
||||
add_model_instance(curr, inst_buffer, inst_id_buffer, i);
|
||||
|
@ -1510,6 +1596,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
break;
|
||||
}
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
}
|
||||
|
||||
// collect options zs for later use
|
||||
|
@ -1692,6 +1779,23 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
for (size_t i = 0; i < m_buffers.size(); ++i) {
|
||||
TBuffer& t_buffer = m_buffers[i];
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) {
|
||||
const InstanceBuffer& inst_buffer = instances[i];
|
||||
if (!inst_buffer.empty()) {
|
||||
t_buffer.model.instances.buffer = inst_buffer;
|
||||
t_buffer.model.instances.s_ids = instances_ids[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
const InstanceBuffer& inst_buffer = instances[i];
|
||||
if (!inst_buffer.empty()) {
|
||||
t_buffer.model.instances.buffer = inst_buffer;
|
||||
t_buffer.model.instances.s_ids = instances_ids[i];
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) {
|
||||
const InstanceBuffer& inst_buffer = instances[i];
|
||||
if (!inst_buffer.empty()) {
|
||||
|
@ -1700,6 +1804,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
}
|
||||
}
|
||||
else {
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
const MultiVertexBuffer& v_multibuffer = vertices[i];
|
||||
for (const VertexBuffer& v_buffer : v_multibuffer) {
|
||||
|
@ -1793,10 +1898,20 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
|
||||
// if adding the indices for the current segment exceeds the threshold size of the current index buffer
|
||||
// create another index buffer
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
size_t indiced_size_to_add = (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) ? t_buffer.model.data.indices_size_bytes() : t_buffer.max_indices_per_segment_size_bytes();
|
||||
if (i_multibuffer.back().size() * sizeof(IBufferType) >= IBUFFER_THRESHOLD_BYTES - indiced_size_to_add) {
|
||||
#else
|
||||
if (i_multibuffer.back().size() * sizeof(IBufferType) >= IBUFFER_THRESHOLD_BYTES - t_buffer.max_indices_per_segment_size_bytes()) {
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
i_multibuffer.push_back(IndexBuffer());
|
||||
vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]);
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point &&
|
||||
t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
#else
|
||||
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point) {
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
Path& last_path = t_buffer.paths.back();
|
||||
last_path.add_sub_path(prev, static_cast<unsigned int>(i_multibuffer.size()) - 1, 0, i - 1);
|
||||
}
|
||||
|
@ -1804,14 +1919,24 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
|
||||
// if adding the vertices for the current segment exceeds the threshold size of the current vertex buffer
|
||||
// create another index buffer
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
size_t vertices_size_to_add = (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) ? t_buffer.model.data.vertices_size_bytes() : t_buffer.max_vertices_per_segment_size_bytes();
|
||||
if (curr_vertex_buffer.second * t_buffer.vertices.vertex_size_bytes() > t_buffer.vertices.max_size_bytes() - vertices_size_to_add) {
|
||||
#else
|
||||
if (curr_vertex_buffer.second * t_buffer.vertices.vertex_size_bytes() > t_buffer.vertices.max_size_bytes() - t_buffer.max_vertices_per_segment_size_bytes()) {
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
i_multibuffer.push_back(IndexBuffer());
|
||||
|
||||
++curr_vertex_buffer.first;
|
||||
curr_vertex_buffer.second = 0;
|
||||
vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]);
|
||||
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point &&
|
||||
t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
#else
|
||||
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point) {
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
Path& last_path = t_buffer.paths.back();
|
||||
last_path.add_sub_path(prev, static_cast<unsigned int>(i_multibuffer.size()) - 1, 0, i - 1);
|
||||
}
|
||||
|
@ -1835,6 +1960,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
add_indices_as_solid(prev, curr, next, t_buffer, curr_vertex_buffer.second, static_cast<unsigned int>(i_multibuffer.size()) - 1, i_buffer, i);
|
||||
break;
|
||||
}
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
case TBuffer::ERenderPrimitiveType::BatchedModel: {
|
||||
add_indices_as_model_batch(t_buffer.model.data, i_buffer, curr_vertex_buffer.second);
|
||||
curr_vertex_buffer.second += t_buffer.model.data.vertices_count();
|
||||
break;
|
||||
}
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
default: { break; }
|
||||
}
|
||||
}
|
||||
|
@ -1849,7 +1981,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
|
|||
for (size_t i = 0; i < m_buffers.size(); ++i) {
|
||||
TBuffer& t_buffer = m_buffers[i];
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::InstancedModel) {
|
||||
#else
|
||||
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model) {
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
const MultiIndexBuffer& i_multibuffer = indices[i];
|
||||
for (const IndexBuffer& i_buffer : i_multibuffer) {
|
||||
|
@ -2125,7 +2261,12 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||
continue;
|
||||
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel ||
|
||||
buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
#else
|
||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) {
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
for (size_t id : buffer.model.instances.s_ids) {
|
||||
if (id < m_layers.get_endpoints_at(m_layers_z_range[0]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < id)
|
||||
continue;
|
||||
|
@ -2190,7 +2331,12 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||
bool found = false;
|
||||
for (const TBuffer& buffer : m_buffers) {
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel ||
|
||||
buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
#else
|
||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) {
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
for (size_t i = 0; i < buffer.model.instances.s_ids.size(); ++i) {
|
||||
if (buffer.model.instances.s_ids[i] == m_sequential_view.current.last) {
|
||||
size_t offset = i * buffer.model.instances.instance_size_floats();
|
||||
|
@ -2351,10 +2497,19 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||
}
|
||||
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
// second pass: for buffers using instanced and batched models, update the instances render ranges
|
||||
#else
|
||||
// second pass: for buffers using instanced models, update the instances render ranges
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
for (size_t b = 0; b < m_buffers.size(); ++b) {
|
||||
TBuffer& buffer = const_cast<TBuffer&>(m_buffers[b]);
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::InstancedModel &&
|
||||
buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel)
|
||||
#else
|
||||
if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Model)
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
continue;
|
||||
|
||||
buffer.model.instances.render_ranges.reset();
|
||||
|
@ -2640,6 +2795,66 @@ void GCodeViewer::render_toolpaths()
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
auto render_as_batched_model = [this](TBuffer& buffer, GLShaderProgram& shader) {
|
||||
#else
|
||||
auto render_as_batched_model = [](TBuffer& buffer, GLShaderProgram& shader) {
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
||||
struct Range
|
||||
{
|
||||
unsigned int first;
|
||||
unsigned int last;
|
||||
bool intersects(const Range& other) const { return (other.last < first || other.first > last) ? false : true; }
|
||||
};
|
||||
Range buffer_range = { 0, 0 };
|
||||
size_t indices_per_instance = buffer.model.data.indices_count();
|
||||
|
||||
for (size_t j = 0; j < buffer.indices.size(); ++j) {
|
||||
const IBuffer& i_buffer = buffer.indices[j];
|
||||
buffer_range.last = buffer_range.first + i_buffer.count / indices_per_instance;
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
|
||||
glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
bool has_normals = buffer.vertices.normal_size_floats() > 0;
|
||||
if (has_normals) {
|
||||
glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
}
|
||||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
|
||||
|
||||
for (auto& range : buffer.model.instances.render_ranges.ranges) {
|
||||
Range range_range = { range.offset, range.offset + range.count };
|
||||
if (range_range.intersects(buffer_range)) {
|
||||
shader.set_uniform("uniform_color", range.color);
|
||||
unsigned int offset = (range_range.first > buffer_range.first) ? range_range.first - buffer_range.first : 0;
|
||||
size_t offset_bytes = static_cast<size_t>(offset) * indices_per_instance * sizeof(IBufferType);
|
||||
Range render_range = { std::max(range_range.first, buffer_range.first), std::min(range_range.last, buffer_range.last) };
|
||||
size_t count = static_cast<size_t>(render_range.last - render_range.first) * indices_per_instance;
|
||||
if (count > 0) {
|
||||
glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)count, GL_UNSIGNED_SHORT, (const void*)offset_bytes));
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
++m_statistics.gl_batched_models_calls_count;
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
|
||||
if (has_normals)
|
||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
|
||||
buffer_range.first = buffer_range.last;
|
||||
}
|
||||
};
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
|
||||
auto line_width = [](double zoom) {
|
||||
|
@ -2663,11 +2878,22 @@ void GCodeViewer::render_toolpaths()
|
|||
shader->start_using();
|
||||
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) {
|
||||
#else
|
||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Model) {
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
shader->set_uniform("emission_factor", 0.25f);
|
||||
render_as_instanced_model(buffer, *shader);
|
||||
shader->set_uniform("emission_factor", 0.0f);
|
||||
}
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
shader->set_uniform("emission_factor", 0.25f);
|
||||
render_as_batched_model(buffer, *shader);
|
||||
shader->set_uniform("emission_factor", 0.0f);
|
||||
}
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
else {
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
for (size_t j = 0; j < buffer.indices.size(); ++j) {
|
||||
|
@ -2833,6 +3059,7 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||
}
|
||||
case EItemType::Circle: {
|
||||
ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size));
|
||||
#if !ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
if (m_buffers[buffer_id(EMoveType::Retract)].shader == "options_120") {
|
||||
draw_list->AddCircleFilled(center, 0.5f * icon_size,
|
||||
ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16);
|
||||
|
@ -2842,6 +3069,7 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||
draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16);
|
||||
}
|
||||
else
|
||||
#endif // !ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16);
|
||||
|
||||
break;
|
||||
|
@ -3487,7 +3715,11 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||
auto add_option = [this, append_item](EMoveType move_type, EOptionsColors color, const std::string& text) {
|
||||
const TBuffer& buffer = m_buffers[buffer_id(move_type)];
|
||||
if (buffer.visible && buffer.has_data())
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
append_item(EItemType::Circle, Options_Colors[static_cast<unsigned int>(color)], text);
|
||||
#else
|
||||
append_item((buffer.shader == "options_110") ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast<unsigned int>(color)], text);
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
};
|
||||
|
||||
// options section
|
||||
|
@ -3707,7 +3939,11 @@ void GCodeViewer::render_statistics()
|
|||
add_counter(std::string("Multi GL_TRIANGLES:"), m_statistics.gl_multi_triangles_calls_count);
|
||||
add_counter(std::string("GL_TRIANGLES:"), m_statistics.gl_triangles_calls_count);
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
ImGui::Separator();
|
||||
add_counter(std::string("Instanced models:"), m_statistics.gl_instanced_models_calls_count);
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
add_counter(std::string("Batched models:"), m_statistics.gl_batched_models_calls_count);
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
}
|
||||
|
||||
|
@ -3739,6 +3975,9 @@ void GCodeViewer::render_statistics()
|
|||
add_counter(std::string("Extrude segments count:"), m_statistics.extrude_segments_count);
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
add_counter(std::string("Instances count:"), m_statistics.instances_count);
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
add_counter(std::string("Batched count:"), m_statistics.batched_count);
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
ImGui::Separator();
|
||||
add_counter(std::string("VBuffers count:"), m_statistics.vbuffers_count);
|
||||
|
|
|
@ -105,9 +105,16 @@ class GCodeViewer
|
|||
};
|
||||
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
// 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
|
||||
#else
|
||||
// buffer containing instances data used to render a toolpaths using instanced models
|
||||
// instance record format: 5 floats -> position.x|position.y|position.z|width|height
|
||||
// which is sent to the shader as -> vec3 (offset) + vec2 (scales) in GLModel::render_instanced()
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
struct InstanceVBuffer
|
||||
{
|
||||
// ranges used to render only subparts of the intances
|
||||
|
@ -130,6 +137,16 @@ class GCodeViewer
|
|||
void reset();
|
||||
};
|
||||
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
enum class EFormat : unsigned char
|
||||
{
|
||||
InstancedModel,
|
||||
BatchedModel
|
||||
};
|
||||
|
||||
EFormat format;
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
|
||||
// cpu-side buffer containing all instances data
|
||||
InstanceBuffer buffer;
|
||||
// indices of the moves for all instances
|
||||
|
@ -138,7 +155,18 @@ class GCodeViewer
|
|||
|
||||
size_t data_size_bytes() const { return s_ids.size() * instance_size_bytes(); }
|
||||
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
size_t instance_size_floats() const {
|
||||
switch (format)
|
||||
{
|
||||
case EFormat::InstancedModel: { return 5; }
|
||||
case EFormat::BatchedModel: { return 3; }
|
||||
default: { return 0; }
|
||||
}
|
||||
}
|
||||
#else
|
||||
size_t instance_size_floats() const { return 5; }
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
size_t instance_size_bytes() const { return instance_size_floats() * sizeof(float); }
|
||||
|
||||
void reset();
|
||||
|
@ -280,7 +308,12 @@ class GCodeViewer
|
|||
Line,
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
Triangle,
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
InstancedModel,
|
||||
BatchedModel
|
||||
#else
|
||||
Model
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#else
|
||||
Triangle
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
|
@ -298,6 +331,9 @@ class GCodeViewer
|
|||
GLModel model;
|
||||
Color color;
|
||||
InstanceVBuffer instances;
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
GLModel::InitializationData data;
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
@ -362,7 +398,15 @@ class GCodeViewer
|
|||
case ERenderPrimitiveType::Triangle: {
|
||||
return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0;
|
||||
}
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
case ERenderPrimitiveType::InstancedModel: { return model.model.is_initialized() && !model.instances.buffer.empty(); }
|
||||
case ERenderPrimitiveType::BatchedModel: {
|
||||
return model.data.vertices_count() > 0 && model.data.indices_count() &&
|
||||
!vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0;
|
||||
}
|
||||
#else
|
||||
case ERenderPrimitiveType::Model: { return model.model.is_initialized() && !model.instances.buffer.empty(); }
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
default: { return false; }
|
||||
}
|
||||
}
|
||||
|
@ -520,6 +564,9 @@ class GCodeViewer
|
|||
int64_t gl_triangles_calls_count{ 0 };
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
int64_t gl_instanced_models_calls_count{ 0 };
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
int64_t gl_batched_models_calls_count{ 0 };
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
// memory
|
||||
int64_t results_size{ 0 };
|
||||
|
@ -541,6 +588,9 @@ class GCodeViewer
|
|||
int64_t extrude_segments_count{ 0 };
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
int64_t instances_count{ 0 };
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
int64_t batched_count{ 0 };
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
int64_t vbuffers_count{ 0 };
|
||||
int64_t ibuffers_count{ 0 };
|
||||
|
@ -569,6 +619,9 @@ class GCodeViewer
|
|||
gl_triangles_calls_count = 0;
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
gl_instanced_models_calls_count = 0;
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
gl_batched_models_calls_count = 0;
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
}
|
||||
|
||||
|
@ -594,6 +647,9 @@ class GCodeViewer
|
|||
extrude_segments_count = 0;
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
instances_count = 0;
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
batched_count = 0;
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
vbuffers_count = 0;
|
||||
ibuffers_count = 0;
|
||||
|
|
|
@ -19,6 +19,26 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
size_t GLModel::InitializationData::vertices_count() const
|
||||
{
|
||||
size_t ret = 0;
|
||||
for (const Entity& entity : entities) {
|
||||
ret += entity.positions.size();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t GLModel::InitializationData::indices_count() const
|
||||
{
|
||||
size_t ret = 0;
|
||||
for (const Entity& entity : entities) {
|
||||
ret += entity.indices.size();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
|
||||
void GLModel::init_from(const InitializationData& data)
|
||||
{
|
||||
if (!m_render_data.empty()) // call reset() if you want to reuse this model
|
||||
|
|
|
@ -48,6 +48,15 @@ namespace GUI {
|
|||
};
|
||||
|
||||
std::vector<Entity> entities;
|
||||
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
size_t vertices_count() const;
|
||||
size_t vertices_size_floats() const { return vertices_count() * 6; }
|
||||
size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); }
|
||||
|
||||
size_t indices_count() const;
|
||||
size_t indices_size_bytes() const { return indices_count() * sizeof(unsigned int); }
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -33,11 +33,19 @@ std::pair<bool, std::string> GLShadersManager::init()
|
|||
|
||||
bool valid = true;
|
||||
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview
|
||||
#else
|
||||
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" });
|
||||
// used to render printbed
|
||||
valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" });
|
||||
// used to render options in gcode preview
|
||||
#if ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3))
|
||||
valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" });
|
||||
#else
|
||||
#if ENABLE_SEAMS_USING_MODELS
|
||||
if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3))
|
||||
valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" });
|
||||
|
@ -49,6 +57,7 @@ std::pair<bool, std::string> GLShadersManager::init()
|
|||
#if ENABLE_SEAMS_USING_MODELS
|
||||
}
|
||||
#endif // ENABLE_SEAMS_USING_MODELS
|
||||
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
|
||||
// used to render extrusion and travel paths as lines in gcode preview
|
||||
valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" });
|
||||
// used to render objects in 3d editor
|
||||
|
|
Loading…
Reference in a new issue