I inquire if the code used in the Ruby Console will not work if I make it into a plug-in

Hello :slight_smile:
I tried to create a plugin that divides in the Z direction when inputting an interval using an inputbox.
There is a problem that the code that worked in the Ruby Console cannot be made into a plug-in.
Of course, my coding skills seem to be the problem :joy:

require 'sketchup.rb'

def create_line
  mod = Sketchup.active_model
  ent = mod.entities
  sel = mod.selection 

  SKETCHUP_CONSOLE.clear

  Sketchup.send_action "selectSelectionTool:"
  prompts = ["1","2"]
  values = [$hg1, $hg2]
  result = UI.inputbox(prompts, vlaues, "커튼월")

  $hg1 = result[0].to_f; $hg2 = result[1].to_f;

  puts(result[0], reuslt[1])

  faces = sel.grep(Sketchup::Face).reject{|f|f.normal.z != 0}
  for f in faces
    btm = f.edges.min_by{|x|x.start.position.z+x.end.position.z}
    sp = btm.start.position.offset(Z_AXIS, $hg1.to_f.mm)
    sp = btm.end.position.offset(Z_AXIS, $hg1.to_f.mm)

    sp2 = btm.start.position.offset(Z_AXIS, $hg1.to_f.mm + $hg2.to_f.mm)
    ep2 = btm.end.position.offset(Z_AXIS, $hg1.to_f.mm + $hg2.to_f.mm)

    new = ent.add_line(sp,ep)
    new = ent.add_line(sp2,ep2)

  end
  
end

# Add a menu item to activate the plugin
UI.menu("Plugins").add_item("Create line") {
  prompts = ["1", "2"]
  defaults = [10, 10]
  input = UI.inputbox(prompts, defaults, "Dimensions")

}

I wonder if it is a code that cannot function with def. Below is the code I proceeded with the ruby console (no def)

  mod = Sketchup.active_model
  ent = mod.entities
  sel = mod.selection 

  SKETCHUP_CONSOLE.clear

  Sketchup.send_action "selectSelectionTool:"
  prompts = ["1","2"]
  values = [$hg1, $hg2]
  result = UI.inputbox(prompts, values, "커튼월")

  $hg1 = result[0].to_f; $hg2 = result[1].to_f;

  puts(result[0], result[1])

  faces = sel.grep(Sketchup::Face).reject{|f|f.normal.z != 0}
  for f in faces
    btm = f.edges.min_by{|x|x.start.position.z+x.end.position.z}
    sp = btm.start.position.offset(Z_AXIS, $hg1.to_f.mm)
    ep = btm.end.position.offset(Z_AXIS, $hg1.to_f.mm)

    sp2 = btm.start.position.offset(Z_AXIS, $hg1.to_f.mm + $hg2.to_f.mm)
    ep2 = btm.end.position.offset(Z_AXIS, $hg1.to_f.mm + $hg2.to_f.mm)

    new = ent.add_line(sp,ep)
    new = ent.add_line(sp2,ep2)

  end

Thanks for any helpful tips or corrections. Always happy to help. Thanks everyone. :innocent:

For general information, see this recent post by me …

2 Likes

There are multiple issues with your snippet. I’ll start with the worst and work my way down the list. It would be very valuable for you to study the Ruby and plugin coding material that @DanRathbun has referenced in multiple posts over the years. There was a recent post of his about this, and you can search the forum for more.

The most important flaws are:

Your menu item doesn’t do anything with the input it gets from the UI.inputbox. Unlike the Ruby console version, the variable named ‘input’ is local to the block tied to the menu item. It is not shared by the code in create_line. The block code will need to call the def’s method, something like

create_line(input)

But that also won’t work because the method isn’t def’d to take any arguments, so there is no way to pass the input to it! The def needs to be

def create_line(argument)
# rest of the code here
end

and then use argument instead of input in the code for create_line.

The UI.inputbox code is repeated in the menu item block and in create_line. That serves no purpose. It should be removed from one or the other. You have two choices: It could be removed from the menu item’s block, in which case there is no argument to pass to create_line (and no need to pass one), though the menu item block still needs to call create_line. Or it could be removed from the def of create_line, in which case you will need to pass the inputbox value as the argument to create_line and process it there.

You have a typo in the puts statement: reuslt[1] should be result[1]. That will cause a runtime error about an undefined variable.

Merely activating the Selection Tool won’t put anything into the selection and won’t pause the execution of create_line to give the user a chance to do so. So, when you grep the selection for Faces, you will only find whatever was already selected before you ran create_line.

Those are the functional issues that will keep it from working at all. Now some other flaws.

You should wrap the def of create_line in a module which you give a name that (you hope) will be unique to you. Do not def methods in the global namespace where they can collide with ones from other similarly careless coders! If you write multiple plugins, you should put another layer of module to protect yourself from the same sort of interaction between different plugins.

Do not use global variables such as $hg1 and $hg2. These pollute the global namespace, and since they aren’t relevant to anything outside create_line, should be just ordinary local variables hg1 and hg2.

You should wrap any actions that modify the model with #start_operation and #commit_operation so that they can be undone as a single step.

Your profile says you are using SketchUp 2015. If that is true, you do need the require ‘sketchup.rb’ statement, but as of several versions ago (2020 maybe?) that file is automatically loaded as SketchUp starts and this require is not needed in current versions.

Why do you need to clear the SKETCHUP_CONSOLE? Only so there won’t be anything else there but the output of your puts statement?

3 Likes

I am grateful for the lengthy problem analysis. thank you. In fact, as an architect, not a programmer, I am currently thinking about how to easily do architectural modeling through sketchup, and I am making several attempts. I’m sorry for confusing you during various attempts as I have no programming knowledge. I made some modifications as per your advice, (Actually, since I am Korean, I am not good at English, so there is confusion about English and programming language) As a result, it is functioning properly, and I will refer to that part in writing the next plug-in. Of course I’ll write it here again, but thanks for the help! :innocent:

Thank you for always being helpful in providing information. I’ll try to understand and ask questions. :pray:

1 Like