Use Ruby To Apply Materials to Spacific Layers
-
Amos, or anyone, can your code be easily modified to apply textures (by their name) to components (by their name) while ignoring all other entities (surfaces, components with names that do not match textures, groups, etc.)?
-
@eric_erb said:
On Sketchup Load it's returning... undefined method `file_loaded' for main:Object. is there something here I'm supposed to change before I save it to plugins?
Oops! Put the following line at the top:
require 'sketchup'
@unknownuser said:
By the way unless it will crash the script otherwise, there's no need for the script to make sure there's a material that matches the layer name before it runs. Like I said... The Layers are always named the same so when I create materials named after the layer names there will always be a material for each of the layers.
Well, it's always good coding practice to put in as much error handling as one can. Ideally (though not necessary in this simple script) one should use begin...rescue...end blocks to trap and handle errors in a clean manner. Besides, this script could be handy for others who may not want to make sure every layer has a material, and vice versa, just to keep it from wiping out their already-assigned materials.
-
Ignoring the fact that you hijacked the thread... I suggest you look at the code posted so far, at the code of some related plugins, and at the SketchUp Ruby API docs, and see if you can come up with something that does what you want. Your idea sounds like a simple extrapolation of the code above. If you start your own thread, I and other Rubyists can answer specific questions as you go.
You may find that you really enjoy programming in Ruby. I certainly do!
Yes, that would be quite simple. Just change the test for Sketchup::Drawingelement to Sketchup::ComponentInstance and e.layer.name to either e.name or e.definition.name. You might want to put in another test for Groups, too.
-
@runnerpack said:
this script could be handy for others who may not want to make sure every layer has a material, and vice versa, just to keep it from wiping out their already-assigned materials.
Sorry, I didn't think about people not wanting to replace all the materials on every layer. Thank you so much RunnerPack. You have been a life saver... Now I just gotta read the little book of ruby a few more times (I just finished the second read) last night), and maybe this will finally click. You know I didn't have near the same difficulty learning AS3 or HTML.
-
Amos, Thanks, I will give it a spin the next time I have a model that I import by component/texture into my model:-) Btw, I am more of a hacker then a Ruby programmer, any hints on "another test for groups" is welcomed.
-
@eric_erb said:
...Thank you so much RunnerPack. You have been a life saver... Now I just gotta read the little book of ruby a few more times (I just finished the second read) last night), and maybe this will finally click. You know I didn't have near the same difficulty learning AS3 or HTML.
You're quite welcome. (I didn't even do much, really...)
If you can make sense of ActionScript, I'm confident you'll learn Ruby in short order. Not to brag, but I haven't read any books on Ruby; I just keep the reference docs handy. And those are from Ruby 1.4.6.
I guess I just learn better by doing, and Ruby makes that process very fast.
-
@honoluludesktop said:
Amos, Thanks, I will give it a spin the next time I have a model that I import by component/texture into my model:-) Btw, I am more of a hacker then a Ruby programmer, any hints on "another test for groups" is welcomed.
I just meant to add another "if" statement to test for Group entities. It's necessary if you use e.definition.name, since Groups don't have definitions. But it would actually take a bit of code refactoring, like so:
module Eric_Erb_and_AJB def self.paint_by_name mod = Sketchup.active_model su_materials = mod.materials begin mod.start_operation("Paint By Layer", true) rescue ArgumentError mod.start_operation("Paint By Layer") end # Loop through entities & apply material based on layer name Sketchup.active_model.entities.each do |e| begin mat = su_materials[e.definition.name] rescue mat = su_materials[e.name] end unless mat.nil? if e.is_a? Sketchup;;ComponentInstance or e.is_a? Sketchup;;Group then e.material = mat end end end mod.commit_operation end end unless file_loaded? File;;basename(__FILE__) UI.menu('Plugins').add_item('Paint by Layer') { Eric_Erb_and_AJB.paint_by_name } file_loaded File;;basename(__FILE__) end
-
Amos, Thanks. Am currently at home. Will work on it at the office tomorrow.
-
Amos, Thanks, this is a big help for me. Any reason why (sometimes) I have to click on the display after the plugin has run in order for the textures to change? Hmm... Sometimes I change the component name from different menus, or change the texture name from diferent menus. Does it matter?
-
Inside the Vray Plugin have tool to apply materials to specific layers.
-
Hi,
This one may help you too: layers_materials.rb to be found at the Ruby Library Depot, "layers Selection"page. -
Man I thought python and Dynamo were hard. I even had a go at lisp but for some reason I cant get my head a round ruby. I like the code above but want to use the clean code but also just add in the layer names and leave the other ones alone. It seams that when I run this it converts all the layers in the model to Default and then the layer color had to be the same as the material name. I like the hash option but cant seem to get it to run on transparent materials and it only paints 1 side. any suggestions
P.S. I am bringing in a dwg (exported from Revit) with 20 or so layers and want to put all the layers to 1 color but windows I want them to be on Translucent Glass Gray
F.E. all layers to color 123_White except 0_EX_Glazing it needs to be on Translucent Glass Gray
Some of the issues
- the import comes in as 1 group (with layers in the group)
- some of the groups come in the main group with groups within groups (doors and Door windows)
Objects come in with a material not defined (<auto1>)so a generic material must be placed on all the objects for the script to have a chance.
Thanks in advance
Advertisement