package Slic3r::TriangleMesh;
use strict;
use warnings;

use List::Util qw(first);
use Slic3r::Geometry qw(X Y);
use Slic3r::Geometry::Clipper qw(union_ex offset);

sub needed_repair {
    my $self = shift;
    
    my $stats = $self->stats;
    return (first { $stats->{$_} > 0 }
        qw(degenerate_facets edges_fixed facets_removed facets_added facets_reversed backwards_edges)) ? 1 : 0;
}

sub center {
    my $self = shift;
    return $self->bounding_box->center;
}

sub used_vertices {
    my $self = shift;
    return $self->vertices;
}

sub bounding_box {
    my $self = shift;
    return Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices);
}

# this will return *scaled* expolygons, so it is expected to be run
# on unscaled meshes
sub horizontal_projection {
    my $self = shift;
    
    my ($facets, $vertices) = ($self->facets, $self->vertices);
    
    my @f = ();
    foreach my $facet (@$facets) {
        push @f, Slic3r::Polygon->new(
            map [ map $_ / &Slic3r::SCALING_FACTOR, @{$vertices->[$_]}[X,Y] ], @$facet
        );
    }
    
    $_->make_counter_clockwise for @f;  # do this after scaling, as winding order might change while doing that
    
    # the offset factor was tuned using groovemount.stl
    return union_ex(offset(\@f, Slic3r::Geometry::scale 0.01), 1);
}

1;