Share

Script17_LabelMeshes.lua

-- Lua example for Autodesk Netfabb 2019.0

-- This script demonstrates an advanced packing scenario
-- Different packing distances for different parts

-- Separates parts by volume into two groups using an arbitrary volume threshold
-- Assigns two different external offsets to parts per group (part distance)
-- Packs resulting parts (ghost parts)
-- Substitutes parts for originals

system:setloggingtooglwindow(true)

volumeThreshold = 1000 -- arbitrary threshold in mm²

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

function GenerateOffsetOfmesh(meshPar, offset)
    local luamesh = meshPar.mesh
    local matrix = meshPar.matrix
    luamesh:applymatrix(matrix)
    local newmesh = luamesh:offset(offset, offset / 3.0, true, false)
    return newmesh
end

OffsetLarge = 5
OffsetSmall = 0.5

function tablelength(T)
    local count = 0
    for _ in pairs(T) do
        count = count + 1
    end
    return count
end

root = tray.root

partsBeforePacking = {}
bakedMeshParts = {}
meshPartsWithOffset = {}
OffsetCorr = {}

-- Register all parts present into a table
for mesh_index = 0, root.meshcount - 1 do
    local traymesh = root:getmesh(mesh_index)
    table.insert(partsBeforePacking, traymesh)
end

-- Make sure all parts exist without additional transformation matrix:
-- Extract mesh information, extract matrix, bake matrix into mesh, add mesh as new part to platform
system:log("partsBeforePacking count" .. tablelength(partsBeforePacking))
for i, traymesh in pairs(partsBeforePacking) do
    local luamesh = traymesh.mesh
    local matrix = traymesh.matrix
    luamesh:applymatrix(matrix)
    table.insert(bakedMeshParts, root:addmesh(luamesh, traymesh.name, tonumber(traymesh.color,16)))
end

-- Then delete original parts from before matrix baking
for i, traymesh in pairs(partsBeforePacking) do
    root:removemesh(traymesh)
end

-- Generate packing dummies.
-- Parts of volume above threshold get a large offset, smaller parts get the small offset
-- Add and register dummy parts
system:log("Generating offset")
for i, traymesh in pairs(bakedMeshParts) do
    if (getVolumeOfmesh(traymesh) > volumeThreshold) then
        local newmesh = GenerateOffsetOfmesh(traymesh, OffsetLarge)
        local newtraymesh = root:addmesh(newmesh)
        newtraymesh:setpackingoption("restriction", "norestriction")
        table.insert(meshPartsWithOffset, newtraymesh)
        table.insert(OffsetCorr, OffsetLarge)
        system:log("This is a large part.")
    else
        local newmesh = GenerateOffsetOfmesh(traymesh, OffsetSmall)
        local newtraymesh = root:addmesh(newmesh)
        newtraymesh:setpackingoption("restriction", "norestriction")
        table.insert(meshPartsWithOffset, newtraymesh)
        table.insert(OffsetCorr, OffsetSmall)
        system:log("This is a small part.")
    end
end

-- Move non-dummy parts out of the way.
system:log("Move old meshes away from platform")
for i, traymesh in pairs(bakedMeshParts) do
    local matrix = traymesh.matrix
    MoveMatrixZ(matrix, 1000)
    traymesh:setmatrix(matrix)
    traymesh:setpackingoption("restriction", "locked")
end

-- Pack dummy parts.
system:log("Pack")
packer = tray:createpacker(tray.packingid_montecarlo)
packer.packing_quality = -1
packer.z_limit = 0.0
packer.start_from_current_positions = false
packer:pack()

-- Apply transformation matrices generated by packing to associated originals.
system:log("Move original parts into place")
for i, traymesh in pairs(bakedMeshParts) do
    local packedMesh = meshPartsWithOffset[i]
    traymesh:setmatrix(packedMesh.matrix)
    local offset = OffsetCorr[i]
end

-- Delete dummy parts.
system:log("remove offset parts")
for i, traymesh in pairs(meshPartsWithOffset) do
    local Mesh = meshPartsWithOffset[i]
    root:removemesh(Mesh)
end

Was this information helpful?