Idea for LUA script to create a knolling layout


RE: Idea for LUA script to create a knolling layout
#4
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

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()


Attached Files Thumbnail(s)
   
Reply
« Next Oldest | Next Newest »



Messages In This Thread
RE: Idea for LUA script to create a knolling layout - by Fredrik Hareide - 2024-10-11, 7:41

Forum Jump:


Users browsing this thread: 20 Guest(s)