Selecting Faces inside multiple groups

Hello,

My extension creates several different groups and I was wondering if there was some Ruby Api that would allow me to select all faces inside the groups that lie on the x-y plane in order to apply a specific texture to them. The issue that I am running into is that since I’m dealing with multiple groups I cannot highlight faces from outside of the groups. Is this possible to do after all of the groups have been created, or do I have to apply the textures inside of each group separately?

Any help would be appreciated,

Thank you.

You can actually select multiple objects in the model by using the instance method ´add´ on the Selection object of the model. However this was never intended by the SketchUp developers, and it can cause odd behavior on movement, grouping or the like.

However you can work on objects in the model directly from Ruby without having them selected in the model. To find faces on the X Y plane you can check for faces with a normal that is parallel to the Z_AXIS using same_direction? If they have to be on the Z = 0plane you can check the Z of an arbitrary vertex.

‘Select’ is perhaps inappropriate - although you can actually make a selection-set that transcends various ‘contexts’, it probably not a good idea…

However, change the word to something like ‘Collect’ then that’s more useful…
So for example, let’s assume you collect all of your groups into an array called ‘groups’…
To collect all of the matching faces you use something like…

faces = []
groups.each{|group|
  group.entities.grep(Sketchup::Face).find_all{|face|
    faces << face if face.normal.parallel?(Z_AXIS) && face.bounds.min.z==0
  }
}
faces.each{|face|
  face.material = "Red" # or whatever
}

This makes all flat faces at Z==0 ‘Red’…

2 Likes

This is what I was looking to do. Like you said, collect is a much better word than select for what I am trying to do. This should allow me to apply a certain texture my upward facing faces. Thanks.

Good afternoon All,

I am a newby in Rubi, I have 2,500 flat groups which i want to give thickness, Joint pushpull can be used but it takes 12minutes and I have 12 sets of 2,500 to do. I have tried it with a script but the one below does the trip but does it for all the faces rather than a selection, can somebody tell me what I do wrong? I copied and pasted section of scripts from various writes, my apologies for that.

model = Sketchup.active_model
ents = model.active_entities
target = Sketchup.active_model.selection[0]
tents = target.entities
faces = tents.grep(Sketchup::Face)
verts =

prompts = ['Push/Pull Distance']
defaults = [0.to_l]
results = UI.inputbox prompts, defaults, 'Distance to Push/Pull'
distance = results[0]   

verts.each do |e|
  faces.push e if e.is_a? Sketchup::Face
end

faces.each do |e|
  e.pushpull distance, true
end

First, I would suggest to open your own topic instead of posting in a multiple other topics… :wink:

Second, You can examine this how to post Ruby code: https://forums.sketchup.com/t/how-to-post-correctly-formatted-and-colorized-code-on-the-forum/46189


Beside there are some unnecessary lines in your code (line 6 and 13-15)

With the 3rd line you are targeting only one (the first) group of the selection. Then the code will find a face in it and will push-pull that one. BUT.

I assume the main issue is because of this behavior of SU:
Copying a group in SketchUp will create a group that shares the same definition. SketchUp implicitly makes group unique when edited from the GUI, and from a user point of view groups could be thought of as always being unique. I guess the groups in a quoestion, are made by just copying like that.

To honor this behavior, call this method before editing a group through the API.
Group#make_unique-instance_method
e.g. inserting this after 3rd line

target.make_unique

will make this target group unique and the push-pull will not “affect” the others

def pushpull_faces_in_selected_groups
  prompts = ['Push/Pull Distance']
  defaults = [0.to_l]
  results = UI.inputbox prompts, defaults, 'Distance to Push/Pull'
  distance = results[0]
  model = Sketchup.active_model
  targets = model.selection.grep(Sketchup::Group)
  targets.each{ |target|
    target.make_unique
    tents = target.entities
    faces = tents.grep(Sketchup::Face)
    faces.each{ |e|
      e.pushpull distance, true
    }
  }
end
pushpull_faces_in_selected_groups

Wonderful, thanks a lot for your assistance Dezmo

You are welcome. Be aware, that the “quick & dirty” code above works only if the groups have only one face…like this:
image

Thats all I need it for, flat surfaces. Pushpull is great but a way slower.

I thought that I found another quicker solution but it failed.
When I use my first script I take of my groups and copy and past in place it in to a new drawing. I run my original script in the new dwg and it push-pulled that part. After copying the pushed groups back in to the original dwg they appear flat again. Copying them to new drawing leaved them push, would you know any reason for that ? (I also used Purge in the original dwg to ensure that the block names are removed)

I guess, It is a similar explanation that my first answer. The SU keep the original group definition in your original file, and when you paste it back the original one takes a priority…