From f82a8475a1ccd7ca9ebddd31d6b60953a26b5f39 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Fri, 11 Jul 2014 20:09:01 +0200 Subject: [PATCH] Use AMF object and volume metadata for handling per-object and per-volume settings --- lib/Slic3r/Format/AMF.pm | 15 ++++++++++ lib/Slic3r/Format/AMF/Parser.pm | 35 ++++++++++++++++------- lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm | 16 ++--------- lib/Slic3r/Print.pm | 3 +- xs/src/Model.cpp | 2 +- xs/src/Model.hpp | 1 + xs/xsp/Model.xsp | 2 ++ 7 files changed, 47 insertions(+), 27 deletions(-) diff --git a/lib/Slic3r/Format/AMF.pm b/lib/Slic3r/Format/AMF.pm index 5dad1001e..d66a60d11 100644 --- a/lib/Slic3r/Format/AMF.pm +++ b/lib/Slic3r/Format/AMF.pm @@ -51,6 +51,12 @@ sub write_file { for my $object_id (0 .. $#{ $model->objects }) { my $object = $model->objects->[$object_id]; printf $fh qq{ \n}, $object_id; + + my $config = $object->config; + foreach my $opt_key (@{$config->get_keys}) { + printf $fh qq{ %s\n}, $opt_key, $config->serialize($opt_key); + } + printf $fh qq{ \n}; printf $fh qq{ \n}; my @vertices_offset = (); @@ -76,6 +82,15 @@ sub write_file { my $vertices_offset = shift @vertices_offset; printf $fh qq{ \n}, (!defined $volume->material_id) ? '' : (sprintf ' materialid="%s"', $volume->material_id); + + my $config = $volume->config; + foreach my $opt_key (@{$config->get_keys}) { + printf $fh qq{ %s\n}, $opt_key, $config->serialize($opt_key); + } + if ($volume->modifier) { + printf $fh qq{ 1\n}; + } + foreach my $facet (@{$volume->mesh->facets}) { printf $fh qq{ \n}; printf $fh qq{ %d\n}, $_, $facet->[$_-1] + $vertices_offset, $_ for 1..3; diff --git a/lib/Slic3r/Format/AMF/Parser.pm b/lib/Slic3r/Format/AMF/Parser.pm index b61746f9a..8d4a839f4 100644 --- a/lib/Slic3r/Format/AMF/Parser.pm +++ b/lib/Slic3r/Format/AMF/Parser.pm @@ -39,9 +39,9 @@ sub start_element { } elsif ($data->{LocalName} eq 'material') { my $material_id = $self->_get_attribute($data, 'id') // '_'; $self->{_material} = $self->{_model}->set_material($material_id); - } elsif ($data->{LocalName} eq 'metadata' && $self->{_tree}[-1] eq 'material') { - $self->{_material_metadata_type} = $self->_get_attribute($data, 'type'); - $self->{_material}->set_attribute($self->{_material_metadata_type}, ""); + } elsif ($data->{LocalName} eq 'metadata') { + $self->{_metadata_type} = $self->_get_attribute($data, 'type'); + $self->{_metadata_value} = ''; } elsif ($data->{LocalName} eq 'constellation') { $self->{_constellation} = 1; # we merge all constellations as we don't support more than one } elsif ($data->{LocalName} eq 'instance' && $self->{_constellation}) { @@ -63,10 +63,8 @@ sub characters { $self->{_vertex}[ $xyz_index{$self->{_coordinate}} ] .= $data->{Data}; } elsif ($self->{_triangle} && defined $self->{_vertex_idx}) { $self->{_triangle}[ $self->{_vertex_idx} ] .= $data->{Data}; - } elsif ($self->{_material_metadata_type}) { - my $value = $self->{_material}->get_attribute($self->{_material_metadata_type}); - $value .= $data->{Data}; - $self->{_material}->set_attribute($self->{_material_metadata_type}, $value); + } elsif ($self->{_metadata_type}) { + $self->{_metadata_value} .= $data->{Data}; } elsif ($self->{_instance_property}) { $self->{_instance}{ $self->{_instance_property} } .= $data->{Data}; } @@ -98,14 +96,29 @@ sub end_element { $self->{_vertex_idx} = undef; } elsif ($data->{LocalName} eq 'material') { $self->{_material} = undef; - } elsif ($data->{LocalName} eq 'metadata' && $self->{_material}) { - if ($self->{_material_metadata_type} =~ /^slic3r\.(.+)/) { + } elsif ($data->{LocalName} eq 'metadata') { + my $value = $self->{_metadata_value}; + if ($self->{_metadata_type} =~ /^slic3r\.(.+)/) { my $opt_key = $1; if (exists $Slic3r::Config::Options->{$opt_key}) { - $self->{_material}->config->set_deserialize($opt_key, $self->{_material}->get_attribute("slic3r.$opt_key")); + my $config; + if ($self->{_material}) { + $config = $self->{_material}->config; + } elsif ($self->{_volume}) { + $config = $self->{_volume}->config; + } elsif ($self->{_object}) { + $config = $self->{_object}->config; + } + + $config->set_deserialize($opt_key, $value) if defined $config; + } elsif ($opt_key eq 'modifier' && $self->{_volume}) { + $self->{_volume}->set_modifier($value); } + } elsif ($self->{_material}) { + $self->{_material}->set_attribute($self->{_metadata_type}, $value); } - $self->{_material_metadata_type} = undef; + $self->{_metadata_type} = undef; + $self->{_metadata_value} = undef; } elsif ($data->{LocalName} eq 'constellation') { $self->{_constellation} = undef; } elsif ($data->{LocalName} eq 'instance') { diff --git a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm index 097f86d12..a987c043f 100644 --- a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm +++ b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm @@ -160,14 +160,11 @@ sub selection_changed { # attach volume material config to settings panel my $volume = $self->{model_object}->volumes->[ $itemData->{volume_id} ]; - my $material = $self->{model_object}->model->get_material($volume->material_id // '_'); - $material //= $volume->assign_unique_material; + $config = $volume->config; $self->{staticbox}->SetLabel('Part Settings'); # get default values @opt_keys = @{Slic3r::Config::PrintRegion->new->get_keys}; - - $config = $material->config; } elsif ($itemData->{type} eq 'object') { # select all object volumes in 3D preview if ($self->{canvas}) { @@ -211,21 +208,12 @@ sub on_btn_load { foreach my $volume (@{$object->volumes}) { my $new_volume = $self->{model_object}->add_volume($volume); $new_volume->set_modifier($is_modifier); - if (!defined $new_volume->material_id) { - # it looks like this block is never entered because all input volumes seem to have an assigned material - # TODO: check we can assume that for any input format - my $material_name = basename($input_file); - $material_name =~ s/\.(stl|obj)$//i; - my $material = $self->{model_object}->model->set_material($material_name); - $new_volume->material_id($material_name); - } # apply the same translation we applied to the object $new_volume->mesh->translate(@{$self->{model_object}->origin_translation}, 0); # set a default extruder value, since user can't add it manually - my $material = $self->{model_object}->model->get_material($new_volume->material_id); - $material->config->set_ifndef('extruder', 1); + $new_volume->config->set_ifndef('extruder', 0); $self->{parts_changed} = 1; } diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index abd25fce1..409e65f1b 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -186,8 +186,9 @@ sub add_model_object { my $config = Slic3r::Config::PrintRegion->new; $config->apply($self->default_region_config); - # override the defaults with per-object config and then with per-material config + # override the defaults with per-object config and then with per-material and per-volume configs $config->apply_dynamic($object_config); + $config->apply_dynamic($volume->config); if (defined $volume->material_id) { my $material_config = $volume->material->config->clone; diff --git a/xs/src/Model.cpp b/xs/src/Model.cpp index 5d24b39b6..abbff5fa0 100644 --- a/xs/src/Model.cpp +++ b/xs/src/Model.cpp @@ -321,7 +321,7 @@ ModelVolume::ModelVolume(ModelObject* object, const TriangleMesh &mesh) {} ModelVolume::ModelVolume(ModelObject* object, const ModelVolume &other) -: object(object), mesh(other.mesh), modifier(other.modifier) +: object(object), mesh(other.mesh), config(other.config), modifier(other.modifier) { this->material_id(other.material_id()); } diff --git a/xs/src/Model.hpp b/xs/src/Model.hpp index 9e2d1234c..293e7d350 100644 --- a/xs/src/Model.hpp +++ b/xs/src/Model.hpp @@ -139,6 +139,7 @@ class ModelVolume friend class ModelObject; public: TriangleMesh mesh; + DynamicPrintConfig config; bool modifier; ModelObject* get_object() const { return this->object; }; diff --git a/xs/xsp/Model.xsp b/xs/xsp/Model.xsp index 798169cc5..1f573cb37 100644 --- a/xs/xsp/Model.xsp +++ b/xs/xsp/Model.xsp @@ -167,6 +167,8 @@ ModelMaterial::attributes() %code%{ THIS->material_id(material_id); %}; Ref material(); + Ref config() + %code%{ RETVAL = &THIS->config; %}; Ref mesh() %code%{ RETVAL = &THIS->mesh; %};