Merge remote-tracking branch 'remotes/origin/scene_manipulators'

This commit is contained in:
bubnikv 2018-05-22 14:32:07 +02:00
commit 306d77559e
11 changed files with 112 additions and 90 deletions

View File

@ -1401,7 +1401,7 @@ sub Render {
if ($self->enable_picking) { if ($self->enable_picking) {
$self->mark_volumes_for_layer_height; $self->mark_volumes_for_layer_height;
$self->volumes->set_print_box($self->bed_bounding_box->x_min, $self->bed_bounding_box->y_min, 0.0, $self->bed_bounding_box->x_max, $self->bed_bounding_box->y_max, $self->{config}->get('max_print_height')); $self->volumes->set_print_box($self->bed_bounding_box->x_min, $self->bed_bounding_box->y_min, 0.0, $self->bed_bounding_box->x_max, $self->bed_bounding_box->y_max, $self->{config}->get('max_print_height'));
$self->volumes->update_outside_state($self->{config}, 0); $self->volumes->check_outside_state($self->{config});
# do not cull backfaces to show broken geometry, if any # do not cull backfaces to show broken geometry, if any
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
} }
@ -2192,10 +2192,8 @@ sub reset_legend_texture {
} }
sub get_current_print_zs { sub get_current_print_zs {
my ($self) = @_; my ($self, $active_only) = @_;
return $self->volumes->get_current_print_zs($active_only);
my $count = $self->volumes->get_current_print_zs();
return $count;
} }
1; 1;

View File

@ -1973,7 +1973,7 @@ 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 $model_fits = $self->{model}->fits_print_volume($self->{config}); my $model_fits = $self->{canvas3D} ? $self->{canvas3D}->volumes->check_outside_state($self->{config}) : 1;
my $method = ($have_objects && ! $export_in_progress && $model_fits) ? 'Enable' : 'Disable'; 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);

View File

@ -237,13 +237,14 @@ sub reload_scene {
# 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)
{ {
if (!$self->{model}->fits_print_volume($self->{config})) { my $contained = $self->volumes->check_outside_state($self->{config});
if (!$contained) {
$self->set_warning_enabled(1); $self->set_warning_enabled(1);
Slic3r::GUI::_3DScene::generate_warning_texture(L("Detected object outside print volume")); Slic3r::GUI::_3DScene::generate_warning_texture(L("Detected object outside print volume"));
$self->on_enable_action_buttons->(0) if ($self->on_enable_action_buttons); $self->on_enable_action_buttons->(0) if ($self->on_enable_action_buttons);
} else { } else {
$self->set_warning_enabled(0); $self->set_warning_enabled(0);
$self->volumes->update_outside_state($self->{config}, 1); $self->volumes->reset_outside_state();
Slic3r::GUI::_3DScene::reset_warning_texture(); Slic3r::GUI::_3DScene::reset_warning_texture();
$self->on_enable_action_buttons->(scalar @{$self->{model}->objects} > 0) if ($self->on_enable_action_buttons); $self->on_enable_action_buttons->(scalar @{$self->{model}->objects} > 0) if ($self->on_enable_action_buttons);
} }

View File

@ -328,22 +328,12 @@ sub load_print {
} }
if ($n_layers == 0) { if ($n_layers == 0) {
$self->enabled(0); $self->reset_sliders;
$self->set_z_range(0,0);
$self->slider_low->Hide;
$self->slider_high->Hide;
$self->{z_label_low}->SetLabel("");
$self->{z_label_high}->SetLabel("");
$self->{z_label_low_idx}->SetLabel("");
$self->{z_label_high_idx}->SetLabel("");
$self->canvas->reset_legend_texture(); $self->canvas->reset_legend_texture();
$self->canvas->Refresh; # clears canvas $self->canvas->Refresh; # clears canvas
return; return;
} }
# used to set the sliders to the extremes of the current zs range
$self->{force_sliders_full_range} = 0;
if ($self->{preferred_color_mode} eq 'tool_or_feature') { if ($self->{preferred_color_mode} eq 'tool_or_feature') {
# It is left to Slic3r to decide whether the print shall be colored by the tool or by the feature. # It is left to Slic3r to decide whether the print shall be colored by the tool or by the feature.
# Color by feature if it is a single extruder print. # Color by feature if it is a single extruder print.
@ -369,6 +359,9 @@ sub load_print {
} }
if ($self->IsShown) { if ($self->IsShown) {
# used to set the sliders to the extremes of the current zs range
$self->{force_sliders_full_range} = 0;
if ($self->gcode_preview_data->empty) { if ($self->gcode_preview_data->empty) {
# load skirt and brim # load skirt and brim
$self->canvas->load_print_toolpaths($self->print, \@colors); $self->canvas->load_print_toolpaths($self->print, \@colors);
@ -387,15 +380,32 @@ sub load_print {
$self->show_hide_ui_elements('full'); $self->show_hide_ui_elements('full');
# recalculates zs and update sliders accordingly # recalculates zs and update sliders accordingly
$self->{layers_z} = $self->canvas->get_current_print_zs(); $self->{layers_z} = $self->canvas->get_current_print_zs(1);
$n_layers = scalar(@{$self->{layers_z}}); $n_layers = scalar(@{$self->{layers_z}});
} if ($n_layers == 0) {
# all layers filtered out
$self->reset_sliders;
$self->canvas->Refresh; # clears canvas
}
}
$self->update_sliders($n_layers); $self->update_sliders($n_layers) if ($n_layers > 0);
$self->_loaded(1); $self->_loaded(1);
} }
} }
sub reset_sliders {
my ($self) = @_;
$self->enabled(0);
$self->set_z_range(0,0);
$self->slider_low->Hide;
$self->slider_high->Hide;
$self->{z_label_low}->SetLabel("");
$self->{z_label_high}->SetLabel("");
$self->{z_label_low_idx}->SetLabel("");
$self->{z_label_high_idx}->SetLabel("");
}
sub update_sliders sub update_sliders
{ {
my ($self, $n_layers) = @_; my ($self, $n_layers) = @_;
@ -410,18 +420,32 @@ sub update_sliders
$z_idx_low = 0; $z_idx_low = 0;
$z_idx_high = $n_layers - 1; $z_idx_high = $n_layers - 1;
} elsif ($z_idx_high < $n_layers && ($self->single_layer || $z_idx_high != 0)) { } elsif ($z_idx_high < $n_layers && ($self->single_layer || $z_idx_high != 0)) {
# use $z_idx # search new indices for nearest z (size of $self->{layers_z} may change in dependence of what is shown)
} else { if (defined($self->{z_low})) {
for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) {
if ($self->{layers_z}[$i] <= $self->{z_low}) {
$z_idx_low = $i;
last;
}
}
}
if (defined($self->{z_high})) {
for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) {
if ($self->{layers_z}[$i] <= $self->{z_high}) {
$z_idx_high = $i;
last;
}
}
}
} elsif ($z_idx_high >= $n_layers) {
# Out of range. Disable 'single layer' view. # Out of range. Disable 'single layer' view.
$self->single_layer(0); $self->single_layer(0);
$self->{checkbox_singlelayer}->SetValue(0); $self->{checkbox_singlelayer}->SetValue(0);
$z_idx_low = 0; $z_idx_low = 0;
$z_idx_high = $n_layers - 1; $z_idx_high = $n_layers - 1;
} } else {
if ($self->single_layer) {
$z_idx_low = $z_idx_high;
} elsif ($z_idx_low > $z_idx_high) {
$z_idx_low = 0; $z_idx_low = 0;
$z_idx_high = $n_layers - 1;
} }
$self->slider_low->SetValue($z_idx_low); $self->slider_low->SetValue($z_idx_low);
@ -437,12 +461,25 @@ sub set_z_range
my ($self, $z_low, $z_high) = @_; my ($self, $z_low, $z_high) = @_;
return if !$self->enabled; return if !$self->enabled;
$self->{z_low} = $z_low;
$self->{z_high} = $z_high;
$self->{z_label_low}->SetLabel(sprintf '%.2f', $z_low); $self->{z_label_low}->SetLabel(sprintf '%.2f', $z_low);
$self->{z_label_high}->SetLabel(sprintf '%.2f', $z_high); $self->{z_label_high}->SetLabel(sprintf '%.2f', $z_high);
my $z_idx_low = 1 + $self->slider_low->GetValue;
my $z_idx_high = 1 + $self->slider_high->GetValue; my $layers_z = $self->canvas->get_current_print_zs(0);
$self->{z_label_low_idx}->SetLabel(sprintf '%d', $z_idx_low); for (my $i = 0; $i < scalar(@{$layers_z}); $i += 1) {
$self->{z_label_high_idx}->SetLabel(sprintf '%d', $z_idx_high); if (($z_low - 1e-6 < @{$layers_z}[$i]) && (@{$layers_z}[$i] < $z_low + 1e-6)) {
$self->{z_label_low_idx}->SetLabel(sprintf '%d', $i + 1);
last;
}
}
for (my $i = 0; $i < scalar(@{$layers_z}); $i += 1) {
if (($z_high - 1e-6 < @{$layers_z}[$i]) && (@{$layers_z}[$i] < $z_high + 1e-6)) {
$self->{z_label_high_idx}->SetLabel(sprintf '%d', $i + 1);
last;
}
}
$self->canvas->set_toolpaths_range($z_low - 1e-6, $z_high + 1e-6); $self->canvas->set_toolpaths_range($z_low - 1e-6, $z_high + 1e-6);
$self->canvas->Refresh if $self->IsShown; $self->canvas->Refresh if $self->IsShown;
} }

View File

@ -451,36 +451,6 @@ void Model::adjust_min_z()
} }
} }
bool Model::fits_print_volume(const DynamicPrintConfig* config) const
{
if (config == nullptr)
return false;
if (objects.empty())
return true;
const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config->option("bed_shape"));
if (opt == nullptr)
return false;
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config->opt_float("max_print_height")));
// Allow the objects to protrude below the print bed
print_volume.min.z = -1e10;
return print_volume.contains(transformed_bounding_box());
}
bool Model::fits_print_volume(const FullPrintConfig &config) const
{
if (objects.empty())
return true;
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(config.bed_shape.values));
BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config.max_print_height));
// Allow the objects to protrude below the print bed
print_volume.min.z = -1e10;
return print_volume.contains(transformed_bounding_box());
}
unsigned int Model::get_auto_extruder_id(unsigned int max_extruders) unsigned int Model::get_auto_extruder_id(unsigned int max_extruders)
{ {
unsigned int id = s_auto_extruder_id; unsigned int id = s_auto_extruder_id;

View File

@ -285,10 +285,6 @@ public:
// Ensures that the min z of the model is not negative // Ensures that the min z of the model is not negative
void adjust_min_z(); void adjust_min_z();
// Returs true if this model is contained into the print volume defined inside the given config
bool fits_print_volume(const DynamicPrintConfig* 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(unsigned int max_extruders); static unsigned int get_auto_extruder_id(unsigned int max_extruders);

View File

@ -522,7 +522,7 @@ std::string Print::validate() const
// Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced. // Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced.
print_volume.min.z = -1e10; print_volume.min.z = -1e10;
for (PrintObject *po : this->objects) { for (PrintObject *po : this->objects) {
if (! print_volume.contains(po->model_object()->tight_bounding_box(false))) if (!print_volume.contains(po->model_object()->tight_bounding_box(false)))
return "Some objects are outside of the print volume."; return "Some objects are outside of the print volume.";
} }

View File

@ -646,29 +646,40 @@ void GLVolumeCollection::render_legacy() const
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }
void GLVolumeCollection::update_outside_state(const DynamicPrintConfig* config, bool all_inside) bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config)
{ {
if (config == nullptr) if (config == nullptr)
return; return false;
const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config->option("bed_shape")); const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config->option("bed_shape"));
if (opt == nullptr) if (opt == nullptr)
return; return false;
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values)); BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config->opt_float("max_print_height"))); BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config->opt_float("max_print_height")));
// Allow the objects to protrude below the print bed // Allow the objects to protrude below the print bed
print_volume.min.z = -1e10; print_volume.min.z = -1e10;
bool contained = true;
for (GLVolume* volume : this->volumes) for (GLVolume* volume : this->volumes)
{ {
if (all_inside) if (volume != nullptr)
{ {
volume->is_outside = false; bool state = print_volume.contains(volume->transformed_bounding_box());
continue; contained &= state;
volume->is_outside = !state;
} }
}
volume->is_outside = !print_volume.contains(volume->transformed_bounding_box()); return contained;
}
void GLVolumeCollection::reset_outside_state()
{
for (GLVolume* volume : this->volumes)
{
if (volume != nullptr)
volume->is_outside = false;
} }
} }
@ -749,13 +760,13 @@ void GLVolumeCollection::update_colors_by_extruder(const DynamicPrintConfig* con
} }
} }
std::vector<double> GLVolumeCollection::get_current_print_zs() const std::vector<double> GLVolumeCollection::get_current_print_zs(bool active_only) const
{ {
// Collect layer top positions of all volumes. // Collect layer top positions of all volumes.
std::vector<double> print_zs; std::vector<double> print_zs;
for (GLVolume *vol : this->volumes) for (GLVolume *vol : this->volumes)
{ {
if (vol->is_active) if (!active_only || vol->is_active)
append(print_zs, vol->print_zs); append(print_zs, vol->print_zs);
} }
std::sort(print_zs.begin(), print_zs.end()); std::sort(print_zs.begin(), print_zs.end());
@ -2446,7 +2457,7 @@ bool _3DScene::_travel_paths_by_type(const GCodePreviewData& preview_data, GLVol
TypesList::iterator type = std::find(types.begin(), types.end(), Type(polyline.type)); TypesList::iterator type = std::find(types.begin(), types.end(), Type(polyline.type));
if (type != types.end()) if (type != types.end())
{ {
type->volume->print_zs.push_back(unscale(polyline.polyline.bounding_box().max.z)); 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.quad_indices.size());
type->volume->offsets.push_back(type->volume->indexed_vertex_array.triangle_indices.size()); type->volume->offsets.push_back(type->volume->indexed_vertex_array.triangle_indices.size());
@ -2512,7 +2523,7 @@ bool _3DScene::_travel_paths_by_feedrate(const GCodePreviewData& preview_data, G
FeedratesList::iterator feedrate = std::find(feedrates.begin(), feedrates.end(), Feedrate(polyline.feedrate)); FeedratesList::iterator feedrate = std::find(feedrates.begin(), feedrates.end(), Feedrate(polyline.feedrate));
if (feedrate != feedrates.end()) if (feedrate != feedrates.end())
{ {
feedrate->volume->print_zs.push_back(unscale(polyline.polyline.bounding_box().max.z)); 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.quad_indices.size());
feedrate->volume->offsets.push_back(feedrate->volume->indexed_vertex_array.triangle_indices.size()); feedrate->volume->offsets.push_back(feedrate->volume->indexed_vertex_array.triangle_indices.size());
@ -2578,7 +2589,7 @@ bool _3DScene::_travel_paths_by_tool(const GCodePreviewData& preview_data, GLVol
ToolsList::iterator tool = std::find(tools.begin(), tools.end(), Tool(polyline.extruder_id)); ToolsList::iterator tool = std::find(tools.begin(), tools.end(), Tool(polyline.extruder_id));
if (tool != tools.end()) if (tool != tools.end())
{ {
tool->volume->print_zs.push_back(unscale(polyline.polyline.bounding_box().max.z)); 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.quad_indices.size());
tool->volume->offsets.push_back(tool->volume->indexed_vertex_array.triangle_indices.size()); tool->volume->offsets.push_back(tool->volume->indexed_vertex_array.triangle_indices.size());
@ -2602,7 +2613,10 @@ void _3DScene::_load_gcode_retractions(const GCodePreviewData& preview_data, GLV
{ {
volumes.volumes.emplace_back(volume); volumes.volumes.emplace_back(volume);
for (const GCodePreviewData::Retraction::Position& position : preview_data.retraction.positions) 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; });
for (const GCodePreviewData::Retraction::Position& position : copy)
{ {
volume->print_zs.push_back(unscale(position.position.z)); 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.quad_indices.size());
@ -2630,7 +2644,10 @@ void _3DScene::_load_gcode_unretractions(const GCodePreviewData& preview_data, G
{ {
volumes.volumes.emplace_back(volume); volumes.volumes.emplace_back(volume);
for (const GCodePreviewData::Retraction::Position& position : preview_data.unretraction.positions) 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; });
for (const GCodePreviewData::Retraction::Position& position : copy)
{ {
volume->print_zs.push_back(unscale(position.position.z)); 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.quad_indices.size());

View File

@ -422,11 +422,13 @@ public:
print_box_max[0] = max_x; print_box_max[1] = max_y; print_box_max[2] = max_z; print_box_max[0] = max_x; print_box_max[1] = max_y; print_box_max[2] = max_z;
} }
void update_outside_state(const DynamicPrintConfig* config, bool all_inside); bool check_outside_state(const DynamicPrintConfig* config);
void reset_outside_state();
void update_colors_by_extruder(const DynamicPrintConfig* config); 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(bool active_only) const;
private: private:
GLVolumeCollection(const GLVolumeCollection &other); GLVolumeCollection(const GLVolumeCollection &other);

View File

@ -92,10 +92,9 @@
int count() int count()
%code{% RETVAL = THIS->volumes.size(); %}; %code{% RETVAL = THIS->volumes.size(); %};
std::vector<double> get_current_print_zs() std::vector<double> get_current_print_zs(bool active_only)
%code{% RETVAL = THIS->get_current_print_zs(); %}; %code{% RETVAL = THIS->get_current_print_zs(active_only); %};
void set_range(double low, double high); void set_range(double low, double high);
void render_VBOs() const; void render_VBOs() const;
@ -104,7 +103,12 @@
void release_geometry(); void release_geometry();
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); bool check_outside_state(DynamicPrintConfig* config)
%code%{
RETVAL = THIS->check_outside_state(config);
%};
void reset_outside_state();
void update_colors_by_extruder(DynamicPrintConfig* config); void update_colors_by_extruder(DynamicPrintConfig* config);
bool move_volume_up(int idx) bool move_volume_up(int idx)

View File

@ -99,9 +99,6 @@
void print_info() const; void print_info() const;
bool fits_print_volume(DynamicPrintConfig* config) const
%code%{ RETVAL = THIS->fits_print_volume(config); %};
bool store_stl(char *path, bool binary) bool store_stl(char *path, bool binary)
%code%{ TriangleMesh mesh = THIS->mesh(); RETVAL = Slic3r::store_stl(path, &mesh, binary); %}; %code%{ TriangleMesh mesh = THIS->mesh(); RETVAL = Slic3r::store_stl(path, &mesh, binary); %};
bool store_amf(char *path, Print* print, bool export_print_config) bool store_amf(char *path, Print* print, bool export_print_config)