Below is a piece of code (credit to Rafael Rivera) which plots points at the vertices of a model in SketchUp.
def pointplot
model = Sketchup.active_model
entities = model.active_entities
selection = model.selection
edges = selection.grep(Sketchup::Edge)
if edges.empty?
msg = 'Select one or more edges before using this tool.'
UI.messagebox(msg)
return
end
vertices = []
edges.each { |edge| vertices << edge.vertices }
vertices.flatten!
vertices.uniq!
vertices.each { |vertex| entities.add_cpoint vertex.position }
end
def check_line
sel = Sketchup.active_model.selection
ok = sel.find { |e| e.typename == "Edge" }
ok ? MF_ENABLED : MF_GRAYED
end
UI.add_context_menu_handler do |menu|
menu.add_separator
item = menu.add_item("Point Plot") { pointplot }
menu.set_validation_proc(item) {check_line}
end
Could someone please explain to me this line of code, what it actually does and why it's necessary for the code to work.
vertices.flatten!
I am aware what ".flatten!" does under normal circumstances. I understand this example perfectly from the rubyapi.org
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten!(1) # => [0, 1, [2, 3], 4, 5]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten!(2) # => [0, 1, 2, 3, 4, 5]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten!(3) # => [0, 1, 2, 3, 4, 5]
[0, 1, 2].flatten!(1) # => nil
But in the world of SketchUp, what does ".flatten!" actually do?
I 'put' the vertices array to my console and I see this as output.
#<Sketchup::Vertex:0x00000180a0788440>
#<Sketchup::Vertex:0x00000180a0788418>
#<Sketchup::Vertex:0x00000180a07883c8>
#<Sketchup::Vertex:0x00000180a07883a0>
#<Sketchup::Vertex:0x00000180a0788440>
#<Sketchup::Vertex:0x00000180a0788418>
#<Sketchup::Vertex:0x00000180a07883c8>
So what am I 'flattening' exactly?
Thanks!
It does exactly the same as the behavior you already observed with flatten
with the only difference that it changes the object on which it is called instead of returning a changed object.
Let's have a look at these three lines:
vertices = []
edges.each { |edge| vertices << edge.vertices }
vertices.flatten!
First, there is an empty array created. Then by iterating over all edges the edges' vertices (which are very likely are stored in an array) are added to the array. That means after this line you have a nested array of vertices that looks like this (pseudo-code):
[[vertice_1, vertice_2], [vertice_3, vertice_4], [vertice_1, vertice_4]]
vertices.flatten!
will then flatten the vertices
to:
[vertice_1, vertice_2, vertice_3, vertice_4, vertice_1, vertice_4]