How to select bottom faces only

How can I select the faces which are visible from the bottom view? So the rest (top, profile) should be omitted.

vac.skp (1.7 MB)

A vacuum cleaner.

SU8

First you need to ensure all of the faces are correctly oriented.
The blue ones need reversing - switch view > hidden0geometry on…


Also some nested-nested containers also need addressing…
So next question…
Please define what you mean by visible from below ?

While you are cleaning up the file, I’d get rid of that absurd material everything is painted with!

4 Likes

All faces which you see here:

Edit the context.
Select All.
In the Ruby Console paste the following:

model=Sketchup.active_model
ss=model.selection
ssa = ss.grep(Sketchup::Face)
ss.clear
ssa.each{|e| ss.add(e) if e.normal.z < 0 }

This then [re]selects all previously selected downwards facing faces…

2 Likes

Great! It works. It would be great if one could save the selected data to some file and import them later. Just like in Photoshop you can select some parts of the image based on layers or channels, so in SU you could save it and use it later.

Please, can you write the conditions which I should use when I want to select the faces from different view?

  • top
  • left
  • right
  • back
  • front

I am adding textures to surface. Thank you

PS: It would be useful to have an addon/plugin to do this.

There are several permutations:

ssa.each{|e| ss.add(e) if e.normal.z < 0 } # for z down faces [the bottom - as in my example]
ssa.each{|e| ss.add(e) if e.normal.z > 0 } # for z up faces [the top]

ssa.each{|e| ss.add(e) if e.normal.z == 0 } # for exactly vertical faces [all ‘sides’]

ssa.each{|e| ss.add(e) if e.normal.x < 0 } #facing left
ssa.each{|e| ss.add(e) if e.normal.x > 0 } #facing right

ssa.each{|e| ss.add(e) if e.normal.y < 0 } #facing front
ssa.each{|e| ss.add(e) if e.normal.y > 0 } #facing back

You can combine the ‘tests’ using &&
So to find all vertical faces looking towards the front, you would use:

ssa.each{|e| ss.add(e) if e.normal.z == 0 && e.normal.y < 0 }

etc…

1 Like

Thank you. This is extremely useful.

Hello Tag,
is it possible to use this algorithm to select bottom faces of mesh? I found that whiles top mesh is covered by correct texture, the bottom of the mesh is covered by some inappropriate texture. Hence I would like to select the mesh faces bottom and cover it with a color or texture. It does not look to me that it works for mesh.

This isn’t quite the same issue…
I assume you mean ‘back-faces’ ?
You should never see the backs of faces ??

However, if you want to affect the ‘back-faces’ in a selection it’s relatively easy…

model = Sketchup.active_model
mat = model.materials["AnExistingMaterialNameInTheModel"]
### 'mat' might be 'nil' if it is not found !
ss = model.selection
faces = ss.grep(Sketchup::Face)
ss.clear
faces.each{|face|
  face.back_material = mat
  ### if mat is 'nil' then the face uses default material on its back
  ss.add(face)
  ### we reselect the face [optional]
}

Now all selected faces have their back-face material reset to be ‘mat’ [or ‘nil’ if ‘mat’ is not found…]

I am entering this line by line from ruby console and it looks like error:

faces.each{|face|
Error: #<SyntaxError: (eval):155: compile error
(eval):155: syntax error, unexpected $end
faces.each{|face|
^>
(eval):155
face.back_material = mat
Error: #<NameError: undefined local variable or method `face’ for main:Object>
(eval):155

Entering it in the console can fail as there are ‘newlines’.
Try this alternative - harder to read but not \n…

faces.each{|face| face.back_material = mat; ss.add(face) }

No problem with this; this is more clear for me when you use semicolor as separator; I am used to use it in programming.

I just tested it and it works. Thank you.

What is the name of default material, when I want to clear all back faces? Should I use this?

mat = model.materials[""]

To remove front materials use:

faces.each{|face| face.material = nil }

to remove back materials use:

faces.each{|face| face.back_material = nil }

mat = model.materials[""]

might well return ‘nil’ but it’s easier to use the above methods…
or just use ‘mat’ but use:

mat = nil

Based on your code, I tried to modify it a bit, to work on a selected entities. But no change visible (especially in the second code).

In the selection find faces … and change their back_material

mat = Sketchup.active_model.materials["map-arctic-region light edited"]; ss = Sketchup.active_model.selection; faces = ss.grep(Sketchup::Face); ss.clear; faces.each{|face| face.back_material = mat; ss.add(face)}

In the selection … set back_material to nil (default value)

ss = Sketchup.active_model.selection; faces = ss.grep(Sketchup::Face); faces.each{|face| face.back_material = nil; }

For me it is more clear to use complete “path” to the model instead of variables.

Looks like it ought to work…
Are you sure the material-name is entered exactly correctly ?

After running the code, type mat to see what’s returned, and ss.to_a to see what’s selected…

This topic was automatically closed after 91 days. New replies are no longer allowed.