$Box::Calc::Box::VERSION
=
'1.0206'
;
has
fill_weight
=> (
is
=>
'rw'
,
default
=> 0,
isa
=>
'Num'
,
);
sub
fill_x {
my
$self
=
shift
;
my
$value
= 0;
foreach
my
$layer
(@{
$self
->layers}) {
$value
=
$layer
->fill_x
if
$layer
->fill_x >
$value
;
}
return
sprintf
(
"%.4f"
,
$value
);
}
sub
fill_y {
my
$self
=
shift
;
my
$value
= 0;
foreach
my
$layer
(@{
$self
->layers}) {
$value
=
$layer
->fill_y
if
$layer
->fill_y >
$value
;
}
return
sprintf
(
"%.4f"
,
$value
);
}
sub
fill_z {
my
$self
=
shift
;
my
$value
= 0;
foreach
my
$layer
(@{
$self
->layers}) {
$value
+=
$layer
->fill_z;
}
return
sprintf
(
"%.4f"
,
$value
);
}
has
id
=> (
is
=>
'ro'
,
default
=>
sub
{ Data::GUID->new->as_string },
);
has
name
=> (
is
=>
'ro'
,
isa
=>
'Str'
,
required
=> 1,
);
has
layers
=> (
is
=>
'rw'
,
isa
=>
'ArrayRef[Box::Calc::Layer]'
,
default
=>
sub
{ [] },
traits
=> [
'Array'
],
handles
=> {
count_layers
=>
'count'
,
}
);
has
void_weight
=> (
is
=>
'rw'
,
lazy
=> 1,
default
=>
sub
{
my
$self
=
shift
;
return
$self
->weight * 0.7;
}
);
sub
calculate_weight {
my
$self
=
shift
;
return
$self
->weight +
$self
->void_weight +
$self
->fill_weight;
}
sub
create_layer {
my
$self
=
shift
;
push
@{
$self
->layers}, Box::Calc::Layer->new(
max_x
=>
$self
->x,
max_y
=>
$self
->y, );
}
sub
BUILD {
my
$self
=
shift
;
$self
->create_layer;
}
sub
pack_item {
my
(
$self
,
$item
,
$count
) =
@_
;
$count
||= 1;
if
(
$count
> 5) {
$log
->
warn
(
$item
->{name}.
' is causing infinite recursion in Box::Calc'
);
$log
->debug(Dumper(
$item
));
return
0;
}
if
(
$item
->weight +
$self
->calculate_weight >=
$self
->max_weight) {
$log
->info(
$item
->{name}.
' would make this box weigh too much, requesting new box.'
);
return
0;
}
if
(
$item
->z >
$self
->z -
$self
->fill_z +
$self
->layers->[-1]->fill_z) {
$log
->info(
$item
->{name}.
' would make the layer too tall to fit in the box, requesting new box.'
);
return
0;
}
if
(
$self
->layers->[-1]->pack_item(
$item
)) {
$self
->fill_weight(
$self
->fill_weight +
$item
->weight);
return
1;
}
else
{
if
(
$item
->z >
$self
->z -
$self
->fill_z) {
$log
->info(
$item
->{name}.
' is too big to create another layer in this box, requesting another box.'
);
return
0;
}
else
{
$self
->create_layer;
return
$self
->pack_item(
$item
,
$count
+ 1);
}
}
}
sub
packing_list {
my
$self
=
shift
;
my
$weight
=
$self
->weight;
my
$list
= {};
foreach
my
$layer
(@{
$self
->layers}) {
$layer
->packing_list(\
$weight
,
$list
)
}
return
(
$weight
,
$list
);
}
sub
packing_instructions {
my
$self
=
shift
;
return
{
x
=>
$self
->x,
y
=>
$self
->y,
z
=>
$self
->z,
fill_x
=>
$self
->fill_x,
fill_y
=>
$self
->fill_y,
fill_z
=>
$self
->fill_z,
name
=>
$self
->name,
id
=>
$self
->id,
weight
=>
$self
->weight,
calculated_weight
=>
$self
->calculate_weight,
used_volume
=>
$self
->used_volume,
fill_volume
=>
$self
->fill_volume,
volume
=>
$self
->volume,
layers
=> [
map
{
$_
->packing_instructions } @{
$self
->layers }],
};
}
sub
used_volume {
my
$self
=
shift
;
return
sum
map
{
$_
->used_volume } @{
$self
->layers };
}
sub
fill_volume {
return
$_
[0]->fill_x *
$_
[0]->fill_y *
$_
[0]->fill_z;
}
no
Moose;
__PACKAGE__->meta->make_immutable;
=
for
Pod::Coverage BUILD