mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-05-02 08:45:01 +08:00
More work to avoid working with vertices outside XS
This commit is contained in:
parent
11e18f681d
commit
a821eb7f3c
@ -1270,7 +1270,7 @@ sub _trigger_model_object {
|
|||||||
|
|
||||||
my $mesh = $model_object->mesh;
|
my $mesh = $model_object->mesh;
|
||||||
$mesh->repair;
|
$mesh->repair;
|
||||||
$self->convex_hull(Slic3r::Polygon->new(@{Math::ConvexHull::MonotoneChain::convex_hull($mesh->used_vertices)}));
|
$self->convex_hull(Slic3r::Polygon->new(@{Math::ConvexHull::MonotoneChain::convex_hull($mesh->vertices)}));
|
||||||
$self->facets(scalar @{$mesh->facets});
|
$self->facets(scalar @{$mesh->facets});
|
||||||
$self->vertices(scalar @{$mesh->vertices});
|
$self->vertices(scalar @{$mesh->vertices});
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use warnings;
|
|||||||
require Exporter;
|
require Exporter;
|
||||||
our @ISA = qw(Exporter);
|
our @ISA = qw(Exporter);
|
||||||
our @EXPORT_OK = qw(
|
our @EXPORT_OK = qw(
|
||||||
PI X Y Z A B X1 Y1 X2 Y2 MIN MAX epsilon slope line_atan lines_parallel
|
PI X Y Z A B X1 Y1 X2 Y2 Z1 Z2 MIN MAX epsilon slope line_atan lines_parallel
|
||||||
line_point_belongs_to_segment points_coincide distance_between_points
|
line_point_belongs_to_segment points_coincide distance_between_points
|
||||||
chained_path_items chained_path_points normalize tan move_points_3D
|
chained_path_items chained_path_points normalize tan move_points_3D
|
||||||
line_length midpoint point_in_polygon point_in_segment segment_in_segment
|
line_length midpoint point_in_polygon point_in_segment segment_in_segment
|
||||||
@ -35,6 +35,8 @@ use constant X1 => 0;
|
|||||||
use constant Y1 => 1;
|
use constant Y1 => 1;
|
||||||
use constant X2 => 2;
|
use constant X2 => 2;
|
||||||
use constant Y2 => 3;
|
use constant Y2 => 3;
|
||||||
|
use constant Z1 => 4;
|
||||||
|
use constant Z2 => 5;
|
||||||
use constant MIN => 0;
|
use constant MIN => 0;
|
||||||
use constant MAX => 1;
|
use constant MAX => 1;
|
||||||
our $parallel_degrees_limit = abs(deg2rad(0.1));
|
our $parallel_degrees_limit = abs(deg2rad(0.1));
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package Slic3r::Geometry::BoundingBox;
|
package Slic3r::Geometry::BoundingBox;
|
||||||
use Moo;
|
use Moo;
|
||||||
use Slic3r::Geometry qw(X Y Z MIN MAX X1 Y1 X2 Y2);
|
|
||||||
|
use List::Util qw(min max);
|
||||||
|
use Slic3r::Geometry qw(X Y Z MIN MAX X1 Y1 X2 Y2 Z1 Z2);
|
||||||
use Storable qw();
|
use Storable qw();
|
||||||
|
|
||||||
has 'extents' => (is => 'ro', required => 1);
|
has 'extents' => (is => 'ro', required => 1);
|
||||||
@ -19,6 +21,18 @@ sub new_from_points {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 2D/3D
|
||||||
|
sub new_from_bb {
|
||||||
|
my $class = shift;
|
||||||
|
my ($bb) = @_;
|
||||||
|
|
||||||
|
return $class->new(extents => [
|
||||||
|
[ $bb->[X1], $bb->[X2] ],
|
||||||
|
[ $bb->[Y1], $bb->[Y2] ],
|
||||||
|
(@$bb == 6) ? [ $bb->[Z1], $bb->[Z2] ] : (),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
# 3D
|
# 3D
|
||||||
sub new_from_points_3D {
|
sub new_from_points_3D {
|
||||||
my $class = shift;
|
my $class = shift;
|
||||||
@ -27,6 +41,24 @@ sub new_from_points_3D {
|
|||||||
return $class->new(extents => [ Slic3r::Geometry::bounding_box_3D($points) ]);
|
return $class->new(extents => [ Slic3r::Geometry::bounding_box_3D($points) ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub merge {
|
||||||
|
my $class = shift;
|
||||||
|
my (@bounding_boxes) = @_;
|
||||||
|
|
||||||
|
my $self = ref($class)
|
||||||
|
? $class
|
||||||
|
: shift @bounding_boxes;
|
||||||
|
|
||||||
|
foreach my $bounding_box (@bounding_boxes) {
|
||||||
|
for my $axis (X .. $#{$self->extents}) {
|
||||||
|
$self->extents->[$axis][MIN] = min($self->extents->[$axis][MIN], $bounding_box->extents->[$axis][MIN]);
|
||||||
|
$self->extents->[$axis][MAX] = max($self->extents->[$axis][MAX], $bounding_box->extents->[$axis][MAX]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
# four-arguments 2D bb
|
# four-arguments 2D bb
|
||||||
sub bb {
|
sub bb {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
@ -159,16 +159,6 @@ sub _arrange {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub vertices {
|
|
||||||
my $self = shift;
|
|
||||||
return [ map @{$_->vertices}, @{$self->objects} ];
|
|
||||||
}
|
|
||||||
|
|
||||||
sub used_vertices {
|
|
||||||
my $self = shift;
|
|
||||||
return [ map @{$_->used_vertices}, @{$self->objects} ];
|
|
||||||
}
|
|
||||||
|
|
||||||
sub size {
|
sub size {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return $self->bounding_box->size;
|
return $self->bounding_box->size;
|
||||||
@ -178,7 +168,7 @@ sub bounding_box {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
if (!defined $self->_bounding_box) {
|
if (!defined $self->_bounding_box) {
|
||||||
$self->_bounding_box(Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices));
|
$self->_bounding_box(Slic3r::Geometry::BoundingBox->merge(map $_->bounding_box, @{$self->objects}));
|
||||||
}
|
}
|
||||||
return $self->_bounding_box;
|
return $self->_bounding_box;
|
||||||
}
|
}
|
||||||
@ -352,11 +342,6 @@ sub mesh {
|
|||||||
return $mesh;
|
return $mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub used_vertices {
|
|
||||||
my $self = shift;
|
|
||||||
return [ map $_->mesh->used_vertices, @{$self->volumes} ];
|
|
||||||
}
|
|
||||||
|
|
||||||
sub size {
|
sub size {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return $self->bounding_box->size;
|
return $self->bounding_box->size;
|
||||||
@ -376,8 +361,10 @@ sub bounding_box {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
if (!defined $self->_bounding_box) {
|
if (!defined $self->_bounding_box) {
|
||||||
# TODO: calculate bb in XS
|
my @meshes = map $_->mesh, @{$self->volumes};
|
||||||
$self->_bounding_box(Slic3r::Geometry::BoundingBox->new_from_points_3D(map $_->mesh->vertices, @{$self->volumes}));
|
my $bounding_box = Slic3r::Geometry::BoundingBox->new_from_bb((shift @meshes)->bb3);
|
||||||
|
$bounding_box->merge(Slic3r::Geometry::BoundingBox->new_from_bb($_->bb3)) for @meshes;
|
||||||
|
$self->_bounding_box($bounding_box);
|
||||||
}
|
}
|
||||||
return $self->_bounding_box;
|
return $self->_bounding_box;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ sub add_model {
|
|||||||
|
|
||||||
# we also align object after transformations so that we only work with positive coordinates
|
# we also align object after transformations so that we only work with positive coordinates
|
||||||
# and the assumption that bounding_box === size works
|
# and the assumption that bounding_box === size works
|
||||||
my $bb = Slic3r::Geometry::BoundingBox->new_from_points_3D([ map @{$_->used_vertices}, grep $_, @meshes ]);
|
my $bb = Slic3r::Geometry::BoundingBox->merge(map $_->bounding_box, grep $_, @meshes);
|
||||||
my @align2 = map -$bb->extents->[$_][MIN], (X,Y,Z);
|
my @align2 = map -$bb->extents->[$_][MIN], (X,Y,Z);
|
||||||
$_->translate(@align2) for grep $_, @meshes;
|
$_->translate(@align2) for grep $_, @meshes;
|
||||||
|
|
||||||
|
@ -144,15 +144,13 @@ sub slice {
|
|||||||
# process facets
|
# process facets
|
||||||
for my $region_id (0 .. $#{$self->meshes}) {
|
for my $region_id (0 .. $#{$self->meshes}) {
|
||||||
my $mesh = $self->meshes->[$region_id] // next; # ignore undef meshes
|
my $mesh = $self->meshes->[$region_id] // next; # ignore undef meshes
|
||||||
|
$mesh->repair;
|
||||||
|
|
||||||
{
|
{
|
||||||
my $m = Slic3r::TriangleMesh->new;
|
my $loops = $mesh->slice([ map $_->slice_z, @{$self->layers} ]);
|
||||||
$m->ReadFromPerl($mesh->vertices, $mesh->facets);
|
for my $layer_id (0..$#$loops) {
|
||||||
$m->repair;
|
|
||||||
my $lines = $m->slice([ map $_->slice_z, @{$self->layers} ]);
|
|
||||||
for my $layer_id (0..$#$lines) {
|
|
||||||
my $layerm = $self->layers->[$layer_id]->regions->[$region_id];
|
my $layerm = $self->layers->[$layer_id]->regions->[$region_id];
|
||||||
$layerm->make_surfaces($lines->[$layer_id]);
|
$layerm->make_surfaces($loops->[$layer_id]);
|
||||||
}
|
}
|
||||||
# TODO: read slicing_errors
|
# TODO: read slicing_errors
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,6 @@ sub center {
|
|||||||
return $self->bounding_box->center;
|
return $self->bounding_box->center;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub used_vertices {
|
|
||||||
my $self = shift;
|
|
||||||
return $self->vertices;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub facets_count {
|
sub facets_count {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return $self->stats->{number_of_facets};
|
return $self->stats->{number_of_facets};
|
||||||
@ -31,7 +26,7 @@ sub facets_count {
|
|||||||
|
|
||||||
sub bounding_box {
|
sub bounding_box {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices);
|
return Slic3r::Geometry::BoundingBox->new_from_bb($self->bb3);
|
||||||
}
|
}
|
||||||
|
|
||||||
# this will return *scaled* expolygons, so it is expected to be run
|
# this will return *scaled* expolygons, so it is expected to be run
|
||||||
|
@ -13,7 +13,7 @@ use Slic3r::Test;
|
|||||||
|
|
||||||
{
|
{
|
||||||
my $print = Slic3r::Test::init_print('20mm_cube', rotation => 45);
|
my $print = Slic3r::Test::init_print('20mm_cube', rotation => 45);
|
||||||
ok !(first { $_ < 0 } map @$_, map @{$_->used_vertices}, grep $_, map @{$_->meshes}, @{$print->objects}),
|
ok !(first { $_ < 0 } map @$_, map @{$_->vertices}, grep $_, map @{$_->meshes}, @{$print->objects}),
|
||||||
"object is still in positive coordinate space even after rotation";
|
"object is still in positive coordinate space even after rotation";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +126,18 @@ TriangleMesh::slice(z)
|
|||||||
OUTPUT:
|
OUTPUT:
|
||||||
RETVAL
|
RETVAL
|
||||||
|
|
||||||
|
std::vector<double>
|
||||||
|
TriangleMesh::bb3()
|
||||||
|
CODE:
|
||||||
|
RETVAL.push_back(THIS->stl.stats.min.x);
|
||||||
|
RETVAL.push_back(THIS->stl.stats.min.y);
|
||||||
|
RETVAL.push_back(THIS->stl.stats.max.x);
|
||||||
|
RETVAL.push_back(THIS->stl.stats.max.y);
|
||||||
|
RETVAL.push_back(THIS->stl.stats.min.z);
|
||||||
|
RETVAL.push_back(THIS->stl.stats.max.z);
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
%}
|
%}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user