I made some adjustments to the script to reset rotation and prepare for inlining. I'm not sure how to inline in LDCad script so here I might need Roland.
But if you inline before running it it's starting to look like something
But if you inline before running it it's starting to look like something
Code:
-- Function to get the X, Y (min), and Z dimensions of a subfile using its bounding box
function getSubfileDimensions(subfile)
local minVec = subfile:getBoundingBoxMin()
local maxVec = subfile:getBoundingBoxMax()
return maxVec:getX() - minVec:getX(), minVec:getY(), maxVec:getZ() - minVec:getZ() -- Return width, minY, and depth
end
-- Function to sort subfiles by their combined XZ size
function sortSubfilesBySizeXZ(a, b)
local widthA, _, depthA = getSubfileDimensions(a)
local widthB, _, depthB = getSubfileDimensions(b)
local sizeA = widthA * depthA
local sizeB = widthB * depthB
return sizeA < sizeB
end
-- Function to reset the rotation of a part to identity
function resetPartRotation(part)
local identityMatrix = ldc.matrix()
identityMatrix:setIdentity()
part:setOri(identityMatrix)
end
-- Function to check if a part is a submodel and print its name if it is
function checkAndPrintSubmodel(part)
local subfile = part:getSubfile()
if subfile:isModel() and subfile:getRefCount() > 0 then
-- print("Submodel name: " .. subfile:getFileName())
-- Do stuff here to inline the submodels
end
end
-- Function to layout parts in a knolling grid arrangement on the XY plane
function knollingLayout()
local ses = ldc.session()
if not ses:isLinked() then
ldc.dialog.runMessage('No active model.')
return
end
local sel = ses:getSelection()
local cnt = sel:getRefCount()
if cnt < 2 then
ldc.dialog.runMessage('At least two items should be selected.')
return
end
local subfiles = {}
-- Collect all subfiles (Parts in the selection)
for i = 1, cnt do
local part = sel:getRef(i)
table.insert(subfiles, part)
checkAndPrintSubmodel(part) -- Check and print submodel name if applicable
end
-- Sort subfiles by size (combined X and Z dimensions)
table.sort(subfiles, function(a, b)
return sortSubfilesBySizeXZ(a:getSubfile(), b:getSubfile())
end)
-- Determine grid dimensions and spacing
local gridSize = 20 -- Minimum grid size, consider part size + desired spacing
local xOffset = 0
local zOffset = 0
local rowWidth = 0
for i, part in ipairs(subfiles) do
local subfile = part:getSubfile()
local width, minY, depth = getSubfileDimensions(subfile) -- X and Z dimensions, and minY for the Y position
-- Reset the part's rotation
resetPartRotation(part)
-- Set the part's position
local pos = ldc.vector(xOffset, minY, zOffset)
part:setPos(pos)
-- Update offset for next part
zOffset = zOffset + depth + gridSize -- Move right to the next column
-- Keep track of the maximum width in the current row
rowWidth = math.max(rowWidth, width + gridSize)
-- Check if we need to start a new row
if zOffset + depth > gridSize * 100 then -- Assuming the grid is 10 columns wide
xOffset = xOffset + rowWidth
zOffset = 0 -- Move down to the next row
rowWidth = 0 -- Reset row width for the new row
end
end
end
-- Register the macro for the knolling layout
function register()
local macro_lo = ldc.macro('Perform knolling layout')
macro_lo:setHint('Arrange elements in a knolling layout based on size in XY plane with Z = 0.')
macro_lo:setEvent('run', 'knollingLayout')
end
register()