Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Slic3r/GUI/3DScene.pm62
-rw-r--r--lib/Slic3r/GUI/Plater/3DPreview.pm14
-rw-r--r--xs/src/slic3r/GUI/3DScene.cpp745
-rw-r--r--xs/src/slic3r/GUI/3DScene.hpp41
-rw-r--r--xs/src/slic3r/GUI/GLCanvas3D.cpp414
-rw-r--r--xs/src/slic3r/GUI/GLCanvas3D.hpp13
-rw-r--r--xs/src/slic3r/GUI/GLCanvas3DManager.cpp24
-rw-r--r--xs/src/slic3r/GUI/GLCanvas3DManager.hpp3
-rw-r--r--xs/xsp/GUI_3DScene.xsp26
9 files changed, 879 insertions, 463 deletions
diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm
index 1476e8c22..a55c4ab16 100644
--- a/lib/Slic3r/GUI/3DScene.pm
+++ b/lib/Slic3r/GUI/3DScene.pm
@@ -2199,56 +2199,36 @@ sub load_object {
return @{$volume_indices};
}
-# Create 3D thick extrusion lines for a skirt and brim.
-# Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes.
-sub load_print_toolpaths {
- my ($self, $print, $colors) = @_;
-
#==============================================================================================================================
- my $useVBOs = Slic3r::GUI::_3DScene::use_VBOs();
- $self->SetCurrent($self->GetContext) if $useVBOs;
- Slic3r::GUI::_3DScene::_load_print_toolpaths($print, $self->volumes, $colors, $useVBOs)
- if ($print->step_done(STEP_SKIRT) && $print->step_done(STEP_BRIM));
-
+## Create 3D thick extrusion lines for a skirt and brim.
+## Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes.
+#sub load_print_toolpaths {
+# my ($self, $print, $colors) = @_;
+#
# $self->SetCurrent($self->GetContext) if $self->UseVBOs;
# Slic3r::GUI::_3DScene::_load_print_toolpaths($print, $self->volumes, $colors, $self->UseVBOs)
# if ($print->step_done(STEP_SKIRT) && $print->step_done(STEP_BRIM));
-#==============================================================================================================================
-}
-
-# Create 3D thick extrusion lines for object forming extrusions.
-# Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
-# one for perimeters, one for infill and one for supports.
-sub load_print_object_toolpaths {
- my ($self, $object, $colors) = @_;
-
-#==============================================================================================================================
- my $useVBOs = Slic3r::GUI::_3DScene::use_VBOs();
- $self->SetCurrent($self->GetContext) if $useVBOs;
- Slic3r::GUI::_3DScene::_load_print_object_toolpaths($object, $self->volumes, $colors, $useVBOs);
-
+#}
+#
+## Create 3D thick extrusion lines for object forming extrusions.
+## Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
+## one for perimeters, one for infill and one for supports.
+#sub load_print_object_toolpaths {
+# my ($self, $object, $colors) = @_;
+#
# $self->SetCurrent($self->GetContext) if $self->UseVBOs;
# Slic3r::GUI::_3DScene::_load_print_object_toolpaths($object, $self->volumes, $colors, $self->UseVBOs);
-#==============================================================================================================================
-}
-
-# Create 3D thick extrusion lines for wipe tower extrusions.
-sub load_wipe_tower_toolpaths {
- my ($self, $print, $colors) = @_;
-
-#==============================================================================================================================
- my $useVBOs = Slic3r::GUI::_3DScene::use_VBOs();
- $self->SetCurrent($self->GetContext) if $useVBOs;
- Slic3r::GUI::_3DScene::_load_wipe_tower_toolpaths($print, $self->volumes, $colors, $useVBOs)
- if ($print->step_done(STEP_WIPE_TOWER));
-
+#}
+#
+## Create 3D thick extrusion lines for wipe tower extrusions.
+#sub load_wipe_tower_toolpaths {
+# my ($self, $print, $colors) = @_;
+#
# $self->SetCurrent($self->GetContext) if $self->UseVBOs;
# Slic3r::GUI::_3DScene::_load_wipe_tower_toolpaths($print, $self->volumes, $colors, $self->UseVBOs)
# if ($print->step_done(STEP_WIPE_TOWER));
-#==============================================================================================================================
-}
-
-#==============================================================================================================================
+#}
+#
#sub load_gcode_preview {
# my ($self, $print, $gcode_preview_data, $colors) = @_;
#
diff --git a/lib/Slic3r/GUI/Plater/3DPreview.pm b/lib/Slic3r/GUI/Plater/3DPreview.pm
index 9ea5069b4..7b713b46f 100644
--- a/lib/Slic3r/GUI/Plater/3DPreview.pm
+++ b/lib/Slic3r/GUI/Plater/3DPreview.pm
@@ -376,10 +376,18 @@ sub load_print {
if ($self->gcode_preview_data->empty) {
# load skirt and brim
- $self->canvas->load_print_toolpaths($self->print, \@colors);
- $self->canvas->load_wipe_tower_toolpaths($self->print, \@colors);
+#==============================================================================================================================
+ Slic3r::GUI::_3DScene::set_print($self->canvas, $self->print);
+ Slic3r::GUI::_3DScene::load_print_toolpaths($self->canvas);
+ Slic3r::GUI::_3DScene::load_wipe_tower_toolpaths($self->canvas, \@colors);
+# $self->canvas->load_print_toolpaths($self->print, \@colors);
+# $self->canvas->load_wipe_tower_toolpaths($self->print, \@colors);
+#==============================================================================================================================
foreach my $object (@{$self->print->objects}) {
- $self->canvas->load_print_object_toolpaths($object, \@colors);
+#==============================================================================================================================
+ Slic3r::GUI::_3DScene::load_print_object_toolpaths($self->canvas, $object, \@colors);
+# $self->canvas->load_print_object_toolpaths($object, \@colors);
+#==============================================================================================================================
# Show the objects in very transparent color.
#my @volume_ids = $self->canvas->load_object($object->model_object);
#$self->canvas->volumes->[$_]->color->[3] = 0.2 for @volume_ids;
diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp
index 47095e1b1..89b7d0a11 100644
--- a/xs/src/slic3r/GUI/3DScene.cpp
+++ b/xs/src/slic3r/GUI/3DScene.cpp
@@ -1348,8 +1348,11 @@ static void point_to_indexed_vertex_array(const Point3& point,
volume.push_triangle(idxs[0], idxs[3], idxs[4]);
}
-static void thick_lines_to_verts(
- const Lines &lines,
+//##################################################################################################################
+void _3DScene::thick_lines_to_verts(
+//static void thick_lines_to_verts(
+//##################################################################################################################
+ const Lines &lines,
const std::vector<double> &widths,
const std::vector<double> &heights,
bool closed,
@@ -1359,7 +1362,10 @@ static void thick_lines_to_verts(
thick_lines_to_indexed_vertex_array(lines, widths, heights, closed, top_z, volume.indexed_vertex_array);
}
-static void thick_lines_to_verts(const Lines3& lines,
+//##################################################################################################################
+void _3DScene::thick_lines_to_verts(const Lines3& lines,
+//static void thick_lines_to_verts(const Lines3& lines,
+//##################################################################################################################
const std::vector<double>& widths,
const std::vector<double>& heights,
bool closed,
@@ -2010,6 +2016,21 @@ static inline std::vector<float> parse_colors(const std::vector<std::string> &sc
}
//##################################################################################################################
+void _3DScene::load_print_toolpaths(wxGLCanvas* canvas)
+{
+ s_canvas_mgr.load_print_toolpaths(canvas);
+}
+
+void _3DScene::load_print_object_toolpaths(wxGLCanvas* canvas, const PrintObject* print_object, const std::vector<std::string>& str_tool_colors)
+{
+ s_canvas_mgr.load_print_object_toolpaths(canvas, print_object, str_tool_colors);
+}
+
+void _3DScene::load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors)
+{
+ s_canvas_mgr.load_wipe_tower_toolpaths(canvas, str_tool_colors);
+}
+
void _3DScene::load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors)
{
s_canvas_mgr.load_gcode_preview(canvas, preview_data, str_tool_colors);
@@ -2102,366 +2123,366 @@ unsigned int _3DScene::finalize_warning_texture()
return s_warning_texture.finalize();
}
-// Create 3D thick extrusion lines for a skirt and brim.
-// Adds a new Slic3r::GUI::3DScene::Volume to volumes.
-void _3DScene::_load_print_toolpaths(
- const Print *print,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors,
- bool use_VBOs)
-{
- if (!print->has_skirt() && print->config.brim_width.value == 0)
- return;
-
- const float color[] = { 0.5f, 1.0f, 0.5f, 1.f }; // greenish
-
- // number of skirt layers
- size_t total_layer_count = 0;
- for (const PrintObject *print_object : print->objects)
- total_layer_count = std::max(total_layer_count, print_object->total_layer_count());
- size_t skirt_height = print->has_infinite_skirt() ?
- total_layer_count :
- std::min<size_t>(print->config.skirt_height.value, total_layer_count);
- if (skirt_height == 0 && print->config.brim_width.value > 0)
- skirt_height = 1;
-
- // get first skirt_height layers (maybe this should be moved to a PrintObject method?)
- const PrintObject *object0 = print->objects.front();
- std::vector<float> print_zs;
- print_zs.reserve(skirt_height * 2);
- for (size_t i = 0; i < std::min(skirt_height, object0->layers.size()); ++ i)
- print_zs.push_back(float(object0->layers[i]->print_z));
- //FIXME why there are support layers?
- for (size_t i = 0; i < std::min(skirt_height, object0->support_layers.size()); ++ i)
- print_zs.push_back(float(object0->support_layers[i]->print_z));
- sort_remove_duplicates(print_zs);
- if (print_zs.size() > skirt_height)
- print_zs.erase(print_zs.begin() + skirt_height, print_zs.end());
-
- volumes->volumes.emplace_back(new GLVolume(color));
- GLVolume &volume = *volumes->volumes.back();
- for (size_t i = 0; i < skirt_height; ++ i) {
- volume.print_zs.push_back(print_zs[i]);
- volume.offsets.push_back(volume.indexed_vertex_array.quad_indices.size());
- volume.offsets.push_back(volume.indexed_vertex_array.triangle_indices.size());
- if (i == 0)
- extrusionentity_to_verts(print->brim, print_zs[i], Point(0, 0), volume);
- extrusionentity_to_verts(print->skirt, print_zs[i], Point(0, 0), volume);
- }
- volume.bounding_box = volume.indexed_vertex_array.bounding_box();
- volume.indexed_vertex_array.finalize_geometry(use_VBOs);
-}
-
-// Create 3D thick extrusion lines for object forming extrusions.
-// Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
-// one for perimeters, one for infill and one for supports.
-void _3DScene::_load_print_object_toolpaths(
- const PrintObject *print_object,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors_str,
- bool use_VBOs)
-{
- std::vector<float> tool_colors = parse_colors(tool_colors_str);
-
- struct Ctxt
- {
- const Points *shifted_copies;
- std::vector<const Layer*> layers;
- bool has_perimeters;
- bool has_infill;
- bool has_support;
- const std::vector<float>* tool_colors;
-
- // Number of vertices (each vertex is 6x4=24 bytes long)
- static const size_t alloc_size_max () { return 131072; } // 3.15MB
-// static const size_t alloc_size_max () { return 65536; } // 1.57MB
-// static const size_t alloc_size_max () { return 32768; } // 786kB
- static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
-
- static const float* color_perimeters () { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow
- static const float* color_infill () { static float color[4] = { 1.0f, 0.5f, 0.5f, 1.f }; return color; } // redish
- static const float* color_support () { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
-
- // For cloring by a tool, return a parsed color.
- bool color_by_tool() const { return tool_colors != nullptr; }
- size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; }
- const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
- int volume_idx(int extruder, int feature) const
- { return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(extruder - 1, 0)) : feature; }
- } ctxt;
-
- ctxt.shifted_copies = &print_object->_shifted_copies;
-
- // order layers by print_z
- ctxt.layers.reserve(print_object->layers.size() + print_object->support_layers.size());
- for (const Layer *layer : print_object->layers)
- ctxt.layers.push_back(layer);
- for (const Layer *layer : print_object->support_layers)
- ctxt.layers.push_back(layer);
- std::sort(ctxt.layers.begin(), ctxt.layers.end(), [](const Layer *l1, const Layer *l2) { return l1->print_z < l2->print_z; });
-
- // Maximum size of an allocation block: 32MB / sizeof(float)
- ctxt.has_perimeters = print_object->state.is_done(posPerimeters);
- ctxt.has_infill = print_object->state.is_done(posInfill);
- ctxt.has_support = print_object->state.is_done(posSupportMaterial);
- ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
-
- BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start";
-
- //FIXME Improve the heuristics for a grain size.
- size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1));
- tbb::spin_mutex new_volume_mutex;
- auto new_volume = [volumes, &new_volume_mutex](const float *color) -> GLVolume* {
- auto *volume = new GLVolume(color);
- new_volume_mutex.lock();
- volume->outside_printer_detection_enabled = false;
- volumes->volumes.emplace_back(volume);
- new_volume_mutex.unlock();
- return volume;
- };
- const size_t volumes_cnt_initial = volumes->volumes.size();
- std::vector<GLVolumeCollection> volumes_per_thread(ctxt.layers.size());
- tbb::parallel_for(
- tbb::blocked_range<size_t>(0, ctxt.layers.size(), grain_size),
- [&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
- std::vector<GLVolume*> vols;
- if (ctxt.color_by_tool()) {
- for (size_t i = 0; i < ctxt.number_tools(); ++ i)
- vols.emplace_back(new_volume(ctxt.color_tool(i)));
- } else
- vols = { new_volume(ctxt.color_perimeters()), new_volume(ctxt.color_infill()), new_volume(ctxt.color_support()) };
- for (GLVolume *vol : vols)
- vol->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
- for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
- const Layer *layer = ctxt.layers[idx_layer];
- for (size_t i = 0; i < vols.size(); ++ i) {
- GLVolume &vol = *vols[i];
- if (vol.print_zs.empty() || vol.print_zs.back() != layer->print_z) {
- vol.print_zs.push_back(layer->print_z);
- vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
- vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
- }
- }
- for (const Point &copy: *ctxt.shifted_copies) {
- for (const LayerRegion *layerm : layer->regions) {
- if (ctxt.has_perimeters)
- extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
- *vols[ctxt.volume_idx(layerm->region()->config.perimeter_extruder.value, 0)]);
- if (ctxt.has_infill) {
- for (const ExtrusionEntity *ee : layerm->fills.entities) {
- // fill represents infill extrusions of a single island.
- const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
- if (! fill->entities.empty())
- extrusionentity_to_verts(*fill, float(layer->print_z), copy,
- *vols[ctxt.volume_idx(
- is_solid_infill(fill->entities.front()->role()) ?
- layerm->region()->config.solid_infill_extruder :
- layerm->region()->config.infill_extruder,
- 1)]);
- }
- }
- }
- if (ctxt.has_support) {
- const SupportLayer *support_layer = dynamic_cast<const SupportLayer*>(layer);
- if (support_layer) {
- for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
- extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy,
- *vols[ctxt.volume_idx(
- (extrusion_entity->role() == erSupportMaterial) ?
- support_layer->object()->config.support_material_extruder :
- support_layer->object()->config.support_material_interface_extruder,
- 2)]);
- }
- }
- }
- for (size_t i = 0; i < vols.size(); ++ i) {
- GLVolume &vol = *vols[i];
- if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
- // Store the vertex arrays and restart their containers,
- vols[i] = new_volume(vol.color);
- GLVolume &vol_new = *vols[i];
- // Assign the large pre-allocated buffers to the new GLVolume.
- vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
- // Copy the content back to the old GLVolume.
- vol.indexed_vertex_array = vol_new.indexed_vertex_array;
- // Finalize a bounding box of the old GLVolume.
- vol.bounding_box = vol.indexed_vertex_array.bounding_box();
- // Clear the buffers, but keep them pre-allocated.
- vol_new.indexed_vertex_array.clear();
- // Just make sure that clear did not clear the reserved memory.
- vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
- }
- }
- }
- for (GLVolume *vol : vols) {
- vol->bounding_box = vol->indexed_vertex_array.bounding_box();
- vol->indexed_vertex_array.shrink_to_fit();
- }
- });
-
- BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results";
- // Remove empty volumes from the newly added volumes.
- volumes->volumes.erase(
- std::remove_if(volumes->volumes.begin() + volumes_cnt_initial, volumes->volumes.end(),
- [](const GLVolume *volume) { return volume->empty(); }),
- volumes->volumes.end());
- for (size_t i = volumes_cnt_initial; i < volumes->volumes.size(); ++ i)
- volumes->volumes[i]->indexed_vertex_array.finalize_geometry(use_VBOs);
-
- BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end";
-}
-
-void _3DScene::_load_wipe_tower_toolpaths(
- const Print *print,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors_str,
- bool use_VBOs)
-{
- if (print->m_wipe_tower_tool_changes.empty())
- return;
-
- std::vector<float> tool_colors = parse_colors(tool_colors_str);
-
- struct Ctxt
- {
- const Print *print;
- const std::vector<float> *tool_colors;
-
- // Number of vertices (each vertex is 6x4=24 bytes long)
- static const size_t alloc_size_max () { return 131072; } // 3.15MB
- static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
-
- static const float* color_support () { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
-
- // For cloring by a tool, return a parsed color.
- bool color_by_tool() const { return tool_colors != nullptr; }
- size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; }
- const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
- int volume_idx(int tool, int feature) const
- { return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(tool, 0)) : feature; }
-
- const std::vector<WipeTower::ToolChangeResult>& tool_change(size_t idx) {
- return priming.empty() ?
- ((idx == print->m_wipe_tower_tool_changes.size()) ? final : print->m_wipe_tower_tool_changes[idx]) :
- ((idx == 0) ? priming : (idx == print->m_wipe_tower_tool_changes.size() + 1) ? final : print->m_wipe_tower_tool_changes[idx - 1]);
- }
- std::vector<WipeTower::ToolChangeResult> priming;
- std::vector<WipeTower::ToolChangeResult> final;
- } ctxt;
-
- ctxt.print = print;
- ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
- if (print->m_wipe_tower_priming)
- ctxt.priming.emplace_back(*print->m_wipe_tower_priming.get());
- if (print->m_wipe_tower_final_purge)
- ctxt.final.emplace_back(*print->m_wipe_tower_final_purge.get());
-
- BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start";
-
- //FIXME Improve the heuristics for a grain size.
- size_t n_items = print->m_wipe_tower_tool_changes.size() + (ctxt.priming.empty() ? 0 : 1);
- size_t grain_size = std::max(n_items / 128, size_t(1));
- tbb::spin_mutex new_volume_mutex;
- auto new_volume = [volumes, &new_volume_mutex](const float *color) -> GLVolume* {
- auto *volume = new GLVolume(color);
- new_volume_mutex.lock();
- volume->outside_printer_detection_enabled = false;
- volumes->volumes.emplace_back(volume);
- new_volume_mutex.unlock();
- return volume;
- };
- const size_t volumes_cnt_initial = volumes->volumes.size();
- std::vector<GLVolumeCollection> volumes_per_thread(n_items);
- tbb::parallel_for(
- tbb::blocked_range<size_t>(0, n_items, grain_size),
- [&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
- // Bounding box of this slab of a wipe tower.
- std::vector<GLVolume*> vols;
- if (ctxt.color_by_tool()) {
- for (size_t i = 0; i < ctxt.number_tools(); ++ i)
- vols.emplace_back(new_volume(ctxt.color_tool(i)));
- } else
- vols = { new_volume(ctxt.color_support()) };
- for (GLVolume *volume : vols)
- volume->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
- for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
- const std::vector<WipeTower::ToolChangeResult> &layer = ctxt.tool_change(idx_layer);
- for (size_t i = 0; i < vols.size(); ++ i) {
- GLVolume &vol = *vols[i];
- if (vol.print_zs.empty() || vol.print_zs.back() != layer.front().print_z) {
- vol.print_zs.push_back(layer.front().print_z);
- vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
- vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
- }
- }
- for (const WipeTower::ToolChangeResult &extrusions : layer) {
- for (size_t i = 1; i < extrusions.extrusions.size();) {
- const WipeTower::Extrusion &e = extrusions.extrusions[i];
- if (e.width == 0.) {
- ++ i;
- continue;
- }
- size_t j = i + 1;
- if (ctxt.color_by_tool())
- for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].tool == e.tool && extrusions.extrusions[j].width > 0.f; ++ j) ;
- else
- for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].width > 0.f; ++ j) ;
- size_t n_lines = j - i;
- Lines lines;
- std::vector<double> widths;
- std::vector<double> heights;
- lines.reserve(n_lines);
- widths.reserve(n_lines);
- heights.assign(n_lines, extrusions.layer_height);
- for (; i < j; ++ i) {
- const WipeTower::Extrusion &e = extrusions.extrusions[i];
- assert(e.width > 0.f);
- const WipeTower::Extrusion &e_prev = *(&e - 1);
- lines.emplace_back(Point::new_scale(e_prev.pos.x, e_prev.pos.y), Point::new_scale(e.pos.x, e.pos.y));
- widths.emplace_back(e.width);
- }
- thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z,
- *vols[ctxt.volume_idx(e.tool, 0)]);
- }
- }
- }
- for (size_t i = 0; i < vols.size(); ++ i) {
- GLVolume &vol = *vols[i];
- if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
- // Store the vertex arrays and restart their containers,
- vols[i] = new_volume(vol.color);
- GLVolume &vol_new = *vols[i];
- // Assign the large pre-allocated buffers to the new GLVolume.
- vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
- // Copy the content back to the old GLVolume.
- vol.indexed_vertex_array = vol_new.indexed_vertex_array;
- // Finalize a bounding box of the old GLVolume.
- vol.bounding_box = vol.indexed_vertex_array.bounding_box();
- // Clear the buffers, but keep them pre-allocated.
- vol_new.indexed_vertex_array.clear();
- // Just make sure that clear did not clear the reserved memory.
- vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
- }
- }
- for (GLVolume *vol : vols) {
- vol->bounding_box = vol->indexed_vertex_array.bounding_box();
- vol->indexed_vertex_array.shrink_to_fit();
- }
- });
-
- BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results";
- // Remove empty volumes from the newly added volumes.
- volumes->volumes.erase(
- std::remove_if(volumes->volumes.begin() + volumes_cnt_initial, volumes->volumes.end(),
- [](const GLVolume *volume) { return volume->empty(); }),
- volumes->volumes.end());
- for (size_t i = volumes_cnt_initial; i < volumes->volumes.size(); ++ i)
- volumes->volumes[i]->indexed_vertex_array.finalize_geometry(use_VBOs);
-
- BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end";
-}
-
//##################################################################################################################
+//// Create 3D thick extrusion lines for a skirt and brim.
+//// Adds a new Slic3r::GUI::3DScene::Volume to volumes.
+//void _3DScene::_load_print_toolpaths(
+// const Print *print,
+// GLVolumeCollection *volumes,
+// const std::vector<std::string> &tool_colors,
+// bool use_VBOs)
+//{
+// if (!print->has_skirt() && print->config.brim_width.value == 0)
+// return;
+//
+// const float color[] = { 0.5f, 1.0f, 0.5f, 1.f }; // greenish
+//
+// // number of skirt layers
+// size_t total_layer_count = 0;
+// for (const PrintObject *print_object : print->objects)
+// total_layer_count = std::max(total_layer_count, print_object->total_layer_count());
+// size_t skirt_height = print->has_infinite_skirt() ?
+// total_layer_count :
+// std::min<size_t>(print->config.skirt_height.value, total_layer_count);
+// if (skirt_height == 0 && print->config.brim_width.value > 0)
+// skirt_height = 1;
+//
+// // get first skirt_height layers (maybe this should be moved to a PrintObject method?)
+// const PrintObject *object0 = print->objects.front();
+// std::vector<float> print_zs;
+// print_zs.reserve(skirt_height * 2);
+// for (size_t i = 0; i < std::min(skirt_height, object0->layers.size()); ++ i)
+// print_zs.push_back(float(object0->layers[i]->print_z));
+// //FIXME why there are support layers?
+// for (size_t i = 0; i < std::min(skirt_height, object0->support_layers.size()); ++ i)
+// print_zs.push_back(float(object0->support_layers[i]->print_z));
+// sort_remove_duplicates(print_zs);
+// if (print_zs.size() > skirt_height)
+// print_zs.erase(print_zs.begin() + skirt_height, print_zs.end());
+//
+// volumes->volumes.emplace_back(new GLVolume(color));
+// GLVolume &volume = *volumes->volumes.back();
+// for (size_t i = 0; i < skirt_height; ++ i) {
+// volume.print_zs.push_back(print_zs[i]);
+// volume.offsets.push_back(volume.indexed_vertex_array.quad_indices.size());
+// volume.offsets.push_back(volume.indexed_vertex_array.triangle_indices.size());
+// if (i == 0)
+// extrusionentity_to_verts(print->brim, print_zs[i], Point(0, 0), volume);
+// extrusionentity_to_verts(print->skirt, print_zs[i], Point(0, 0), volume);
+// }
+// volume.bounding_box = volume.indexed_vertex_array.bounding_box();
+// volume.indexed_vertex_array.finalize_geometry(use_VBOs);
+//}
+//
+//// Create 3D thick extrusion lines for object forming extrusions.
+//// Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
+//// one for perimeters, one for infill and one for supports.
+//void _3DScene::_load_print_object_toolpaths(
+// const PrintObject *print_object,
+// GLVolumeCollection *volumes,
+// const std::vector<std::string> &tool_colors_str,
+// bool use_VBOs)
+//{
+// std::vector<float> tool_colors = parse_colors(tool_colors_str);
+//
+// struct Ctxt
+// {
+// const Points *shifted_copies;
+// std::vector<const Layer*> layers;
+// bool has_perimeters;
+// bool has_infill;
+// bool has_support;
+// const std::vector<float>* tool_colors;
+//
+// // Number of vertices (each vertex is 6x4=24 bytes long)
+// static const size_t alloc_size_max () { return 131072; } // 3.15MB
+//// static const size_t alloc_size_max () { return 65536; } // 1.57MB
+//// static const size_t alloc_size_max () { return 32768; } // 786kB
+// static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
+//
+// static const float* color_perimeters () { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow
+// static const float* color_infill () { static float color[4] = { 1.0f, 0.5f, 0.5f, 1.f }; return color; } // redish
+// static const float* color_support () { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
+//
+// // For cloring by a tool, return a parsed color.
+// bool color_by_tool() const { return tool_colors != nullptr; }
+// size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; }
+// const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
+// int volume_idx(int extruder, int feature) const
+// { return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(extruder - 1, 0)) : feature; }
+// } ctxt;
+//
+// ctxt.shifted_copies = &print_object->_shifted_copies;
+//
+// // order layers by print_z
+// ctxt.layers.reserve(print_object->layers.size() + print_object->support_layers.size());
+// for (const Layer *layer : print_object->layers)
+// ctxt.layers.push_back(layer);
+// for (const Layer *layer : print_object->support_layers)
+// ctxt.layers.push_back(layer);
+// std::sort(ctxt.layers.begin(), ctxt.layers.end(), [](const Layer *l1, const Layer *l2) { return l1->print_z < l2->print_z; });
+//
+// // Maximum size of an allocation block: 32MB / sizeof(float)
+// ctxt.has_perimeters = print_object->state.is_done(posPerimeters);
+// ctxt.has_infill = print_object->state.is_done(posInfill);
+// ctxt.has_support = print_object->state.is_done(posSupportMaterial);
+// ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
+//
+// BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start";
+//
+// //FIXME Improve the heuristics for a grain size.
+// size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1));
+// tbb::spin_mutex new_volume_mutex;
+// auto new_volume = [volumes, &new_volume_mutex](const float *color) -> GLVolume* {
+// auto *volume = new GLVolume(color);
+// new_volume_mutex.lock();
+// volume->outside_printer_detection_enabled = false;
+// volumes->volumes.emplace_back(volume);
+// new_volume_mutex.unlock();
+// return volume;
+// };
+// const size_t volumes_cnt_initial = volumes->volumes.size();
+// std::vector<GLVolumeCollection> volumes_per_thread(ctxt.layers.size());
+// tbb::parallel_for(
+// tbb::blocked_range<size_t>(0, ctxt.layers.size(), grain_size),
+// [&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
+// std::vector<GLVolume*> vols;
+// if (ctxt.color_by_tool()) {
+// for (size_t i = 0; i < ctxt.number_tools(); ++ i)
+// vols.emplace_back(new_volume(ctxt.color_tool(i)));
+// } else
+// vols = { new_volume(ctxt.color_perimeters()), new_volume(ctxt.color_infill()), new_volume(ctxt.color_support()) };
+// for (GLVolume *vol : vols)
+// vol->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+// for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
+// const Layer *layer = ctxt.layers[idx_layer];
+// for (size_t i = 0; i < vols.size(); ++ i) {
+// GLVolume &vol = *vols[i];
+// if (vol.print_zs.empty() || vol.print_zs.back() != layer->print_z) {
+// vol.print_zs.push_back(layer->print_z);
+// vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
+// vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
+// }
+// }
+// for (const Point &copy: *ctxt.shifted_copies) {
+// for (const LayerRegion *layerm : layer->regions) {
+// if (ctxt.has_perimeters)
+// extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
+// *vols[ctxt.volume_idx(layerm->region()->config.perimeter_extruder.value, 0)]);
+// if (ctxt.has_infill) {
+// for (const ExtrusionEntity *ee : layerm->fills.entities) {
+// // fill represents infill extrusions of a single island.
+// const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
+// if (! fill->entities.empty())
+// extrusionentity_to_verts(*fill, float(layer->print_z), copy,
+// *vols[ctxt.volume_idx(
+// is_solid_infill(fill->entities.front()->role()) ?
+// layerm->region()->config.solid_infill_extruder :
+// layerm->region()->config.infill_extruder,
+// 1)]);
+// }
+// }
+// }
+// if (ctxt.has_support) {
+// const SupportLayer *support_layer = dynamic_cast<const SupportLayer*>(layer);
+// if (support_layer) {
+// for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
+// extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy,
+// *vols[ctxt.volume_idx(
+// (extrusion_entity->role() == erSupportMaterial) ?
+// support_layer->object()->config.support_material_extruder :
+// support_layer->object()->config.support_material_interface_extruder,
+// 2)]);
+// }
+// }
+// }
+// for (size_t i = 0; i < vols.size(); ++ i) {
+// GLVolume &vol = *vols[i];
+// if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
+// // Store the vertex arrays and restart their containers,
+// vols[i] = new_volume(vol.color);
+// GLVolume &vol_new = *vols[i];
+// // Assign the large pre-allocated buffers to the new GLVolume.
+// vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
+// // Copy the content back to the old GLVolume.
+// vol.indexed_vertex_array = vol_new.indexed_vertex_array;
+// // Finalize a bounding box of the old GLVolume.
+// vol.bounding_box = vol.indexed_vertex_array.bounding_box();
+// // Clear the buffers, but keep them pre-allocated.
+// vol_new.indexed_vertex_array.clear();
+// // Just make sure that clear did not clear the reserved memory.
+// vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+// }
+// }
+// }
+// for (GLVolume *vol : vols) {
+// vol->bounding_box = vol->indexed_vertex_array.bounding_box();
+// vol->indexed_vertex_array.shrink_to_fit();
+// }
+// });
+//
+// BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results";
+// // Remove empty volumes from the newly added volumes.
+// volumes->volumes.erase(
+// std::remove_if(volumes->volumes.begin() + volumes_cnt_initial, volumes->volumes.end(),
+// [](const GLVolume *volume) { return volume->empty(); }),
+// volumes->volumes.end());
+// for (size_t i = volumes_cnt_initial; i < volumes->volumes.size(); ++ i)
+// volumes->volumes[i]->indexed_vertex_array.finalize_geometry(use_VBOs);
+//
+// BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end";
+//}
+//
+//void _3DScene::_load_wipe_tower_toolpaths(
+// const Print *print,
+// GLVolumeCollection *volumes,
+// const std::vector<std::string> &tool_colors_str,
+// bool use_VBOs)
+//{
+// if (print->m_wipe_tower_tool_changes.empty())
+// return;
+//
+// std::vector<float> tool_colors = parse_colors(tool_colors_str);
+//
+// struct Ctxt
+// {
+// const Print *print;
+// const std::vector<float> *tool_colors;
+//
+// // Number of vertices (each vertex is 6x4=24 bytes long)
+// static const size_t alloc_size_max () { return 131072; } // 3.15MB
+// static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
+//
+// static const float* color_support () { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
+//
+// // For cloring by a tool, return a parsed color.
+// bool color_by_tool() const { return tool_colors != nullptr; }
+// size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; }
+// const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
+// int volume_idx(int tool, int feature) const
+// { return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(tool, 0)) : feature; }
+//
+// const std::vector<WipeTower::ToolChangeResult>& tool_change(size_t idx) {
+// return priming.empty() ?
+// ((idx == print->m_wipe_tower_tool_changes.size()) ? final : print->m_wipe_tower_tool_changes[idx]) :
+// ((idx == 0) ? priming : (idx == print->m_wipe_tower_tool_changes.size() + 1) ? final : print->m_wipe_tower_tool_changes[idx - 1]);
+// }
+// std::vector<WipeTower::ToolChangeResult> priming;
+// std::vector<WipeTower::ToolChangeResult> final;
+// } ctxt;
+//
+// ctxt.print = print;
+// ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
+// if (print->m_wipe_tower_priming)
+// ctxt.priming.emplace_back(*print->m_wipe_tower_priming.get());
+// if (print->m_wipe_tower_final_purge)
+// ctxt.final.emplace_back(*print->m_wipe_tower_final_purge.get());
+//
+// BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start";
+//
+// //FIXME Improve the heuristics for a grain size.
+// size_t n_items = print->m_wipe_tower_tool_changes.size() + (ctxt.priming.empty() ? 0 : 1);
+// size_t grain_size = std::max(n_items / 128, size_t(1));
+// tbb::spin_mutex new_volume_mutex;
+// auto new_volume = [volumes, &new_volume_mutex](const float *color) -> GLVolume* {
+// auto *volume = new GLVolume(color);
+// new_volume_mutex.lock();
+// volume->outside_printer_detection_enabled = false;
+// volumes->volumes.emplace_back(volume);
+// new_volume_mutex.unlock();
+// return volume;
+// };
+// const size_t volumes_cnt_initial = volumes->volumes.size();
+// std::vector<GLVolumeCollection> volumes_per_thread(n_items);
+// tbb::parallel_for(
+// tbb::blocked_range<size_t>(0, n_items, grain_size),
+// [&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
+// // Bounding box of this slab of a wipe tower.
+// std::vector<GLVolume*> vols;
+// if (ctxt.color_by_tool()) {
+// for (size_t i = 0; i < ctxt.number_tools(); ++ i)
+// vols.emplace_back(new_volume(ctxt.color_tool(i)));
+// } else
+// vols = { new_volume(ctxt.color_support()) };
+// for (GLVolume *volume : vols)
+// volume->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+// for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
+// const std::vector<WipeTower::ToolChangeResult> &layer = ctxt.tool_change(idx_layer);
+// for (size_t i = 0; i < vols.size(); ++ i) {
+// GLVolume &vol = *vols[i];
+// if (vol.print_zs.empty() || vol.print_zs.back() != layer.front().print_z) {
+// vol.print_zs.push_back(layer.front().print_z);
+// vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
+// vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
+// }
+// }
+// for (const WipeTower::ToolChangeResult &extrusions : layer) {
+// for (size_t i = 1; i < extrusions.extrusions.size();) {
+// const WipeTower::Extrusion &e = extrusions.extrusions[i];
+// if (e.width == 0.) {
+// ++ i;
+// continue;
+// }
+// size_t j = i + 1;
+// if (ctxt.color_by_tool())
+// for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].tool == e.tool && extrusions.extrusions[j].width > 0.f; ++ j) ;
+// else
+// for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].width > 0.f; ++ j) ;
+// size_t n_lines = j - i;
+// Lines lines;
+// std::vector<double> widths;
+// std::vector<double> heights;
+// lines.reserve(n_lines);
+// widths.reserve(n_lines);
+// heights.assign(n_lines, extrusions.layer_height);
+// for (; i < j; ++ i) {
+// const WipeTower::Extrusion &e = extrusions.extrusions[i];
+// assert(e.width > 0.f);
+// const WipeTower::Extrusion &e_prev = *(&e - 1);
+// lines.emplace_back(Point::new_scale(e_prev.pos.x, e_prev.pos.y), Point::new_scale(e.pos.x, e.pos.y));
+// widths.emplace_back(e.width);
+// }
+// thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z,
+// *vols[ctxt.volume_idx(e.tool, 0)]);
+// }
+// }
+// }
+// for (size_t i = 0; i < vols.size(); ++ i) {
+// GLVolume &vol = *vols[i];
+// if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
+// // Store the vertex arrays and restart their containers,
+// vols[i] = new_volume(vol.color);
+// GLVolume &vol_new = *vols[i];
+// // Assign the large pre-allocated buffers to the new GLVolume.
+// vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
+// // Copy the content back to the old GLVolume.
+// vol.indexed_vertex_array = vol_new.indexed_vertex_array;
+// // Finalize a bounding box of the old GLVolume.
+// vol.bounding_box = vol.indexed_vertex_array.bounding_box();
+// // Clear the buffers, but keep them pre-allocated.
+// vol_new.indexed_vertex_array.clear();
+// // Just make sure that clear did not clear the reserved memory.
+// vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+// }
+// }
+// for (GLVolume *vol : vols) {
+// vol->bounding_box = vol->indexed_vertex_array.bounding_box();
+// vol->indexed_vertex_array.shrink_to_fit();
+// }
+// });
+//
+// BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results";
+// // Remove empty volumes from the newly added volumes.
+// volumes->volumes.erase(
+// std::remove_if(volumes->volumes.begin() + volumes_cnt_initial, volumes->volumes.end(),
+// [](const GLVolume *volume) { return volume->empty(); }),
+// volumes->volumes.end());
+// for (size_t i = volumes_cnt_initial; i < volumes->volumes.size(); ++ i)
+// volumes->volumes[i]->indexed_vertex_array.finalize_geometry(use_VBOs);
+//
+// BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end";
+//}
+//
//void _3DScene::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors, bool use_VBOs)
//{
// // helper functions to select data in dependence of the extrusion view type
diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp
index 69530b84f..ee6547657 100644
--- a/xs/src/slic3r/GUI/3DScene.hpp
+++ b/xs/src/slic3r/GUI/3DScene.hpp
@@ -611,6 +611,9 @@ public:
//##################################################################################################################
//##################################################################################################################
+ static void load_print_toolpaths(wxGLCanvas* canvas);
+ static void load_print_object_toolpaths(wxGLCanvas* canvas, const PrintObject* print_object, const std::vector<std::string>& str_tool_colors);
+ static void load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors);
static void load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors);
// static void load_gcode_preview(const Print* print, const GCodePreviewData* preview_data, GLVolumeCollection* volumes, const std::vector<std::string>& str_tool_colors, bool use_VBOs);
//##################################################################################################################
@@ -633,25 +636,29 @@ public:
static void reset_warning_texture();
static unsigned int finalize_warning_texture();
- static void _load_print_toolpaths(
- const Print *print,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors,
- bool use_VBOs);
-
- static void _load_print_object_toolpaths(
- const PrintObject *print_object,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors,
- bool use_VBOs);
-
- static void _load_wipe_tower_toolpaths(
- const Print *print,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors_str,
- bool use_VBOs);
+//##################################################################################################################
+// static void _load_print_toolpaths(
+// const Print *print,
+// GLVolumeCollection *volumes,
+// const std::vector<std::string> &tool_colors,
+// bool use_VBOs);
+//
+// static void _load_print_object_toolpaths(
+// const PrintObject *print_object,
+// GLVolumeCollection *volumes,
+// const std::vector<std::string> &tool_colors,
+// bool use_VBOs);
+//
+// static void _load_wipe_tower_toolpaths(
+// const Print *print,
+// GLVolumeCollection *volumes,
+// const std::vector<std::string> &tool_colors_str,
+// bool use_VBOs);
+//##################################################################################################################
//##################################################################################################################
+ static void thick_lines_to_verts(const Lines& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, double top_z, GLVolume& volume);
+ static void thick_lines_to_verts(const Lines3& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, const Point& copy, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionLoop& extrusion_loop, float print_z, const Point& copy, GLVolume& volume);
diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp
index 37f1d6b50..a06079744 100644
--- a/xs/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp
@@ -13,6 +13,11 @@
#include <wx/image.h>
#include <wx/timer.h>
+#include <tbb/parallel_for.h>
+#include <tbb/spin_mutex.h>
+
+#include <boost/log/trivial.hpp>
+
#include <iostream>
#include <float.h>
@@ -1346,6 +1351,371 @@ void GLCanvas3D::set_toolpaths_range(double low, double high)
m_volumes->set_range(low, high);
}
+void GLCanvas3D::load_print_toolpaths()
+{
+ if ((m_print == nullptr) || (m_volumes == nullptr))
+ return;
+
+ if (!m_print->state.is_done(psSkirt) || !m_print->state.is_done(psBrim))
+ return;
+
+ if (!m_print->has_skirt() && (m_print->config.brim_width.value == 0))
+ return;
+
+ const float color[] = { 0.5f, 1.0f, 0.5f, 1.0f }; // greenish
+
+ // number of skirt layers
+ size_t total_layer_count = 0;
+ for (const PrintObject* print_object : m_print->objects)
+ {
+ total_layer_count = std::max(total_layer_count, print_object->total_layer_count());
+ }
+ size_t skirt_height = m_print->has_infinite_skirt() ? total_layer_count : std::min<size_t>(m_print->config.skirt_height.value, total_layer_count);
+ if ((skirt_height == 0) && (m_print->config.brim_width.value > 0))
+ skirt_height = 1;
+
+ // get first skirt_height layers (maybe this should be moved to a PrintObject method?)
+ const PrintObject* object0 = m_print->objects.front();
+ std::vector<float> print_zs;
+ print_zs.reserve(skirt_height * 2);
+ for (size_t i = 0; i < std::min(skirt_height, object0->layers.size()); ++i)
+ {
+ print_zs.push_back(float(object0->layers[i]->print_z));
+ }
+ //FIXME why there are support layers?
+ for (size_t i = 0; i < std::min(skirt_height, object0->support_layers.size()); ++i)
+ {
+ print_zs.push_back(float(object0->support_layers[i]->print_z));
+ }
+ sort_remove_duplicates(print_zs);
+ if (print_zs.size() > skirt_height)
+ print_zs.erase(print_zs.begin() + skirt_height, print_zs.end());
+
+ m_volumes->volumes.emplace_back(new GLVolume(color));
+ GLVolume& volume = *m_volumes->volumes.back();
+ for (size_t i = 0; i < skirt_height; ++i) {
+ volume.print_zs.push_back(print_zs[i]);
+ volume.offsets.push_back(volume.indexed_vertex_array.quad_indices.size());
+ volume.offsets.push_back(volume.indexed_vertex_array.triangle_indices.size());
+ if (i == 0)
+ _3DScene::extrusionentity_to_verts(m_print->brim, print_zs[i], Point(0, 0), volume);
+
+ _3DScene::extrusionentity_to_verts(m_print->skirt, print_zs[i], Point(0, 0), volume);
+ }
+ volume.bounding_box = volume.indexed_vertex_array.bounding_box();
+ volume.indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
+}
+
+void GLCanvas3D::load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors)
+{
+ std::vector<float> tool_colors = _parse_colors(str_tool_colors);
+
+ struct Ctxt
+ {
+ const Points *shifted_copies;
+ std::vector<const Layer*> layers;
+ bool has_perimeters;
+ bool has_infill;
+ bool has_support;
+ const std::vector<float>* tool_colors;
+
+ // Number of vertices (each vertex is 6x4=24 bytes long)
+ static const size_t alloc_size_max() { return 131072; } // 3.15MB
+ // static const size_t alloc_size_max () { return 65536; } // 1.57MB
+ // static const size_t alloc_size_max () { return 32768; } // 786kB
+ static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
+
+ static const float* color_perimeters() { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow
+ static const float* color_infill() { static float color[4] = { 1.0f, 0.5f, 0.5f, 1.f }; return color; } // redish
+ static const float* color_support() { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
+
+ // For cloring by a tool, return a parsed color.
+ bool color_by_tool() const { return tool_colors != nullptr; }
+ size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; }
+ const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
+ int volume_idx(int extruder, int feature) const
+ {
+ return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(extruder - 1, 0)) : feature;
+ }
+ } ctxt;
+
+ if (m_volumes == nullptr)
+ return;
+
+ ctxt.shifted_copies = &print_object._shifted_copies;
+
+ // order layers by print_z
+ ctxt.layers.reserve(print_object.layers.size() + print_object.support_layers.size());
+ for (const Layer *layer : print_object.layers)
+ ctxt.layers.push_back(layer);
+ for (const Layer *layer : print_object.support_layers)
+ ctxt.layers.push_back(layer);
+ std::sort(ctxt.layers.begin(), ctxt.layers.end(), [](const Layer *l1, const Layer *l2) { return l1->print_z < l2->print_z; });
+
+ // Maximum size of an allocation block: 32MB / sizeof(float)
+ ctxt.has_perimeters = print_object.state.is_done(posPerimeters);
+ ctxt.has_infill = print_object.state.is_done(posInfill);
+ ctxt.has_support = print_object.state.is_done(posSupportMaterial);
+ ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start";
+
+ //FIXME Improve the heuristics for a grain size.
+ size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1));
+ tbb::spin_mutex new_volume_mutex;
+ auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* {
+ auto *volume = new GLVolume(color);
+ new_volume_mutex.lock();
+ volume->outside_printer_detection_enabled = false;
+ m_volumes->volumes.emplace_back(volume);
+ new_volume_mutex.unlock();
+ return volume;
+ };
+ const size_t volumes_cnt_initial = m_volumes->volumes.size();
+ std::vector<GLVolumeCollection> volumes_per_thread(ctxt.layers.size());
+ tbb::parallel_for(
+ tbb::blocked_range<size_t>(0, ctxt.layers.size(), grain_size),
+ [&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
+ std::vector<GLVolume*> vols;
+ if (ctxt.color_by_tool()) {
+ for (size_t i = 0; i < ctxt.number_tools(); ++i)
+ vols.emplace_back(new_volume(ctxt.color_tool(i)));
+ }
+ else
+ vols = { new_volume(ctxt.color_perimeters()), new_volume(ctxt.color_infill()), new_volume(ctxt.color_support()) };
+ for (GLVolume *vol : vols)
+ vol->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+ for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) {
+ const Layer *layer = ctxt.layers[idx_layer];
+ for (size_t i = 0; i < vols.size(); ++i) {
+ GLVolume &vol = *vols[i];
+ if (vol.print_zs.empty() || vol.print_zs.back() != layer->print_z) {
+ vol.print_zs.push_back(layer->print_z);
+ vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
+ vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
+ }
+ }
+ for (const Point &copy : *ctxt.shifted_copies) {
+ for (const LayerRegion *layerm : layer->regions) {
+ if (ctxt.has_perimeters)
+ _3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
+ *vols[ctxt.volume_idx(layerm->region()->config.perimeter_extruder.value, 0)]);
+ if (ctxt.has_infill) {
+ for (const ExtrusionEntity *ee : layerm->fills.entities) {
+ // fill represents infill extrusions of a single island.
+ const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
+ if (!fill->entities.empty())
+ _3DScene::extrusionentity_to_verts(*fill, float(layer->print_z), copy,
+ *vols[ctxt.volume_idx(
+ is_solid_infill(fill->entities.front()->role()) ?
+ layerm->region()->config.solid_infill_extruder :
+ layerm->region()->config.infill_extruder,
+ 1)]);
+ }
+ }
+ }
+ if (ctxt.has_support) {
+ const SupportLayer *support_layer = dynamic_cast<const SupportLayer*>(layer);
+ if (support_layer) {
+ for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
+ _3DScene::extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy,
+ *vols[ctxt.volume_idx(
+ (extrusion_entity->role() == erSupportMaterial) ?
+ support_layer->object()->config.support_material_extruder :
+ support_layer->object()->config.support_material_interface_extruder,
+ 2)]);
+ }
+ }
+ }
+ for (size_t i = 0; i < vols.size(); ++i) {
+ GLVolume &vol = *vols[i];
+ if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
+ // Store the vertex arrays and restart their containers,
+ vols[i] = new_volume(vol.color);
+ GLVolume &vol_new = *vols[i];
+ // Assign the large pre-allocated buffers to the new GLVolume.
+ vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
+ // Copy the content back to the old GLVolume.
+ vol.indexed_vertex_array = vol_new.indexed_vertex_array;
+ // Finalize a bounding box of the old GLVolume.
+ vol.bounding_box = vol.indexed_vertex_array.bounding_box();
+ // Clear the buffers, but keep them pre-allocated.
+ vol_new.indexed_vertex_array.clear();
+ // Just make sure that clear did not clear the reserved memory.
+ vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+ }
+ }
+ }
+ for (GLVolume *vol : vols) {
+ vol->bounding_box = vol->indexed_vertex_array.bounding_box();
+ vol->indexed_vertex_array.shrink_to_fit();
+ }
+ });
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results";
+ // Remove empty volumes from the newly added volumes.
+ m_volumes->volumes.erase(
+ std::remove_if(m_volumes->volumes.begin() + volumes_cnt_initial, m_volumes->volumes.end(),
+ [](const GLVolume *volume) { return volume->empty(); }),
+ m_volumes->volumes.end());
+ for (size_t i = volumes_cnt_initial; i < m_volumes->volumes.size(); ++i)
+ m_volumes->volumes[i]->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end";
+}
+
+void GLCanvas3D::load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors)
+{
+ if ((m_volumes == nullptr) || (m_print == nullptr) || m_print->m_wipe_tower_tool_changes.empty())
+ return;
+
+ if (!m_print->state.is_done(psWipeTower))
+ return;
+
+ std::vector<float> tool_colors = _parse_colors(str_tool_colors);
+
+ struct Ctxt
+ {
+ const Print *print;
+ const std::vector<float> *tool_colors;
+
+ // Number of vertices (each vertex is 6x4=24 bytes long)
+ static const size_t alloc_size_max() { return 131072; } // 3.15MB
+ static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
+
+ static const float* color_support() { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
+
+ // For cloring by a tool, return a parsed color.
+ bool color_by_tool() const { return tool_colors != nullptr; }
+ size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; }
+ const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
+ int volume_idx(int tool, int feature) const
+ {
+ return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(tool, 0)) : feature;
+ }
+
+ const std::vector<WipeTower::ToolChangeResult>& tool_change(size_t idx) {
+ return priming.empty() ?
+ ((idx == print->m_wipe_tower_tool_changes.size()) ? final : print->m_wipe_tower_tool_changes[idx]) :
+ ((idx == 0) ? priming : (idx == print->m_wipe_tower_tool_changes.size() + 1) ? final : print->m_wipe_tower_tool_changes[idx - 1]);
+ }
+ std::vector<WipeTower::ToolChangeResult> priming;
+ std::vector<WipeTower::ToolChangeResult> final;
+ } ctxt;
+
+ ctxt.print = m_print;
+ ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
+ if (m_print->m_wipe_tower_priming)
+ ctxt.priming.emplace_back(*m_print->m_wipe_tower_priming.get());
+ if (m_print->m_wipe_tower_final_purge)
+ ctxt.final.emplace_back(*m_print->m_wipe_tower_final_purge.get());
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start";
+
+ //FIXME Improve the heuristics for a grain size.
+ size_t n_items = m_print->m_wipe_tower_tool_changes.size() + (ctxt.priming.empty() ? 0 : 1);
+ size_t grain_size = std::max(n_items / 128, size_t(1));
+ tbb::spin_mutex new_volume_mutex;
+ auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* {
+ auto *volume = new GLVolume(color);
+ new_volume_mutex.lock();
+ volume->outside_printer_detection_enabled = false;
+ m_volumes->volumes.emplace_back(volume);
+ new_volume_mutex.unlock();
+ return volume;
+ };
+ const size_t volumes_cnt_initial = m_volumes->volumes.size();
+ std::vector<GLVolumeCollection> volumes_per_thread(n_items);
+ tbb::parallel_for(
+ tbb::blocked_range<size_t>(0, n_items, grain_size),
+ [&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
+ // Bounding box of this slab of a wipe tower.
+ std::vector<GLVolume*> vols;
+ if (ctxt.color_by_tool()) {
+ for (size_t i = 0; i < ctxt.number_tools(); ++i)
+ vols.emplace_back(new_volume(ctxt.color_tool(i)));
+ }
+ else
+ vols = { new_volume(ctxt.color_support()) };
+ for (GLVolume *volume : vols)
+ volume->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+ for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) {
+ const std::vector<WipeTower::ToolChangeResult> &layer = ctxt.tool_change(idx_layer);
+ for (size_t i = 0; i < vols.size(); ++i) {
+ GLVolume &vol = *vols[i];
+ if (vol.print_zs.empty() || vol.print_zs.back() != layer.front().print_z) {
+ vol.print_zs.push_back(layer.front().print_z);
+ vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
+ vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
+ }
+ }
+ for (const WipeTower::ToolChangeResult &extrusions : layer) {
+ for (size_t i = 1; i < extrusions.extrusions.size();) {
+ const WipeTower::Extrusion &e = extrusions.extrusions[i];
+ if (e.width == 0.) {
+ ++i;
+ continue;
+ }
+ size_t j = i + 1;
+ if (ctxt.color_by_tool())
+ for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].tool == e.tool && extrusions.extrusions[j].width > 0.f; ++j);
+ else
+ for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].width > 0.f; ++j);
+ size_t n_lines = j - i;
+ Lines lines;
+ std::vector<double> widths;
+ std::vector<double> heights;
+ lines.reserve(n_lines);
+ widths.reserve(n_lines);
+ heights.assign(n_lines, extrusions.layer_height);
+ for (; i < j; ++i) {
+ const WipeTower::Extrusion &e = extrusions.extrusions[i];
+ assert(e.width > 0.f);
+ const WipeTower::Extrusion &e_prev = *(&e - 1);
+ lines.emplace_back(Point::new_scale(e_prev.pos.x, e_prev.pos.y), Point::new_scale(e.pos.x, e.pos.y));
+ widths.emplace_back(e.width);
+ }
+ _3DScene::thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z,
+ *vols[ctxt.volume_idx(e.tool, 0)]);
+ }
+ }
+ }
+ for (size_t i = 0; i < vols.size(); ++i) {
+ GLVolume &vol = *vols[i];
+ if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
+ // Store the vertex arrays and restart their containers,
+ vols[i] = new_volume(vol.color);
+ GLVolume &vol_new = *vols[i];
+ // Assign the large pre-allocated buffers to the new GLVolume.
+ vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
+ // Copy the content back to the old GLVolume.
+ vol.indexed_vertex_array = vol_new.indexed_vertex_array;
+ // Finalize a bounding box of the old GLVolume.
+ vol.bounding_box = vol.indexed_vertex_array.bounding_box();
+ // Clear the buffers, but keep them pre-allocated.
+ vol_new.indexed_vertex_array.clear();
+ // Just make sure that clear did not clear the reserved memory.
+ vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+ }
+ }
+ for (GLVolume *vol : vols) {
+ vol->bounding_box = vol->indexed_vertex_array.bounding_box();
+ vol->indexed_vertex_array.shrink_to_fit();
+ }
+ });
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results";
+ // Remove empty volumes from the newly added volumes.
+ m_volumes->volumes.erase(
+ std::remove_if(m_volumes->volumes.begin() + volumes_cnt_initial, m_volumes->volumes.end(),
+ [](const GLVolume *volume) { return volume->empty(); }),
+ m_volumes->volumes.end());
+ for (size_t i = volumes_cnt_initial; i < m_volumes->volumes.size(); ++i)
+ m_volumes->volumes[i]->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end";
+}
+
void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors)
{
if ((m_canvas != nullptr) && (m_volumes != nullptr) && (m_print != nullptr))
@@ -2416,28 +2786,6 @@ static inline int hex_digit_to_int(const char c)
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
}
-std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& colors)
-{
- std::vector<float> output(colors.size() * 4, 1.0f);
- for (size_t i = 0; i < colors.size(); ++i) {
- const std::string& color = colors[i];
- const char* c = color.data() + 1;
- if ((color.size() == 7) && (color.front() == '#'))
- {
- for (size_t j = 0; j < 3; ++j)
- {
- int digit1 = hex_digit_to_int(*c++);
- int digit2 = hex_digit_to_int(*c++);
- if ((digit1 == -1) || (digit2 == -1))
- break;
-
- output[i * 4 + j] = float(digit1 * 16 + digit2) / 255.0f;
- }
- }
- }
- return output;
-}
-
void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
{
// helper functions to select data in dependence of the extrusion view type
@@ -3008,5 +3356,27 @@ void GLCanvas3D::_update_gcode_volumes_visibility(const GCodePreviewData& previe
}
}
+std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& colors)
+{
+ std::vector<float> output(colors.size() * 4, 1.0f);
+ for (size_t i = 0; i < colors.size(); ++i) {
+ const std::string& color = colors[i];
+ const char* c = color.data() + 1;
+ if ((color.size() == 7) && (color.front() == '#'))
+ {
+ for (size_t j = 0; j < 3; ++j)
+ {
+ int digit1 = hex_digit_to_int(*c++);
+ int digit2 = hex_digit_to_int(*c++);
+ if ((digit1 == -1) || (digit2 == -1))
+ break;
+
+ output[i * 4 + j] = float(digit1 * 16 + digit2) / 255.0f;
+ }
+ }
+ }
+ return output;
+}
+
} // namespace GUI
} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp
index 69934a822..4b2f82d85 100644
--- a/xs/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp
@@ -411,6 +411,15 @@ public:
std::vector<double> get_current_print_zs(bool active_only) const;
void set_toolpaths_range(double low, double high);
+ // Create 3D thick extrusion lines for a skirt and brim.
+ // Adds a new Slic3r::GUI::3DScene::Volume to volumes.
+ void load_print_toolpaths();
+ // Create 3D thick extrusion lines for object forming extrusions.
+ // Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
+ // one for perimeters, one for infill and one for supports.
+ void load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors);
+ // Create 3D thick extrusion lines for wipe tower extrusions
+ void load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors);
void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors);
void register_on_viewport_changed_callback(void* callback);
@@ -472,8 +481,6 @@ private:
void _start_timer();
void _stop_timer();
- static std::vector<float> _parse_colors(const std::vector<std::string>& colors);
-
// generates gcode extrusion paths geometry
void _load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
// generates gcode travel paths geometry
@@ -489,6 +496,8 @@ private:
void _load_shells();
// sets gcode geometry visibility according to user selection
void _update_gcode_volumes_visibility(const GCodePreviewData& preview_data);
+
+ static std::vector<float> _parse_colors(const std::vector<std::string>& colors);
};
} // namespace GUI
diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp
index 850ccc697..3f903b9b3 100644
--- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp
+++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp
@@ -450,6 +450,30 @@ void GLCanvas3DManager::set_toolpaths_range(wxGLCanvas* canvas, double low, doub
it->second->set_toolpaths_range(low, high);
}
+void GLCanvas3DManager::load_print_toolpaths(wxGLCanvas* canvas)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->load_print_toolpaths();
+}
+
+void GLCanvas3DManager::load_print_object_toolpaths(wxGLCanvas* canvas, const PrintObject* print_object, const std::vector<std::string>& tool_colors)
+{
+ if (print_object == nullptr)
+ return;
+
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->load_print_object_toolpaths(*print_object, tool_colors);
+}
+
+void GLCanvas3DManager::load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->load_wipe_tower_toolpaths(str_tool_colors);
+}
+
void GLCanvas3DManager::load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors)
{
if (preview_data == nullptr)
diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp
index 5a874de12..0d741d550 100644
--- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp
+++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp
@@ -95,6 +95,9 @@ public:
std::vector<double> get_current_print_zs(wxGLCanvas* canvas, bool active_only) const;
void set_toolpaths_range(wxGLCanvas* canvas, double low, double high);
+ void load_print_toolpaths(wxGLCanvas* canvas);
+ void load_print_object_toolpaths(wxGLCanvas* canvas, const PrintObject* print_object, const std::vector<std::string>& tool_colors);
+ void load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors);
void load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors);
void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback);
diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp
index 8b454d3c3..f6f5134d6 100644
--- a/xs/xsp/GUI_3DScene.xsp
+++ b/xs/xsp/GUI_3DScene.xsp
@@ -511,31 +511,25 @@ reset_warning_texture()
_3DScene::reset_warning_texture();
void
-_load_print_toolpaths(print, volumes, tool_colors, use_VBOs)
- Print *print;
- GLVolumeCollection *volumes;
- std::vector<std::string> tool_colors;
- int use_VBOs;
+load_print_toolpaths(canvas)
+ SV *canvas;
CODE:
- _3DScene::_load_print_toolpaths(print, volumes, tool_colors, use_VBOs != 0);
+ _3DScene::load_print_toolpaths((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
void
-_load_print_object_toolpaths(print_object, volumes, tool_colors, use_VBOs)
- PrintObject *print_object;
- GLVolumeCollection *volumes;
+load_print_object_toolpaths(canvas, print_object, tool_colors)
+ SV *canvas;
+ PrintObject *print_object;
std::vector<std::string> tool_colors;
- int use_VBOs;
CODE:
- _3DScene::_load_print_object_toolpaths(print_object, volumes, tool_colors, use_VBOs != 0);
+ _3DScene::load_print_object_toolpaths((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), print_object, tool_colors);
void
-_load_wipe_tower_toolpaths(print, volumes, tool_colors, use_VBOs)
- Print *print;
- GLVolumeCollection *volumes;
+load_wipe_tower_toolpaths(canvas, tool_colors)
+ SV *canvas;
std::vector<std::string> tool_colors;
- int use_VBOs;
CODE:
- _3DScene::_load_wipe_tower_toolpaths(print, volumes, tool_colors, use_VBOs != 0);
+ _3DScene::load_wipe_tower_toolpaths((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), tool_colors);
void
load_gcode_preview(canvas, preview_data, str_tool_colors)