mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 09:17:52 -06:00
Merge remote-tracking branch 'origin/scene_manipulators'
This commit is contained in:
commit
913cdef297
12 changed files with 238 additions and 63 deletions
|
@ -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 ($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 $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}->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_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_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});
|
$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});
|
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,
|
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);
|
glBegin(GL_QUADS);
|
||||||
glVertex3f($bar_left, $bar_bottom, 0);
|
glVertex3f($bar_left, $bar_bottom, 0);
|
||||||
glVertex3f($bar_right, $bar_bottom, 0);
|
glVertex3f($bar_right, $bar_bottom, 0);
|
||||||
glVertex3f($bar_right, $bar_top, $volume->bounding_box->z_max);
|
glVertex3f($bar_right, $bar_top, $z_max);
|
||||||
glVertex3f($bar_left, $bar_top, $volume->bounding_box->z_max);
|
glVertex3f($bar_left, $bar_top, $z_max);
|
||||||
glEnd();
|
glEnd();
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
$self->{layer_height_edit_shader}->disable;
|
$self->{layer_height_edit_shader}->disable;
|
||||||
|
@ -1572,7 +1575,6 @@ sub draw_active_object_annotations {
|
||||||
|
|
||||||
# Paint the graph.
|
# Paint the graph.
|
||||||
#FIXME show some kind of legend.
|
#FIXME show some kind of legend.
|
||||||
my $print_object = $self->{print}->get_object($object_idx);
|
|
||||||
my $max_z = unscale($print_object->size->z);
|
my $max_z = unscale($print_object->size->z);
|
||||||
my $profile = $print_object->model_object->layer_height_profile;
|
my $profile = $print_object->model_object->layer_height_profile;
|
||||||
my $layer_height = $print_object->config->get('layer_height');
|
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
|
sub opengl_info
|
||||||
{
|
{
|
||||||
my ($self, %params) = @_;
|
my ($self, %params) = @_;
|
||||||
|
@ -1823,7 +1830,6 @@ sub _fragment_shader_Gouraud {
|
||||||
return <<'FRAGMENT';
|
return <<'FRAGMENT';
|
||||||
#version 110
|
#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);
|
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
// x = tainted, y = specular;
|
// x = tainted, y = specular;
|
||||||
|
@ -1836,11 +1842,9 @@ uniform vec4 uniform_color;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// if the fragment is outside the print volume use predefined color
|
// if the fragment is outside the print volume -> use darker color
|
||||||
vec4 color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? OUTSIDE_COLOR : uniform_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);
|
||||||
gl_FragColor = vec4(intensity.y, intensity.y, intensity.y, 0.0) + color * intensity.x;
|
|
||||||
gl_FragColor.a = color.a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FRAGMENT
|
FRAGMENT
|
||||||
|
@ -1932,8 +1936,6 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
|
||||||
|
|
||||||
#define INTENSITY_AMBIENT 0.3
|
#define INTENSITY_AMBIENT 0.3
|
||||||
|
|
||||||
uniform float z_to_texture_row;
|
|
||||||
|
|
||||||
// x = tainted, y = specular;
|
// x = tainted, y = specular;
|
||||||
varying vec2 intensity;
|
varying vec2 intensity;
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,6 @@ sub new {
|
||||||
$self->{btn_reslice}->Enable($enable);
|
$self->{btn_reslice}->Enable($enable);
|
||||||
$self->{btn_print}->Enable($enable);
|
$self->{btn_print}->Enable($enable);
|
||||||
$self->{btn_send_gcode}->Enable($enable);
|
$self->{btn_send_gcode}->Enable($enable);
|
||||||
$self->{btn_export_stl}->Enable($enable);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Initialize 3D plater
|
# 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
|
# if the object is too large (more than 5 times the bed), scale it down
|
||||||
my $size = $o->bounding_box->size;
|
my $size = $o->bounding_box->size;
|
||||||
my $ratio = max(@$size[X,Y]) / unscale(max(@$bed_size[X,Y]));
|
my $ratio = max($size->x / unscale($bed_size->x), $size->y / unscale($bed_size->y));
|
||||||
if ($ratio > 5) {
|
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};
|
$_->set_scaling_factor(1/$ratio) for @{$o->instances};
|
||||||
$scaled_down = 1;
|
$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 $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
|
$self->{"btn_$_"}->$method
|
||||||
for grep $self->{"btn_$_"}, qw(reslice export_gcode print send_gcode);
|
for grep $self->{"btn_$_"}, qw(reslice export_gcode print send_gcode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
# checks for geometry outside the print volume to render it accordingly
|
||||||
if (scalar @{$self->volumes} > 0)
|
if (scalar @{$self->volumes} > 0)
|
||||||
{
|
{
|
||||||
|
@ -230,6 +232,9 @@ sub reload_scene {
|
||||||
Slic3r::GUI::_3DScene::reset_warning_texture();
|
Slic3r::GUI::_3DScene::reset_warning_texture();
|
||||||
$self->on_enable_action_buttons->(1) if ($self->on_enable_action_buttons);
|
$self->on_enable_action_buttons->(1) if ($self->on_enable_action_buttons);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$self->set_warning_enabled(0);
|
||||||
|
Slic3r::GUI::_3DScene::reset_warning_texture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ sub new {
|
||||||
label => 'Z',
|
label => 'Z',
|
||||||
default => $self->{cut_options}{z},
|
default => $self->{cut_options}{z},
|
||||||
min => 0,
|
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,
|
full_width => 1,
|
||||||
));
|
));
|
||||||
{
|
{
|
||||||
|
@ -247,6 +247,7 @@ sub _update {
|
||||||
$self->{cut_options}{z},
|
$self->{cut_options}{z},
|
||||||
[@expolygons],
|
[@expolygons],
|
||||||
);
|
);
|
||||||
|
$self->{canvas}->update_volumes_colors_by_extruder($self->GetParent->{config});
|
||||||
$self->{canvas}->Render;
|
$self->{canvas}->Render;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use utf8;
|
||||||
use File::Basename qw(basename);
|
use File::Basename qw(basename);
|
||||||
use Wx qw(:misc :sizer :treectrl :button :keycode wxTAB_TRAVERSAL wxSUNKEN_BORDER wxBITMAP_TYPE_PNG wxID_CANCEL wxMOD_CONTROL
|
use Wx qw(:misc :sizer :treectrl :button :keycode wxTAB_TRAVERSAL wxSUNKEN_BORDER wxBITMAP_TYPE_PNG wxID_CANCEL wxMOD_CONTROL
|
||||||
wxTheApp);
|
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 base 'Wx::Panel';
|
||||||
|
|
||||||
use constant ICON_OBJECT => 0;
|
use constant ICON_OBJECT => 0;
|
||||||
|
@ -88,7 +88,7 @@ sub new {
|
||||||
$self->{btn_move_down}->SetFont($Slic3r::GUI::small_font);
|
$self->{btn_move_down}->SetFont($Slic3r::GUI::small_font);
|
||||||
|
|
||||||
# part settings panel
|
# 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);
|
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);
|
$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->load_object($self->{model_object}, undef, undef, [0]);
|
||||||
$canvas->set_auto_bed_shape;
|
$canvas->set_auto_bed_shape;
|
||||||
$canvas->SetSize([500,700]);
|
$canvas->SetSize([500,700]);
|
||||||
|
$canvas->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config});
|
||||||
$canvas->zoom_to_volumes;
|
$canvas->zoom_to_volumes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +191,14 @@ sub new {
|
||||||
EVT_BUTTON($self, $self->{btn_split}, \&on_btn_split);
|
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_up}, \&on_btn_move_up);
|
||||||
EVT_BUTTON($self, $self->{btn_move_down}, \&on_btn_move_down);
|
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;
|
$self->reload_tree;
|
||||||
|
|
||||||
|
@ -400,8 +409,8 @@ sub on_tree_key_down {
|
||||||
my ($self, $event) = @_;
|
my ($self, $event) = @_;
|
||||||
my $keycode = $event->GetKeyCode;
|
my $keycode = $event->GetKeyCode;
|
||||||
# Wx >= 0.9911
|
# Wx >= 0.9911
|
||||||
if (defined(&Wx::TreeEvent::GetKeyEvent) &&
|
if (defined(&Wx::TreeEvent::GetKeyEvent)) {
|
||||||
($event->GetKeyEvent->GetModifiers & wxMOD_CONTROL)) {
|
if ($event->GetKeyEvent->GetModifiers & wxMOD_CONTROL) {
|
||||||
if ($keycode == WXK_UP) {
|
if ($keycode == WXK_UP) {
|
||||||
$event->Skip;
|
$event->Skip;
|
||||||
$self->on_btn_move_up;
|
$self->on_btn_move_up;
|
||||||
|
@ -409,6 +418,9 @@ sub on_tree_key_down {
|
||||||
$event->Skip;
|
$event->Skip;
|
||||||
$self->on_btn_move_down;
|
$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}->reset_objects;
|
||||||
$self->{canvas}->load_object($self->{model_object});
|
$self->{canvas}->load_object($self->{model_object});
|
||||||
$self->{canvas}->zoom_to_volumes;
|
$self->{canvas}->zoom_to_volumes;
|
||||||
|
$self->{canvas}->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config});
|
||||||
$self->{canvas}->Render;
|
$self->{canvas}->Render;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -508,6 +521,25 @@ sub PartSettingsChanged {
|
||||||
return $self->{part_settings_changed};
|
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 {
|
sub _update {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
my ($m_x, $m_y, $m_z) = ($self->{move_options}{x}, $self->{move_options}{y}, $self->{move_options}{z});
|
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};
|
push @objects, $self->{model_object};
|
||||||
$self->{canvas}->reset_objects;
|
$self->{canvas}->reset_objects;
|
||||||
$self->{canvas}->load_object($_, undef, [0]) for @objects;
|
$self->{canvas}->load_object($_, undef, [0]) for @objects;
|
||||||
|
$self->{canvas}->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config});
|
||||||
$self->{canvas}->Render;
|
$self->{canvas}->Render;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
unsigned int Model::s_auto_extruder_id = 1;
|
||||||
|
|
||||||
Model::Model(const Model &other)
|
Model::Model(const Model &other)
|
||||||
{
|
{
|
||||||
// copy materials
|
// copy materials
|
||||||
|
@ -406,9 +408,18 @@ void Model::convert_multipart_object()
|
||||||
ModelObject* object = new ModelObject(this);
|
ModelObject* object = new ModelObject(this);
|
||||||
object->input_file = this->objects.front()->input_file;
|
object->input_file = this->objects.front()->input_file;
|
||||||
|
|
||||||
|
reset_auto_extruder_id();
|
||||||
|
|
||||||
for (const ModelObject* o : this->objects)
|
for (const ModelObject* o : this->objects)
|
||||||
for (const ModelVolume* v : o->volumes)
|
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)
|
for (const ModelInstance* i : this->objects.front()->instances)
|
||||||
object->add_instance(*i);
|
object->add_instance(*i);
|
||||||
|
@ -466,6 +477,28 @@ bool Model::fits_print_volume(const FullPrintConfig &config) const
|
||||||
return print_volume.contains(transformed_bounding_box());
|
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) :
|
ModelObject::ModelObject(Model *model, const ModelObject &other, bool copy_volumes) :
|
||||||
name(other.name),
|
name(other.name),
|
||||||
input_file(other.input_file),
|
input_file(other.input_file),
|
||||||
|
@ -830,33 +863,9 @@ void ModelObject::cut(coordf_t z, Model* model) const
|
||||||
lower->add_volume(*volume);
|
lower->add_volume(*volume);
|
||||||
} else {
|
} else {
|
||||||
TriangleMesh upper_mesh, lower_mesh;
|
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");
|
printf("Cutting mesh patch\n");
|
||||||
TriangleMeshSlicer tms(&volume->mesh);
|
TriangleMeshSlicer tms(&volume->mesh);
|
||||||
tms.cut(cut_z, &upper_mesh, &lower_mesh);
|
tms.cut(z, &upper_mesh, &lower_mesh);
|
||||||
}
|
|
||||||
|
|
||||||
upper_mesh.repair();
|
upper_mesh.repair();
|
||||||
lower_mesh.repair();
|
lower_mesh.repair();
|
||||||
|
@ -995,6 +1004,9 @@ size_t ModelVolume::split()
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
size_t ivolume = std::find(this->object->volumes.begin(), this->object->volumes.end(), this) - this->object->volumes.begin();
|
size_t ivolume = std::find(this->object->volumes.begin(), this->object->volumes.end(), this) - this->object->volumes.begin();
|
||||||
std::string name = this->name;
|
std::string name = this->name;
|
||||||
|
|
||||||
|
Model::reset_auto_extruder_id();
|
||||||
|
|
||||||
for (TriangleMesh *mesh : meshptrs) {
|
for (TriangleMesh *mesh : meshptrs) {
|
||||||
mesh->repair();
|
mesh->repair();
|
||||||
if (idx == 0)
|
if (idx == 0)
|
||||||
|
@ -1004,6 +1016,7 @@ size_t ModelVolume::split()
|
||||||
char str_idx[64];
|
char str_idx[64];
|
||||||
sprintf(str_idx, "_%d", idx + 1);
|
sprintf(str_idx, "_%d", idx + 1);
|
||||||
this->object->volumes[ivolume]->name = name + str_idx;
|
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;
|
delete mesh;
|
||||||
++ idx;
|
++ idx;
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,6 +230,8 @@ private:
|
||||||
// all objects may share mutliple materials.
|
// all objects may share mutliple materials.
|
||||||
class Model
|
class Model
|
||||||
{
|
{
|
||||||
|
static unsigned int s_auto_extruder_id;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Materials are owned by a model and referenced by objects through t_model_material_id.
|
// Materials are owned by a model and referenced by objects through t_model_material_id.
|
||||||
// Single material may be shared by multiple models.
|
// Single material may be shared by multiple models.
|
||||||
|
@ -288,6 +290,10 @@ public:
|
||||||
bool fits_print_volume(const FullPrintConfig &config) const;
|
bool fits_print_volume(const FullPrintConfig &config) const;
|
||||||
|
|
||||||
void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); }
|
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();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "../../libslic3r/GCode/PreviewData.hpp"
|
#include "../../libslic3r/GCode/PreviewData.hpp"
|
||||||
#include "../../libslic3r/Print.hpp"
|
#include "../../libslic3r/Print.hpp"
|
||||||
#include "../../libslic3r/Slicing.hpp"
|
#include "../../libslic3r/Slicing.hpp"
|
||||||
|
#include "../../slic3r/GUI/PresetBundle.hpp"
|
||||||
#include "GCode/Analyzer.hpp"
|
#include "GCode/Analyzer.hpp"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -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()));
|
glUniform1f(z_texture_row_to_normalized_id, (GLfloat)(1.0f / layer_height_texture_height()));
|
||||||
|
|
||||||
if (z_cursor_id >= 0)
|
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)
|
if (z_cursor_band_width_id >= 0)
|
||||||
glUniform1f(z_cursor_band_width_id, (GLfloat)layer_height_texture_data.edit_band_width);
|
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);
|
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)
|
void GLVolume::generate_layer_height_texture(PrintObject *print_object, bool force)
|
||||||
{
|
{
|
||||||
GLTexture *tex = this->layer_height_texture.get();
|
GLTexture *tex = this->layer_height_texture.get();
|
||||||
|
@ -381,6 +387,15 @@ std::vector<int> GLVolumeCollection::load_object(
|
||||||
std::vector<int> volumes_idx;
|
std::vector<int> volumes_idx;
|
||||||
for (int volume_idx = 0; volume_idx < int(model_object->volumes.size()); ++ volume_idx) {
|
for (int volume_idx = 0; volume_idx < int(model_object->volumes.size()); ++ volume_idx) {
|
||||||
const ModelVolume *model_volume = model_object->volumes[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) {
|
for (int instance_idx : instance_idxs) {
|
||||||
const ModelInstance *instance = model_object->instances[instance_idx];
|
const ModelInstance *instance = model_object->instances[instance_idx];
|
||||||
TriangleMesh mesh = model_volume->mesh;
|
TriangleMesh mesh = model_volume->mesh;
|
||||||
|
@ -410,8 +425,14 @@ std::vector<int> GLVolumeCollection::load_object(
|
||||||
v.drag_group_id = obj_idx * 1000;
|
v.drag_group_id = obj_idx * 1000;
|
||||||
else if (drag_by == "instance")
|
else if (drag_by == "instance")
|
||||||
v.drag_group_id = obj_idx * 1000 + instance_idx;
|
v.drag_group_id = obj_idx * 1000 + instance_idx;
|
||||||
|
|
||||||
if (!model_volume->modifier)
|
if (!model_volume->modifier)
|
||||||
|
{
|
||||||
v.layer_height_texture = layer_height_texture;
|
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.composite_id = obj_idx * 1000000;
|
||||||
v.select_group_id = obj_idx * 1000000;
|
v.select_group_id = obj_idx * 1000000;
|
||||||
v.drag_group_id = obj_idx * 1000;
|
v.drag_group_id = obj_idx * 1000;
|
||||||
|
v.is_wipe_tower = true;
|
||||||
return int(this->volumes.size() - 1);
|
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<const ConfigOptionStrings*>(config->option("extruder_colour"));
|
||||||
|
if (extruders_opt == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ConfigOptionStrings* filamemts_opt = dynamic_cast<const ConfigOptionStrings*>(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<Color> 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<double> GLVolumeCollection::get_current_print_zs() const
|
std::vector<double> GLVolumeCollection::get_current_print_zs() const
|
||||||
{
|
{
|
||||||
// Collect layer top positions of all volumes.
|
// Collect layer top positions of all volumes.
|
||||||
|
|
|
@ -246,12 +246,15 @@ public:
|
||||||
composite_id(-1),
|
composite_id(-1),
|
||||||
select_group_id(-1),
|
select_group_id(-1),
|
||||||
drag_group_id(-1),
|
drag_group_id(-1),
|
||||||
|
extruder_id(0),
|
||||||
selected(false),
|
selected(false),
|
||||||
is_active(true),
|
is_active(true),
|
||||||
zoom_to_volumes(true),
|
zoom_to_volumes(true),
|
||||||
outside_printer_detection_enabled(true),
|
outside_printer_detection_enabled(true),
|
||||||
is_outside(false),
|
is_outside(false),
|
||||||
hover(false),
|
hover(false),
|
||||||
|
is_modifier(false),
|
||||||
|
is_wipe_tower(false),
|
||||||
tverts_range(0, size_t(-1)),
|
tverts_range(0, size_t(-1)),
|
||||||
qverts_range(0, size_t(-1))
|
qverts_range(0, size_t(-1))
|
||||||
{
|
{
|
||||||
|
@ -287,6 +290,8 @@ public:
|
||||||
int select_group_id;
|
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.
|
// 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;
|
int drag_group_id;
|
||||||
|
// An ID containing the extruder ID (used to select color).
|
||||||
|
int extruder_id;
|
||||||
// Is this object selected?
|
// Is this object selected?
|
||||||
bool selected;
|
bool selected;
|
||||||
// Whether or not this volume is active for rendering
|
// Whether or not this volume is active for rendering
|
||||||
|
@ -299,6 +304,10 @@ public:
|
||||||
bool is_outside;
|
bool is_outside;
|
||||||
// Boolean: Is mouse over this object?
|
// Boolean: Is mouse over this object?
|
||||||
bool hover;
|
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.
|
// Interleaved triangles & normals with indexed triangles & quads.
|
||||||
GLIndexedVertexArray indexed_vertex_array;
|
GLIndexedVertexArray indexed_vertex_array;
|
||||||
|
@ -352,10 +361,7 @@ public:
|
||||||
return (layer_height_texture.get() == nullptr) ? 0 :
|
return (layer_height_texture.get() == nullptr) ? 0 :
|
||||||
(void*)(layer_height_texture->data.data() + layer_height_texture->width * layer_height_texture->height * 4);
|
(void*)(layer_height_texture->data.data() + layer_height_texture->width * layer_height_texture->height * 4);
|
||||||
}
|
}
|
||||||
double layer_height_texture_z_to_row_id() const {
|
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);
|
|
||||||
}
|
|
||||||
void generate_layer_height_texture(PrintObject *print_object, bool force);
|
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)
|
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_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
|
// Returns a vector containing the sorted list of all the print_zs of the volumes contained in this collection
|
||||||
std::vector<double> get_current_print_zs() const;
|
std::vector<double> get_current_print_zs() const;
|
||||||
|
|
|
@ -990,7 +990,7 @@ static inline int hex_digit_to_int(const char c)
|
||||||
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
|
(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;
|
rgb_out[0] = rgb_out[1] = rgb_out[2] = 0;
|
||||||
if (scolor.size() != 7 || scolor.front() != '#')
|
if (scolor.size() != 7 || scolor.front() != '#')
|
||||||
|
|
|
@ -117,6 +117,8 @@ public:
|
||||||
// preset if the current print or filament preset is not compatible.
|
// preset if the current print or filament preset is not compatible.
|
||||||
void update_compatible_with_printer(bool select_other_if_incompatible);
|
void update_compatible_with_printer(bool select_other_if_incompatible);
|
||||||
|
|
||||||
|
static bool parse_color(const std::string &scolor, unsigned char *rgb_out);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string load_system_presets();
|
std::string load_system_presets();
|
||||||
|
|
||||||
|
|
|
@ -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 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_outside_state(DynamicPrintConfig* config, bool all_inside);
|
||||||
|
void update_colors_by_extruder(DynamicPrintConfig* config);
|
||||||
|
|
||||||
bool move_volume_up(int idx)
|
bool move_volume_up(int idx)
|
||||||
%code%{
|
%code%{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue