Hej guys, I am new to Ruby API and am trying to create a component (possibly with its definition) with selected face after pushpull.
I made two codes, No.1 tries to select surface and then pushpull and to make it into a component but I failed when to make component due to my limited programming knowledge in Ruby for Sketchup. No.2 works with the line but not the face.
Here is the code No.1 (failed)
# Dependencies
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
# User's input
Thickness = 10
# Iterate through selection
sel.each do e # e is an element in sel and this is for loop in Ruby
# Check face
if e.is_a SketchupFace
# Extrude
group = ent.add_group
e.pushpull Thickness
#comp = group.to_component (not working)
end
end
`
Here is the code No.2 (and this works but this is based on only the selected line rather than the face that I want to select)
# Dependencies
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
new_comp_def = Sketchup.active_model.definitions.add(thickness.to_s + träregel med isolering)
#User data (input)
thickness = 220.mm
height = 3700.mm
# Get the first entity in the selection
entity = sel.first
# Get the starting point of the first entity
point_start = entity.start.position
point_end = entity.end.position
# Get the x, y, and z position of the starting point
x_1 = point_start.x
y_1 = point_start.y
z_1 = point_start.z
# Get the x, y, and z position of the end point
x_2 = point_end.x
y_2 = point_end.y
z_2 = point_end.z
point_1 = [x_1, y_1, z_1]
point_2 = [x_2, y_2, z_2]
point_3 = [x_2, y_2, z_2 + height]
point_4 = [x_1, y_1, z_1 + height]
# Actions
#group = ent.add_group (usefull)
face = new_comp_def.entities.add_face point_1, point_2, point_3, point_4
face.pushpull thickness
trans = GeomTransformation.new
Sketchup.active_model.active_entities.add_instance(new_comp_def, trans)
`
I would like to get some tips for No.1 code to make the volume of pushpulled and selected face into a component with its definition.
Pleas post code not images of code. Periodically the server has lost all images for the forum.
To make a component. Start by adding a new Defintion to the model’s DefinitionList collection.
Then add your edges and faces to the definition’s Entities collection, instead of the model’s.
Lastly add an instance of the new definition to the model’s Entities collection at some tranformation.
I made two codes, No.1 tries to select surface and then pushpull and to make it into a component but I could not due to my limited programming knowledge in Ruby API for Sketchup. No.2 works with the line but not the face.
Here is the code No.1 (failed)
# Dependencies
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
# User's input
Thickness = 10
# Iterate through selection
sel.each do e # e is an element in sel and this is for loop in Ruby
# Check face
if e.is_a SketchupFace
# Extrude
group = ent.add_group
e.pushpull Thickness
#comp = group.to_component (not working)
end
end
`
Here is the code No.2 (and this works but this is based on only the selected line rather than the face that I want to select)
# Dependencies
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
new_comp_def = Sketchup.active_model.definitions.add(thickness.to_s + träregel med isolering)
#User data (input)
thickness = 220.mm
height = 3700.mm
# Get the first entity in the selection
entity = sel.first
# Get the starting point of the first entity
point_start = entity.start.position
point_end = entity.end.position
# Get the x, y, and z position of the starting point
x_1 = point_start.x
y_1 = point_start.y
z_1 = point_start.z
# Get the x, y, and z position of the end point
x_2 = point_end.x
y_2 = point_end.y
z_2 = point_end.z
point_1 = [x_1, y_1, z_1]
point_2 = [x_2, y_2, z_2]
point_3 = [x_2, y_2, z_2 + height]
point_4 = [x_1, y_1, z_1 + height]
# Actions
#group = ent.add_group (usefull)
face = new_comp_def.entities.add_face point_1, point_2, point_3, point_4
face.pushpull thickness
trans = GeomTransformation.new
Sketchup.active_model.active_entities.add_instance(new_comp_def, trans)
`
I would like to get some tips for No.1 code to make the volume of pushpulled and selected face into a component with its definition.
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
# User's input
Thickness = 10
# Iterate through selection
sel.each {|e|
# Check face
if e.is_a? Sketchup::Face
# Extrude
e.pushpull(Thickness, true)
end
}
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
# User's input
Thickness = 10
onlyFaces = sel.grep(Sketchup::Face)
# Iterate through faces
onlyFaces.each {|f|
group = ent.add_group(f)
f.pushpull(Thickness, true)
status = group.to_component
}
if you only want a group remove the line status = group.to_component
… otherwise, if the user is within a group or component editing context, SketchUp can crash when the #add_group(face) call is made.
In other words, the new group and the drawing element arguments must be in the same editing context (which is normally the active_model.active_entities.)
Your closing } should be lined up with the line with it’s opening {, ie …
# Iterate through faces
onlyFaces.each { |f|
group = ent.add_group(f)
f.pushpull(Thickness, true)
status = group.to_component
}
The reason is that the indent guidelines in your editor will not help you line up the start and end of code blocks.
Ie, wrong:
Ie, correct the guideline shows the start of the block lined up with the end of the block:
In Ruby constants and specifically module and class identifiers start with a capital character.
They are also CamelCase (akaSnakeCase,) with no spaces and each word starting with a capital letter.
Local variables are all lower_case with underscore character in place of spaces.
See also: UI.inputbox for getting input values from the user.
Actually the #each iterator that most collections in Ruby have is not exactly a for loop.
Ruby does have a dedicated for loop. It looks like this …
for e in sel
# do stuff with e here ...
end
The difference in Ruby is that #each is a method call and for is an interpreter function.
(It used to be that forwas faster, but not so much anymore with Ruby 2 and higher.)
Code should seek to identify the specific face to operate upon.
Since in this scenario there is only 1 face, there is no need to iterate the selection or the new group.
So the each loop can go away …
face = sel.grep(Sketchup::Face).first
if face # nil if grep found no faces
group = ent.add_group(face)
# Just in case SketchUp gave the face a new reference:
face = group.grep(Sketchup::Face).first
face.pushpull(thickness, true)
inst = group.to_component
inst.definition.name= "Box Component"
inst.name= "Box 1"
end