Share

Script19_AdvancedPacking2.lua

-- Lua example for Autodesk Netfabb 2019.0

-- Packs the current tray with an additional feature:
-- All large parts are packed in the center of the build room

function checkErrorCodeMCpacker(errorcodepar)
    if errorcodepar == 0 then
        system:log("Monte Carlo packing is finished. No problems encountered.")
    elseif errorcodepar == 1 then
        system:log("Monte Carlo packing is finished. There is not enough place for all parts in the tray.")
    elseif errorcodepar == 2 then
        system:log("Monte Carlo packing is finished. Some parts are too large for the given tray.")
    elseif errorcodepar == 3 then
        system:log("Monte Carlo packing failed: All parts are too large for the given tray.")
    elseif errorcodepar == 4 then
        system:log("Monte Carlo packing failed: There are no parts to pack.")
    elseif errorcodepar == 5 then
        system:log("Monte Carlo packing failed: Starting from current positions is not possible.")
    else
        system:log("Monte Carlo packing failed: Unknown error.")
    end
end

function MoveMatrixZ(matrix, value)
    local tmp = matrix:get(2, 2)
    matrix:set(3, 2, tmp + value)
end

function getVolumeOfmesh(meshPar)
    local luamesh = meshPar.mesh
    local matrix = meshPar.matrix
    luamesh:applymatrix(matrix)
    return luamesh.volume
end

system:setloggingtooglwindow(true)

pa_id = tray.packingid_montecarlo

packer = tray:createpacker(pa_id)
boundingboxOrig = packer:getoutbox()
boundingbox = packer:getoutbox()

tempMaxX = boundingbox.maxx
tempMaxY = boundingbox.maxy

boundingbox.minx = 100 -- For the first packing run the packing area is reduced.
boundingbox.miny = 100

boundingbox.maxx = tempMaxX - 100
boundingbox.maxy = tempMaxY - 100

packer:setoutbox(boundingbox)

volumeThreshold = 10000 -- Volume threshold in cubic millimeters; everything higher is considered a large part and is packed in the center

if pa_id == tray.packingid_montecarlo then
    -- Setting options for Monte Carlo packing
    packer.packing_quality = -1
    packer.z_limit = 0.0 -- artificial ceiling; if this is set to zero, the default value, MachineSizeZ, is be used
    packer.start_from_current_positions = false
end

root = tray.root
meshesOrig = {}
for mesh_index = 0, root.meshcount - 1 do
    local traymesh = root:getmesh(mesh_index)
    table.insert(meshesOrig, traymesh)
end

-- All meshes above the build platform
system:log("Move old meshes from the build platform")
for i, traymesh in pairs(meshesOrig) do
    local matrix = traymesh.matrix
    MoveMatrixZ(matrix, 1000)
    traymesh:setmatrix(matrix)
end

-- Lock positions of small parts for now
for i, traymesh in pairs(meshesOrig) do
    if (getVolumeOfmesh(traymesh) > volumeThreshold) then
        traymesh:setpackingoption("restriction", "norestriction")
    else
        traymesh:setpackingoption("restriction", "locked")
    end
end

-- Pack large things
local errorcode = packer:pack()

-- Unlock and pack small things
packer:setoutbox(boundingboxOrig)
for i, traymesh in pairs(meshesOrig) do
    if (getVolumeOfmesh(traymesh) < volumeThreshold) then
        traymesh:setpackingoption("restriction", "norestriction")
    else
        traymesh:setpackingoption("restriction", "locked")
    end
end
local errorcode = packer:pack()
checkErrorCodeMCpacker(errorcode)

Was this information helpful?