Ported _slice_region() to C++/XS

This commit is contained in:
Alessandro Ranellucci 2016-12-20 20:51:07 +01:00
parent ec9c1fe654
commit 32fdd4d7ee
4 changed files with 60 additions and 40 deletions

View File

@ -335,39 +335,6 @@ sub slice {
$self->set_step_done(STEP_SLICE);
}
# called from slice()
sub _slice_region {
my ($self, $region_id, $z, $modifier) = @_;
return [] if !@{$self->get_region_volumes($region_id)};
# compose mesh
my $mesh;
foreach my $volume_id (@{ $self->get_region_volumes($region_id) }) {
my $volume = $self->model_object->volumes->[$volume_id];
next if $volume->modifier && !$modifier;
next if !$volume->modifier && $modifier;
if (defined $mesh) {
$mesh->merge($volume->mesh);
} else {
$mesh = $volume->mesh->clone;
}
}
return if !defined $mesh;
# transform mesh
# we ignore the per-instance transformations currently and only
# consider the first one
$self->model_object->instances->[0]->transform_mesh($mesh, 1);
# align mesh to Z = 0 (it should be already aligned actually) and apply XY shift
$mesh->translate((map unscale(-$_), @{$self->_copies_shift}), -$self->model_object->bounding_box->z_min);
# perform actual slicing
return $mesh->slice($z);
}
sub make_perimeters {
my ($self) = @_;

View File

@ -100,7 +100,7 @@ class PrintObject
PrintState<PrintObjectStep> state;
Print* print();
ModelObject* model_object();
ModelObject* model_object() { return this->_model_object; };
Points copies() const;
bool add_copy(const Pointf &point);
@ -136,6 +136,7 @@ class PrintObject
void detect_surfaces_type();
void process_external_surfaces();
void bridge_over_infill();
std::vector<ExPolygons> _slice_region(size_t region_id, std::vector<float> z, bool modifier);
void _make_perimeters();
void _infill();

View File

@ -40,12 +40,6 @@ PrintObject::print()
return this->_print;
}
ModelObject*
PrintObject::model_object()
{
return this->_model_object;
}
Points
PrintObject::copies() const
{
@ -665,6 +659,45 @@ PrintObject::bridge_over_infill()
}
}
// called from slice()
std::vector<ExPolygons>
PrintObject::_slice_region(size_t region_id, std::vector<float> z, bool modifier)
{
std::vector<ExPolygons> layers;
std::vector<int> &region_volumes = this->region_volumes[region_id];
if (region_volumes.empty()) return layers;
ModelObject &object = *this->model_object();
// compose mesh
TriangleMesh mesh;
for (std::vector<int>::const_iterator it = region_volumes.begin();
it != region_volumes.end(); ++it) {
const ModelVolume &volume = *object.volumes[*it];
if (volume.modifier != modifier) continue;
mesh.merge(volume.mesh);
}
if (mesh.facets_count() == 0) return layers;
// transform mesh
// we ignore the per-instance transformations currently and only
// consider the first one
object.instances[0]->transform_mesh(&mesh, true);
// align mesh to Z = 0 (it should be already aligned actually) and apply XY shift
mesh.translate(
unscale(this->_copies_shift.x),
unscale(this->_copies_shift.y),
-object.bounding_box().min.z
);
// perform actual slicing
TriangleMeshSlicer<Z>(&mesh).slice(z, &layers);
return layers;
}
void
PrintObject::_make_perimeters()
{

View File

@ -110,6 +110,25 @@ _constant()
void detect_surfaces_type();
void process_external_surfaces();
void bridge_over_infill();
SV* _slice_region(size_t region_id, std::vector<double> z, bool modifier)
%code%{
std::vector<float> z_f(z.begin(), z.end());
std::vector<ExPolygons> layers = THIS->_slice_region(region_id, z_f, modifier);
AV* layers_av = newAV();
size_t len = layers.size();
if (len > 0) av_extend(layers_av, len-1);
for (unsigned int i = 0; i < layers.size(); i++) {
AV* expolygons_av = newAV();
len = layers[i].size();
if (len > 0) av_extend(expolygons_av, len-1);
unsigned int j = 0;
for (ExPolygons::iterator it = layers[i].begin(); it != layers[i].end(); ++it) {
av_store(expolygons_av, j++, perl_to_SV_clone_ref(*it));
}
av_store(layers_av, i, newRV_noinc((SV*)expolygons_av));
}
RETVAL = (SV*)newRV_noinc((SV*)layers_av);
%};
void _make_perimeters();
void _infill();