Basic Cube Grid Wireframe Script (Cubic Array)

Hi Guys,

I’m after a really basic Wireframe grid script that will allow me to input an overall X,Y,Z bounding box size (invisible cube) in mm that will then be filled as close as possible to that with smaller cubes where I can specify the X,Y and Z for the smaller cube.

It is to help me do quick analysis and quantification.

In the screenshot, the Green “Y” for example, I may have typed 13000mm for the bounding box, but my Y length shorter boxes would only build up to as close as that with the set Y length that I had specified for the smaller box.

Okay, so how far have you got with this project?

Do you have any specific coding questions?

Just starting. I’m doing this manually usually. I have 3D componentry that I have to copy and paste to get an idea of what will fit within an area. But that is slow.
With a quick Grid script as outlined, I can quickly generate different sized cubic grids to get a quick idea of what fits.

Once the grid is formed I can quickly throw the componentry at the wireframe if need be

This is what Chat GPT is throwing at me… :joy:

write RUBY Script for sketchup.
Input wireframe cube size x, y and z lengths.
Input overall copy length in x, y and z directions
generate cube as a Group and Copy cube in the x, y and z directions up to the overall lengths.

require 'sketchup.rb'

# Method to draw a wireframe cube
def draw_wireframe_cube(x, y, z)
  model = Sketchup.active_model
  entities = model.active_entities

  # Define the points for the vertices of the cube
  points = [
    [0, 0, 0],
    [x, 0, 0],
    [x, y, 0],
    [0, y, 0],
    [0, 0, z],
    [x, 0, z],
    [x, y, z],
    [0, y, z]
  ]

  # Draw the edges of the cube
  edges = []
  points.each_with_index do |point, index|
    next_point_index = (index + 1) % points.size
    next_point = points[next_point_index]
    edges << entities.add_line(point, next_point)
  end

  # Connect the corresponding points to form the cube
  (0..3).each do |i|
    entities.add_line(points[i], points[i + 4])
  end

  model.commit_operation

  # Create a group from the cube
  group = entities.add_group(edges)
  group
end

# Method to create the user interface
def create_ui
  prompts = ['Cube Size X:', 'Cube Size Y:', 'Cube Size Z:', 'Overall Length X:', 'Overall Length Y:', 'Overall Length Z:']
  defaults = ['100', '100', '100', '1000', '1000', '1000']

  input = UI.inputbox(prompts, defaults, 'Wireframe Cube Copy')

  if input
    cube_x = input[0].to_f
    cube_y = input[1].to_f
    cube_z = input[2].to_f
    overall_x = input[3].to_f
    overall_y = input[4].to_f
    overall_z = input[5].to_f

    # Draw wireframe cube
    cube_group = draw_wireframe_cube(cube_x, cube_y, cube_z)

    # Copy the cube in X direction
    num_copies_x = (overall_x / cube_x).to_i
    for i in 1..num_copies_x
      new_cube_group = cube_group.copy
      new_cube_group.move!([cube_x * i, 0, 0])
    end

    # Copy the cube in Y direction
    num_copies_y = (overall_y / cube_y).to_i
    for j in 1..num_copies_y
      new_cube_group = cube_group.copy
      new_cube_group.move!([0, cube_y * j, 0])
    end

    # Copy the cube in Z direction
    num_copies_z = (overall_z / cube_z).to_i
    for k in 1..num_copies_z
      new_cube_group = cube_group.copy
      new_cube_group.move!([0, 0, cube_z * k])
    end
  end
end

# Add a menu item to trigger the UI
UI.menu('Plugins').add_item('Wireframe Cube Copy') { create_ui }

Please place your code between backticks.

For example:

This section is between triple backticks. Like this: 

``` Your code here ```

[How to] Post correctly formatted and colorized code on the forum? - Developers - SketchUp Community

1 Like

Thanks… I was wondering how to do that…

1 Like

It’s easy to use a plugin like this 3DGridline. You don’t have to code.

I was trying to look for a simple plugin but couldn’t find one…

That one looks tedious, you have to hand type all of your coordinates, I could be typing 50+ coordinates, then generate, then realising that doesn’t quite work for what I need, so then to go and edit or retype all coords again, it would be quicker to copy and paste pre-made boxes like I already do

It looks like you are creating boxes from edges and putting each box into a group. For grids you might use other approaches, like guides and guidelines, or view draw (which is different from geometry and not so ‘heavy’ in your models).

SU has a Grid Tool and if you install it you can see an example “grid.rb” along with a “parametric.rb” that you might find useful.

Thanks 3DxJFD I’ll look into that tomorrow.

1 Like
module NOcGPT
module Forum
  extend self
  @@loaded = false unless defined?(@@loaded)
  
  def draw_wireframe_cube(pt, model)
    entities = model.active_entities
    bb = Geom::BoundingBox.new
    bb.add(ORIGIN, pt)
    cr = (0..7).map{ |i| bb.corner(i) }
    qd = [
       [cr[0], cr[1], cr[3], cr[2]],
       [cr[0], cr[1], cr[5], cr[4]],
       [cr[1], cr[3], cr[7], cr[5]],
       [cr[3], cr[2], cr[6], cr[7]],
       [cr[2], cr[0], cr[4], cr[6]],
       [cr[4], cr[5], cr[7], cr[6]]
      ]
    group = entities.add_group
    qd.each{|q|
      face = group.entities.add_face q
      face.erase!
    }
    group
  end

  def create_ui
    prompts = ['Cube Size X:', 'Cube Size Y:', 'Cube Size Z:', 'Overall Length X:', 'Overall Length Y:', 'Overall Length Z:']
    @defaults ||= ['100', '100', '100', '1000', '1000', '1000']

    input = UI.inputbox(prompts, @defaults, 'Wireframe Cubes')

    if input
      model = Sketchup.active_model
      model.start_operation("Wireframe Cubes", true)
      cube_x = input[0].to_l
      cube_y = input[1].to_l
      cube_z = input[2].to_l
      overall_x = input[3].to_l
      overall_y = input[4].to_l
      overall_z = input[5].to_l
      @defaults = [cube_x, cube_y, cube_z, overall_x, overall_y, overall_z]
      
      cube_group = draw_wireframe_cube([cube_x, cube_y, cube_z], model)
      count = 0
      for i in 0..(overall_x / cube_x).to_i - 1
        for j in 0..(overall_y / cube_y).to_i - 1
          for k in 0..(overall_z / cube_z).to_i - 1
            new_cube_group = cube_group.copy
            new_cube_group.move!([cube_x * i, cube_y * j, cube_z * k])
            count += 1
          end
        end
      end
      cube_group.erase!
      model.commit_operation
      plural = count > 1 ? "s" : ""
      UI.messagebox("#{count} Wireframe cube#{plural} created")
    end
  end
  unless @@loaded
    @@loaded = true
    UI.menu('Plugins').add_item('Wireframe Cubes') { create_ui }
  end
end
end

Ask the robot for an explanation! :stuck_out_tongue_winking_eye:

2 Likes

Thankyou @dezmo! This is it! Perfect!

I asked ChatGPT what it thought of your code and if it was better than the code it gave me and it said, “both codes have their strengths and weaknesses” :joy:

“Excuse me, Doctor A.I., which one of the procedures will you be using for my open heart surgery?”

Dr. A.I.: “Oh, not to worry, they all have their strengths and weaknesses.”

2 Likes

@dezmo you’ve got me all excited now… would it be easy enough to add a function into this to add diagonal lines into areas specified by me? The attached model file would give you an idea of what I’m talking about. The diagonals always go point to point in the Z direction at the distance that is specified in the “Cube Size Z” part of your code. Even if it is only done up one X Face and one Y Face for the full height, it then makes it quick and easy to copy and past them along to where they are needed.

And, would it be easy enough to make it so that all:
X (red axis) Direction edges go on a tag called “Ledgers”
Y (green axis) Direction edges go on a tag called “Transoms”
Z (blue axis) Direction edges go on a tag called “Standards”

If the diagonals were possible, these would ideally go on the “Braces” tag.

I have coloured by Tag:

For context, we do large scale scaffolding projects to support concrete structures. So what I am doing with all of this helps to estimate and quantify in the early stages.


Form Support Birdcage RUBY Coded.skp (124.1 KB)

Another possibility would be to use materials and color edges by material instead of tags on edges.

1 Like

Menu: Extension / Support BirdCage by Dezmo
'quick&dirty! Does not really tested.
No warranties, use at your own risk!

module Dezmo
module SupportBirdCage
  extend self
  @@loaded = false unless defined?(@@loaded)
  
  def draw_wireframe_cube(pt, model)
    entities = model.active_entities
    bb = Geom::BoundingBox.new
    bb.add(ORIGIN, pt)
    cr = (0..7).map{ |i| bb.corner(i) }
    qd = [
       [cr[0], cr[1], cr[3], cr[2]],
       [cr[0], cr[1], cr[5], cr[4]],
       [cr[1], cr[3], cr[7], cr[5]],
       [cr[3], cr[2], cr[6], cr[7]],
       [cr[2], cr[0], cr[4], cr[6]],
       [cr[4], cr[5], cr[7], cr[6]]
      ]
    group = entities.add_group
    qd.each{|q|
      face = group.entities.add_face q
      face.erase!
    }
    lx = model.layers.add("Ledgers")
    ly = model.layers.add("Transoms")
    lz = model.layers.add("Standards")
    lb = model.layers.add("Braces")
    group.entities.grep(Sketchup::Edge){|e|
      if e.line[1].parallel?(X_AXIS)
        e.layer = lx
      elsif e.line[1].parallel?(Y_AXIS)
        e.layer = ly
      elsif e.line[1].parallel?(Z_AXIS)
        e.layer = lz
      end
    }
    groupx = entities.add_group
    ex = groupx.entities.add_line(cr[0], cr[5])
    groupy = entities.add_group
    ey = groupy.entities.add_line(cr[2], cr[4])
    groupx.layer = lb
    groupy.layer = lb
    [ group, groupx, groupy ]
  end

  def create_ui
    prompts = ['Cube Size X:', 'Cube Size Y:', 'Cube Size Z:', 'Overall Length X:', 'Overall Length Y:', 'Overall Length Z:']
    @defaults ||= ['100', '100', '100', '500', '500', '500']

    input = UI.inputbox(prompts, @defaults, 'Wireframe Cubes')

    if input
      model = Sketchup.active_model
      model.start_operation("Wireframe Cubes", true)
      cube_x = input[0].to_l
      cube_y = input[1].to_l
      cube_z = input[2].to_l
      overall_x = input[3].to_l
      overall_y = input[4].to_l
      overall_z = input[5].to_l
      @defaults = [cube_x, cube_y, cube_z, overall_x, overall_y, overall_z]
      
      cube_group, groupx, groupy = draw_wireframe_cube([cube_x, cube_y, cube_z], model)
      count = 0
      for i in 0..(overall_x / cube_x).to_i - 1
        for j in 0..(overall_y / cube_y).to_i - 1
          for k in 0..(overall_z / cube_z).to_i - 1
            new_cube_group = cube_group.copy
            new_cube_group.move!([cube_x * i, cube_y * j, cube_z * k])
            count += 1
          end
        end
      end
      cube_group.erase!
      
      ptsx = groupx.entities.grep(Sketchup::Edge)[0].vertices.map(&:position)
      ptsy = groupy.entities.grep(Sketchup::Edge)[0].vertices.map(&:position)
      ((overall_z / cube_z).to_i - 1).times do
        ptsx[0].z += cube_z
        ptsx[1].z += cube_z
        groupx.entities.add_edges(ptsx)
        ptsy[0].z += cube_z
        ptsy[1].z += cube_z
        groupy.entities.add_edges(ptsy)
      end
      
      model.commit_operation
      plural = count > 1 ? "s" : ""
      UI.messagebox("#{count} Wireframe cube#{plural} created\n1-1 X-Y base 'Braces' added.")
    end
  end
  
  unless @@loaded
    @@loaded = true
    UI.menu('Plugins').add_item('Support BirdCage by Dezmo') { create_ui }
  end
  
end
end

@dezmo mate, you are a bloody legend! Thank you so much for this. It works just fine and you have achieved everything I have asked!

1 Like