Pack3d is the geometry packing tool for 3d printing here. Authentise's Pack3d codebase was forked from Fogleman's pack3d. Pack3d is written in golang and the installation instructions can be found in the CONTRIBUTING.md
Run go run cmd/pack3d/main.go --help
for command line help.
The most common command line usage is as:
pack3d --input_config_json_filename=input.json --output_packing_json_filename=output
Pack3d takes an input JSON file describing the size of a build plate, a list of items to pack, and the spacing between them.
Then pack3d will do stochastic (random re-tries) packing to pack as much as it can fit into the given build volume.
It returns a JSON file describing how the input items should be transformed to be packed, and their resulting volumes. Notice the absence of the extension of the output
file. This is because an stl
file could optionally also be written as output by pack3d.
See CONTRIBUTING.md
Pack3d is a multi-step process:
- Importing We start by loading the 3d meshes of all the input models and applying scaling and manufacturing rotation. This is distinct from the rotation the packing algorithm applies.
- Packing Packing is done largely handled by the original forked code. This is done via an 'annealing' process, which tries multiple orientations and tweaking towards a minimum 'energy'. This process can fail. In that case, we either try just restarting the process (might have gotten stuck in a local minimum), or, if it's taken too long, we reduce the number of items to pack. We use binary search to find the maximum number of items to pack.
- Exporting We take the transformations of the packed items and export them to a JSON format. Note that if a model was not packed, it's transformation is a null matrix (all zeroes).
{
"build_volume": [100, 100, 100], // Array of 3 floats
"spacing": 5, // Float
"items": [
{
"filename": "logo.stl", // Path to model file
"count": 3, // Number of this item to pack
"scale": 2.0, // Scale this item
"axes_lock": [ // Fixed angles if set, otherwise the packing algorithm is free to rotate models about this axis
"theta_x": 0.0,
"theta_y": 0.0,
"theta_z": null
], // If not supplied, treated as all values are null
"copack": [
{
"filename": "tests/jenkins_tests/corner.stl" // List of file names to copack
}
], // If not supplied, treated as empty
},
],
}
The name axes_lock
(aka mfg_orientation
) indicate of X/Y/Z need to be in an exact orientation in the final \ packed built plate. If set, that axis can't be changed during the annealing packing.
{
"build_volume": [100, 100, 100],
"spacing": 5,
"items": [
{
"filename": "tests/jenkins_tests/logo.stl",
"count": 3,
"scale": 2.0,
"axes_lock": [
"theta_x": 0.0,
"theta_y": 0.0,
"theta_z": 0.0
],
"copack": [
{
"filename": "tests/jenkins_tests/corner.stl"
}
]
},
{
"filename": "tests/jenkins_tests/cube.stl",
"count": 2,
"scale": 4.0,
"axes_lock": [
"theta_x": 0.0,
"theta_y": 0.0,
"theta_z": 0.0
],
},
{
"filename": "tests/jenkins_tests/cube.stl",
"count": 5,
"scale": 1.0,
"axes_lock": [
"theta_x": 0.0,
"theta_y": 0.0,
"theta_z": 0.0
],
}
]
}
-
The co-packed objects have VolumeWithSpacing = 0. This is because their volume is already contemplated in the value of the main co-packing object's VolumeWithSpacing.
-
Notice the scaling is already calculated into the 4x4 translation & rotation matrix.
-
pack3d can either fail to pack a set of objects entirely - an error status is displayed in the command line, or pack3d can manage to pack fewer objects in such case the objects that did not make it into the build volume will have a null Transformation =
[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 1]
.
[
{
"Filename": "tests/jenkins_tests/logo.stl",
"Transformation": [
[ 0, 0, -2, -36.092921290618406],
[-2, 0, 0, -4.735731505145346],
[ 0, 2, 0, 8.056191563929794],
[ 0, 0, 0, 1]
],
"VolumeWithSpacing": 5138.241184594143
},
{
"Filename": "tests/jenkins_tests/logo.stl",
"Transformation": [
[ 0, 0, 2, -36.09345621544282],
[ 2, 0, 0, -21.623185522659124],
[ 0, 2, 0, -8.785596546107582],
[ 0, 0, 0, 1]
],
"VolumeWithSpacing": 5138.241184594143
},
{
"Filename": "tests/jenkins_tests/cube.stl",
"Transformation": [
[ 0, 4, 0, -4.439943270386402],
[ 0, 0, 4, -11.647772698025165],
[ 4, 0, 0, -28.684157525681382],
[ 0, 0, 0, 1]
],
"VolumeWithSpacing": 76765.625
},
.
.
.
.
]
]
List of issues discovered in 2024 update. These are limitations which are largely avoided if the build plate is sufficiently larger than the collective volume of items to pack.
- If the volume of the items to pack is close to the build plate volume, sometimes pack3d will happily exceed the build plates volume. i. This is an issue with the internal algorithm of pack3d (i.e not Authentise code)
If we can't pack all models, we use binary search to find the highest number we can. If there's a small number of models, the "candidate" in binary search might become 0. In that case, the program crashes.- We do not check the bounding volumes of the models we're packing compared to the build plate. This means: a. We will attempt to pack items which will never fit on the build plate, when we should be exiting early. b. We will waste attempts by packing too many items whose collective volume is greater than the build plate's.