diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index c05de06c67..13460cfed2 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -1527,10 +1527,13 @@ sub draw_active_object_annotations { my ($reset_left, $reset_bottom, $reset_right, $reset_top) = $self->_variable_layer_thickness_reset_rect_viewport; my $z_cursor_relative = $self->_variable_layer_thickness_bar_mouse_cursor_z_relative; + my $print_object = $self->{print}->get_object($object_idx); + my $z_max = $print_object->model_object->bounding_box->z_max; + $self->{layer_height_edit_shader}->enable; $self->{layer_height_edit_shader}->set_uniform('z_to_texture_row', $volume->layer_height_texture_z_to_row_id); $self->{layer_height_edit_shader}->set_uniform('z_texture_row_to_normalized', 1. / $volume->layer_height_texture_height); - $self->{layer_height_edit_shader}->set_uniform('z_cursor', $volume->bounding_box->z_max * $z_cursor_relative); + $self->{layer_height_edit_shader}->set_uniform('z_cursor', $z_max * $z_cursor_relative); $self->{layer_height_edit_shader}->set_uniform('z_cursor_band_width', $self->{layer_height_edit_band_width}); glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_z_texture_id}); glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $volume->layer_height_texture_width, $volume->layer_height_texture_height, @@ -1552,8 +1555,8 @@ sub draw_active_object_annotations { glBegin(GL_QUADS); glVertex3f($bar_left, $bar_bottom, 0); glVertex3f($bar_right, $bar_bottom, 0); - glVertex3f($bar_right, $bar_top, $volume->bounding_box->z_max); - glVertex3f($bar_left, $bar_top, $volume->bounding_box->z_max); + glVertex3f($bar_right, $bar_top, $z_max); + glVertex3f($bar_left, $bar_top, $z_max); glEnd(); glBindTexture(GL_TEXTURE_2D, 0); $self->{layer_height_edit_shader}->disable; @@ -1572,7 +1575,6 @@ sub draw_active_object_annotations { # Paint the graph. #FIXME show some kind of legend. - my $print_object = $self->{print}->get_object($object_idx); my $max_z = unscale($print_object->size->z); my $profile = $print_object->model_object->layer_height_profile; my $layer_height = $print_object->config->get('layer_height'); @@ -1677,6 +1679,11 @@ sub draw_warning { } } +sub update_volumes_colors_by_extruder { + my ($self, $config) = @_; + $self->volumes->update_colors_by_extruder($config); +} + sub opengl_info { my ($self, %params) = @_; @@ -1823,7 +1830,6 @@ sub _fragment_shader_Gouraud { return <<'FRAGMENT'; #version 110 -const vec4 OUTSIDE_COLOR = vec4(0.24, 0.42, 0.62, 1.0); const vec3 ZERO = vec3(0.0, 0.0, 0.0); // x = tainted, y = specular; @@ -1836,11 +1842,9 @@ uniform vec4 uniform_color; void main() { - // if the fragment is outside the print volume use predefined color - vec4 color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? OUTSIDE_COLOR : uniform_color; - - gl_FragColor = vec4(intensity.y, intensity.y, intensity.y, 0.0) + color * intensity.x; - gl_FragColor.a = color.a; + // if the fragment is outside the print volume -> use darker color + vec3 color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(uniform_color.rgb, ZERO, 0.3333) : uniform_color.rgb; + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + color * intensity.x, uniform_color.a); } FRAGMENT @@ -1932,8 +1936,6 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); #define INTENSITY_AMBIENT 0.3 -uniform float z_to_texture_row; - // x = tainted, y = specular; varying vec2 intensity; diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 89bbd45466..d59865491c 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -104,7 +104,6 @@ sub new { $self->{btn_reslice}->Enable($enable); $self->{btn_print}->Enable($enable); $self->{btn_send_gcode}->Enable($enable); - $self->{btn_export_stl}->Enable($enable); }; # Initialize 3D plater @@ -737,8 +736,14 @@ sub load_model_objects { { # if the object is too large (more than 5 times the bed), scale it down my $size = $o->bounding_box->size; - my $ratio = max(@$size[X,Y]) / unscale(max(@$bed_size[X,Y])); - if ($ratio > 5) { + my $ratio = max($size->x / unscale($bed_size->x), $size->y / unscale($bed_size->y)); + if ($ratio > 10000) { + # the size of the object is too big -> this could lead to overflow when moving to clipper coordinates, + # so scale down the mesh + $o->scale_xyz(Slic3r::Pointf3->new(1/$ratio, 1/$ratio, 1/$ratio)); + $scaled_down = 1; + } + elsif ($ratio > 5) { $_->set_scaling_factor(1/$ratio) for @{$o->instances}; $scaled_down = 1; } @@ -1914,7 +1919,8 @@ sub object_list_changed { } my $export_in_progress = $self->{export_gcode_output_file} || $self->{send_gcode_file}; - my $method = ($have_objects && ! $export_in_progress) ? 'Enable' : 'Disable'; + my $model_fits = $self->{model}->fits_print_volume($self->{config}); + my $method = ($have_objects && ! $export_in_progress && $model_fits) ? 'Enable' : 'Disable'; $self->{"btn_$_"}->$method for grep $self->{"btn_$_"}, qw(reslice export_gcode print send_gcode); } diff --git a/lib/Slic3r/GUI/Plater/3D.pm b/lib/Slic3r/GUI/Plater/3D.pm index cffacfef47..dce60e2c44 100644 --- a/lib/Slic3r/GUI/Plater/3D.pm +++ b/lib/Slic3r/GUI/Plater/3D.pm @@ -217,6 +217,8 @@ sub reload_scene { } } + $self->update_volumes_colors_by_extruder($self->{config}); + # checks for geometry outside the print volume to render it accordingly if (scalar @{$self->volumes} > 0) { @@ -230,6 +232,9 @@ sub reload_scene { Slic3r::GUI::_3DScene::reset_warning_texture(); $self->on_enable_action_buttons->(1) if ($self->on_enable_action_buttons); } + } else { + $self->set_warning_enabled(0); + Slic3r::GUI::_3DScene::reset_warning_texture(); } } diff --git a/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm b/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm index 7712bd01d0..7b5752cd2b 100644 --- a/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm +++ b/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm @@ -60,7 +60,7 @@ sub new { label => 'Z', default => $self->{cut_options}{z}, min => 0, - max => $self->{model_object}->bounding_box->size->z * $self->{model_object}->instances->[0]->scaling_factor, + max => $self->{model_object}->bounding_box->size->z, full_width => 1, )); { @@ -247,6 +247,7 @@ sub _update { $self->{cut_options}{z}, [@expolygons], ); + $self->{canvas}->update_volumes_colors_by_extruder($self->GetParent->{config}); $self->{canvas}->Render; } } diff --git a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm index 8a8e6064c8..f7e38ed873 100644 --- a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm +++ b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm @@ -9,7 +9,7 @@ use utf8; use File::Basename qw(basename); use Wx qw(:misc :sizer :treectrl :button :keycode wxTAB_TRAVERSAL wxSUNKEN_BORDER wxBITMAP_TYPE_PNG wxID_CANCEL wxMOD_CONTROL wxTheApp); -use Wx::Event qw(EVT_BUTTON EVT_TREE_ITEM_COLLAPSING EVT_TREE_SEL_CHANGED EVT_TREE_KEY_DOWN); +use Wx::Event qw(EVT_BUTTON EVT_TREE_ITEM_COLLAPSING EVT_TREE_SEL_CHANGED EVT_TREE_KEY_DOWN EVT_KEY_DOWN); use base 'Wx::Panel'; use constant ICON_OBJECT => 0; @@ -88,7 +88,7 @@ sub new { $self->{btn_move_down}->SetFont($Slic3r::GUI::small_font); # part settings panel - $self->{settings_panel} = Slic3r::GUI::Plater::OverrideSettingsPanel->new($self, on_change => sub { $self->{part_settings_changed} = 1; }); + $self->{settings_panel} = Slic3r::GUI::Plater::OverrideSettingsPanel->new($self, on_change => sub { $self->{part_settings_changed} = 1; $self->_update_canvas; }); my $settings_sizer = Wx::StaticBoxSizer->new($self->{staticbox} = Wx::StaticBox->new($self, -1, "Part Settings"), wxVERTICAL); $settings_sizer->Add($self->{settings_panel}, 1, wxEXPAND | wxALL, 0); @@ -162,6 +162,7 @@ sub new { $canvas->load_object($self->{model_object}, undef, undef, [0]); $canvas->set_auto_bed_shape; $canvas->SetSize([500,700]); + $canvas->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config}); $canvas->zoom_to_volumes; } @@ -190,6 +191,14 @@ sub new { EVT_BUTTON($self, $self->{btn_split}, \&on_btn_split); EVT_BUTTON($self, $self->{btn_move_up}, \&on_btn_move_up); EVT_BUTTON($self, $self->{btn_move_down}, \&on_btn_move_down); + EVT_KEY_DOWN($canvas, sub { + my ($canvas, $event) = @_; + if ($event->GetKeyCode == WXK_DELETE) { + $canvas->GetParent->on_btn_delete; + } else { + $event->Skip; + } + }); $self->reload_tree; @@ -400,14 +409,17 @@ sub on_tree_key_down { my ($self, $event) = @_; my $keycode = $event->GetKeyCode; # Wx >= 0.9911 - if (defined(&Wx::TreeEvent::GetKeyEvent) && - ($event->GetKeyEvent->GetModifiers & wxMOD_CONTROL)) { - if ($keycode == WXK_UP) { - $event->Skip; - $self->on_btn_move_up; - } elsif ($keycode == WXK_DOWN) { - $event->Skip; - $self->on_btn_move_down; + if (defined(&Wx::TreeEvent::GetKeyEvent)) { + if ($event->GetKeyEvent->GetModifiers & wxMOD_CONTROL) { + if ($keycode == WXK_UP) { + $event->Skip; + $self->on_btn_move_up; + } elsif ($keycode == WXK_DOWN) { + $event->Skip; + $self->on_btn_move_down; + } + } elsif ($keycode == WXK_DELETE) { + $self->on_btn_delete; } } } @@ -478,6 +490,7 @@ sub _parts_changed { $self->{canvas}->reset_objects; $self->{canvas}->load_object($self->{model_object}); $self->{canvas}->zoom_to_volumes; + $self->{canvas}->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config}); $self->{canvas}->Render; } } @@ -508,6 +521,25 @@ sub PartSettingsChanged { return $self->{part_settings_changed}; } +sub _update_canvas { + my ($self) = @_; + + if ($self->{canvas}) { + $self->{canvas}->reset_objects; + $self->{canvas}->load_object($self->{model_object}); + + # restore selection, if any + if (my $itemData = $self->get_selection) { + if ($itemData->{type} eq 'volume') { + $self->{canvas}->volumes->[ $itemData->{volume_id} ]->set_selected(1); + } + } + + $self->{canvas}->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config}); + $self->{canvas}->Render; + } +} + sub _update { my ($self) = @_; my ($m_x, $m_y, $m_z) = ($self->{move_options}{x}, $self->{move_options}{y}, $self->{move_options}{z}); @@ -528,6 +560,7 @@ sub _update { push @objects, $self->{model_object}; $self->{canvas}->reset_objects; $self->{canvas}->load_object($_, undef, [0]) for @objects; + $self->{canvas}->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config}); $self->{canvas}->Render; } diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp index ad2ce54cd2..bda49421d0 100644 --- a/xs/src/libslic3r/Model.cpp +++ b/xs/src/libslic3r/Model.cpp @@ -16,6 +16,8 @@ namespace Slic3r { + unsigned int Model::s_auto_extruder_id = 1; + Model::Model(const Model &other) { // copy materials @@ -405,10 +407,19 @@ void Model::convert_multipart_object() ModelObject* object = new ModelObject(this); object->input_file = this->objects.front()->input_file; - + + reset_auto_extruder_id(); + for (const ModelObject* o : this->objects) for (const ModelVolume* v : o->volumes) - object->add_volume(*v)->name = o->name; + { + ModelVolume* new_v = object->add_volume(*v); + if (new_v != nullptr) + { + new_v->name = o->name; + new_v->config.set_deserialize("extruder", get_auto_extruder_id_as_string()); + } + } for (const ModelInstance* i : this->objects.front()->instances) object->add_instance(*i); @@ -466,6 +477,28 @@ bool Model::fits_print_volume(const FullPrintConfig &config) const return print_volume.contains(transformed_bounding_box()); } +unsigned int Model::get_auto_extruder_id() +{ + unsigned int id = s_auto_extruder_id; + + if (++s_auto_extruder_id > 4) + reset_auto_extruder_id(); + + return id; +} + +std::string Model::get_auto_extruder_id_as_string() +{ + char str_extruder[64]; + sprintf(str_extruder, "%ud", get_auto_extruder_id()); + return str_extruder; +} + +void Model::reset_auto_extruder_id() +{ + s_auto_extruder_id = 1; +} + ModelObject::ModelObject(Model *model, const ModelObject &other, bool copy_volumes) : name(other.name), input_file(other.input_file), @@ -830,33 +863,9 @@ void ModelObject::cut(coordf_t z, Model* model) const lower->add_volume(*volume); } else { TriangleMesh upper_mesh, lower_mesh; - // TODO: shouldn't we use object bounding box instead of per-volume bb? - coordf_t cut_z = z + volume->mesh.bounding_box().min.z; - if (false) { -// if (volume->mesh.has_multiple_patches()) { - // Cutting algorithm does not work on intersecting meshes. - // As we are not sure whether the meshes don't intersect, - // we rather split the mesh into multiple non-intersecting pieces. - TriangleMeshPtrs meshptrs = volume->mesh.split(); - for (TriangleMeshPtrs::iterator mesh = meshptrs.begin(); mesh != meshptrs.end(); ++mesh) { - printf("Cutting mesh patch %d of %d\n", int(mesh - meshptrs.begin()), int(meshptrs.size())); - (*mesh)->repair(); - TriangleMeshSlicer tms(*mesh); - if (mesh == meshptrs.begin()) { - tms.cut(cut_z, &upper_mesh, &lower_mesh); - } else { - TriangleMesh upper_mesh_this, lower_mesh_this; - tms.cut(cut_z, &upper_mesh_this, &lower_mesh_this); - upper_mesh.merge(upper_mesh_this); - lower_mesh.merge(lower_mesh_this); - } - delete *mesh; - } - } else { - printf("Cutting mesh patch\n"); - TriangleMeshSlicer tms(&volume->mesh); - tms.cut(cut_z, &upper_mesh, &lower_mesh); - } + printf("Cutting mesh patch\n"); + TriangleMeshSlicer tms(&volume->mesh); + tms.cut(z, &upper_mesh, &lower_mesh); upper_mesh.repair(); lower_mesh.repair(); @@ -995,6 +1004,9 @@ size_t ModelVolume::split() size_t idx = 0; size_t ivolume = std::find(this->object->volumes.begin(), this->object->volumes.end(), this) - this->object->volumes.begin(); std::string name = this->name; + + Model::reset_auto_extruder_id(); + for (TriangleMesh *mesh : meshptrs) { mesh->repair(); if (idx == 0) @@ -1004,6 +1016,7 @@ size_t ModelVolume::split() char str_idx[64]; sprintf(str_idx, "_%d", idx + 1); this->object->volumes[ivolume]->name = name + str_idx; + this->object->volumes[ivolume]->config.set_deserialize("extruder", Model::get_auto_extruder_id_as_string()); delete mesh; ++ idx; } diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp index bf7f60e36c..0c0ffe7769 100644 --- a/xs/src/libslic3r/Model.hpp +++ b/xs/src/libslic3r/Model.hpp @@ -230,6 +230,8 @@ private: // all objects may share mutliple materials. class Model { + static unsigned int s_auto_extruder_id; + public: // Materials are owned by a model and referenced by objects through t_model_material_id. // Single material may be shared by multiple models. @@ -288,6 +290,10 @@ public: bool fits_print_volume(const FullPrintConfig &config) const; void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); } + + static unsigned int get_auto_extruder_id(); + static std::string get_auto_extruder_id_as_string(); + static void reset_auto_extruder_id(); }; } diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 7298bc131f..aa86ae203f 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -9,6 +9,7 @@ #include "../../libslic3r/GCode/PreviewData.hpp" #include "../../libslic3r/Print.hpp" #include "../../libslic3r/Slicing.hpp" +#include "../../slic3r/GUI/PresetBundle.hpp" #include "GCode/Analyzer.hpp" #include @@ -304,7 +305,7 @@ void GLVolume::render_using_layer_height() const glUniform1f(z_texture_row_to_normalized_id, (GLfloat)(1.0f / layer_height_texture_height())); if (z_cursor_id >= 0) - glUniform1f(z_cursor_id, (GLfloat)(bounding_box.max.z * layer_height_texture_data.z_cursor_relative)); + glUniform1f(z_cursor_id, (GLfloat)(layer_height_texture_data.print_object->model_object()->bounding_box().max.z * layer_height_texture_data.z_cursor_relative)); if (z_cursor_band_width_id >= 0) glUniform1f(z_cursor_band_width_id, (GLfloat)layer_height_texture_data.edit_band_width); @@ -326,6 +327,11 @@ void GLVolume::render_using_layer_height() const glUseProgram(current_program_id); } +double GLVolume::layer_height_texture_z_to_row_id() const +{ + return (this->layer_height_texture.get() == nullptr) ? 0.0 : double(this->layer_height_texture->cells - 1) / (double(this->layer_height_texture->width) * this->layer_height_texture_data.print_object->model_object()->bounding_box().max.z); +} + void GLVolume::generate_layer_height_texture(PrintObject *print_object, bool force) { GLTexture *tex = this->layer_height_texture.get(); @@ -381,6 +387,15 @@ std::vector GLVolumeCollection::load_object( std::vector volumes_idx; for (int volume_idx = 0; volume_idx < int(model_object->volumes.size()); ++ volume_idx) { const ModelVolume *model_volume = model_object->volumes[volume_idx]; + + int extruder_id = -1; + if (!model_volume->modifier) + { + extruder_id = model_volume->config.has("extruder") ? model_volume->config.option("extruder")->getInt() : 0; + if (extruder_id == 0) + extruder_id = model_object->config.has("extruder") ? model_object->config.option("extruder")->getInt() : 0; + } + for (int instance_idx : instance_idxs) { const ModelInstance *instance = model_object->instances[instance_idx]; TriangleMesh mesh = model_volume->mesh; @@ -410,8 +425,14 @@ std::vector GLVolumeCollection::load_object( v.drag_group_id = obj_idx * 1000; else if (drag_by == "instance") v.drag_group_id = obj_idx * 1000 + instance_idx; - if (! model_volume->modifier) + + if (!model_volume->modifier) + { v.layer_height_texture = layer_height_texture; + if (extruder_id != -1) + v.extruder_id = extruder_id; + } + v.is_modifier = model_volume->modifier; } } @@ -443,6 +464,7 @@ int GLVolumeCollection::load_wipe_tower_preview( v.composite_id = obj_idx * 1000000; v.select_group_id = obj_idx * 1000000; v.drag_group_id = obj_idx * 1000; + v.is_wipe_tower = true; return int(this->volumes.size() - 1); } @@ -647,6 +669,83 @@ void GLVolumeCollection::update_outside_state(const DynamicPrintConfig* config, } } +void GLVolumeCollection::update_colors_by_extruder(const DynamicPrintConfig* config) +{ + static const float inv_255 = 1.0f / 255.0f; + + struct Color + { + std::string text; + unsigned char rgb[3]; + + Color() + : text("") + { + rgb[0] = 255; + rgb[1] = 255; + rgb[2] = 255; + } + + void set(const std::string& text, unsigned char* rgb) + { + this->text = text; + ::memcpy((void*)this->rgb, (const void*)rgb, 3 * sizeof(unsigned char)); + } + }; + + if (config == nullptr) + return; + + const ConfigOptionStrings* extruders_opt = dynamic_cast(config->option("extruder_colour")); + if (extruders_opt == nullptr) + return; + + const ConfigOptionStrings* filamemts_opt = dynamic_cast(config->option("filament_colour")); + if (filamemts_opt == nullptr) + return; + + unsigned int colors_count = std::max((unsigned int)extruders_opt->values.size(), (unsigned int)filamemts_opt->values.size()); + if (colors_count == 0) + return; + + std::vector colors(colors_count); + + unsigned char rgb[3]; + for (unsigned int i = 0; i < colors_count; ++i) + { + const std::string& txt_color = config->opt_string("extruder_colour", i); + if (PresetBundle::parse_color(txt_color, rgb)) + { + colors[i].set(txt_color, rgb); + } + else + { + const std::string& txt_color = config->opt_string("filament_colour", i); + if (PresetBundle::parse_color(txt_color, rgb)) + colors[i].set(txt_color, rgb); + } + } + + for (GLVolume* volume : volumes) + { + if ((volume == nullptr) || volume->is_modifier || volume->is_wipe_tower) + continue; + + int extruder_id = volume->extruder_id - 1; + if ((extruder_id < 0) || ((unsigned int)colors.size() <= extruder_id)) + extruder_id = 0; + + const Color& color = colors[extruder_id]; + if (!color.text.empty()) + { + for (int i = 0; i < 3; ++i) + { + volume->color[i] = (float)color.rgb[i] * inv_255; + } + } + } +} + std::vector GLVolumeCollection::get_current_print_zs() const { // Collect layer top positions of all volumes. diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index f94dda0661..8f03e47746 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -246,12 +246,15 @@ public: composite_id(-1), select_group_id(-1), drag_group_id(-1), + extruder_id(0), selected(false), is_active(true), zoom_to_volumes(true), outside_printer_detection_enabled(true), is_outside(false), hover(false), + is_modifier(false), + is_wipe_tower(false), tverts_range(0, size_t(-1)), qverts_range(0, size_t(-1)) { @@ -287,6 +290,8 @@ public: int select_group_id; // An ID for group dragging. It may be the same for all meshes of all object instances, or for just a single object instance. int drag_group_id; + // An ID containing the extruder ID (used to select color). + int extruder_id; // Is this object selected? bool selected; // Whether or not this volume is active for rendering @@ -299,6 +304,10 @@ public: bool is_outside; // Boolean: Is mouse over this object? bool hover; + // Wheter or not this volume has been generated from a modifier + bool is_modifier; + // Wheter or not this volume has been generated from the wipe tower + bool is_wipe_tower; // Interleaved triangles & normals with indexed triangles & quads. GLIndexedVertexArray indexed_vertex_array; @@ -352,10 +361,7 @@ public: return (layer_height_texture.get() == nullptr) ? 0 : (void*)(layer_height_texture->data.data() + layer_height_texture->width * layer_height_texture->height * 4); } - double layer_height_texture_z_to_row_id() const { - return (this->layer_height_texture.get() == nullptr) ? 0. : - double(this->layer_height_texture->cells - 1) / (double(this->layer_height_texture->width) * bounding_box.max.z); - } + double layer_height_texture_z_to_row_id() const; void generate_layer_height_texture(PrintObject *print_object, bool force); void set_layer_height_texture_data(unsigned int texture_id, unsigned int shader_id, PrintObject* print_object, float z_cursor_relative, float edit_band_width) @@ -417,6 +423,7 @@ public: } void update_outside_state(const DynamicPrintConfig* config, bool all_inside); + void update_colors_by_extruder(const DynamicPrintConfig* config); // Returns a vector containing the sorted list of all the print_zs of the volumes contained in this collection std::vector get_current_print_zs() const; diff --git a/xs/src/slic3r/GUI/PresetBundle.cpp b/xs/src/slic3r/GUI/PresetBundle.cpp index e80c9ce48f..207968f1b5 100644 --- a/xs/src/slic3r/GUI/PresetBundle.cpp +++ b/xs/src/slic3r/GUI/PresetBundle.cpp @@ -990,7 +990,7 @@ static inline int hex_digit_to_int(const char c) (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; } -static inline bool parse_color(const std::string &scolor, unsigned char *rgb_out) +bool PresetBundle::parse_color(const std::string &scolor, unsigned char *rgb_out) { rgb_out[0] = rgb_out[1] = rgb_out[2] = 0; if (scolor.size() != 7 || scolor.front() != '#') diff --git a/xs/src/slic3r/GUI/PresetBundle.hpp b/xs/src/slic3r/GUI/PresetBundle.hpp index 8e89590ac9..c0307c977c 100644 --- a/xs/src/slic3r/GUI/PresetBundle.hpp +++ b/xs/src/slic3r/GUI/PresetBundle.hpp @@ -117,6 +117,8 @@ public: // preset if the current print or filament preset is not compatible. void update_compatible_with_printer(bool select_other_if_incompatible); + static bool parse_color(const std::string &scolor, unsigned char *rgb_out); + private: std::string load_system_presets(); diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index 915d964d13..86d0aeba29 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -105,6 +105,7 @@ void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z); void update_outside_state(DynamicPrintConfig* config, bool all_inside); + void update_colors_by_extruder(DynamicPrintConfig* config); bool move_volume_up(int idx) %code%{