New experimental autospeed feature. #2810
This commit is contained in:
parent
6e280ab8cb
commit
7f70da97b4
@ -27,6 +27,7 @@ has '_seam_position' => (is => 'ro', default => sub { {} }); # $object => p
|
|||||||
has 'first_layer' => (is => 'rw', default => sub {0}); # this flag triggers first layer speeds
|
has 'first_layer' => (is => 'rw', default => sub {0}); # this flag triggers first layer speeds
|
||||||
has 'elapsed_time' => (is => 'rw', default => sub {0} ); # seconds
|
has 'elapsed_time' => (is => 'rw', default => sub {0} ); # seconds
|
||||||
has 'last_pos' => (is => 'rw', default => sub { Slic3r::Point->new(0,0) } );
|
has 'last_pos' => (is => 'rw', default => sub { Slic3r::Point->new(0,0) } );
|
||||||
|
has 'volumetric_speed' => (is => 'rw', default => sub {0});
|
||||||
|
|
||||||
sub apply_print_config {
|
sub apply_print_config {
|
||||||
my ($self, $print_config) = @_;
|
my ($self, $print_config) = @_;
|
||||||
@ -298,11 +299,13 @@ sub _extrude_path {
|
|||||||
die "Invalid speed";
|
die "Invalid speed";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my $F = $speed * 60; # convert mm/sec to mm/min
|
|
||||||
|
|
||||||
if ($self->first_layer) {
|
if ($self->first_layer) {
|
||||||
$F = $self->config->get_abs_value_over('first_layer_speed', $F/60) * 60;
|
$speed = $self->config->get_abs_value_over('first_layer_speed', $speed);
|
||||||
}
|
}
|
||||||
|
if ($self->volumetric_speed != 0) {
|
||||||
|
$speed ||= $self->volumetric_speed / $path->mm3_per_mm;
|
||||||
|
}
|
||||||
|
my $F = $speed * 60; # convert mm/sec to mm/min
|
||||||
|
|
||||||
# extrude arc or line
|
# extrude arc or line
|
||||||
$gcode .= ";_BRIDGE_FAN_START\n" if $path->is_bridge && $self->enable_cooling_markers;
|
$gcode .= ";_BRIDGE_FAN_START\n" if $path->is_bridge && $self->enable_cooling_markers;
|
||||||
|
@ -450,6 +450,7 @@ sub build {
|
|||||||
infill_every_layers infill_only_where_needed
|
infill_every_layers infill_only_where_needed
|
||||||
solid_infill_every_layers fill_angle solid_infill_below_area
|
solid_infill_every_layers fill_angle solid_infill_below_area
|
||||||
only_retract_when_crossing_perimeters infill_first
|
only_retract_when_crossing_perimeters infill_first
|
||||||
|
max_print_speed max_volumetric_speed
|
||||||
perimeter_speed small_perimeter_speed external_perimeter_speed infill_speed
|
perimeter_speed small_perimeter_speed external_perimeter_speed infill_speed
|
||||||
solid_infill_speed top_solid_infill_speed support_material_speed
|
solid_infill_speed top_solid_infill_speed support_material_speed
|
||||||
support_material_interface_speed bridge_speed gap_fill_speed
|
support_material_interface_speed bridge_speed gap_fill_speed
|
||||||
@ -607,6 +608,11 @@ sub build {
|
|||||||
$optgroup->append_single_option_line('first_layer_acceleration');
|
$optgroup->append_single_option_line('first_layer_acceleration');
|
||||||
$optgroup->append_single_option_line('default_acceleration');
|
$optgroup->append_single_option_line('default_acceleration');
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
my $optgroup = $page->new_optgroup('Autospeed (advanced)');
|
||||||
|
$optgroup->append_single_option_line('max_print_speed');
|
||||||
|
$optgroup->append_single_option_line('max_volumetric_speed');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ has '_brim_done' => (is => 'rw');
|
|||||||
has '_second_layer_things_done' => (is => 'rw');
|
has '_second_layer_things_done' => (is => 'rw');
|
||||||
has '_last_obj_copy' => (is => 'rw');
|
has '_last_obj_copy' => (is => 'rw');
|
||||||
|
|
||||||
use List::Util qw(first sum);
|
use List::Util qw(first sum min max);
|
||||||
use Slic3r::Flow ':roles';
|
use Slic3r::Flow ':roles';
|
||||||
use Slic3r::Geometry qw(X Y scale unscale chained_path convex_hull);
|
use Slic3r::Geometry qw(X Y scale unscale chained_path convex_hull);
|
||||||
use Slic3r::Geometry::Clipper qw(JT_SQUARE union_ex offset);
|
use Slic3r::Geometry::Clipper qw(JT_SQUARE union_ex offset);
|
||||||
@ -40,9 +40,60 @@ sub BUILD {
|
|||||||
layer_count => $layer_count,
|
layer_count => $layer_count,
|
||||||
enable_cooling_markers => 1,
|
enable_cooling_markers => 1,
|
||||||
);
|
);
|
||||||
|
$self->_gcodegen($gcodegen);
|
||||||
$gcodegen->apply_print_config($self->config);
|
$gcodegen->apply_print_config($self->config);
|
||||||
$gcodegen->set_extruders($self->print->extruders);
|
$gcodegen->set_extruders($self->print->extruders);
|
||||||
$self->_gcodegen($gcodegen);
|
|
||||||
|
# initialize autospeed
|
||||||
|
{
|
||||||
|
# get the minimum cross-section used in the print
|
||||||
|
my @mm3_per_mm = ();
|
||||||
|
foreach my $object (@{$self->print->objects}) {
|
||||||
|
foreach my $region_id (0..$#{$self->print->regions}) {
|
||||||
|
my $region = $self->print->get_region($region_id);
|
||||||
|
foreach my $layer (@{$object->layers}) {
|
||||||
|
my $layerm = $layer->get_region($region_id);
|
||||||
|
if ($region->config->get_abs_value('perimeter_speed') == 0
|
||||||
|
|| $region->config->get_abs_value('small_perimeter_speed') == 0
|
||||||
|
|| $region->config->get_abs_value('external_perimeter_speed') == 0
|
||||||
|
|| $region->config->get_abs_value('bridge_speed') == 0) {
|
||||||
|
push @mm3_per_mm, $layerm->perimeters->min_mm3_per_mm;
|
||||||
|
}
|
||||||
|
if ($region->config->get_abs_value('infill_speed') == 0
|
||||||
|
|| $region->config->get_abs_value('solid_infill_speed') == 0
|
||||||
|
|| $region->config->get_abs_value('top_solid_infill_speed') == 0
|
||||||
|
|| $region->config->get_abs_value('bridge_speed') == 0) {
|
||||||
|
push @mm3_per_mm, $layerm->fills->min_mm3_per_mm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($object->config->get_abs_value('support_material_speed') == 0
|
||||||
|
|| $object->config->get_abs_value('support_material_interface_speed') == 0) {
|
||||||
|
foreach my $layer (@{$object->support_layers}) {
|
||||||
|
push @mm3_per_mm, $layer->support_fills->min_mm3_per_mm;
|
||||||
|
push @mm3_per_mm, $layer->support_interface_fills->min_mm3_per_mm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
my $min_mm3_per_mm = min(@mm3_per_mm);
|
||||||
|
if ($min_mm3_per_mm > 0) {
|
||||||
|
# In order to honor max_print_speed we need to find a target volumetric
|
||||||
|
# speed that we can use throughout the print. So we define this target
|
||||||
|
# volumetric speed as the volumetric speed produced by printing the
|
||||||
|
# smallest cross-section at the maximum speed: any larger cross-section
|
||||||
|
# will need slower feedrates.
|
||||||
|
my $volumetric_speed = $min_mm3_per_mm * $self->config->max_print_speed;
|
||||||
|
|
||||||
|
# limit such volumetric speed with max_volumetric_speed if set
|
||||||
|
if ($self->config->max_volumetric_speed > 0) {
|
||||||
|
$volumetric_speed = min(
|
||||||
|
$volumetric_speed,
|
||||||
|
$self->config->max_volumetric_speed,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$gcodegen->volumetric_speed($volumetric_speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->_cooling_buffer(Slic3r::GCode::CoolingBuffer->new(
|
$self->_cooling_buffer(Slic3r::GCode::CoolingBuffer->new(
|
||||||
|
@ -6,17 +6,28 @@
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
|
use constant PI => 3.141592653589793238;
|
||||||
|
my @filament_diameter = split /,/, $ENV{SLIC3R_FILAMENT_DIAMETER};
|
||||||
|
|
||||||
my $E = 0;
|
my $E = 0;
|
||||||
my ($X, $Y);
|
my $T = 0;
|
||||||
|
my ($X, $Y, $F);
|
||||||
while (<>) {
|
while (<>) {
|
||||||
|
if (/^G1.*? F([0-9.]+)/) {
|
||||||
|
$F = $1;
|
||||||
|
}
|
||||||
if (/^G1 X([0-9.]+) Y([0-9.]+).*? E([0-9.]+)/) {
|
if (/^G1 X([0-9.]+) Y([0-9.]+).*? E([0-9.]+)/) {
|
||||||
my ($x, $y, $e) = ($1, $2, $3);
|
my ($x, $y, $e) = ($1, $2, $3);
|
||||||
my $e_length = $e - $E;
|
my $e_length = $e - $E;
|
||||||
if ($e_length > 0 && defined $X && defined $Y) {
|
if ($e_length > 0 && defined $X && defined $Y) {
|
||||||
my $dist = sqrt( (($x-$X)**2) + (($y-$Y)**2) );
|
my $dist = sqrt( (($x-$X)**2) + (($y-$Y)**2) );
|
||||||
if ($dist > 0) {
|
if ($dist > 0) {
|
||||||
my $flowrate = sprintf '%.2f', $e_length / $dist;
|
my $mm_per_mm = $e_length / $dist; # dE/dXY
|
||||||
s/(\R+)/ ; XY dist = $dist ; E dist = $e_length ; E\/XY = $flowrate mm\/mm$1/;
|
my $mm3_per_mm = ($filament_diameter[$T] ** 2) * PI/4 * $mm_per_mm;
|
||||||
|
my $vol_speed = $F/60 * $mm3_per_mm;
|
||||||
|
my $comment = sprintf ' ; dXY = %.3fmm ; dE = %.5fmm ; dE/XY = %.5fmm/mm; volspeed = %.5fmm^3/sec',
|
||||||
|
$dist, $e_length, $mm_per_mm, $vol_speed;
|
||||||
|
s/(\R+)/$comment$1/;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$E = $e;
|
$E = $e;
|
||||||
@ -33,6 +44,9 @@ while (<>) {
|
|||||||
if (/^G92 E0/) {
|
if (/^G92 E0/) {
|
||||||
$E = 0;
|
$E = 0;
|
||||||
}
|
}
|
||||||
|
if (/^T(\d+)/) {
|
||||||
|
$T = $1;
|
||||||
|
}
|
||||||
print;
|
print;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "ExPolygonCollection.hpp"
|
#include "ExPolygonCollection.hpp"
|
||||||
#include "ClipperUtils.hpp"
|
#include "ClipperUtils.hpp"
|
||||||
#include "Extruder.hpp"
|
#include "Extruder.hpp"
|
||||||
|
#include <cmath>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
@ -375,6 +376,20 @@ ExtrusionLoop::grow() const
|
|||||||
return pp;
|
return pp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
ExtrusionLoop::min_mm3_per_mm() const
|
||||||
|
{
|
||||||
|
double min_mm3_per_mm = 0;
|
||||||
|
for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path) {
|
||||||
|
if (min_mm3_per_mm == 0) {
|
||||||
|
min_mm3_per_mm = path->mm3_per_mm;
|
||||||
|
} else {
|
||||||
|
min_mm3_per_mm = fmin(min_mm3_per_mm, path->mm3_per_mm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return min_mm3_per_mm;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
REGISTER_CLASS(ExtrusionLoop, "ExtrusionLoop");
|
REGISTER_CLASS(ExtrusionLoop, "ExtrusionLoop");
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,6 +50,7 @@ class ExtrusionEntity
|
|||||||
virtual Point first_point() const = 0;
|
virtual Point first_point() const = 0;
|
||||||
virtual Point last_point() const = 0;
|
virtual Point last_point() const = 0;
|
||||||
virtual Polygons grow() const = 0;
|
virtual Polygons grow() const = 0;
|
||||||
|
virtual double min_mm3_per_mm() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<ExtrusionEntity*> ExtrusionEntitiesPtr;
|
typedef std::vector<ExtrusionEntity*> ExtrusionEntitiesPtr;
|
||||||
@ -81,6 +82,9 @@ class ExtrusionPath : public ExtrusionEntity
|
|||||||
double xofs, double yofs, std::string extrusion_axis,
|
double xofs, double yofs, std::string extrusion_axis,
|
||||||
std::string gcode_line_suffix) const;
|
std::string gcode_line_suffix) const;
|
||||||
Polygons grow() const;
|
Polygons grow() const;
|
||||||
|
double min_mm3_per_mm() const {
|
||||||
|
return this->mm3_per_mm;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const;
|
void _inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const;
|
||||||
@ -117,6 +121,7 @@ class ExtrusionLoop : public ExtrusionEntity
|
|||||||
bool is_infill() const;
|
bool is_infill() const;
|
||||||
bool is_solid_infill() const;
|
bool is_solid_infill() const;
|
||||||
Polygons grow() const;
|
Polygons grow() const;
|
||||||
|
double min_mm3_per_mm() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "ExtrusionEntityCollection.hpp"
|
#include "ExtrusionEntityCollection.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
@ -137,6 +138,37 @@ ExtrusionEntityCollection::items_count() const
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns a single vector of pointers to all non-collection items contained in this one */
|
||||||
|
void
|
||||||
|
ExtrusionEntityCollection::flatten(ExtrusionEntityCollection* retval) const
|
||||||
|
{
|
||||||
|
for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
|
||||||
|
if ((*it)->is_collection()) {
|
||||||
|
ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
|
||||||
|
ExtrusionEntityCollection contents;
|
||||||
|
collection->flatten(&contents);
|
||||||
|
retval->entities.insert(retval->entities.end(), contents.entities.begin(), contents.entities.end());
|
||||||
|
} else {
|
||||||
|
retval->entities.push_back((*it)->clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
ExtrusionEntityCollection::min_mm3_per_mm() const
|
||||||
|
{
|
||||||
|
double min_mm3_per_mm = 0;
|
||||||
|
for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
|
||||||
|
double mm3_per_mm = (*it)->min_mm3_per_mm();
|
||||||
|
if (min_mm3_per_mm == 0) {
|
||||||
|
min_mm3_per_mm = mm3_per_mm;
|
||||||
|
} else {
|
||||||
|
min_mm3_per_mm = fmin(min_mm3_per_mm, mm3_per_mm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return min_mm3_per_mm;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
// there is no ExtrusionLoop::Collection or ExtrusionEntity::Collection
|
// there is no ExtrusionLoop::Collection or ExtrusionEntity::Collection
|
||||||
REGISTER_CLASS(ExtrusionEntityCollection, "ExtrusionPath::Collection");
|
REGISTER_CLASS(ExtrusionEntityCollection, "ExtrusionPath::Collection");
|
||||||
|
@ -30,6 +30,8 @@ class ExtrusionEntityCollection : public ExtrusionEntity
|
|||||||
Point last_point() const;
|
Point last_point() const;
|
||||||
Polygons grow() const;
|
Polygons grow() const;
|
||||||
size_t items_count() const;
|
size_t items_count() const;
|
||||||
|
void flatten(ExtrusionEntityCollection* retval) const;
|
||||||
|
double min_mm3_per_mm() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -501,6 +501,22 @@ PrintConfigDef::build_def() {
|
|||||||
Options["min_print_speed"].min = 0;
|
Options["min_print_speed"].min = 0;
|
||||||
Options["min_print_speed"].max = 1000;
|
Options["min_print_speed"].max = 1000;
|
||||||
|
|
||||||
|
Options["max_print_speed"].type = coFloat;
|
||||||
|
Options["max_print_speed"].label = "Max print speed";
|
||||||
|
Options["max_print_speed"].tooltip = "When setting other speed settings to 0 Slic3r will autocalculate the optimal speed in order to keep constant extruder pressure. This experimental setting is used to set the highest print speed you want to allow.";
|
||||||
|
Options["max_print_speed"].sidetext = "mm/s";
|
||||||
|
Options["max_print_speed"].cli = "max-print-speed=f";
|
||||||
|
Options["max_print_speed"].min = 1;
|
||||||
|
Options["max_print_speed"].max = 1000;
|
||||||
|
|
||||||
|
Options["max_volumetric_speed"].type = coFloat;
|
||||||
|
Options["max_volumetric_speed"].label = "Max volumetric speed";
|
||||||
|
Options["max_volumetric_speed"].tooltip = "When setting other speed settings to 0 Slic3r will autocalculate the optimal speed in order to keep constant extruder pressure. This experimental setting is used to set the maximum volumetric speed your extruder supports.";
|
||||||
|
Options["max_volumetric_speed"].sidetext = "mm³/s";
|
||||||
|
Options["max_volumetric_speed"].cli = "max-volumetric-speed=f";
|
||||||
|
Options["max_volumetric_speed"].min = 0;
|
||||||
|
Options["max_volumetric_speed"].max = 1000;
|
||||||
|
|
||||||
Options["min_skirt_length"].type = coFloat;
|
Options["min_skirt_length"].type = coFloat;
|
||||||
Options["min_skirt_length"].label = "Minimum extrusion length";
|
Options["min_skirt_length"].label = "Minimum extrusion length";
|
||||||
Options["min_skirt_length"].tooltip = "Generate no less than the number of skirt loops required to consume the specified amount of filament on the bottom layer. For multi-extruder machines, this minimum applies to each extruder.";
|
Options["min_skirt_length"].tooltip = "Generate no less than the number of skirt loops required to consume the specified amount of filament on the bottom layer. For multi-extruder machines, this minimum applies to each extruder.";
|
||||||
|
@ -306,6 +306,8 @@ class GCodeConfig : public virtual StaticPrintConfig
|
|||||||
ConfigOptionBool gcode_comments;
|
ConfigOptionBool gcode_comments;
|
||||||
ConfigOptionEnum<GCodeFlavor> gcode_flavor;
|
ConfigOptionEnum<GCodeFlavor> gcode_flavor;
|
||||||
ConfigOptionString layer_gcode;
|
ConfigOptionString layer_gcode;
|
||||||
|
ConfigOptionFloat max_print_speed;
|
||||||
|
ConfigOptionFloat max_volumetric_speed;
|
||||||
ConfigOptionFloat pressure_advance;
|
ConfigOptionFloat pressure_advance;
|
||||||
ConfigOptionFloats retract_length;
|
ConfigOptionFloats retract_length;
|
||||||
ConfigOptionFloats retract_length_toolchange;
|
ConfigOptionFloats retract_length_toolchange;
|
||||||
@ -331,6 +333,8 @@ class GCodeConfig : public virtual StaticPrintConfig
|
|||||||
this->gcode_comments.value = false;
|
this->gcode_comments.value = false;
|
||||||
this->gcode_flavor.value = gcfRepRap;
|
this->gcode_flavor.value = gcfRepRap;
|
||||||
this->layer_gcode.value = "";
|
this->layer_gcode.value = "";
|
||||||
|
this->max_print_speed.value = 80;
|
||||||
|
this->max_volumetric_speed.value = 0;
|
||||||
this->pressure_advance.value = 0;
|
this->pressure_advance.value = 0;
|
||||||
this->retract_length.values.resize(1);
|
this->retract_length.values.resize(1);
|
||||||
this->retract_length.values[0] = 2;
|
this->retract_length.values[0] = 2;
|
||||||
@ -361,6 +365,8 @@ class GCodeConfig : public virtual StaticPrintConfig
|
|||||||
if (opt_key == "gcode_comments") return &this->gcode_comments;
|
if (opt_key == "gcode_comments") return &this->gcode_comments;
|
||||||
if (opt_key == "gcode_flavor") return &this->gcode_flavor;
|
if (opt_key == "gcode_flavor") return &this->gcode_flavor;
|
||||||
if (opt_key == "layer_gcode") return &this->layer_gcode;
|
if (opt_key == "layer_gcode") return &this->layer_gcode;
|
||||||
|
if (opt_key == "max_print_speed") return &this->max_print_speed;
|
||||||
|
if (opt_key == "max_volumetric_speed") return &this->max_volumetric_speed;
|
||||||
if (opt_key == "pressure_advance") return &this->pressure_advance;
|
if (opt_key == "pressure_advance") return &this->pressure_advance;
|
||||||
if (opt_key == "retract_length") return &this->retract_length;
|
if (opt_key == "retract_length") return &this->retract_length;
|
||||||
if (opt_key == "retract_length_toolchange") return &this->retract_length_toolchange;
|
if (opt_key == "retract_length_toolchange") return &this->retract_length_toolchange;
|
||||||
|
@ -28,6 +28,12 @@
|
|||||||
%code{% RETVAL = THIS->entities.size(); %};
|
%code{% RETVAL = THIS->entities.size(); %};
|
||||||
int items_count()
|
int items_count()
|
||||||
%code{% RETVAL = THIS->items_count(); %};
|
%code{% RETVAL = THIS->items_count(); %};
|
||||||
|
ExtrusionEntityCollection* flatten()
|
||||||
|
%code{%
|
||||||
|
RETVAL = new ExtrusionEntityCollection();
|
||||||
|
THIS->flatten(RETVAL);
|
||||||
|
%};
|
||||||
|
double min_mm3_per_mm();
|
||||||
bool empty()
|
bool empty()
|
||||||
%code{% RETVAL = THIS->entities.empty(); %};
|
%code{% RETVAL = THIS->entities.empty(); %};
|
||||||
std::vector<size_t> orig_indices()
|
std::vector<size_t> orig_indices()
|
||||||
|
Loading…
Reference in New Issue
Block a user