I have a vector (for now, [0., 0., 1.]) and I want to find all the faces that are pointing away from it.

To do that, I'm currently putting the mesh data into a bmesh, iterating trough each face, calculating the sine of the angle between the vertices and getting all faces that return negative values, using this:

def unit_vector(vector):
  """ Returns the unit vector of the vector.  """
  return vector / np.linalg.norm(vector)

def cos_angle_between(v1, v2):
  """ Returns the cosine of the angle between vectors 'v1' and 'v2' """
  v1_u = unit_vector(v1)
  v2_u = unit_vector(v2)
  return np.clip(np.dot(v1_u, v2_u), -1.0, 1.0)

upVector = np.array([0., 0., 1.])
downFaceList = []

for face in bm.faces:
  v_cos = cos_angle_between(upVector, face.normal)
  if (v_cos < 0):

The meshes that I'm working with each has over 300,000 faces, so it's taking a lot of time to find all these faces. The user will be able to edit the direction of the up vertice (and see the new result), so performance optimization is a must.

Is there a faster way to get such faces?

  • 1
    $\begingroup$ just a hint: in Edit Mode you can use Shift+G->Normal with treshold 0.5: bpy.ops.mesh.select_similar(type='NORMAL', treshold=0.5) and select the inverse. This way you only use internal operators which are much faster since they are in C. Only thing you need is a dummy face with your desired normal. $\endgroup$ – Dimali Oct 20 '17 at 19:42
  • 1
    $\begingroup$ Why not use the blender vector type. test vector.angle(face.normal). docs.blender.org/api/blender_python_api_current/… $\endgroup$ – batFINGER Oct 20 '17 at 19:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.