I use this in Sketchup 7, and it’s very quick. I use the same plugin in Sketchup 2015, and it’s painfully slow. Any Ideas? Remove Materials Mine.rb (928 Bytes)
What is it for? Why do you use it? You can purge materials that you do not use.
Yes, your correct. But this adds a toolbar item and icon, and then the script selects all, removes all materials from the front and back faces, and then purges all the materials from the model. I do this a lot, so I made this. In Sketchup 7 it’s almost instant, but in Sketchup 2015, the script can take a couple of minutes to work.
toolbar = UI::Toolbar.new “Remove All Mats”
cmd = UI::Command.new(“Remove All Mats”) {
model = Sketchup.active_model
model.selection.add( model.active_entities.to_a )
model.entities.each { |e|
e.material = nil if e.respond_to?( :material )
e.back_material = nil if e.respond_to?( :back_material )
}
model.definitions.each { |d|
next if d.image?
d.entities.each { |e|
e.material = nil if e.respond_to?( :material )
e.back_material = nil if e.respond_to?( :back_material )
}
}
len=model.materials.length.to_s
model.materials.purge_unused
puts "Materials “+len+” >>> "+model.materials.length.to_s
}
cmd.small_icon = “No Mats.png”
cmd.large_icon = “No Mats.png”
cmd.tooltip = “Remove All Mats”
cmd.status_bar_text = “Removing All Materials”
cmd.menu_text = “Remove All Mats”
toolbar = toolbar.add_item cmd
toolbar.show
as this is your own code I move this to the Ruby forum…
you have poor structure and a couple of un-needed lines…
# you shouldn't wrap it all in the cmd
cmd = UI::Command.new(“Remove All Mats”) {
# why do add to the selection
model.selection.add( model.active_entities.to_a )
# and then use
model.entities.each
# also why have menu text without a menu item
cmd.menu_text = "Remove All Mats"
since v8 there is materials #remove
, but it wasn’t bug free until v14…
# wrap the logic in a method
def remove_mats
model = Sketchup.active_model
ents = model.active_entities.to_a
mats = model.materials
len = mats.length
# check version
if Sketchup.version.to_i >= 14
mats.to_a.each{|mat|mats.remove(mat)}
else
ents.each do |e|
e.material = nil if e.respond_to?( :material )
e.back_material = nil if e.respond_to?( :back_material )
end
model.definitions.each do |d|
next if d.image?
d.entities.each do |e|
e.material = nil if e.respond_to?( :material )
e.back_material = nil if e.respond_to?( :back_material )
end
end
mats.purge_unused
end
puts "Materials: #{len} >>> #{mats.length}"
end
# call the logic as your comand
cmd = UI::Command.new("Remove All Mats") { remove_mats }
toolbar = UI::Toolbar.new "Remove All Mats"
cmd.small_icon = cmd.large_icon = "No Mats.png"
cmd.tooltip = "Remove All Mats"
cmd.status_bar_text = "Removing All Materials"
# cmd.menu_text = "Remove All Mats"
tb = toolbar.add_item cmd
# allow toolbar to be turned off
tb.get_last_state == -1 ? tb.show : tb.restore
john
Thank you but, I get this response…
Error Loading File Remove Materials Mine.rb
Error: #<NameError: undefined local variable or method tb' for main:Object> C:/Users/Mark/AppData/Roaming/SketchUp/SketchUp 2015/SketchUp/Plugins/Remove Materials Mine.rb:38:in
<top (required)>’
No, this is just snippets of code I get from reading forums and such. I barely understand any of it. (Obviously).
I just deleted the line…
allow toolbar to be turned off
toolbar.get_last_state == -1 ? tb.show : tb.restore
And that did it. Thank you very much !!!
I edited the toolbar to work…
john
Thank you again. I wish I understood this stuff, so I wouldn’t have to ask such dumb questions.
Given that, a few thoughts…
You use .respond_to?
in your code, but you’re checking the read-only attributes, :material
& :back_material
. It would be better to check the write attributes, :material=
& :back_material=
. Obviously, we know that these attributes are read/write, but…
One item that would not typically be the source of large performance issues (especially in SU), but everything adds up…
.respond_to?
checks a rather large list of attributes/methods, as all that are in the inheritance chain are checked. From the docs, either at File: SketchUp Ruby API — SketchUp Ruby API main or http://ruby.sketchup.com/, you’ll see only two classes with the .material
attributes, Sketchup::Drawingelement
& Sketchup::Face
. The docs for Face say that the .material
attributes are inherited from Drawingelement
.
You can check this with the following, which shows only the attributes & methods defined for an ‘instance’ of the Class/Module, with no inherited items (the false
parameter does that, omit it or change to true, and all items are shown).
puts Sketchup::Face.public_instance_methods(false).sort
It shows that material
is not a native attribute of Face. Also, from the docs, the back_material
attributes only exists in Face.
Hence, rather than e.respond_to?(:material)
, you could use e.is_a?(Sketchup::Drawingelement)
. Likewise, e.respond_to?(:back_material)
could be replaced with e.is_a?(Sketchup::Face)
.
I haven’t benchmarked the differences (probably very small unless you have a lot of entities), and SU could totally change the API tomorrow (unlikely), but typically, with a shorter list, the search time will decrease.
And finally, it may be easier (and quicker?) to replace the ents.each
and d.entities.each
blocks with:
ents.grep(Sketchup::Drawingelement).each { |e| e.material = nil }
ents.grep(Sketchup::Face).each { |e| e.back_material = nil }
Just some ideas. Lighting guy? A long time ago, I used to be Vari-Lite trained/certified…
I’m sure what your saying here has value. But, I don’t really understand any of it. I’m able to copy and paste, and fumble to kinda make a working plugin. That’s my skill level in Ruby for Sketchup. Yes. A lighting guy here. The last “known” show I did was Phantom (of the Opera) in Las Vegas. We had VL3k’s, 2416’s, and four VL5b’s. Thanks for the advice on Ruby here. With the decision to make Sketchup a web only application, eventually, I’m not sure how much more of life Ruby has.
Maybe i’m missing something, but i can’t see anything like start_operation and commit_operation in your code.
Try adding
model.start_operation("removeMats", true)
right after the line
model = Sketchup.active_model
and a
model.commit_operation()
before your last closing curly brackets.
Michael
This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.