From ef8695da1d64d14616887295cbd0cb88f3b805d9 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 8 Apr 2017 10:57:16 +0200 Subject: [PATCH] Update and restore t/loops.t --- t/loops.t | 64 ++++++++++++++----------------- xs/src/libslic3r/TriangleMesh.cpp | 7 ++++ xs/src/libslic3r/TriangleMesh.hpp | 1 + xs/xsp/TriangleMesh.xsp | 1 + 4 files changed, 38 insertions(+), 35 deletions(-) diff --git a/t/loops.t b/t/loops.t index e662469ca..d2bf77176 100644 --- a/t/loops.t +++ b/t/loops.t @@ -2,7 +2,6 @@ use Test::More; use strict; use warnings; -plan skip_all => 'temporarily disabled'; plan tests => 4; BEGIN { @@ -12,46 +11,41 @@ BEGIN { } use Slic3r; +use Slic3r::Geometry qw(Z epsilon scale); use Slic3r::Test; { - # We only need to slice at one height, so we'll build a non-manifold mesh - # that still produces complete loops at that height. Triangular walls are - # enough for this purpose. - # Basically we want to check what happens when three concentric loops happen + # We want to check what happens when three concentric loops happen # to be at the same height, the two external ones being ccw and the other being - # a hole, thus cw. - my (@vertices, @facets) = (); - Slic3r::Test::add_facet($_, \@vertices, \@facets) for - # external surface below the slicing Z - [ [0,0,0], [20,0,10], [0,0,10] ], - [ [20,0,0], [20,20,10], [20,0,10] ], - [ [20,20,0], [0,20,10], [20,20,10] ], - [ [0,20,0], [0,0,10], [0,20,10] ], - - # external insetted surface above the slicing Z - [ [2,2,10], [18,2,10], [2,2,20] ], - [ [18,2,10], [18,18,10], [18,2,20] ], - [ [18,18,10], [2,18,10], [18,18,20] ], - [ [2,18,10], [2,2,10], [2,18,20] ], - - # insetted hole below the slicing Z - [ [15,5,0], [5,5,10], [15,5,10] ], - [ [15,15,0], [15,5,10], [15,15,10] ], - [ [5,15,0], [15,15,10], [5,15,10] ], - [ [5,5,0], [5,15,10], [5,5,10] ]; + # a hole, thus cw. So we create three cubes, centered around origin, the internal + # one having reversed normals. + my $mesh1 = Slic3r::Test::mesh('20mm_cube'); - my $mesh = Slic3r::TriangleMesh->new; - $mesh->ReadFromPerl(\@vertices, \@facets); - $mesh->analyze; - my @lines = map $mesh->intersect_facet($_, 10), 0..$#facets; - my $loops = Slic3r::TriangleMesh::make_loops(\@lines); - is scalar(@$loops), 3, 'correct number of loops detected'; - is scalar(grep $_->is_counter_clockwise, @$loops), 2, 'correct number of ccw loops detected'; + # center around origin + my $bb = $mesh1->bounding_box; + $mesh1->translate( + -($bb->x_min + $bb->size->x/2), + -($bb->y_min + $bb->size->y/2), #// + -($bb->z_min + $bb->size->z/2), + ); - my @surfaces = Slic3r::Layer::Region::_merge_loops($loops, 0); - is scalar(@surfaces), 1, 'one surface detected'; - is scalar(@{$surfaces[0]->expolygon})-1, 1, 'surface has one hole'; + my $mesh2 = $mesh1->clone; + $mesh2->scale(1.2); + + my $mesh3 = $mesh2->clone; + $mesh3->scale(1.2); + + $mesh1->reverse_normals; + ok $mesh1->volume < 0, 'reverse_normals'; + + my $all_meshes = Slic3r::TriangleMesh->new; + $all_meshes->merge($_) for $mesh1, $mesh2, $mesh3; + + my $loops = $all_meshes->slice_at(Z, 0); + is scalar(@$loops), 1, 'one expolygon returned'; + is scalar(@{$loops->[0]->holes}), 1, 'expolygon has one hole'; + ok abs(-$loops->[0]->holes->[0]->area - scale($bb->size->x)*scale($bb->size->y)) < epsilon, #)) + 'hole has expected size'; } __END__ diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp index 2a52c865f..cba0a7977 100644 --- a/xs/src/libslic3r/TriangleMesh.cpp +++ b/xs/src/libslic3r/TriangleMesh.cpp @@ -511,6 +511,13 @@ TriangleMesh::require_shared_vertices() if (this->stl.v_shared == NULL) stl_generate_shared_vertices(&(this->stl)); } +void +TriangleMesh::reverse_normals() +{ + stl_reverse_all_facets(&this->stl); + if (this->stl.stats.volume != -1) this->stl.stats.volume *= -1.0; +} + void TriangleMesh::extrude_tin(float offset) { diff --git a/xs/src/libslic3r/TriangleMesh.hpp b/xs/src/libslic3r/TriangleMesh.hpp index 51a4e9df4..271324282 100644 --- a/xs/src/libslic3r/TriangleMesh.hpp +++ b/xs/src/libslic3r/TriangleMesh.hpp @@ -59,6 +59,7 @@ class TriangleMesh size_t facets_count() const; void extrude_tin(float offset); void require_shared_vertices(); + void reverse_normals(); static TriangleMesh make_cube(double x, double y, double z); static TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/360)); diff --git a/xs/xsp/TriangleMesh.xsp b/xs/xsp/TriangleMesh.xsp index 373cba12e..47f7c7558 100644 --- a/xs/xsp/TriangleMesh.xsp +++ b/xs/xsp/TriangleMesh.xsp @@ -41,6 +41,7 @@ %code{% RETVAL = THIS->bounding_box().center(); %}; int facets_count(); void reset_repair_stats(); + void reverse_normals(); %{