I have a collection of boxes that belong to a layer called “Boxes”. This is the way I create every box:
entities = model.active_entites
model.active_layer = 'Boxes'
gr = entities.add_group
gr.name = "box_" + box_name
entities = gr.entities
# Here I define the faces of the box
box_name is requested by a UI.inputbox. The boxes are correctly generated.
The question is, how to delete a specific group? I provide a name to the box, but I just don’t know how to have access to a group and remove it. Sorry, I’m new to the Ruby API.
I’m trying to step through the model and delete all groups named “plates”. The challenge is that these groups are nested in several components throughout the model. It looks like the code you posted only works for the active context. It doesn’t work if the group is nested inside of a component.
model=Sketchup.active_model
gpname='plates'
gps=model.active_entities.grep(Sketchup::Group).find_all{|g| g.name==gpname }
model.active_entities.erase_entities(gps) if gps[0]
Context: The model is an imported truss model. I don’t need the plates, so I’m trying to delete all the metal plates on each truss in order to speed up the model a bit. They are all in a group named “plates”.
A simple solution ... if you can't figure it out from the clue ...
def delete_truss_gussets(name = 'plates')
dlist = Sketchup.active_model.definitions
cdef = dlist[name]
if cdef && cdef.group?
cdef.instances.each do |inst|
inst.erase!
end
dlist.remove(cdef) rescue dlist.purge_unused
end
end
I tried your solution, but it had no effect. Maybe it’s due to the model hierarchy. Does the Sketchup.active_model.definitions only look at components? or maybe I need to explode the main group that contains everything? I’ve attached screenshot to illustrate model hierarchy.
NO. This collection contains ALL definitions (ie, Component, Groups and Image definitions.)
So I added some informational statements to provide feedback in the console …
def delete_truss_gussets(name = 'plates')
dlist = Sketchup.active_model.definitions
cdef = dlist[name]
puts "group definition \"#{name}\" : "<<cdef.inspect
if cdef && cdef.group?
count = cdef.instances.size
puts " Number of instances : #{count}"
if count > 0
cdef.instances.each do |inst|
inst.erase!
end
dlist.remove(cdef) rescue dlist.purge_unused
else
puts "Nothing to remove nor purge."
end
else
puts "Group definition could not be found."
end
end
… ran it on your model, and got the "Group definition could not be found." message.
So then went and inspected one of the trusses, and realized that the instances are named "plates"not the definitions.
This means we’ll need to add in a check to test for instance names.
Matt, that is a heavy model. It was too slow to work with on my ten year old computer, so I had to test it on one truss at first, but it does seem to work on the whole model if you give it a couple of minutes.
module GM
module DeletePlates
extend self
def find_groups(entities)
all_groups = []
entities.each do |entity|
if entity.is_a?(Sketchup::Group) || entity.is_a?(Sketchup::ComponentInstance)
all_groups << entity
all_groups.concat(find_groups(entity.definition.entities))
end #if
end # entities.each
return all_groups
end #find_groups
def remove_plates
model = Sketchup.active_model
ents = model.entities
model.start_operation('Delete Truss Plates', true)
groups = find_groups(ents)
groups.select!{|g| g.definition.group?}.select!{|g| g.name == "plates"}
puts ("Removing #{groups.size} plates group(s).")
groups.each do |g|
g.erase! unless g.deleted?
end #groups.each
model.commit_operation
end #remove_plates
this_file = __FILE__
unless file_loaded?(this_file)
menu = UI.menu("Plugins").add_item("Delete Plates") {self::remove_plates}
file_loaded(this_file)
end #unless
end #DeletePlates
end #GM
Here is my final … it takes a few minutes to delete the groups inside an operation.
EDIT: Actually, made a change. debug is now a named argument.
(Note SketchUp itself is purging the unused group definitions from the Definitions collection because they no longer have any instances. We have no control over this.)
def delete_truss_gussets(inst_name = 'plates', debug: false)
gussets_deleted = []
groups_deleted = 0
model = Sketchup.active_model
dlist = model.definitions
puts
puts "Begin Truss Gusset Purging"
model.start_operation('Purge Gusset Groups',true)
#
dlist.each do |cdef|
next unless cdef.group? && cdef.instances.size > 0 &&
cdef.instances[0].name == inst_name
papa = cdef.instances[0].parent
if papa.name.start_with?('T') && papa.instances.size > 0 &&
papa.instances[0].layer.name.start_with?('Trusses')
cname = cdef.name
puts " Processing gusset group defintion: \"#{cname}\"" if debug
cdef.instances.each_with_index do |inst,i|
if inst.name == inst_name
puts " Deleting \"#{inst_name}\" instance index #{i}" if debug
gussets_deleted << cname if cdef.instances.size == 1
inst.erase!
groups_deleted += 1
end
end
end
end
puts "Number of gusset group instances deleted: #{groups_deleted}"
puts "Number of gusset group definitions to purge: #{gussets_deleted.size}"
puts
puts " ... please wait, Purging ..."
puts
#
model.commit_operation
#
orphans = []
dlist.each do |cdef|
if !cdef.group? && !cdef.image? && cdef.instances.size == 0
orphans << cdef
end
end
if orphans.size > 0
puts "Number of orphaned definitions that can be purged: #{orphans.size}"
names = orphans.map {|cdef| cdef.name }
puts names.inspect if debug
choice = UI.messagebox("Purge #{orphans.size} Gusset Components ?",MB_YESNO)
if choice == IDYES
model.start_operation('Purge Gusset Components',true)
#
if dlist.respond_to?(:remove)
orphans.each {|cdef| dlist.remove(cdef) }
else
dlist.purge_unused
end
#
model.commit_operation
end
end
puts "Done\n"
end
the group’s definition still has some instances in use by the model entities or some other definition’s entities collection,
… or possibly
if the group’s definition has no more instances, but Ruby’s garbage collection has not yet run and cleaned up the group’s definition object.
Of course not, because the #erase! method only applies to group instances, not their definition object. If called upon a definition, this exception will be raised:
Error: #<TypeError: Cannot determine parent of entity>