LDraw.org Discussion Forums

Full Version: Simple LDCad script
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
So, I wrote my first script for LDCad, hooray! Cool

It is a simple macro to transpose two colors in a selection. You might use it if you have built a huge checkered floor out of tiles and realized you have the pattern backwards!

I'm sure there are ways to improve it, but I'm actually pleased I was able to work it out in one day. Big Grin

Here it is:
Code:
genTools=require('genTools')

function runColorSwap()

  local ses=ldc.session()
  local sel=ses:getSelection()
  local cnt=sel:getRefCount()
 
  if not ses:isLinked() then
    ldc.dialog.runMessage('No active model.')
    return
  end

  if cnt==0 then
    ldc.dialog.runMessage('No selection active.')
    return
  elseif cnt<2 then
    ldc.dialog.runMessage('At least two items must be selected.')
    return
  end

  local colors={}
 
  local function has_value (tab, val)
    for k, v in ipairs(tab) do
        if v == val then
            return true
        end
    end

    return false
  end

  for i=1,cnt do
    local ref=sel:getRef(i)
    local col=ref:getColor()
    if not has_value(colors, col) then
      table.insert(colors, col)
    end
  end

  if #colors==2 then
    for i=1,cnt do
      local ref=sel:getRef(i)
      local col=ref:getColor()
      if col==colors[1] then
        ref:setColor(colors[2])
      elseif col==colors[2] then
        ref:setColor(colors[1])
      end
    end
  else ldc.dialog.runMessage('The selection must contain exactly two colors.')
  end
end
--===================

function register()

  local macro=ldc.macro('Color swap')
  macro:setHint('Transposes two colors in a selection.')
  macro:setEvent('run', 'runColorSwap')
end

register()

Suggestions are welcome!
(2022-03-25, 4:27)N. W. Perry Wrote: [ -> ]So, I wrote my first script for LDCad, hooray! Cool
Congratulations, be careful though it can be addictive Big Grin

Minor potential bug:
Code:
local cnt=sel:getRefCount()
will cause a runtime error when no model is open, easily fixed by moving the line (and the one above it) below the ses:isLinked() test.
(2022-03-25, 19:56)Roland Melkert Wrote: [ -> ]Minor potential bug:
Code:
local cnt=sel:getRefCount()
will cause a runtime error when no model is open, easily fixed by moving the line (and the one above it) below the ses:isLinked() test.

Fixed. Couldn't I also move the local variables col and ref up higher somewhere, so I don't have to repeat them?

My next attempt will be a macro to comment out BUFEXCHG lines. I think I know how to identify the affected ref lines, now to learn how to actually alter them. :-)
(2022-03-25, 22:33)N. W. Perry Wrote: [ -> ]Couldn't I also move the local variables col and ref up higher somewhere, so I don't have to repeat them?

Yes, just write them without the value assignment.


(2022-03-25, 22:33)N. W. Perry Wrote: [ -> ]My next attempt will be a macro to comment out BUFEXCHG lines. I think I know how to identify the affected ref lines, now to learn how to actually alter them. :-)

scripts can't actually modify lines on a string level (mostly because of the undo tracking), but you get the same effect by creating a new line and deleting the old one.

For an example of this see the global mlcad.lua script.
(2022-03-25, 22:57)Roland Melkert Wrote: [ -> ]Yes, just write them without the value assignment.

I couldn't get them to work except inside the loops themselves (which meant I had to declare them in both loops). But the cnt variable does, for some reason.

(2022-03-25, 22:57)Roland Melkert Wrote: [ -> ]scripts can't actually modify lines on a string level (mostly because of the undo tracking), but you get the same effect by creating a new line and deleting the old one.

For an example of this see the global mlcad.lua script.

Yes, I'll be studying that one tonight. :-)