sketchucation logo sketchucation
    • 登入
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    🔌 Smart Spline | Fluid way to handle splines for furniture design and complex structures. Download

    Use Ruby To Apply Materials to Spacific Layers

    已排程 已置頂 已鎖定 已移動 Developers' Forum
    24 貼文 8 Posters 11.0k 瀏覽 8 Watching
    正在載入更多貼文
    • 從舊到新
    • 從新到舊
    • 最多點贊
    回覆
    • 在新貼文中回覆
    登入後回覆
    此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
    • E 離線
      Eric_Erb
      最後由 編輯

      Hello, and Thank you all in advance for your advice. I'd like to start my saying I've been modeling in sketchup, rhino, and solidworks for years but I am very new to programing. The program we use automatically exports our designs as .dxf files with layers. Part of my job requires me to import these files to sketchup and apply a material to each layer of the dxf. These layers are always named the same and the materials are always the same so there must me a way to write a little ruby script that will automatically apply those materials to their respective layers. Can anyone help me out?

      1 條回覆 最後回覆 回覆 引用 0
      • thomthomT 離線
        thomthom
        最後由 編輯

        SU doesn't read the layer colour of DWGs?

        Just to clarify:

        1. You want to apply materials to the actual geoemtry instead of using Colour By Layers?
          or
        2. You want to set up a layer colour scheme which you can apply when you import DWGs?

        Thomas Thomassen — SketchUp Monkey & Coding addict
        List of my plugins and link to the CookieWare fund

        1 條回覆 最後回覆 回覆 引用 0
        • E 離線
          Eric_Erb
          最後由 編輯

          I have to do like 50 of these things a day so I'd like to automate it basically. I really don't care what method or medium I need to use as long as it will for instance apply the brick material to any layer named Wall_Surfaces whenever I open a file. It just seemed like from my research Ruby would be my best bet, but I am wide open to other options.

          1 條回覆 最後回覆 回覆 引用 0
          • J 離線
            Jim
            最後由 編輯

            I think there's a little confusion about what exactly you need.

            SketchUp has a "Color by Layer" feature built in. So i think what needs clarified is if you are using "Color by Layer" and need to assign materials to the Layers, or if you need to apply the materials to objects in the Model as a function of their Layer.

            And I hope that's clearer than mud.

            Hi

            1 條回覆 最後回覆 回覆 引用 0
            • E 離線
              Eric_Erb
              最後由 編輯

              I need to apply the materials to objects in the Model based on their Layer... Hopefully automatically

              1 條回覆 最後回覆 回覆 引用 0
              • J 離線
                Jim
                最後由 編輯

                Well, that's not hard.

                I would set up a template that contains your materials in-model.

                Is there a relationship between the Layer names and Material names? No matter, but it would make the code smaller.

                What happens when we hit a Group? Does the material get applied to the Group, or do you need to apply the materials to the entities in the Group?

                What about Component Instances? Is the material applied to the Instance, the entities in the Instance, or even the Instance's Definition?

                The following (untested) code might be enough to get you going. It applies materials to the top-level entities only, and does not try to drill-down into Group or Components.


                eric_erb.rb

                Hi

                1 條回覆 最後回覆 回覆 引用 0
                • E 離線
                  Eric_Erb
                  最後由 編輯

                  Thank you Jim! I'm trying to make that bit of code work now. To answer your questions...I could easily rename the materials if it meant simpler code. My layer names are formatted "Wall_Surfaces", "Roof_Surface", etc. so I could rename the material on the walls "Wall_Surface" if that would help. I'm not sure what the difference is in applying a material to a group or the entities within a group. If you're asking if groups will need to include different materials for it's entities, no. All the entities within a group are the same material. Also, there is only one instance of each component.

                  1 條回覆 最後回覆 回覆 引用 0
                  • E 離線
                    Eric_Erb
                    最後由 編輯

                    Alright, I've been messing around with the code... This is it as it is now...
                    ` module Eric_Erb
                    def self.color_by_layer
                    su_materials = Sketchup.active_model.materials
                    my_materials = Hash.new
                    my_materials["Wall_Surfaces"] = su_materials["Roofing_Metal_Standing_Seam_Red"]
                    my_materials["Roof_Surface"] = su_materials["Roofing_Slate_Tan"]
                    # .. and so on.

                    begin
                        Sketchup.active_model.start_operation("Color By Layer", true)
                    rescue ArgumentError
                        Sketchup.active_model.start_operation("Color By Layer")
                    end
                    # Loop through entities & apply material based on layer name
                    Sketchup.active_model.entities.each do |entity|
                        if entity.is_a? Sketchup::Drawingelement
                    	entity.material = my_materials[entity.layer.name]
                        end
                    end
                    Sketchup.active_model.commit_operation
                    end
                    

                    end

                    UI.menu('Plugins').add_item("Color by Layer") { Eric_Erb.color_by_layer }`

                    I didn't add anymore Layers to apply materials to just to see if I could get it running as is. It doesn't apply materials though. The line: su_materials = Sketchup.active_model.materials, I thought that might mean "referance the materials already active in the model", so I created a couple shapes on different layers and applied the materials I wanted to use to those and when I ran the plug-in it actually removed the materials from my new layers, so I guess I interpreted that line wrong. I'm sure my error is completely obvious to people like you that can rap their heads around coding like this (which is absolutely amazing by the way), but can you tell me where I'm messing this up?

                    1 條回覆 最後回覆 回覆 引用 0
                    • RunnerPackR 離線
                      RunnerPack
                      最後由 編輯

                      @eric_erb said:

                      The line: su_materials = Sketchup.active_model.materials, I thought that might mean "referance the materials already active in the model", so I created a couple shapes on different layers and applied the materials I wanted to use to those and when I ran the plug-in it actually removed the materials from my new layers, so I guess I interpreted that line wrong.

                      No, you interpreted correctly. That is exactly what it means. The only explanation I have for the code removing materials (which I assume means setting them to the default material) is that there is a mismatch between the names of your materials or layers and the contents of your hash.

                      My idea would be to skip the hash and just make sure the names of layers and their respective materials are the same. i.e. anything on the "Roof" layer is painted with the material called "Roof", and so on.

                      Here's the code for that (which also checks if the material exists before changing it):

                      
                      module Eric_Erb
                      
                          def self.paint_by_layer
                              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|
                                  mat = su_materials[e.layer.name]
                                  unless mat.nil?
                      	            if e.is_a? Sketchup;;Drawingelement then
                      	                e.material = mat
                      					e.back_material = mat if e.respond_to?('back_material=')
                                  	end
                                  end
                              end
                      
                              mod.commit_operation
                          end
                      
                      end
                      
                      unless file_loaded? File;;basename(__FILE__)
                          UI.menu('Plugins').add_item('Paint by Layer') { Eric_Erb.paint_by_layer }
                          file_loaded File;;basename(__FILE__)
                      end
                      
                      

                      (As you can see, I also attached it for downloading.)

                      If you do stick with the hash, it may make it easier to edit if you declare it like:

                      
                      my_materials = {
                          "Wall_Surfaces" => su_materials["Roofing_Metal_Standing_Seam_Red"],
                          "Roof_Surface" => su_materials["Roofing_Slate_Tan"]
                          # .. and so on.
                      }
                      
                      

                      Also, when testing, don't paint the objects beforehand. Just make some layers, make a material for each layer with the same name, make a face on each layer, and run the script.

                      I hope that helps.


                      Paints each entity with a material named after its layer.

                      You might have noticed... I'm a bit of a ferpectionist.

                      1 條回覆 最後回覆 回覆 引用 0
                      • E 離線
                        Eric_Erb
                        最後由 編輯

                        Thank you RunnerPack, I'll try that approach right now. Yes, I did mean setting them to the default materials

                        1 條回覆 最後回覆 回覆 引用 0
                        • E 離線
                          Eric_Erb
                          最後由 編輯

                          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? 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.

                          1 條回覆 最後回覆 回覆 引用 0
                          • bagateloB 離線
                            bagatelo
                            最後由 編輯

                            I want a plugin that deletes some materials of the scene, even if they are in use, in a similar way that as we deleted several emails in our email account. Maybe if it was possible to substitute several materials for one in one time, this would be also interesting. Another thing that I want would be the possibility of add a word or number in begin of all the materials of the object or scene.

                            "I'm organizing my library components from SketchUp, and because I use V-Ray to render my images, I put useful components names of the materials under the name of the component, to edit in V-Ray."

                            So, I wonder if it would be possible to create a script that renames the materials of these components according to some criteria. For example, suppose that I am editing a component called "table 045.skp" and it has the following materials: mapple wood, metal, white paint, etc.. After we run the script, the material would have the following names, such as:
                            wood mapple >> "wood table 045 01",
                            Metal >> "wood table 045 02",
                            white paint >> "wood table 045 03"

                            The reason for this is that it's confusing to locate in the scene the names of the materials of the componentes for editing in Vray.

                            Thanks...

                            While the cat's away, the mice will play

                            1 條回覆 最後回覆 回覆 引用 0
                            • honoluludesktopH 離線
                              honoluludesktop
                              最後由 編輯

                              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.)?

                              1 條回覆 最後回覆 回覆 引用 0
                              • RunnerPackR 離線
                                RunnerPack
                                最後由 編輯

                                @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. 😄

                                You might have noticed... I'm a bit of a ferpectionist.

                                1 條回覆 最後回覆 回覆 引用 0
                                • RunnerPackR 離線
                                  RunnerPack
                                  最後由 編輯

                                  @bagatelo:

                                  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! 😄

                                  @honoluludesktop:

                                  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.

                                  You might have noticed... I'm a bit of a ferpectionist.

                                  1 條回覆 最後回覆 回覆 引用 0
                                  • E 離線
                                    Eric_Erb
                                    最後由 編輯

                                    @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.

                                    1 條回覆 最後回覆 回覆 引用 0
                                    • honoluludesktopH 離線
                                      honoluludesktop
                                      最後由 編輯

                                      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.

                                      1 條回覆 最後回覆 回覆 引用 0
                                      • RunnerPackR 離線
                                        RunnerPack
                                        最後由 編輯

                                        @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.

                                        You might have noticed... I'm a bit of a ferpectionist.

                                        1 條回覆 最後回覆 回覆 引用 0
                                        • RunnerPackR 離線
                                          RunnerPack
                                          最後由 編輯

                                          @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
                                          
                                          

                                          You might have noticed... I'm a bit of a ferpectionist.

                                          1 條回覆 最後回覆 回覆 引用 0
                                          • honoluludesktopH 離線
                                            honoluludesktop
                                            最後由 編輯

                                            Amos, Thanks. Am currently at home. Will work on it at the office tomorrow.

                                            1 條回覆 最後回覆 回覆 引用 0
                                            • 1
                                            • 2
                                            • 1 / 2
                                            • 第一個貼文
                                              最後的貼文
                                            Buy SketchPlus
                                            Buy SUbD
                                            Buy WrapR
                                            Buy eBook
                                            Buy Modelur
                                            Buy Vertex Tools
                                            Buy SketchCuisine
                                            Buy FormFonts

                                            Advertisement