From the Ruby API documentation for DefinitionList:
#remove(definition) ⇒ Boolean
The #remove method is used to remove a component definition from the definition list with the given component definition. This will remove all instances of the definition.
Note that you have to retrieve the Definition object first so you can pass it to this method. As usual, beware of using this method in a loop over the DefinitionList, as you risk errors whenever you modify a collection while iterating over its contents.
Remember that defn.remove is available only >= v2018, so it’s limiting for your user-base…
To delete a particular definition in all versions you can use defn.entities.clear!
To find a definition ‘by name’ use: defn=model.definitions['some_name']
or some similar methods to get a matching definition…
The ...entities.clear! method works within a model.start_operation... up to model.commit_operation block...
Otherwise it is done cleanly.
I took the time to follow your TIG tips and this example seems to work:
model = Sketchup.active_model
defn = model.definitions
model.start_operation('delete', true)
defn.each do |d|
if d.name == "TOTO"
d.entities.clear!
end
end
model.commit_operation
At the moment your code looks at every definition and clears the entities of one with a name match.
You could streamline it…
If you used something like: match=defn['TOTO']
then match.entiites.clear! if match
Also you don’t need to set up a separate start...commit block IF your larger code has already started an operation, then simply use that…
Here is a small example that now allows me to purge the components of Click-Cuisine 2, with a dynamic attribute.
There may be simpler methods to do the same thing!
If you have ideas do not hesitate to post your codes.
mod = Sketchup.active_model
defs = mod.definitions
# create an array of all the definitions with the clc2 attribute.
defs_lst = []
mod.definitions.each do |d|
attribut = d.get_attribute 'dynamic_attributes','clc2'
unless attribut.nil?
defs_lst << d
end
end
# create an array of entities with the clc2 attribute.
defs_mod = []
mod.entities.each do |e|
attribut = e.get_attribute 'dynamic_attributes','clc2'
unless attribut.nil?
defs_mod << e.definition
end
end
# subtraction to keep only unused clc2 definitions.
defs_notused = defs_lst - defs_mod
# delete all unused entities and definitions clc2.
mod.start_operation('defs_purge', true)
defs_notused.each do |defpurg|
defs.each do |d|
if d == defpurg
d.entities.clear!
end
end
end
mod.commit_operation
The example below purges the components present in the list “b”, if they are not used and takes into account all the nesting levels:
def defs_in_model_sketchup(ents, defs_mod)
ents.grep(Sketchup::ComponentInstance).each do |e|
defs_mod << e.definition.name
defs_in_model_sketchup(e.definition.entities, defs_mod)
end
end
defs_mod = []
mod = Sketchup.active_model
ent = mod.entities
defs_in_model_sketchup(ent, defs_mod)
defs = mod.definitions
defs_lst = []
mod.definitions.each{ |d| defs_lst << d.name }
defs_notused = defs_lst - defs_mod
defs_purge = []
defs_notused.each do |a|
['BOUTEIL','BOX','DECO','BOOK','SALADIER'].each do |b|
if a.include?(b)
defs_purge << a
end
end
end
mod.start_operation('defs_purge', true)
defs_purge.each do |defpurg|
defs.each do |d|
if d.name == defpurg
d.entities.clear!
end
end
end
mod.commit_operation
if and unless can be used in “modifier posiition” at the end of a statement.
This helps make code more readable (and have less lines and less nested blocks)
when it is a simple statement …