Ensure exactly one face is selected

New to Ruby, moderate experience with SU.

I am writing an extension, and the first thing I need to do is make sure the user has selected exactly one face. For example, if there are 10 rectangles in the model, the user has to select just one of them before running the extension. Here’s the code I’m trying:

# Make sure only one face is selected
selection = Sketchup.active_model.selection
faces = selection.grep(Sketchup::Face)
face_count = faces.count()

if face_count != 1 then
	puts face_count.to_s + ' faces selected'
	exit
end

I put a few rectangles in my model. No matter how many rectangles I select, the console says “0 faces selected” What am I doing wrong? (And is there a more elegant way to include a code snippet in this forum?)

My first question is what had you selected before running this snippet? It will only find faces among whatever you have selected in the GUI or added to the selection in Ruby. If you want to search an entire collection, you should work with its Entities collection instead of the selection, as in

Sketchup.active_model.entities.grep(Sketchup::Face)

For proper presentation of Ruby code in the forum, put ```ruby on the line before the code and ``` on the line after it. That will format it nicely and colorize it as you see in my sample.

Edit: on a second look, you don’t need or want the exit statement! That will attempt to abort the interpreter

In SU, I do the following a few times:

  1. Use the rectangle tool to draw a rectangle.
  2. Click inside the rectangle (shows the dotted shading).
  3. Press P on the keyboatd to invoke the Push tool, then drag upwards an inch or so.
  4. Hit the spacebar to revert to the plain arrow, then triple-click on my shape, right-click and select Make Group.

When I have done this a few times, I have a bunch of shapes (technically “rectangular prisms” or “cuboids”) in my model. I then click on one of them and run my extension. I get “0 faces selected”.

But I think I just figured it out. I need to first edit a cuboid shape, then click on a face to show the dotted shading. Then when I run my code, it correctly responds “1 faces selected”. My error was thinking that simply clicking on a group would to select it would automagically produce a selection that contained the faces within that group. It doesn’t.

So now I am wondering how to recurse into a group or component and find all the faces nested inside the group.

There’s the problem. Grep is a purely Ruby method, it does not understand anything about SketchUp models. If there is not a Face directly in what you have selected, grep will not probe into groups or components to find one.

Read up on groups and components in the Ruby API documentation and see if you can figure it out. Come back if you run into further problems. Good luck!

Thanks for your help – and kindness to a newb. I will do more reading and fiddling!

FYI:

if !selection.empty? && selection.single_object?
  # test the selections's first and only member for a face
end
2 Likes

You have a group in your selection, that’s the reason why you receive that answer.
Faces and edges are inside the group.
Change Sketchup::Face by Sketchup::Group in grep method and see the difference.