Add Materials to DWG imported layers (groups and instances)

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. have been trying to modify someone else code with no success

P.S. I am bringing in a dwg (exported from Revit) with 30 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

  1. the import comes in as 1 group (with layers in the group)
  2. 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 ()so a generic material must be placed on all the objects for the script to have a chance.
    using some lings gets me close but doesn’t do the back faces (so windows are not completely see through

Thanks in advance
P.S. the code I am trying to modify is on this page
https://sketchucation.com/forums/viewtopic.php?f=180&t=22337&p=663388#p663388blocks.skp (94.8 KB)

Lisp is a functional language also better known as “stupid parenthesis land”.
It is vastly different than dynamic OOP multi-paradigm languages like Python and Ruby (which are quite similar except for some syntax differences. Ie, it’s relatively easy to translate one into the other.)

In order to use any API extension to the Ruby language, an author needs to learn core Ruby.
To that end I’ve created a pinned set of resource lists in this category …

All file imports do this (regardless of source format.) You usually need to explode this imported object if you want it’s entities at the top level.

Secondly, in the UI, “Layers” have been renamed “Tags” (but the old class name persists in the APIs.)
SketchUp tags (layers) are not geometric collections. They are display behaviors that multiple entities can be “tagged” with to tell the display pipeline how to show them.

These are Material names, and it’s actually "0128_White" (not "123_White".)

The main issue you will have is that the Sketchup::Layer#color= setter method only takes a Sketchup::Color instance object or a predefined color name (listed in the class Overview.)

So if you do …

model = Sketchup.active_model
layers = model.layers
layers["Generic"].color= "0128_White"

… you get this exception raised:

Error: #<ArgumentError: Cannot find color named 0128_White>

Instead you need to steal the RGBA properties from the Sketchup::Material objects, but you need to temporarily load them into the model’s Sketchup::Materials collection.
Ex:

model = Sketchup.active_model
materials = model.materials

# Get white color:
filename = 'Materials/Colors-Named/0128_White.skm'
path = Sketchup.find_support_file(filename)
material = materials.load(path)
white_color = material.color
#=> Color(255, 255, 255, 255)
layers.each do |layer|
  layer.color= white_color unless layer.name == '0_EX_Glazing'
end
materials.remove(material)

# Get gray glass color:
filename = 'Materials/Glass and Mirrors/Translucent Glass Gray.skm'
path = Sketchup.find_support_file(filename)
material = materials.load(path)
glass_color = material.color
#=> Color(128, 128, 128, 255)
# Notice how the result did not return the correct alpha ?
# So we have to specifically get that property thus:
glass_color.alpha= material.alpha
#=> 0.5
layers["0_EX_Glazing"].color= glass_color
#=> Color(128, 128, 128, 127)
# See how the alpha was correctly set ?
materials.remove(material)

# Set the style to use Color By Tag (Layer):
model.rendering_options["DisplayColorByLayer"]= true

scroll to see all example code.

1 Like

Now … For the example scenario I show above (rendering style in “Color By Tag”) what most do is set up a Style for this and also a Scene page that uses this style, and they can switch to it any time they need to see objects in layer colors.

(This also assumes there are other scene pages uses other styles for presentation, printing, textured materials, etc. Name these kinds of scenes and styles for how they are shown and you’ll always know which scene page tab to click on.
It helps to also have a “Work” scene page set to Monochrome model for modeling because it helps you see when faces are turned inside out.)

In SketchUp, this is also called the “default material” which reality is not anything.
Ie, the object’s material property is set to nil.

When this is the case, the faces for complex objects (group or component instances) will be displayed in the FrontColor and BackColor for the Style in use. (The model itself can have an active style set, but each Scene page can use it’s own Style.)
These colors are set so that you can tell if faces are reversed as the BackColor is a gray-blue. Some users even a brighter annoying color that cannot be ignored for this purpose.

See Sketchup::RenderingOptions for more information.

It is normal to have face’s or child object material property set to nil within group and component definition entities collections, because when instances get a material assigned, any child faces or objects (for that particular instance) will be displayed with the parent instance’s material if their material is nil.
To override this behavior, individual child faces and objects can be painted with an explicit material assignment. (Wood surfaces are usually done this way so that woodgrain scale and position can be adjusted for realism. Ie, for woodgrain parent painting just does not look good.)


In summary, You don’t really need to paint everything with a “white” material, nor set most layers to a “White” color, if the default FrontColor for the Scene page’s Style is set to White.

WOW thanks for the help you are pointing me in so many great directions. (you should be a teacher!!!) one thing about the material it doesn’t paint the back side of the material how do you do that?

Thank you so much in advance

1 Like

Ok a little ahead of my issue looks like I am still having issues.
Problems in order

  1. i use a template that has the materials already loaded (so the script breaks) works fine if I dont already have the materials loaded
  2. paints 1 side of the layer (temporary) once I click on the material tab the layer goes back to white

Thanks in advance

Well, first of all, you can either have rendering set to “Color By Tag (Layer)” OR “Shaded With Textures” (which are Material average color and textures) displayed. But not both at the same time.

If you have rendering set to show material assignments (either “Shaded” or "Shaded with Textures’,) and are painting the “containers” (ie, group or component instances) and both the front and back sides of their faces are set to nil, then both face sides should display with the parent instance’s material.

But you can override any face using …

face.material= some_material
face.back_material= some_other_material

Of course you can use the same material if you choose. (Ie, transparent glass material so that you can see through the window from either side, etc.)

Well, think about it. You use a conditional statement to first test whether the material is already loaded.
if so, use it, if not load it first.

This is a perfect exercise to write up a little method to return a reference to a material object.

Answer (click to expand ...)
def get_material( mat_name, matl_folder )
  model = Sketchup.active_model
  materials = model.materials
  matl = materials[mat_name] # nil if not found
  return matl if matl
  # otherwise load it:
  matlpath = "Materials/#{matl_folder}/#{mat_name}.skm"
  path = Sketchup.find_support_file(matlpath)
  matl = materials.load(path)
  matl ? matl : false
end

Check that return result is truthy before using the returned object reference.

Huh? Once again, SketchUp tags/layers are nothing more than a display property sheet that the display engine can use to know how to display multiple objects, regardless of their position in the model hierarchy.

They (layers/tags) are not Sketchup::Drawingelement subclass objects, and are not geometric collections. So you cannot “paint” a layer. You can assign a layer’s property to use a Sketchup::Color instance, but as I said before, you cannot (yet) assign a Sketchup::Material instance to a layer/tag. (It has been requested to be able to assign materials to layers, but it has not yet been implemented.)

So just being a data construct holding properties, a layer/tag cannot “have” a side.

I’m not sure what you mean by “material tab” … do you mean the Materials inspector panel in a tray ?

It might help to post snips from the screen (use snipping tool.)

Be aware that if you click on any material in the Materials inspector panel (from any collection, ie, the “In Model” collection or one of the collections on disk,) no matter what you active tool is, SketchUp will automatically activate the Paint Bucket tool.
This tool is only useful if you have rendering set to either “Shaded” or “Shaded with Textures”.
It is not useful if you have any other rendering mode set, including “Color by Tag (Layer)”, since you cannot see that you’ve actually painted an object or a surface.

So, I think you need to learn more about SketchUp rendering, Styles, and setting up Scenes with their own style.

If you are going to be using “Color by Tag (Layer)”, then paint with materials is not needed and has no use.

If you do want to use materials, then you must not use “Color by Tag (Layer)” rendering, and must use either “Shaded” or “Shaded with Textures”.

See the User Guide on …

Clarification: When you use “Color by Tag (Layer)” rendering, it is just a display mode.
It does not apply the color objects that layers have assigned to them, to any actual drawing element object’s, edge’s or face’s material property pointer.

So using “Color by Tag (Layer)” rendering will ignore any actual drawing element object’s, edge’s or face’s material property pointer. And instead, will use the layer color assignments to display the drawing elements.

Okay ?

This is why you can set up a special scene page that uses it’s own style set to “Color by Tag (Layer)” rendering, for when you want to see the model displayed in an organizational way.
And then set up another scene page with it’s own style set to a textured rendering style for presentation, animation or plotting etc.