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:
Diffstat (limited to 'xs/src/slic3r/GUI/3DScene.cpp')
-rw-r--r--xs/src/slic3r/GUI/3DScene.cpp1241
1 files changed, 316 insertions, 925 deletions
diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp
index cb2e08e1f..09e10ac28 100644
--- a/xs/src/slic3r/GUI/3DScene.cpp
+++ b/xs/src/slic3r/GUI/3DScene.cpp
@@ -433,6 +433,7 @@ std::vector<int> GLVolumeCollection::load_object(
v.extruder_id = extruder_id;
}
v.is_modifier = model_volume->modifier;
+ v.outside_printer_detection_enabled = !model_volume->modifier;
}
}
@@ -663,7 +664,7 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config)
bool contained = true;
for (GLVolume* volume : this->volumes)
{
- if (volume != nullptr)
+ if ((volume != nullptr) && !volume->is_modifier)
{
bool state = print_volume.contains(volume->transformed_bounding_box());
contained &= state;
@@ -1348,8 +1349,8 @@ 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(
+ const Lines &lines,
const std::vector<double> &widths,
const std::vector<double> &heights,
bool closed,
@@ -1359,7 +1360,7 @@ 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,
const std::vector<double>& widths,
const std::vector<double>& heights,
bool closed,
@@ -1377,7 +1378,7 @@ static void thick_point_to_verts(const Point3& point,
}
// Fill in the qverts and tverts with quads and triangles for the extrusion_path.
-static inline void extrusionentity_to_verts(const ExtrusionPath &extrusion_path, float print_z, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionPath &extrusion_path, float print_z, GLVolume &volume)
{
Lines lines = extrusion_path.polyline.lines();
std::vector<double> widths(lines.size(), extrusion_path.width);
@@ -1386,7 +1387,7 @@ static inline void extrusionentity_to_verts(const ExtrusionPath &extrusion_path,
}
// Fill in the qverts and tverts with quads and triangles for the extrusion_path.
-static inline void extrusionentity_to_verts(const ExtrusionPath &extrusion_path, float print_z, const Point &copy, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionPath &extrusion_path, float print_z, const Point &copy, GLVolume &volume)
{
Polyline polyline = extrusion_path.polyline;
polyline.remove_duplicate_points();
@@ -1398,7 +1399,7 @@ static inline void extrusionentity_to_verts(const ExtrusionPath &extrusion_path,
}
// Fill in the qverts and tverts with quads and triangles for the extrusion_loop.
-static inline void extrusionentity_to_verts(const ExtrusionLoop &extrusion_loop, float print_z, const Point &copy, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionLoop &extrusion_loop, float print_z, const Point &copy, GLVolume &volume)
{
Lines lines;
std::vector<double> widths;
@@ -1416,7 +1417,7 @@ static inline void extrusionentity_to_verts(const ExtrusionLoop &extrusion_loop,
}
// Fill in the qverts and tverts with quads and triangles for the extrusion_multi_path.
-static inline void extrusionentity_to_verts(const ExtrusionMultiPath &extrusion_multi_path, float print_z, const Point &copy, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionMultiPath &extrusion_multi_path, float print_z, const Point &copy, GLVolume &volume)
{
Lines lines;
std::vector<double> widths;
@@ -1433,15 +1434,13 @@ static inline void extrusionentity_to_verts(const ExtrusionMultiPath &extrusion_
thick_lines_to_verts(lines, widths, heights, false, print_z, volume);
}
-static void extrusionentity_to_verts(const ExtrusionEntity *extrusion_entity, float print_z, const Point &copy, GLVolume &volume);
-
-static inline void extrusionentity_to_verts(const ExtrusionEntityCollection &extrusion_entity_collection, float print_z, const Point &copy, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionEntityCollection &extrusion_entity_collection, float print_z, const Point &copy, GLVolume &volume)
{
for (const ExtrusionEntity *extrusion_entity : extrusion_entity_collection.entities)
extrusionentity_to_verts(extrusion_entity, print_z, copy, volume);
}
-static void extrusionentity_to_verts(const ExtrusionEntity *extrusion_entity, float print_z, const Point &copy, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionEntity *extrusion_entity, float print_z, const Point &copy, GLVolume &volume)
{
if (extrusion_entity != nullptr) {
auto *extrusion_path = dynamic_cast<const ExtrusionPath*>(extrusion_entity);
@@ -1468,7 +1467,7 @@ static void extrusionentity_to_verts(const ExtrusionEntity *extrusion_entity, fl
}
}
-static void polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume)
+void _3DScene::polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume)
{
Lines3 lines = polyline.lines();
std::vector<double> widths(lines.size(), width);
@@ -1476,14 +1475,14 @@ static void polyline3_to_verts(const Polyline3& polyline, double width, double h
thick_lines_to_verts(lines, widths, heights, false, volume);
}
-static void point3_to_verts(const Point3& point, double width, double height, GLVolume& volume)
+void _3DScene::point3_to_verts(const Point3& point, double width, double height, GLVolume& volume)
{
thick_point_to_verts(point, width, height, volume);
}
-_3DScene::GCodePreviewVolumeIndex _3DScene::s_gcode_preview_volume_index;
_3DScene::LegendTexture _3DScene::s_legend_texture;
_3DScene::WarningTexture _3DScene::s_warning_texture;
+GUI::GLCanvas3DManager _3DScene::s_canvas_mgr;
unsigned int _3DScene::TextureBase::finalize()
{
@@ -1720,1049 +1719,441 @@ bool _3DScene::LegendTexture::generate(const GCodePreviewData& preview_data, con
return true;
}
-void _3DScene::_glew_init()
-{
- glewInit();
+void _3DScene::init_gl()
+{
+ s_canvas_mgr.init_gl();
}
-static inline int hex_digit_to_int(const char c)
+std::string _3DScene::get_gl_info(bool format_as_html, bool extensions)
{
- return
- (c >= '0' && c <= '9') ? int(c - '0') :
- (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
- (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
+ return s_canvas_mgr.get_gl_info(format_as_html, extensions);
}
-static inline std::vector<float> parse_colors(const std::vector<std::string> &scolors)
+bool _3DScene::use_VBOs()
{
- std::vector<float> output(scolors.size() * 4, 1.f);
- for (size_t i = 0; i < scolors.size(); ++ i) {
- const std::string &scolor = scolors[i];
- const char *c = scolor.data() + 1;
- if (scolor.size() == 7 && scolor.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.f;
- }
- }
- }
- return output;
+ return s_canvas_mgr.use_VBOs();
}
-void _3DScene::load_gcode_preview(const Print* print, const GCodePreviewData* preview_data, GLVolumeCollection* volumes, const std::vector<std::string>& str_tool_colors, bool use_VBOs)
+bool _3DScene::add_canvas(wxGLCanvas* canvas)
{
- if ((preview_data == nullptr) || (volumes == nullptr))
- return;
-
- if (volumes->empty())
- {
- std::vector<float> tool_colors = parse_colors(str_tool_colors);
-
- s_gcode_preview_volume_index.reset();
-
- _load_gcode_extrusion_paths(*preview_data, *volumes, tool_colors, use_VBOs);
- _load_gcode_travel_paths(*preview_data, *volumes, tool_colors, use_VBOs);
- _load_gcode_retractions(*preview_data, *volumes, use_VBOs);
- _load_gcode_unretractions(*preview_data, *volumes, use_VBOs);
-
- if (volumes->empty())
- reset_legend_texture();
- else
- {
- _generate_legend_texture(*preview_data, tool_colors);
-
- // removes empty volumes
- volumes->volumes.erase(std::remove_if(volumes->volumes.begin(), volumes->volumes.end(),
- [](const GLVolume *volume) { return volume->print_zs.empty(); }),
- volumes->volumes.end());
-
- _load_shells(*print, *volumes, use_VBOs);
- }
- }
-
- _update_gcode_volumes_visibility(*preview_data, *volumes);
+ return s_canvas_mgr.add(canvas);
}
-unsigned int _3DScene::get_legend_texture_width()
+bool _3DScene::remove_canvas(wxGLCanvas* canvas)
{
- return s_legend_texture.get_texture_width();
+ return s_canvas_mgr.remove(canvas);
}
-unsigned int _3DScene::get_legend_texture_height()
+void _3DScene::remove_all_canvases()
{
- return s_legend_texture.get_texture_height();
+ s_canvas_mgr.remove_all();
}
-void _3DScene::reset_legend_texture()
+bool _3DScene::init(wxGLCanvas* canvas)
{
- s_legend_texture.reset_texture();
+ return s_canvas_mgr.init(canvas);
}
-unsigned int _3DScene::finalize_legend_texture()
+void _3DScene::set_as_dirty(wxGLCanvas* canvas)
{
- return s_legend_texture.finalize();
+ s_canvas_mgr.set_as_dirty(canvas);
}
-unsigned int _3DScene::get_warning_texture_width()
+unsigned int _3DScene::get_volumes_count(wxGLCanvas* canvas)
{
- return s_warning_texture.get_texture_width();
+ return s_canvas_mgr.get_volumes_count(canvas);
}
-unsigned int _3DScene::get_warning_texture_height()
+void _3DScene::reset_volumes(wxGLCanvas* canvas)
{
- return s_warning_texture.get_texture_height();
+ s_canvas_mgr.reset_volumes(canvas);
}
-void _3DScene::generate_warning_texture(const std::string& msg)
+void _3DScene::deselect_volumes(wxGLCanvas* canvas)
{
- s_warning_texture.generate(msg);
+ s_canvas_mgr.deselect_volumes(canvas);
}
-void _3DScene::reset_warning_texture()
+void _3DScene::select_volume(wxGLCanvas* canvas, unsigned int id)
{
- s_warning_texture.reset_texture();
+ s_canvas_mgr.select_volume(canvas, id);
}
-unsigned int _3DScene::finalize_warning_texture()
+void _3DScene::update_volumes_selection(wxGLCanvas* canvas, const std::vector<int>& selections)
{
- return s_warning_texture.finalize();
+ s_canvas_mgr.update_volumes_selection(canvas, selections);
}
-// 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)
+bool _3DScene::check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config)
{
- 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);
+ return s_canvas_mgr.check_volumes_outside_state(canvas, config);
}
-// 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)
+bool _3DScene::move_volume_up(wxGLCanvas* canvas, unsigned int id)
{
- 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";
+ return s_canvas_mgr.move_volume_up(canvas, id);
}
-void _3DScene::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors, bool use_VBOs)
+bool _3DScene::move_volume_down(wxGLCanvas* canvas, unsigned int id)
{
- // helper functions to select data in dependence of the extrusion view type
- struct Helper
- {
- static float path_filter(GCodePreviewData::Extrusion::EViewType type, const ExtrusionPath& path)
- {
- switch (type)
- {
- case GCodePreviewData::Extrusion::FeatureType:
- return (float)path.role();
- case GCodePreviewData::Extrusion::Height:
- return path.height;
- case GCodePreviewData::Extrusion::Width:
- return path.width;
- case GCodePreviewData::Extrusion::Feedrate:
- return path.feedrate;
- case GCodePreviewData::Extrusion::VolumetricRate:
- return path.feedrate * (float)path.mm3_per_mm;
- case GCodePreviewData::Extrusion::Tool:
- return (float)path.extruder_id;
- }
-
- return 0.0f;
- }
-
- static GCodePreviewData::Color path_color(const GCodePreviewData& data, const std::vector<float>& tool_colors, float value)
- {
- switch (data.extrusion.view_type)
- {
- case GCodePreviewData::Extrusion::FeatureType:
- return data.get_extrusion_role_color((ExtrusionRole)(int)value);
- case GCodePreviewData::Extrusion::Height:
- return data.get_height_color(value);
- case GCodePreviewData::Extrusion::Width:
- return data.get_width_color(value);
- case GCodePreviewData::Extrusion::Feedrate:
- return data.get_feedrate_color(value);
- case GCodePreviewData::Extrusion::VolumetricRate:
- return data.get_volumetric_rate_color(value);
- case GCodePreviewData::Extrusion::Tool:
- {
- GCodePreviewData::Color color;
- ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + (unsigned int)value * 4), 4 * sizeof(float));
- return color;
- }
- }
-
- return GCodePreviewData::Color::Dummy;
- }
- };
-
- // Helper structure for filters
- struct Filter
- {
- float value;
- ExtrusionRole role;
- GLVolume* volume;
-
- Filter(float value, ExtrusionRole role)
- : value(value)
- , role(role)
- , volume(nullptr)
- {
- }
-
- bool operator == (const Filter& other) const
- {
- if (value != other.value)
- return false;
-
- if (role != other.role)
- return false;
-
- return true;
- }
- };
+ return s_canvas_mgr.move_volume_down(canvas, id);
+}
- typedef std::vector<Filter> FiltersList;
- size_t initial_volumes_count = volumes.volumes.size();
+void _3DScene::set_objects_selections(wxGLCanvas* canvas, const std::vector<int>& selections)
+{
+ s_canvas_mgr.set_objects_selections(canvas, selections);
+}
- // detects filters
- FiltersList filters;
- for (const GCodePreviewData::Extrusion::Layer& layer : preview_data.extrusion.layers)
- {
- for (const ExtrusionPath& path : layer.paths)
- {
- ExtrusionRole role = path.role();
- float path_filter = Helper::path_filter(preview_data.extrusion.view_type, path);
- if (std::find(filters.begin(), filters.end(), Filter(path_filter, role)) == filters.end())
- filters.emplace_back(path_filter, role);
- }
- }
+void _3DScene::set_config(wxGLCanvas* canvas, DynamicPrintConfig* config)
+{
+ s_canvas_mgr.set_config(canvas, config);
+}
- // nothing to render, return
- if (filters.empty())
- return;
+void _3DScene::set_print(wxGLCanvas* canvas, Print* print)
+{
+ s_canvas_mgr.set_print(canvas, print);
+}
- // creates a new volume for each filter
- for (Filter& filter : filters)
- {
- s_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Extrusion, (unsigned int)filter.role, (unsigned int)volumes.volumes.size());
- GLVolume* volume = new GLVolume(Helper::path_color(preview_data, tool_colors, filter.value).rgba);
- if (volume != nullptr)
- {
- filter.volume = volume;
- volumes.volumes.emplace_back(volume);
- }
- else
- {
- // an error occourred - restore to previous state and return
- s_gcode_preview_volume_index.first_volumes.pop_back();
- if (initial_volumes_count != volumes.volumes.size())
- {
- std::vector<GLVolume*>::iterator begin = volumes.volumes.begin() + initial_volumes_count;
- std::vector<GLVolume*>::iterator end = volumes.volumes.end();
- for (std::vector<GLVolume*>::iterator it = begin; it < end; ++it)
- {
- GLVolume* volume = *it;
- delete volume;
- }
- volumes.volumes.erase(begin, end);
- return;
- }
- }
- }
+void _3DScene::set_model(wxGLCanvas* canvas, Model* model)
+{
+ s_canvas_mgr.set_model(canvas, model);
+}
- // populates volumes
- for (const GCodePreviewData::Extrusion::Layer& layer : preview_data.extrusion.layers)
- {
- for (const ExtrusionPath& path : layer.paths)
- {
- float path_filter = Helper::path_filter(preview_data.extrusion.view_type, path);
- FiltersList::iterator filter = std::find(filters.begin(), filters.end(), Filter(path_filter, path.role()));
- if (filter != filters.end())
- {
- filter->volume->print_zs.push_back(layer.z);
- filter->volume->offsets.push_back(filter->volume->indexed_vertex_array.quad_indices.size());
- filter->volume->offsets.push_back(filter->volume->indexed_vertex_array.triangle_indices.size());
+void _3DScene::set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape)
+{
+ return s_canvas_mgr.set_bed_shape(canvas, shape);
+}
- extrusionentity_to_verts(path, layer.z, *filter->volume);
- }
- }
- }
+void _3DScene::set_auto_bed_shape(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.set_auto_bed_shape(canvas);
+}
- // finalize volumes and sends geometry to gpu
- if (volumes.volumes.size() > initial_volumes_count)
- {
- for (size_t i = initial_volumes_count; i < volumes.volumes.size(); ++i)
- {
- GLVolume* volume = volumes.volumes[i];
- volume->bounding_box = volume->indexed_vertex_array.bounding_box();
- volume->indexed_vertex_array.finalize_geometry(use_VBOs);
- }
- }
+BoundingBoxf3 _3DScene::get_volumes_bounding_box(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.get_volumes_bounding_box(canvas);
}
-void _3DScene::_load_gcode_travel_paths(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors, bool use_VBOs)
+void _3DScene::set_axes_length(wxGLCanvas* canvas, float length)
{
- size_t initial_volumes_count = volumes.volumes.size();
- s_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Travel, 0, (unsigned int)initial_volumes_count);
+ s_canvas_mgr.set_axes_length(canvas, length);
+}
- bool res = true;
- switch (preview_data.extrusion.view_type)
- {
- case GCodePreviewData::Extrusion::Feedrate:
- {
- res = _travel_paths_by_feedrate(preview_data, volumes);
- break;
- }
- case GCodePreviewData::Extrusion::Tool:
- {
- res = _travel_paths_by_tool(preview_data, volumes, tool_colors);
- break;
- }
- default:
- {
- res = _travel_paths_by_type(preview_data, volumes);
- break;
- }
- }
+void _3DScene::set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons)
+{
+ return s_canvas_mgr.set_cutting_plane(canvas, z, polygons);
+}
- if (!res)
- {
- // an error occourred - restore to previous state and return
- if (initial_volumes_count != volumes.volumes.size())
- {
- std::vector<GLVolume*>::iterator begin = volumes.volumes.begin() + initial_volumes_count;
- std::vector<GLVolume*>::iterator end = volumes.volumes.end();
- for (std::vector<GLVolume*>::iterator it = begin; it < end; ++it)
- {
- GLVolume* volume = *it;
- delete volume;
- }
- volumes.volumes.erase(begin, end);
- }
+void _3DScene::set_color_by(wxGLCanvas* canvas, const std::string& value)
+{
+ return s_canvas_mgr.set_color_by(canvas, value);
+}
- return;
- }
+void _3DScene::set_select_by(wxGLCanvas* canvas, const std::string& value)
+{
+ return s_canvas_mgr.set_select_by(canvas, value);
+}
- // finalize volumes and sends geometry to gpu
- if (volumes.volumes.size() > initial_volumes_count)
- {
- for (size_t i = initial_volumes_count; i < volumes.volumes.size(); ++i)
- {
- GLVolume* volume = volumes.volumes[i];
- volume->bounding_box = volume->indexed_vertex_array.bounding_box();
- volume->indexed_vertex_array.finalize_geometry(use_VBOs);
- }
- }
+void _3DScene::set_drag_by(wxGLCanvas* canvas, const std::string& value)
+{
+ return s_canvas_mgr.set_drag_by(canvas, value);
}
-bool _3DScene::_travel_paths_by_type(const GCodePreviewData& preview_data, GLVolumeCollection& volumes)
+bool _3DScene::is_layers_editing_enabled(wxGLCanvas* canvas)
{
- // Helper structure for types
- struct Type
- {
- GCodePreviewData::Travel::EType value;
- GLVolume* volume;
+ return s_canvas_mgr.is_layers_editing_enabled(canvas);
+}
- explicit Type(GCodePreviewData::Travel::EType value)
- : value(value)
- , volume(nullptr)
- {
- }
+bool _3DScene::is_layers_editing_allowed(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.is_layers_editing_allowed(canvas);
+}
- bool operator == (const Type& other) const
- {
- return value == other.value;
- }
- };
+bool _3DScene::is_shader_enabled(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.is_shader_enabled(canvas);
+}
- typedef std::vector<Type> TypesList;
+bool _3DScene::is_reload_delayed(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.is_reload_delayed(canvas);
+}
- // colors travels by travel type
+void _3DScene::enable_layers_editing(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_layers_editing(canvas, enable);
+}
- // detects types
- TypesList types;
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- if (std::find(types.begin(), types.end(), Type(polyline.type)) == types.end())
- types.emplace_back(polyline.type);
- }
+void _3DScene::enable_warning_texture(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_warning_texture(canvas, enable);
+}
- // nothing to render, return
- if (types.empty())
- return true;
+void _3DScene::enable_legend_texture(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_legend_texture(canvas, enable);
+}
- // creates a new volume for each type
- for (Type& type : types)
- {
- GLVolume* volume = new GLVolume(preview_data.travel.type_colors[type.value].rgba);
- if (volume == nullptr)
- return false;
- else
- {
- type.volume = volume;
- volumes.volumes.emplace_back(volume);
- }
- }
+void _3DScene::enable_picking(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_picking(canvas, enable);
+}
- // populates volumes
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- TypesList::iterator type = std::find(types.begin(), types.end(), Type(polyline.type));
- if (type != types.end())
- {
- type->volume->print_zs.push_back(unscale(polyline.polyline.bounding_box().min.z));
- type->volume->offsets.push_back(type->volume->indexed_vertex_array.quad_indices.size());
- type->volume->offsets.push_back(type->volume->indexed_vertex_array.triangle_indices.size());
+void _3DScene::enable_moving(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_moving(canvas, enable);
+}
- polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *type->volume);
- }
- }
+void _3DScene::enable_gizmos(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_gizmos(canvas, enable);
+}
- return true;
+void _3DScene::enable_shader(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_shader(canvas, enable);
}
-bool _3DScene::_travel_paths_by_feedrate(const GCodePreviewData& preview_data, GLVolumeCollection& volumes)
+void _3DScene::enable_force_zoom_to_bed(wxGLCanvas* canvas, bool enable)
{
- // Helper structure for feedrate
- struct Feedrate
- {
- float value;
- GLVolume* volume;
+ s_canvas_mgr.enable_force_zoom_to_bed(canvas, enable);
+}
- explicit Feedrate(float value)
- : value(value)
- , volume(nullptr)
- {
- }
+void _3DScene::allow_multisample(wxGLCanvas* canvas, bool allow)
+{
+ s_canvas_mgr.allow_multisample(canvas, allow);
+}
- bool operator == (const Feedrate& other) const
- {
- return value == other.value;
- }
- };
+void _3DScene::zoom_to_bed(wxGLCanvas* canvas)
+{
+ s_canvas_mgr.zoom_to_bed(canvas);
+}
- typedef std::vector<Feedrate> FeedratesList;
+void _3DScene::zoom_to_volumes(wxGLCanvas* canvas)
+{
+ s_canvas_mgr.zoom_to_volumes(canvas);
+}
- // colors travels by feedrate
+void _3DScene::select_view(wxGLCanvas* canvas, const std::string& direction)
+{
+ s_canvas_mgr.select_view(canvas, direction);
+}
- // detects feedrates
- FeedratesList feedrates;
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- if (std::find(feedrates.begin(), feedrates.end(), Feedrate(polyline.feedrate)) == feedrates.end())
- feedrates.emplace_back(polyline.feedrate);
- }
+void _3DScene::set_viewport_from_scene(wxGLCanvas* canvas, wxGLCanvas* other)
+{
+ s_canvas_mgr.set_viewport_from_scene(canvas, other);
+}
- // nothing to render, return
- if (feedrates.empty())
- return true;
+void _3DScene::update_volumes_colors_by_extruder(wxGLCanvas* canvas)
+{
+ s_canvas_mgr.update_volumes_colors_by_extruder(canvas);
+}
- // creates a new volume for each feedrate
- for (Feedrate& feedrate : feedrates)
- {
- GLVolume* volume = new GLVolume(preview_data.get_feedrate_color(feedrate.value).rgba);
- if (volume == nullptr)
- return false;
- else
- {
- feedrate.volume = volume;
- volumes.volumes.emplace_back(volume);
- }
- }
+void _3DScene::render(wxGLCanvas* canvas)
+{
+ s_canvas_mgr.render(canvas);
+}
- // populates volumes
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- FeedratesList::iterator feedrate = std::find(feedrates.begin(), feedrates.end(), Feedrate(polyline.feedrate));
- if (feedrate != feedrates.end())
- {
- feedrate->volume->print_zs.push_back(unscale(polyline.polyline.bounding_box().min.z));
- feedrate->volume->offsets.push_back(feedrate->volume->indexed_vertex_array.quad_indices.size());
- feedrate->volume->offsets.push_back(feedrate->volume->indexed_vertex_array.triangle_indices.size());
+std::vector<double> _3DScene::get_current_print_zs(wxGLCanvas* canvas, bool active_only)
+{
+ return s_canvas_mgr.get_current_print_zs(canvas, active_only);
+}
- polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *feedrate->volume);
- }
- }
+void _3DScene::set_toolpaths_range(wxGLCanvas* canvas, double low, double high)
+{
+ s_canvas_mgr.set_toolpaths_range(canvas, low, high);
+}
- return true;
+void _3DScene::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_viewport_changed_callback(canvas, callback);
}
-bool _3DScene::_travel_paths_by_tool(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors)
+void _3DScene::register_on_double_click_callback(wxGLCanvas* canvas, void* callback)
{
- // Helper structure for tool
- struct Tool
- {
- unsigned int value;
- GLVolume* volume;
+ s_canvas_mgr.register_on_double_click_callback(canvas, callback);
+}
- explicit Tool(unsigned int value)
- : value(value)
- , volume(nullptr)
- {
- }
+void _3DScene::register_on_right_click_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_right_click_callback(canvas, callback);
+}
- bool operator == (const Tool& other) const
- {
- return value == other.value;
- }
- };
+void _3DScene::register_on_select_object_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_select_object_callback(canvas, callback);
+}
- typedef std::vector<Tool> ToolsList;
+void _3DScene::register_on_model_update_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_model_update_callback(canvas, callback);
+}
- // colors travels by tool
+void _3DScene::register_on_remove_object_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_remove_object_callback(canvas, callback);
+}
- // detects tools
- ToolsList tools;
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- if (std::find(tools.begin(), tools.end(), Tool(polyline.extruder_id)) == tools.end())
- tools.emplace_back(polyline.extruder_id);
- }
+void _3DScene::register_on_arrange_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_arrange_callback(canvas, callback);
+}
- // nothing to render, return
- if (tools.empty())
- return true;
+void _3DScene::register_on_rotate_object_left_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_rotate_object_left_callback(canvas, callback);
+}
- // creates a new volume for each tool
- for (Tool& tool : tools)
- {
- GLVolume* volume = new GLVolume(tool_colors.data() + tool.value * 4);
- if (volume == nullptr)
- return false;
- else
- {
- tool.volume = volume;
- volumes.volumes.emplace_back(volume);
- }
- }
+void _3DScene::register_on_rotate_object_right_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_rotate_object_right_callback(canvas, callback);
+}
- // populates volumes
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- ToolsList::iterator tool = std::find(tools.begin(), tools.end(), Tool(polyline.extruder_id));
- if (tool != tools.end())
- {
- tool->volume->print_zs.push_back(unscale(polyline.polyline.bounding_box().min.z));
- tool->volume->offsets.push_back(tool->volume->indexed_vertex_array.quad_indices.size());
- tool->volume->offsets.push_back(tool->volume->indexed_vertex_array.triangle_indices.size());
+void _3DScene::register_on_scale_object_uniformly_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_scale_object_uniformly_callback(canvas, callback);
+}
- polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *tool->volume);
- }
- }
+void _3DScene::register_on_increase_objects_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_increase_objects_callback(canvas, callback);
+}
- return true;
+void _3DScene::register_on_decrease_objects_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_decrease_objects_callback(canvas, callback);
}
-void _3DScene::_load_gcode_retractions(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, bool use_VBOs)
+void _3DScene::register_on_instance_moved_callback(wxGLCanvas* canvas, void* callback)
{
- s_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Retraction, 0, (unsigned int)volumes.volumes.size());
+ s_canvas_mgr.register_on_instance_moved_callback(canvas, callback);
+}
- // nothing to render, return
- if (preview_data.retraction.positions.empty())
- return;
+void _3DScene::register_on_wipe_tower_moved_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_wipe_tower_moved_callback(canvas, callback);
+}
- GLVolume* volume = new GLVolume(preview_data.retraction.color.rgba);
- if (volume != nullptr)
- {
- volumes.volumes.emplace_back(volume);
+void _3DScene::register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_enable_action_buttons_callback(canvas, callback);
+}
- GCodePreviewData::Retraction::PositionsList copy(preview_data.retraction.positions);
- std::sort(copy.begin(), copy.end(), [](const GCodePreviewData::Retraction::Position& p1, const GCodePreviewData::Retraction::Position& p2){ return p1.position.z < p2.position.z; });
+void _3DScene::register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_gizmo_scale_uniformly_callback(canvas, callback);
+}
- for (const GCodePreviewData::Retraction::Position& position : copy)
- {
- volume->print_zs.push_back(unscale(position.position.z));
- volume->offsets.push_back(volume->indexed_vertex_array.quad_indices.size());
- volume->offsets.push_back(volume->indexed_vertex_array.triangle_indices.size());
+static inline int hex_digit_to_int(const char c)
+{
+ return
+ (c >= '0' && c <= '9') ? int(c - '0') :
+ (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
+ (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
+}
- point3_to_verts(position.position, position.width, position.height, *volume);
+static inline std::vector<float> parse_colors(const std::vector<std::string> &scolors)
+{
+ std::vector<float> output(scolors.size() * 4, 1.f);
+ for (size_t i = 0; i < scolors.size(); ++ i) {
+ const std::string &scolor = scolors[i];
+ const char *c = scolor.data() + 1;
+ if (scolor.size() == 7 && scolor.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.f;
+ }
}
-
- // finalize volumes and sends geometry to gpu
- volume->bounding_box = volume->indexed_vertex_array.bounding_box();
- volume->indexed_vertex_array.finalize_geometry(use_VBOs);
}
+ return output;
}
-void _3DScene::_load_gcode_unretractions(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, bool use_VBOs)
+std::vector<int> _3DScene::load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector<int> instance_idxs)
{
- s_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Unretraction, 0, (unsigned int)volumes.volumes.size());
-
- // nothing to render, return
- if (preview_data.unretraction.positions.empty())
- return;
+ return s_canvas_mgr.load_object(canvas, model_object, obj_idx, instance_idxs);
+}
- GLVolume* volume = new GLVolume(preview_data.unretraction.color.rgba);
- if (volume != nullptr)
- {
- volumes.volumes.emplace_back(volume);
+std::vector<int> _3DScene::load_object(wxGLCanvas* canvas, const Model* model, int obj_idx)
+{
+ return s_canvas_mgr.load_object(canvas, model, obj_idx);
+}
- GCodePreviewData::Retraction::PositionsList copy(preview_data.unretraction.positions);
- std::sort(copy.begin(), copy.end(), [](const GCodePreviewData::Retraction::Position& p1, const GCodePreviewData::Retraction::Position& p2){ return p1.position.z < p2.position.z; });
+void _3DScene::reload_scene(wxGLCanvas* canvas, bool force)
+{
+ s_canvas_mgr.reload_scene(canvas, force);
+}
- for (const GCodePreviewData::Retraction::Position& position : copy)
- {
- volume->print_zs.push_back(unscale(position.position.z));
- volume->offsets.push_back(volume->indexed_vertex_array.quad_indices.size());
- volume->offsets.push_back(volume->indexed_vertex_array.triangle_indices.size());
+void _3DScene::load_print_toolpaths(wxGLCanvas* canvas)
+{
+ s_canvas_mgr.load_print_toolpaths(canvas);
+}
- point3_to_verts(position.position, position.width, position.height, *volume);
- }
+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);
+}
- // finalize volumes and sends geometry to gpu
- volume->bounding_box = volume->indexed_vertex_array.bounding_box();
- volume->indexed_vertex_array.finalize_geometry(use_VBOs);
- }
+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::_update_gcode_volumes_visibility(const GCodePreviewData& preview_data, GLVolumeCollection& volumes)
+void _3DScene::load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors)
{
- unsigned int size = (unsigned int)s_gcode_preview_volume_index.first_volumes.size();
- for (unsigned int i = 0; i < size; ++i)
- {
- std::vector<GLVolume*>::iterator begin = volumes.volumes.begin() + s_gcode_preview_volume_index.first_volumes[i].id;
- std::vector<GLVolume*>::iterator end = (i + 1 < size) ? volumes.volumes.begin() + s_gcode_preview_volume_index.first_volumes[i + 1].id : volumes.volumes.end();
+ s_canvas_mgr.load_gcode_preview(canvas, preview_data, str_tool_colors);
+}
- for (std::vector<GLVolume*>::iterator it = begin; it != end; ++it)
- {
- GLVolume* volume = *it;
- volume->outside_printer_detection_enabled = false;
+void _3DScene::generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
+{
+ s_legend_texture.generate(preview_data, tool_colors);
+}
- switch (s_gcode_preview_volume_index.first_volumes[i].type)
- {
- case GCodePreviewVolumeIndex::Extrusion:
- {
- if ((ExtrusionRole)s_gcode_preview_volume_index.first_volumes[i].flag == erCustom)
- volume->zoom_to_volumes = false;
-
- volume->is_active = preview_data.extrusion.is_role_flag_set((ExtrusionRole)s_gcode_preview_volume_index.first_volumes[i].flag);
- break;
- }
- case GCodePreviewVolumeIndex::Travel:
- {
- volume->is_active = preview_data.travel.is_visible;
- volume->zoom_to_volumes = false;
- break;
- }
- case GCodePreviewVolumeIndex::Retraction:
- {
- volume->is_active = preview_data.retraction.is_visible;
- volume->zoom_to_volumes = false;
- break;
- }
- case GCodePreviewVolumeIndex::Unretraction:
- {
- volume->is_active = preview_data.unretraction.is_visible;
- volume->zoom_to_volumes = false;
- break;
- }
- case GCodePreviewVolumeIndex::Shell:
- {
- volume->is_active = preview_data.shell.is_visible;
- volume->color[3] = 0.25f;
- volume->zoom_to_volumes = false;
- break;
- }
- default:
- {
- volume->is_active = false;
- volume->zoom_to_volumes = false;
- break;
- }
- }
- }
- }
+unsigned int _3DScene::get_legend_texture_width()
+{
+ return s_legend_texture.get_texture_width();
}
-void _3DScene::_generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
+unsigned int _3DScene::get_legend_texture_height()
{
- s_legend_texture.generate(preview_data, tool_colors);
+ return s_legend_texture.get_texture_height();
}
-void _3DScene::_load_shells(const Print& print, GLVolumeCollection& volumes, bool use_VBOs)
+void _3DScene::reset_legend_texture()
{
- size_t initial_volumes_count = volumes.volumes.size();
- s_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Shell, 0, (unsigned int)initial_volumes_count);
+ s_legend_texture.reset_texture();
+}
- if (print.objects.empty())
- // nothing to render, return
- return;
+unsigned int _3DScene::finalize_legend_texture()
+{
+ return s_legend_texture.finalize();
+}
- // adds objects' volumes
- unsigned int object_id = 0;
- for (PrintObject* obj : print.objects)
- {
- ModelObject* model_obj = obj->model_object();
+unsigned int _3DScene::get_warning_texture_width()
+{
+ return s_warning_texture.get_texture_width();
+}
- std::vector<int> instance_ids(model_obj->instances.size());
- for (int i = 0; i < model_obj->instances.size(); ++i)
- {
- instance_ids[i] = i;
- }
+unsigned int _3DScene::get_warning_texture_height()
+{
+ return s_warning_texture.get_texture_height();
+}
- for (ModelInstance* instance : model_obj->instances)
- {
- volumes.load_object(model_obj, object_id, instance_ids, "object", "object", "object", use_VBOs);
- }
+void _3DScene::generate_warning_texture(const std::string& msg)
+{
+ s_warning_texture.generate(msg);
+}
- ++object_id;
- }
+void _3DScene::reset_warning_texture()
+{
+ s_warning_texture.reset_texture();
+}
- // adds wipe tower's volume
- coordf_t max_z = print.objects[0]->model_object()->get_model()->bounding_box().max.z;
- const PrintConfig& config = print.config;
- unsigned int extruders_count = config.nozzle_diameter.size();
- if ((extruders_count > 1) && config.single_extruder_multi_material && config.wipe_tower && !config.complete_objects) {
- const float width_per_extruder = 15.f; // a simple workaround after wipe_tower_per_color_wipe got obsolete
- volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, width_per_extruder * (extruders_count - 1), max_z, config.wipe_tower_rotation_angle, use_VBOs);
- }
+unsigned int _3DScene::finalize_warning_texture()
+{
+ return s_warning_texture.finalize();
}
} // namespace Slic3r