Trying to learn to use layers and objects in API

I am trying to make both objects and layers in the API and I am having trouble. I would like for the layer to give color to the object but it seems that some of the faces don’t belong to the correct object. below I will include the code. The problem lies in the last image where the insulator layer’s face has the via’s color. Any resources for learning the API would be appreciated. I already browsed through the resources listed in the forums. I just am a visual/from code learner.


model = Sketchup.active_model # Open model
entities = model.active_entities
layers_array = model.layers

# add layers to the array.
layers_array.add "insulator"
layers_array.add "via"

model.active_layer= layers_array["insulator"]
entities = model.active_entities
# Add the group to the entities in the model
insulator = entities.add_group = "insulator"

# make some points
scale =
top =
pts = [[0,0,0],[scale,0,0],[scale,scale,0],[0,scale,0],[0,0,0]]

# add points to group
face = insulator.entities.add_face pts
if face.normal.z == -1
face.pushpull top

# now the via
model.active_layer= layers_array["via"]
entities = model.active_entities
# Add the group to the entities in the model
via = entities.add_group = "via"
# get group entities
ent2 = via.entities

scale =
centering =
pts = [[centering,centering,top],[scale+centering,centering,top],[scale+centering,scale+centering,top],[centering,scale+centering,top],[centering,centering,top]]

face2 = ent2.add_face pts
if face2.normal.z == 1

via_copy = via.parent.entities.add_instance(via.definition, via.transformation)

insulator = via.subtract(insulator) = "insulator"

via = via_copy # let the copy now be grp1 = "via"
zface = via.entities.find {|ent| ent.typename == "Face" &&    ent.normal == [0, 0, -1]}

model.rendering_options['DisplayColorByLayer']= true # colors each layer

Full view nothing off.

Layer Insulator tag view off

Layer Via tag off

Group insulator tag off

Group Via tag off

I believe the source of your problems is that you are making one of your tags (still called “layers” in the API for backward compatibility) active before adding geometry to the model. This causes new edges and faces to use that tag. But in SketchUp only groups and components should use tags, edges and faces should always use untagged (aka Layer0). Instead, you should leave untagged active and explicitly assign each of your groups to use the appropriate layer, as

insulator_tag = layers_array.add "insulator"
via_tag = layers_array.add "via"
# get rid of the line that says 
#model.active_layer= layers_array["insulator"]
# then later
insulator = entities.add_group = "insulator"
insulator.layer = insulator_tag
# and likewise a bit further do the same for via
# kill the line saying
#model.active_layer= layers_array["via"]
# then do
via = entities.add_group = "via"
via.layer = via_tag

Note: the same best practice applies when drawing by hand in SketchUp

Edit: There is more going on as well. I think your creation of copies of groups is losing their association with tags.

Edit2: yes, because editing a group or making a copy creates a new, distinct group, you also need to assign the tags to via_copy (which replaces via) and to insulator (which gets replaced by the subtract operation).

Here’s the result of making those various changes:


1 Like

Some further thoughts:

Even in a sample like this, you should enclose your code in a module so that it can’t collide with anything else.

module Cwatts
  # put your code here

When you search for a Face, use for example

zface = via.entities.find {|ent| ent.is_a?(Sketchup::Face &&    ent.normal == [0, 0, -1]}

string comparison in Ruby is vastly slower than is_a?. It won’t make a difference in this short example, but in a more complicated loop it can slow things down by a large amount!

… also beware that Enumerable#find will return nil when nothing is found, so always check the result before using it.

if zface
  # do something with zface

… or …

call_some_method(zface) unless zface.nil?

… etc. …

Thanks! so should I make groups then assign them to layers at the end? Also, if you don’t mind me asking. How can I make a gif like the one you show so that I can easily post questions without having a bunch of different images?

It doesn’t matter whether you assign a layer to a group before or after adding edges and faces to it, just that you assign the layer to the group itself and not to those contents. Or in this case, after making the copies.

I use a little free utility called LICEcap.

Thanks! That worked great. The code you included was missing a parenthesis though. Should have been:

zface = via.entities.find {|ent| ent.is_a?(Sketchup::Face) &&    ent.normal == [0, 0, -1]}

Oops! Correct. I just slammed that in without actually running it :flushed:

That’s okay I appreciate your help!