mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-15 10:47:50 -06:00
Never scale TriangleMesh objects
This commit is contained in:
parent
46e3b3180e
commit
e75dbf37fa
6 changed files with 33 additions and 16 deletions
|
@ -11,7 +11,7 @@ has 'upper_layer' => (is => 'rw', weak_ref => 1);
|
||||||
has 'regions' => (is => 'ro', default => sub { [] });
|
has 'regions' => (is => 'ro', default => sub { [] });
|
||||||
has 'slicing_errors' => (is => 'rw');
|
has 'slicing_errors' => (is => 'rw');
|
||||||
|
|
||||||
has 'slice_z' => (is => 'ro', required => 1); # Z used for slicing in scaled coordinates
|
has 'slice_z' => (is => 'ro', required => 1); # Z used for slicing in unscaled coordinates
|
||||||
has 'print_z' => (is => 'ro', required => 1); # Z used for printing in unscaled coordinates
|
has 'print_z' => (is => 'ro', required => 1); # Z used for printing in unscaled coordinates
|
||||||
has 'height' => (is => 'ro', required => 1); # layer height in unscaled coordinates
|
has 'height' => (is => 'ro', required => 1); # layer height in unscaled coordinates
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ sub _merge_loops {
|
||||||
$slices = offset2_ex($slices, +$safety_offset, -$safety_offset);
|
$slices = offset2_ex($slices, +$safety_offset, -$safety_offset);
|
||||||
|
|
||||||
Slic3r::debugf "Layer %d (slice_z = %.2f, print_z = %.2f): %d surface(s) having %d holes detected from %d polylines\n",
|
Slic3r::debugf "Layer %d (slice_z = %.2f, print_z = %.2f): %d surface(s) having %d holes detected from %d polylines\n",
|
||||||
$self->id, unscale($self->slice_z), $self->print_z,
|
$self->id, $self->slice_z, $self->print_z,
|
||||||
scalar(@$slices), scalar(map @{$_->holes}, @$slices), scalar(@$loops)
|
scalar(@$slices), scalar(map @{$_->holes}, @$slices), scalar(@$loops)
|
||||||
if $Slic3r::debug;
|
if $Slic3r::debug;
|
||||||
|
|
||||||
|
|
|
@ -129,8 +129,6 @@ sub add_model {
|
||||||
$mesh->rotate($object->instances->[0]->rotation, $object->center_2D);
|
$mesh->rotate($object->instances->[0]->rotation, $object->center_2D);
|
||||||
$mesh->scale($object->instances->[0]->scaling_factor);
|
$mesh->scale($object->instances->[0]->scaling_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
$mesh->scale(1 / &Slic3r::SCALING_FACTOR);
|
|
||||||
$mesh->repair;
|
$mesh->repair;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +138,9 @@ sub add_model {
|
||||||
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;
|
||||||
|
|
||||||
|
my $scaled_bb = $bb->clone;
|
||||||
|
$scaled_bb->scale(1 / &Slic3r::SCALING_FACTOR);
|
||||||
|
|
||||||
# initialize print object
|
# initialize print object
|
||||||
push @{$self->objects}, Slic3r::Print::Object->new(
|
push @{$self->objects}, Slic3r::Print::Object->new(
|
||||||
print => $self,
|
print => $self,
|
||||||
|
@ -150,7 +151,7 @@ sub add_model {
|
||||||
? (map [ scale($_->offset->[X] - $align[X]) - $align2[X], scale($_->offset->[Y] - $align[Y]) - $align2[Y] ], @{$object->instances})
|
? (map [ scale($_->offset->[X] - $align[X]) - $align2[X], scale($_->offset->[Y] - $align[Y]) - $align2[Y] ], @{$object->instances})
|
||||||
: [0,0],
|
: [0,0],
|
||||||
],
|
],
|
||||||
size => $bb->size, # transformed size
|
size => $scaled_bb->size, # transformed size
|
||||||
input_file => $object->input_file,
|
input_file => $object->input_file,
|
||||||
config_overrides => $object->config,
|
config_overrides => $object->config,
|
||||||
layer_height_ranges => $object->layer_height_ranges,
|
layer_height_ranges => $object->layer_height_ranges,
|
||||||
|
@ -514,7 +515,7 @@ EOF
|
||||||
my @previous_layer_slices = ();
|
my @previous_layer_slices = ();
|
||||||
for my $layer_id (0..$self->layer_count-1) {
|
for my $layer_id (0..$self->layer_count-1) {
|
||||||
my @layers = map $_->layers->[$layer_id], @{$self->objects};
|
my @layers = map $_->layers->[$layer_id], @{$self->objects};
|
||||||
printf $fh qq{ <g id="layer%d" slic3r:z="%s">\n}, $layer_id, unscale +(grep defined $_, @layers)[0]->slice_z;
|
printf $fh qq{ <g id="layer%d" slic3r:z="%s">\n}, $layer_id, +(grep defined $_, @layers)[0]->slice_z;
|
||||||
|
|
||||||
my @current_layer_slices = ();
|
my @current_layer_slices = ();
|
||||||
for my $obj_idx (0 .. $#{$self->objects}) {
|
for my $obj_idx (0 .. $#{$self->objects}) {
|
||||||
|
|
|
@ -63,7 +63,7 @@ sub BUILD {
|
||||||
id => $id,
|
id => $id,
|
||||||
height => $height,
|
height => $height,
|
||||||
print_z => $print_z,
|
print_z => $print_z,
|
||||||
slice_z => scale $slice_z,
|
slice_z => $slice_z,
|
||||||
);
|
);
|
||||||
if (@{$self->layers} >= 2) {
|
if (@{$self->layers} >= 2) {
|
||||||
$self->layers->[-2]->upper_layer($self->layers->[-1]);
|
$self->layers->[-2]->upper_layer($self->layers->[-1]);
|
||||||
|
|
|
@ -165,7 +165,7 @@ void
|
||||||
TriangleMesh::slice(const std::vector<double> &z, std::vector<Polygons> &layers)
|
TriangleMesh::slice(const std::vector<double> &z, std::vector<Polygons> &layers)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
This method gets called with a list of Z coordinates and outputs
|
This method gets called with a list of unscaled Z coordinates and outputs
|
||||||
a vector pointer having the same number of items as the original list.
|
a vector pointer having the same number of items as the original list.
|
||||||
Each item is a vector of polygons created by slicing our mesh at the
|
Each item is a vector of polygons created by slicing our mesh at the
|
||||||
given heights.
|
given heights.
|
||||||
|
@ -240,10 +240,21 @@ TriangleMesh::slice(const std::vector<double> &z, std::vector<Polygons> &layers)
|
||||||
|
|
||||||
std::vector<IntersectionLines> lines(z.size());
|
std::vector<IntersectionLines> lines(z.size());
|
||||||
|
|
||||||
|
// clone shared vertices coordinates and scale them
|
||||||
|
stl_vertex* v_scaled_shared = (stl_vertex*)calloc(this->stl.stats.shared_vertices, sizeof(stl_vertex));
|
||||||
|
std::copy(this->stl.v_shared, this->stl.v_shared + this->stl.stats.shared_vertices, v_scaled_shared);
|
||||||
|
for (int i = 0; i < this->stl.stats.shared_vertices; i++) {
|
||||||
|
v_scaled_shared[i].x /= SCALING_FACTOR;
|
||||||
|
v_scaled_shared[i].y /= SCALING_FACTOR;
|
||||||
|
v_scaled_shared[i].z /= SCALING_FACTOR;
|
||||||
|
}
|
||||||
|
|
||||||
for (int facet_idx = 0; facet_idx < this->stl.stats.number_of_facets; facet_idx++) {
|
for (int facet_idx = 0; facet_idx < this->stl.stats.number_of_facets; facet_idx++) {
|
||||||
stl_facet* facet = &(this->stl.facet_start[facet_idx]);
|
stl_facet* facet = &this->stl.facet_start[facet_idx];
|
||||||
float min_z = fminf(facet->vertex[0].z, fminf(facet->vertex[1].z, facet->vertex[2].z));
|
|
||||||
float max_z = fmaxf(facet->vertex[0].z, fmaxf(facet->vertex[1].z, facet->vertex[2].z));
|
// find facet extents
|
||||||
|
double min_z = fminf(facet->vertex[0].z, fminf(facet->vertex[1].z, facet->vertex[2].z));
|
||||||
|
double max_z = fmaxf(facet->vertex[0].z, fmaxf(facet->vertex[1].z, facet->vertex[2].z));
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG
|
#ifdef SLIC3R_DEBUG
|
||||||
printf("\n==> FACET %d (%f,%f,%f - %f,%f,%f - %f,%f,%f):\n", facet_idx,
|
printf("\n==> FACET %d (%f,%f,%f - %f,%f,%f - %f,%f,%f):\n", facet_idx,
|
||||||
|
@ -260,6 +271,7 @@ TriangleMesh::slice(const std::vector<double> &z, std::vector<Polygons> &layers)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find layer extents
|
||||||
std::vector<double>::const_iterator min_layer, max_layer;
|
std::vector<double>::const_iterator min_layer, max_layer;
|
||||||
min_layer = std::lower_bound(z.begin(), z.end(), min_z); // first layer whose slice_z is >= min_z
|
min_layer = std::lower_bound(z.begin(), z.end(), min_z); // first layer whose slice_z is >= min_z
|
||||||
max_layer = std::upper_bound(z.begin() + (min_layer - z.begin()), z.end(), max_z) - 1; // last layer whose slice_z is <= max_z
|
max_layer = std::upper_bound(z.begin() + (min_layer - z.begin()), z.end(), max_z) - 1; // last layer whose slice_z is <= max_z
|
||||||
|
@ -269,7 +281,8 @@ TriangleMesh::slice(const std::vector<double> &z, std::vector<Polygons> &layers)
|
||||||
|
|
||||||
for (std::vector<double>::const_iterator it = min_layer; it != max_layer + 1; ++it) {
|
for (std::vector<double>::const_iterator it = min_layer; it != max_layer + 1; ++it) {
|
||||||
std::vector<double>::size_type layer_idx = it - z.begin();
|
std::vector<double>::size_type layer_idx = it - z.begin();
|
||||||
double slice_z = *it;
|
double slice_z_u = *it; // unscaled
|
||||||
|
double slice_z = slice_z_u / SCALING_FACTOR;
|
||||||
std::vector<IntersectionPoint> points;
|
std::vector<IntersectionPoint> points;
|
||||||
std::vector< std::vector<IntersectionPoint>::size_type > points_on_layer;
|
std::vector< std::vector<IntersectionPoint>::size_type > points_on_layer;
|
||||||
bool found_horizontal_edge = false;
|
bool found_horizontal_edge = false;
|
||||||
|
@ -289,8 +302,8 @@ TriangleMesh::slice(const std::vector<double> &z, std::vector<Polygons> &layers)
|
||||||
int edge_id = facets_edges[facet_idx][j % 3];
|
int edge_id = facets_edges[facet_idx][j % 3];
|
||||||
int a_id = this->stl.v_indices[facet_idx].vertex[j % 3];
|
int a_id = this->stl.v_indices[facet_idx].vertex[j % 3];
|
||||||
int b_id = this->stl.v_indices[facet_idx].vertex[(j+1) % 3];
|
int b_id = this->stl.v_indices[facet_idx].vertex[(j+1) % 3];
|
||||||
stl_vertex* a = &(this->stl.v_shared[a_id]);
|
stl_vertex* a = &v_scaled_shared[a_id];
|
||||||
stl_vertex* b = &(this->stl.v_shared[b_id]);
|
stl_vertex* b = &v_scaled_shared[b_id];
|
||||||
|
|
||||||
if (a->z == b->z && a->z == slice_z) {
|
if (a->z == b->z && a->z == slice_z) {
|
||||||
// edge is horizontal and belongs to the current layer
|
// edge is horizontal and belongs to the current layer
|
||||||
|
@ -298,7 +311,7 @@ TriangleMesh::slice(const std::vector<double> &z, std::vector<Polygons> &layers)
|
||||||
/* We assume that this method is never being called for horizontal
|
/* We assume that this method is never being called for horizontal
|
||||||
facets, so no other edge is going to be on this layer. */
|
facets, so no other edge is going to be on this layer. */
|
||||||
IntersectionLine line;
|
IntersectionLine line;
|
||||||
if (facet->vertex[0].z < slice_z || facet->vertex[1].z < slice_z || facet->vertex[2].z < slice_z) {
|
if (facet->vertex[0].z < slice_z_u || facet->vertex[1].z < slice_z_u || facet->vertex[2].z < slice_z_u) {
|
||||||
line.edge_type = feTop;
|
line.edge_type = feTop;
|
||||||
std::swap(a, b);
|
std::swap(a, b);
|
||||||
std::swap(a_id, b_id);
|
std::swap(a_id, b_id);
|
||||||
|
@ -367,6 +380,8 @@ TriangleMesh::slice(const std::vector<double> &z, std::vector<Polygons> &layers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(v_scaled_shared);
|
||||||
|
|
||||||
// build loops
|
// build loops
|
||||||
layers.resize(z.size());
|
layers.resize(z.size());
|
||||||
for (std::vector<IntersectionLines>::iterator it = lines.begin(); it != lines.end(); ++it) {
|
for (std::vector<IntersectionLines>::iterator it = lines.begin(); it != lines.end(); ++it) {
|
||||||
|
|
|
@ -80,9 +80,10 @@ my $cube = {
|
||||||
$m->repair;
|
$m->repair;
|
||||||
my @z = (2,4,8,6,8,10,12,14,16,18,20);
|
my @z = (2,4,8,6,8,10,12,14,16,18,20);
|
||||||
my $result = $m->slice(\@z);
|
my $result = $m->slice(\@z);
|
||||||
|
my $SCALING_FACTOR = 0.000001;
|
||||||
for my $i (0..$#z) {
|
for my $i (0..$#z) {
|
||||||
is scalar(@{$result->[$i]}), 1, 'number of returned polygons per layer';
|
is scalar(@{$result->[$i]}), 1, 'number of returned polygons per layer';
|
||||||
is $result->[$i][0]->area, 20*20, 'size of returned polygon';
|
is $result->[$i][0]->area, 20*20/($SCALING_FACTOR**2), 'size of returned polygon';
|
||||||
ok $result->[$i][0]->is_counter_clockwise, 'orientation of returned polygon';
|
ok $result->[$i][0]->is_counter_clockwise, 'orientation of returned polygon';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue