mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	
		
			
				
	
	
		
			158 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
package Slic3r::Geometry::BoundingBox;
 | 
						|
use Moo;
 | 
						|
 | 
						|
use List::Util qw(min max);
 | 
						|
use Slic3r::Geometry qw(X Y Z MIN MAX X1 Y1 X2 Y2 Z1 Z2);
 | 
						|
use Storable qw();
 | 
						|
 | 
						|
has 'extents' => (is => 'ro', required => 1);
 | 
						|
 | 
						|
sub clone { Storable::dclone($_[0]) }
 | 
						|
 | 
						|
# 2D
 | 
						|
sub new_from_points {
 | 
						|
    my $class = shift;
 | 
						|
    my ($points) = @_;
 | 
						|
    
 | 
						|
    my $bb = [ Slic3r::Geometry::bounding_box($points) ];
 | 
						|
    return $class->new(extents => [
 | 
						|
        [ $bb->[X1], $bb->[X2] ],
 | 
						|
        [ $bb->[Y1], $bb->[Y2] ],
 | 
						|
    ]);
 | 
						|
}
 | 
						|
 | 
						|
# 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
 | 
						|
sub new_from_points_3D {
 | 
						|
    my $class = shift;
 | 
						|
    my ($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
 | 
						|
sub bb {
 | 
						|
    my $self = shift;
 | 
						|
    my $extents = $self->extents;
 | 
						|
    return [ $extents->[X][MIN], $extents->[Y][MIN], $extents->[X][MAX], $extents->[Y][MAX] ];
 | 
						|
}
 | 
						|
 | 
						|
sub polygon {
 | 
						|
    my $self = shift;
 | 
						|
    
 | 
						|
    my $e = $self->extents;
 | 
						|
    return Slic3r::Polygon->new(
 | 
						|
        [ $e->[X][MIN], $e->[Y][MIN] ],
 | 
						|
        [ $e->[X][MAX], $e->[Y][MIN] ],
 | 
						|
        [ $e->[X][MAX], $e->[Y][MAX] ],
 | 
						|
        [ $e->[X][MIN], $e->[Y][MAX] ],
 | 
						|
    );
 | 
						|
}
 | 
						|
 | 
						|
# note to $self
 | 
						|
sub rotate {
 | 
						|
    die "Rotating an axis-aligned bounding box doesn't make any sense";
 | 
						|
}
 | 
						|
 | 
						|
sub scale {
 | 
						|
    my $self = shift;
 | 
						|
    my ($factor) = @_;
 | 
						|
    
 | 
						|
    for (@{$self->extents}) {
 | 
						|
        $_ *= $factor for @$_[MIN,MAX];
 | 
						|
    }
 | 
						|
    
 | 
						|
    $self;
 | 
						|
}
 | 
						|
 | 
						|
sub translate {
 | 
						|
    my $self = shift;
 | 
						|
    my @shift = @_;
 | 
						|
    
 | 
						|
    for my $axis (X .. $#{$self->extents}) {
 | 
						|
        $self->extents->[$axis][MIN] += $shift[$axis];
 | 
						|
        $self->extents->[$axis][MAX] += $shift[$axis];
 | 
						|
    }
 | 
						|
    
 | 
						|
    $self;
 | 
						|
}
 | 
						|
 | 
						|
sub size {
 | 
						|
    my $self = shift;
 | 
						|
    
 | 
						|
    my $extents = $self->extents;
 | 
						|
    return [ map $extents->[$_][MAX] - $extents->[$_][MIN], grep $extents->[$_], (X,Y,Z) ];
 | 
						|
}
 | 
						|
 | 
						|
sub center {
 | 
						|
    my $self = shift;
 | 
						|
    
 | 
						|
    my $extents = $self->extents;
 | 
						|
    return [ map +($extents->[$_][MAX] + $extents->[$_][MIN])/2, grep $extents->[$_], (X,Y,Z) ];
 | 
						|
}
 | 
						|
 | 
						|
sub center_2D {
 | 
						|
    my $self = shift;
 | 
						|
    return Slic3r::Point->new(@{$self->center}[X,Y]);
 | 
						|
}
 | 
						|
 | 
						|
sub min_point {
 | 
						|
    my $self = shift;
 | 
						|
    return Slic3r::Point->new($self->extents->[X][MIN], $self->extents->[Y][MIN]);
 | 
						|
}
 | 
						|
 | 
						|
sub max_point {
 | 
						|
    my $self = shift;
 | 
						|
    return Slic3r::Point->new($self->extents->[X][MAX], $self->extents->[Y][MAX]);
 | 
						|
}
 | 
						|
 | 
						|
sub x_min {
 | 
						|
    my $self = shift;
 | 
						|
    return $self->extents->[X][MIN];
 | 
						|
}
 | 
						|
 | 
						|
sub x_max {
 | 
						|
    my $self = shift;
 | 
						|
    return $self->extents->[X][MAX];
 | 
						|
}
 | 
						|
 | 
						|
sub y_min {
 | 
						|
    my $self = shift;
 | 
						|
    return $self->extents->[Y][MIN];
 | 
						|
}
 | 
						|
 | 
						|
sub y_max {
 | 
						|
    my $self = shift;
 | 
						|
    return $self->extents->[Y][MAX];
 | 
						|
}
 | 
						|
 | 
						|
1;
 |