Top surface multiple face selection

Hello,
Does anybody have experineces with multiple face selection? I’ve recently encountered this topic, and I am trying to find the best way to select only the top surface with a code.

One of my ideas is to use face normals to find the location and orientation of faces and select only those I need. Is there a better way to do this?

I have created a simplified example of what I need; the red surface is the one I need to select (surface is red only for demonstrational purposes). I will need this to work even for more complicated surfaces.


There is a link to the BLEND file:
https://1drv.ms/u/s!AtBhBiBGPhtAjlCDzvj46upw1F1U?e=r36dGe

Thanks in advance.

well, you say that you want surfaces facing upward, but in your demonstration you have faces pointing outward that are selected- which is it? If you’re just looking to select faces that are pointing up, using the normal is the obvious answer. you could even check the dot product of each normal against the up vector and give yourself a margin for error so the surface doesn’t have to be facing directly up if you wanted.

if, however, you’re looking for a script that can somehow know the difference between the faces pointing outward on the extruded segment vs the faces pointing outward on the larger segment, i think you may be out of luck.

I am not saying that I want to select just the surface facing upward. I want to select the top surface, which I have for better understanding colored red.

In other words, I need to select everything but base (bottom and sides aligning to bottom).

I am not exactly looking for a script but for a different perspective, ideas, and experiences of other users, who may have encountered this topic and can have insightful advice, that may ease my issue.

to start with, you’ll need to be able to define “top surface” in plain language. If the only way to describe it is to show an image, then you’re relying on human intuition to understand it- and outside of ML there’s not really many options for automating something like this.

A useful exercise before writing any code is to try explaining it in plain language to someone (or yourself) first. this is sometimes called rubber ducking.

For example, if you were able to say “any geometry that has a vertex with a Z coordinate greater than zero should be considered the top”, that’s something you could write a script for.

This is all a round about way of saying- based solely on the image you’ve posted, there is no way to do what you’re asking. If you’re able to give more information (such as Z>0 is the top), there may be some way- but as it currently stands it’s not possible to write a script to intrinsically understand “top” in such broad terms.

I think there was a selection mode to select verts (or faces) by side and choose the direction

you could just use that operator in the script if you need, or maybe you’ll automate the process of setting the origin back and forth so you can defined from which point on the faces should be selected by defining a Vertex to jump to. you could also use the cursor to place the origin to cursor and then put it back where it was after you run the selection operator

I do understand you and programming quite well, there is no need to explain that to me.

I am not exactly used to Blender (and mesh) itself, it is quite a comprehensive set of new functions to me; that is the reason I posted my issue. I just do not know if I can get some coordinates or some other information I could find useful for a solution of my issue.

In the language, you requested: I need to choose all faces except five with the lowest Z coordinates.

Basically, I need to get coordinates of faces, I am already capable to do the rest.

sounds pretty straightforward to me, here you go!
this script will give you all of the faces except the ‘bottom most 5 faces’ of any mesh in local space.

import bpy, bmesh

obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)

face_height = []
for f in bm.faces:
    # as you're no doubt aware, faces don't actually have coordinates, so I'm just going 
    # to assume you want face centers i guess? also you didn't specify if this was a world
    # or local space need, so if you want world space you're going to want to multiply the
    # world matrix first.
    face_height.append((f, f.calc_center_median()[2]))
    
face_height.sort(key = lambda x: x[1])

for f, _ in face_height[5:]:
    f.select = True
    
bm.select_flush_mode()
bmesh.update_edit_mesh(obj.data)
1 Like