Ported some methods including add_model_object() and apply_config() to XS

This commit is contained in:
Alessandro Ranellucci 2014-11-09 12:25:59 +01:00
parent 6b4015f9ac
commit 3e4c572164
14 changed files with 312 additions and 254 deletions

View file

@ -174,19 +174,6 @@ sub _handle_legacy {
return ($opt_key, $value);
}
sub set_ifndef {
my $self = shift;
my ($opt_key, $value, $deserialize) = @_;
if (!$self->has($opt_key)) {
if ($deserialize) {
$self->set_deserialize($opt_key, $value);
} else {
$self->set($opt_key, $value);
}
}
}
sub as_ini {
my ($self) = @_;
@ -213,23 +200,6 @@ sub setenv {
}
}
sub equals {
my ($self, $other) = @_;
return @{ $self->diff($other) } == 0;
}
# this will *ignore* options not present in both configs
sub diff {
my ($self, $other) = @_;
my @diff = ();
foreach my $opt_key (sort @{$self->get_keys}) {
push @diff, $opt_key
if $other->has($opt_key) && $other->serialize($opt_key) ne $self->serialize($opt_key);
}
return [@diff];
}
# this method is idempotent by design and only applies to ::DynamicConfig or ::Full
# objects because it performs cross checks
sub validate {

View file

@ -34,189 +34,6 @@ sub status_cb {
return $status_cb // sub {};
}
sub apply_config {
my ($self, $config) = @_;
$config = $config->clone;
$config->normalize;
# apply variables to placeholder parser
$self->placeholder_parser->apply_config($config);
my $invalidated = 0;
# handle changes to print config
my $print_diff = $self->config->diff($config);
if (@$print_diff) {
$self->config->apply_dynamic($config);
$invalidated = 1
if $self->invalidate_state_by_config_options($print_diff);
}
# handle changes to object config defaults
$self->default_object_config->apply_dynamic($config);
foreach my $object (@{$self->objects}) {
# we don't assume that $config contains a full ObjectConfig,
# so we base it on the current print-wise default
my $new = $self->default_object_config->clone;
$new->apply_dynamic($config);
# we override the new config with object-specific options
my $model_object_config = $object->model_object->config->clone;
$model_object_config->normalize;
$new->apply_dynamic($model_object_config);
# check whether the new config is different from the current one
my $diff = $object->config->diff($new);
if (@$diff) {
$object->config->apply($new);
$invalidated = 1
if $object->invalidate_state_by_config_options($diff);
}
}
# handle changes to regions config defaults
$self->default_region_config->apply_dynamic($config);
# All regions now have distinct settings.
# Check whether applying the new region config defaults we'd get different regions.
my $rearrange_regions = 0;
my @other_region_configs = ();
REGION: foreach my $region_id (0..($self->region_count - 1)) {
my $region = $self->regions->[$region_id];
my @this_region_configs = ();
foreach my $object (@{$self->objects}) {
foreach my $volume_id (@{ $object->get_region_volumes($region_id) }) {
my $volume = $object->model_object->volumes->[$volume_id];
my $new = $self->default_region_config->clone;
foreach my $other_config ($object->model_object->config, $volume->config) {
my $other_config = $other_config->clone;
$other_config->normalize;
$new->apply_dynamic($other_config);
}
if ($volume->material_id ne '') {
my $material_config = $object->model_object->model->get_material($volume->material_id)->config->clone;
$material_config->normalize;
$new->apply_dynamic($material_config);
}
if (defined first { !$_->equals($new) } @this_region_configs) {
# if the new config for this volume differs from the other
# volume configs currently associated to this region, it means
# the region subdivision does not make sense anymore
$rearrange_regions = 1;
last REGION;
}
push @this_region_configs, $new;
if (defined first { $_->equals($new) } @other_region_configs) {
# if the new config for this volume equals any of the other
# volume configs that are not currently associated to this
# region, it means the region subdivision does not make
# sense anymore
$rearrange_regions = 1;
last REGION;
}
# if we're here and the new region config is different from the old
# one, we need to apply the new config and invalidate all objects
# (possible optimization: only invalidate objects using this region)
my $region_config_diff = $region->config->diff($new);
if (@$region_config_diff) {
$region->config->apply($new);
foreach my $o (@{$self->objects}) {
$invalidated = 1
if $o->invalidate_state_by_config_options($region_config_diff);
}
}
}
}
push @other_region_configs, @this_region_configs;
}
if ($rearrange_regions) {
# the current subdivision of regions does not make sense anymore.
# we need to remove all objects and re-add them
my @model_objects = map $_->model_object, @{$self->objects};
$self->clear_objects;
$self->add_model_object($_) for @model_objects;
$invalidated = 1;
}
return $invalidated;
}
# caller is responsible for supplying models whose objects don't collide
# and have explicit instance positions
sub add_model_object {
my $self = shift;
my ($object, $obj_idx) = @_;
my $object_config = $object->config->clone;
$object_config->normalize;
# initialize print object and store it at the given position
my $o;
if (defined $obj_idx) {
$o = $self->set_new_object($obj_idx, $object, $object->raw_bounding_box);
} else {
$o = $self->add_object($object, $object->raw_bounding_box);
}
$o->set_copies([ map Slic3r::Point->new_scale(@{ $_->offset }), @{ $object->instances } ]);
$o->set_layer_height_ranges($object->layer_height_ranges);
# TODO: translate _trigger_copies to C++, then this can be done by
# PrintObject constructor
$o->_trigger_copies;
foreach my $volume_id (0..$#{$object->volumes}) {
my $volume = $object->volumes->[$volume_id];
# get the config applied to this volume: start from our global defaults
my $config = Slic3r::Config::PrintRegion->new;
$config->apply($self->default_region_config);
# override the defaults with per-object config and then with per-volume and per-material configs
foreach my $other_config ($object_config, $volume->config) {
my $other_config = $other_config->clone;
$other_config->normalize;
$config->apply_dynamic($other_config);
}
if ($volume->material_id ne '') {
my $material_config = $volume->material->config->clone;
$material_config->normalize;
$config->apply_dynamic($material_config);
}
# find an existing print region with the same config
my $region_id;
foreach my $i (0..($self->region_count - 1)) {
my $region = $self->regions->[$i];
if ($config->equals($region->config)) {
$region_id = $i;
last;
}
}
# if no region exists with the same config, create a new one
if (!defined $region_id) {
my $r = $self->add_region();
$r->config->apply($config);
$region_id = $self->region_count - 1;
}
# assign volume to region
$o->add_region_volume($region_id, $volume_id);
}
# apply config to print object
$o->config->apply($self->default_object_config);
$o->config->apply_dynamic($object_config);
}
sub reload_object {
my ($self, $obj_idx) = @_;

View file

@ -32,34 +32,12 @@ sub support_layers {
return [ map $self->get_support_layer($_), 0..($self->support_layer_count - 1) ];
}
# TODO: translate to C++, then call it from constructor (see also
# Print->add_model_object)
sub _trigger_copies {
my $self = shift;
# TODO: should this mean point is 0,0?
return if !defined $self->_copies_shift;
# order copies with a nearest neighbor search and translate them by _copies_shift
$self->set_shifted_copies([
map {
my $c = $_->clone;
$c->translate(@{ $self->_copies_shift });
$c;
} @{$self->copies}[@{chained_path($self->copies)}]
]);
$self->print->invalidate_step(STEP_SKIRT);
$self->print->invalidate_step(STEP_BRIM);
}
# in unscaled coordinates
sub add_copy {
my ($self, $x, $y) = @_;
my @copies = @{$self->copies};
push @copies, Slic3r::Point->new_scale($x, $y);
$self->set_copies(\@copies);
$self->_trigger_copies;
}
sub delete_last_copy {
@ -67,13 +45,11 @@ sub delete_last_copy {
my @copies = $self->copies;
pop @copies;
$self->set_copies(\@copies);
$self->_trigger_copies;
}
sub delete_all_copies {
my ($self) = @_;
$self->set_copies([]);
$self->_trigger_copies;
}
# this is the *total* layer count (including support layers)

View file

@ -27,6 +27,27 @@ ConfigBase::apply(const ConfigBase &other, bool ignore_nonexistent) {
}
}
bool
ConfigBase::equals(ConfigBase &other) {
return this->diff(other).empty();
}
// this will *ignore* options not present in both configs
t_config_option_keys
ConfigBase::diff(ConfigBase &other) {
t_config_option_keys diff;
t_config_option_keys my_keys;
this->keys(&my_keys);
for (t_config_option_keys::const_iterator opt_key = my_keys.begin(); opt_key != my_keys.end(); ++opt_key) {
if (other.has(*opt_key) && other.serialize(*opt_key) != this->serialize(*opt_key)) {
diff.push_back(*opt_key);
}
}
return diff;
}
std::string
ConfigBase::serialize(const t_config_option_key opt_key) {
ConfigOption* opt = this->option(opt_key);
@ -248,6 +269,18 @@ ConfigBase::set_deserialize(const t_config_option_key opt_key, SV* str) {
return this->set_deserialize(opt_key, value);
}
void
ConfigBase::set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize)
{
if (!this->has(opt_key)) {
if (deserialize) {
this->set_deserialize(opt_key, value);
} else {
this->set(opt_key, value);
}
}
}
#endif
DynamicConfig& DynamicConfig::operator= (DynamicConfig other)

View file

@ -464,8 +464,11 @@ class ConfigBase
virtual const ConfigOption* option(const t_config_option_key opt_key) const = 0;
virtual void keys(t_config_option_keys *keys) const = 0;
void apply(const ConfigBase &other, bool ignore_nonexistent = false);
bool equals(ConfigBase &other);
t_config_option_keys diff(ConfigBase &other);
std::string serialize(const t_config_option_key opt_key);
bool set_deserialize(const t_config_option_key opt_key, std::string str);
void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false);
double get_abs_value(const t_config_option_key opt_key);
double get_abs_value(const t_config_option_key opt_key, double ratio_over);

View file

@ -25,7 +25,7 @@ sort_points (Point a, Point b)
/* This implementation is based on Andrew's monotone chain 2D convex hull algorithm */
void
convex_hull(Points &points, Polygon* hull)
convex_hull(Points points, Polygon* hull)
{
assert(points.size() >= 3);
// sort input points
@ -55,12 +55,12 @@ convex_hull(Points &points, Polygon* hull)
/* accepts an arrayref of points and returns a list of indices
according to a nearest-neighbor walk */
void
chained_path(Points &points, std::vector<Points::size_type> &retval, Point start_near)
chained_path(const Points &points, std::vector<Points::size_type> &retval, Point start_near)
{
PointPtrs my_points;
std::map<Point*,Points::size_type> indices;
PointConstPtrs my_points;
std::map<const Point*,Points::size_type> indices;
my_points.reserve(points.size());
for (Points::iterator it = points.begin(); it != points.end(); ++it) {
for (Points::const_iterator it = points.begin(); it != points.end(); ++it) {
my_points.push_back(&*it);
indices[&*it] = it - points.begin();
}
@ -75,7 +75,7 @@ chained_path(Points &points, std::vector<Points::size_type> &retval, Point start
}
void
chained_path(Points &points, std::vector<Points::size_type> &retval)
chained_path(const Points &points, std::vector<Points::size_type> &retval)
{
if (points.empty()) return; // can't call front() on empty vector
chained_path(points, retval, points.front());

View file

@ -11,9 +11,9 @@ using boost::polygon::voronoi_diagram;
namespace Slic3r { namespace Geometry {
void convex_hull(Points &points, Polygon* hull);
void chained_path(Points &points, std::vector<Points::size_type> &retval, Point start_near);
void chained_path(Points &points, std::vector<Points::size_type> &retval);
void convex_hull(Points points, Polygon* hull);
void chained_path(const Points &points, std::vector<Points::size_type> &retval, Point start_near);
void chained_path(const Points &points, std::vector<Points::size_type> &retval);
template<class T> void chained_path_items(Points &points, T &items, T &retval);
bool directions_parallel(double angle1, double angle2, double max_diff = 0);

View file

@ -40,6 +40,12 @@ Point::translate(double x, double y)
this->y += y;
}
void
Point::translate(const Point &vector)
{
this->translate(vector.x, vector.y);
}
void
Point::rotate(double angle, const Point &center)
{

View file

@ -27,10 +27,14 @@ class Point
Point(int _x, int _y): x(_x), y(_y) {};
Point(long long _x, long long _y): x(_x), y(_y) {}; // for Clipper
Point(double x, double y);
static Point new_scale(coordf_t x, coordf_t y) {
return Point(scale_(x), scale_(y));
};
bool operator==(const Point& rhs) const;
std::string wkt() const;
void scale(double factor);
void translate(double x, double y);
void translate(const Point &vector);
void rotate(double angle, const Point &center);
bool coincides_with(const Point &point) const;
bool coincides_with_epsilon(const Point &point) const;

View file

@ -308,6 +308,189 @@ Print::max_allowed_layer_height() const
return *std::max_element(nozzle_diameter.begin(), nozzle_diameter.end());
}
/* Caller is responsible for supplying models whose objects don't collide
and have explicit instance positions */
void
Print::add_model_object(ModelObject* model_object, int idx)
{
DynamicPrintConfig object_config = model_object->config; // clone
object_config.normalize();
// initialize print object and store it at the given position
PrintObject* o;
{
BoundingBoxf3 bb;
model_object->raw_bounding_box(&bb);
o = (idx != -1)
? this->set_new_object(idx, model_object, bb)
: this->add_object(model_object, bb);
}
{
Points copies;
for (ModelInstancePtrs::const_iterator i = model_object->instances.begin(); i != model_object->instances.end(); ++i) {
copies.push_back(Point::new_scale((*i)->offset.x, (*i)->offset.y));
}
o->set_copies(copies);
}
o->layer_height_ranges = model_object->layer_height_ranges;
for (ModelVolumePtrs::const_iterator v_i = model_object->volumes.begin(); v_i != model_object->volumes.end(); ++v_i) {
size_t volume_id = v_i - model_object->volumes.begin();
ModelVolume* volume = *v_i;
// get the config applied to this volume
PrintRegionConfig config = this->_region_config_from_model_volume(*volume);
// find an existing print region with the same config
int region_id = -1;
for (PrintRegionPtrs::const_iterator region = this->regions.begin(); region != this->regions.end(); ++region) {
if (config.equals((*region)->config)) {
region_id = region - this->regions.begin();
break;
}
}
// if no region exists with the same config, create a new one
if (region_id == -1) {
PrintRegion* r = this->add_region();
r->config.apply(config);
region_id = this->regions.size() - 1;
}
// assign volume to region
o->add_region_volume(region_id, volume_id);
}
// apply config to print object
o->config.apply(this->default_object_config);
o->config.apply(object_config, true);
}
bool
Print::apply_config(DynamicPrintConfig config)
{
// we get a copy of the config object so we can modify it safely
config.normalize();
// apply variables to placeholder parser
this->placeholder_parser.apply_config(config);
bool invalidated = false;
// handle changes to print config
t_config_option_keys print_diff = this->config.diff(config);
if (!print_diff.empty()) {
this->config.apply(config, true);
if (this->invalidate_state_by_config_options(print_diff))
invalidated = true;
}
// handle changes to object config defaults
this->default_object_config.apply(config, true);
FOREACH_OBJECT(this, obj_ptr) {
// we don't assume that config contains a full ObjectConfig,
// so we base it on the current print-wise default
PrintObjectConfig new_config = this->default_object_config;
new_config.apply(config, true);
// we override the new config with object-specific options
{
DynamicPrintConfig model_object_config = (*obj_ptr)->model_object()->config;
model_object_config.normalize();
new_config.apply(model_object_config, true);
}
// check whether the new config is different from the current one
t_config_option_keys diff = (*obj_ptr)->config.diff(new_config);
if (!diff.empty()) {
(*obj_ptr)->config.apply(new_config, true);
if ((*obj_ptr)->invalidate_state_by_config_options(diff))
invalidated = true;
}
}
// handle changes to regions config defaults
this->default_region_config.apply(config, true);
// All regions now have distinct settings.
// Check whether applying the new region config defaults we'd get different regions.
bool rearrange_regions = false;
std::vector<PrintRegionConfig> other_region_configs;
FOREACH_REGION(this, it_r) {
size_t region_id = it_r - this->regions.begin();
PrintRegion* region = *it_r;
std::vector<PrintRegionConfig> this_region_configs;
FOREACH_OBJECT(this, it_o) {
PrintObject* object = *it_o;
std::vector<int> &region_volumes = object->region_volumes[region_id];
for (std::vector<int>::const_iterator volume_id = region_volumes.begin(); volume_id != region_volumes.end(); ++volume_id) {
ModelVolume* volume = object->model_object()->volumes[*volume_id];
PrintRegionConfig new_config = this->_region_config_from_model_volume(*volume);
for (std::vector<PrintRegionConfig>::iterator it = this_region_configs.begin(); it != this_region_configs.end(); ++it) {
// if the new config for this volume differs from the other
// volume configs currently associated to this region, it means
// the region subdivision does not make sense anymore
if (!it->equals(new_config)) {
rearrange_regions = true;
goto NEXT_REGION;
}
}
this_region_configs.push_back(new_config);
for (std::vector<PrintRegionConfig>::iterator it = other_region_configs.begin(); it != other_region_configs.end(); ++it) {
// if the new config for this volume equals any of the other
// volume configs that are not currently associated to this
// region, it means the region subdivision does not make
// sense anymore
if (it->equals(new_config)) {
rearrange_regions = true;
goto NEXT_REGION;
}
}
// if we're here and the new region config is different from the old
// one, we need to apply the new config and invalidate all objects
// (possible optimization: only invalidate objects using this region)
t_config_option_keys region_config_diff = region->config.diff(new_config);
if (!region_config_diff.empty()) {
region->config.apply(new_config);
FOREACH_OBJECT(this, o) {
if ((*o)->invalidate_state_by_config_options(region_config_diff))
invalidated = true;
}
}
}
}
other_region_configs.insert(other_region_configs.end(), this_region_configs.begin(), this_region_configs.end());
NEXT_REGION:
continue;
}
if (rearrange_regions) {
// the current subdivision of regions does not make sense anymore.
// we need to remove all objects and re-add them
ModelObjectPtrs model_objects;
FOREACH_OBJECT(this, o) {
model_objects.push_back((*o)->model_object());
}
this->clear_objects();
for (ModelObjectPtrs::iterator it = model_objects.begin(); it != model_objects.end(); ++it) {
this->add_model_object(*it);
}
invalidated = true;
}
return invalidated;
}
void
Print::init_extruders()
{
@ -324,6 +507,28 @@ Print::init_extruders()
this->state.set_done(psInitExtruders);
}
PrintRegionConfig
Print::_region_config_from_model_volume(const ModelVolume &volume)
{
PrintRegionConfig config = this->default_region_config;
{
DynamicPrintConfig other_config = volume.get_object()->config;
other_config.normalize();
config.apply(other_config, true);
}
{
DynamicPrintConfig other_config = volume.config;
other_config.normalize();
config.apply(other_config, true);
}
if (!volume.material_id().empty()) {
DynamicPrintConfig material_config = volume.material()->config;
material_config.normalize();
config.apply(material_config, true);
}
return config;
}
bool
Print::has_support_material() const
{

View file

@ -8,6 +8,7 @@
#include "PrintConfig.hpp"
#include "Point.hpp"
#include "Layer.hpp"
#include "Model.hpp"
#include "PlaceholderParser.hpp"
@ -70,7 +71,6 @@ class PrintObject
public:
// vector of (vectors of volume ids), indexed by region_id
std::vector<std::vector<int> > region_volumes;
Points copies; // Slic3r::Point objects in scaled G-code coordinates
PrintObjectConfig config;
t_layer_height_ranges layer_height_ranges;
@ -95,7 +95,10 @@ class PrintObject
Print* print();
ModelObject* model_object();
Points copies() const;
void set_copies(const Points &points);
// adds region_id, too, if necessary
void add_region_volume(int region_id, int volume_id);
@ -119,6 +122,7 @@ class PrintObject
private:
Print* _print;
ModelObject* _model_object;
Points _copies; // Slic3r::Point objects in scaled G-code coordinates
// TODO: call model_object->get_bounding_box() instead of accepting
// parameter
@ -164,6 +168,8 @@ class Print
bool invalidate_step(PrintStep step);
bool invalidate_all_steps();
void add_model_object(ModelObject* model_object, int idx = -1);
bool apply_config(DynamicPrintConfig config);
void init_extruders();
std::set<size_t> extruders() const;
@ -174,6 +180,7 @@ class Print
private:
void clear_regions();
void delete_region(size_t idx);
PrintRegionConfig _region_config_from_model_volume(const ModelVolume &volume);
};
#define FOREACH_BASE(type, container, iterator) for (type::const_iterator iterator = (container).begin(); iterator != (container).end(); ++iterator)

View file

@ -1,5 +1,6 @@
#include "Print.hpp"
#include "BoundingBox.hpp"
#include "Geometry.hpp"
namespace Slic3r {
@ -21,8 +22,6 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Bounding
this->_copies_shift = Point(
scale_(modobj_bbox.min.x), scale_(modobj_bbox.min.y));
// TODO: $self->_trigger_copies;
// Scale the object size and store it
Pointf3 size = modobj_bbox.size();
this->size = Point3(scale_(size.x), scale_(size.y), scale_(size.z));
@ -45,6 +44,35 @@ PrintObject::model_object()
return this->_model_object;
}
Points
PrintObject::copies() const
{
return this->_copies;
}
void
PrintObject::set_copies(const Points &points)
{
this->_copies = points;
// order copies with a nearest neighbor search and translate them by _copies_shift
this->_shifted_copies.clear();
this->_shifted_copies.reserve(points.size());
// order copies with a nearest-neighbor search
std::vector<Points::size_type> ordered_copies;
Slic3r::Geometry::chained_path(points, ordered_copies);
for (std::vector<Points::size_type>::const_iterator it = ordered_copies.begin(); it != ordered_copies.end(); ++it) {
Point copy = points[*it];
copy.translate(this->_copies_shift);
this->_shifted_copies.push_back(copy);
}
this->_print->invalidate_step(psSkirt);
this->_print->invalidate_step(psBrim);
}
void
PrintObject::add_region_volume(int region_id, int volume_id)
{

View file

@ -14,12 +14,15 @@
SV* get_at(t_config_option_key opt_key, int i);
bool set(t_config_option_key opt_key, SV* value);
bool set_deserialize(t_config_option_key opt_key, SV* str);
void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false);
std::string serialize(t_config_option_key opt_key);
double get_abs_value(t_config_option_key opt_key);
%name{get_abs_value_over}
double get_abs_value(t_config_option_key opt_key, double ratio_over);
void apply(DynamicPrintConfig* other)
%code{% THIS->apply(*other, true); %};
std::vector<std::string> diff(DynamicPrintConfig* other)
%code{% RETVAL = THIS->diff(*other); %};
void apply_static(FullPrintConfig* other)
%code{% THIS->apply(*other, true); %};
std::vector<std::string> get_keys()
@ -37,6 +40,7 @@
SV* get_at(t_config_option_key opt_key, int i);
bool set(t_config_option_key opt_key, SV* value);
bool set_deserialize(t_config_option_key opt_key, SV* str);
void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false);
std::string serialize(t_config_option_key opt_key);
double get_abs_value(t_config_option_key opt_key);
%name{get_abs_value_over}
@ -58,6 +62,7 @@
SV* get_at(t_config_option_key opt_key, int i);
bool set(t_config_option_key opt_key, SV* value);
bool set_deserialize(t_config_option_key opt_key, SV* str);
void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false);
std::string serialize(t_config_option_key opt_key);
double get_abs_value(t_config_option_key opt_key);
%name{get_abs_value_over}
@ -77,6 +82,7 @@
SV* get_at(t_config_option_key opt_key, int i);
bool set(t_config_option_key opt_key, SV* value);
bool set_deserialize(t_config_option_key opt_key, SV* str);
void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false);
std::string serialize(t_config_option_key opt_key);
double get_abs_value(t_config_option_key opt_key);
%name{get_abs_value_over}
@ -98,6 +104,7 @@
SV* get_at(t_config_option_key opt_key, int i);
bool set(t_config_option_key opt_key, SV* value);
bool set_deserialize(t_config_option_key opt_key, SV* str);
void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false);
std::string serialize(t_config_option_key opt_key);
double get_abs_value(t_config_option_key opt_key);
%name{get_abs_value_over}
@ -119,6 +126,7 @@
SV* get_at(t_config_option_key opt_key, int i);
bool set(t_config_option_key opt_key, SV* value);
bool set_deserialize(t_config_option_key opt_key, SV* str);
void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false);
std::string serialize(t_config_option_key opt_key);
double get_abs_value(t_config_option_key opt_key);
%name{get_abs_value_over}

View file

@ -56,8 +56,7 @@ _constant()
Ref<ModelObject> model_object();
Ref<PrintObjectConfig> config()
%code%{ RETVAL = &THIS->config; %};
Points copies()
%code%{ RETVAL = THIS->copies; %};
Points copies();
t_layer_height_ranges layer_height_ranges()
%code%{ RETVAL = THIS->layer_height_ranges; %};
Ref<Point3> size()
@ -75,8 +74,7 @@ _constant()
void set_shifted_copies(Points value)
%code%{ THIS->_shifted_copies = value; %};
void set_copies(Points copies)
%code%{ THIS->copies = copies; %};
void set_copies(Points copies);
void set_layer_height_ranges(t_layer_height_ranges layer_height_ranges)
%code%{ THIS->layer_height_ranges = layer_height_ranges; %};
@ -169,6 +167,9 @@ _constant()
double max_allowed_layer_height() const;
bool has_support_material() const;
void add_model_object(ModelObject* model_object, int idx = -1);
bool apply_config(DynamicPrintConfig* config)
%code%{ RETVAL = THIS->apply_config(*config); %};
void init_extruders();
%{