skjolber / 3d-bin-container-packing

A variant of the Largest Area Fit First (LAFF) algorithm + brute force algorithm
Apache License 2.0
430 stars 118 forks source link

Packing Not Respecting Stacking Constraint #865

Closed KurtisWhiteman closed 7 months ago

KurtisWhiteman commented 7 months ago

I've looked through the open and closed issues regarding Stacking and Constraints which are all at least a year old now so I'm hoping this isn't an issue but rather me not being able to figure out what's wrong but.

It looks like the code doesn't account for a StackConstraint that's been applied to a Box?

I'm trying to fit X amount of boxes into a container and to not stack boxes over the maxSupportedWeight on other boxes. Not every box will not be able to stack but those that can't be stacked should not be stacked on top of (at all but specifying a weight is fine).

I adapted the LaffPackagerTest.testPackager to test this but it does not work and I can't figure out how or why. I've pasted this test below.

I've added a maxSupportedWeight of 5 to the 3rd(bright red) box. The 2 other items are over 5 in weight but the visualiser shows the 1st box(dark red) on top of the 3rd box(bright red) instead of being next to it and placing the 1st box(green) on top of the 1st box(dark red)

Adding rotate3D or doing the same in PlainPackagerTest.testPlainPackager nets the same issue though with a different orientation of packing. (both big boxes on the ground with smallest box on top of StackConstraint box).

I am still trying to wrap my head around everything in this package such as Surfaces, StackValue, Stackables to see if maybe I'm just missing something?

Would appreciate any help. Apologies if I haven't made the issue clear. Appreciate what you've done as well. chrome_CX2TizfpAN

@Test
public void testPackager() throws Exception {

StackConstraint stackConstraint = new DefaultStackValueConstraint(5);

List<ContainerItem> containerCustom = ContainerItem
        .newListBuilder()
        .withContainer(Container.newBuilder().withDescription("1").withEmptyWeight(1).withSize(40, 100, 100).withMaxLoadWeight(1000).build(), 1)
        .build();

FastLargestAreaFitFirstPackager packager = FastLargestAreaFitFirstPackager.newBuilder().build();

List<StackableItem> products = new ArrayList<>();

products.add(new StackableItem(Box.newBuilder().withDescription("1").withSize(20, 20, 20).withRotate3D().withWeight(7).build(), 1));
products.add(new StackableItem(Box.newBuilder().withDescription("2").withSize(40, 40, 20).withRotate3D().withWeight(6).build(), 1));
products.add(new StackableItem(Box.newBuilder().withDescription("3").withSize(40, 60, 20).withWeight(10).withConstraint(stackConstraint).build(), 1));

PackagerResult build = packager.newResultBuilder().withContainers(containerCustom).withMaxContainerCount(1).withStackables(products).build();
if(build.isSuccess()) {
    write(build.getContainers());
} else {
    fail();
}
}
skjolber commented 7 months ago

The constraint mechanism is really crude, it only works for the containers and has not good way of determining the resulting load on the existing boxes. So making things work as in your unit test is a future improvement I am afraid.

KurtisWhiteman commented 7 months ago

Understood. No worries and appreciate the reply! Godspeed :)