I'd like to delete the polygons which normals have negative y coordinates. With this script I can have the vector representing polygon's normal displayed:

import bpy

current_obj = bpy.context.active_object

print("="*40) # printing marker
for polygon in current_obj.data.polygons:
    verts_in_face = polygon.vertices[:]
    norm = polygon.normal
    print("face index", polygon.index)
    print("normal", polygon.normal)

My problem is that I simply can't check for y coordinate of this vector: I've tried:


etc. I'm getting "Syntax error: invalid syntax" pointing at [1] or .y. In this case, it isn't possible to check vector's y coordinate against 0 in if statement, so I can't pick up the vectors which y coords are >=0.

  • $\begingroup$ what is the full error message. $\endgroup$ – zeffii May 14 '15 at 9:20
  • 2
    $\begingroup$ Your problem is somewhere else, the code works for me. I can even check polygon.normal.y > 0. There is a syntax error in your code, can you show the code? $\endgroup$ – Jaroslav Jerryno Novotny May 14 '15 at 9:21
  • $\begingroup$ @Jerryno - my full code was posted above except if(polygon.normal.y > 0) above last two lines. $\endgroup$ – przemulala May 15 '15 at 13:01

What you're asking for is this:

Using ops

import bpy

# if named..
# obj = bpy.data.objects['IcoSphere']  
obj = bpy.context.active_object  
me = obj.data

# must be in object mode, to refresh face selections and data
bpy.ops.object.mode_set(mode = 'OBJECT') 

faces = me.polygons
for f in faces:
    f.select = (f.normal.y < 0.0)

# to remove using this method we switch to edit mode, and back after removal.

bpy.ops.object.mode_set(mode = 'EDIT') 
bpy.ops.object.mode_set(mode = 'OBJECT') 

This is essentially a scripted walk through of what you would be doing if you inspected each face normal and selected only those that had a negative y coordinate, then at the end it would delete the selected faces.

There are other ways to do this, but this might give some insight. This is the after shot:

enter image description here

Using bmesh


warning, the context parameter of bmesh.ops delete is a little undocumented, but is described here

import bpy
import bmesh

obj = bpy.context.active_object  
me = obj.data

bm = bmesh.new()   # create an empty BMesh
bm.from_mesh(me)   # fill it in from a Mesh

faces = [f for f in bm.faces if (f.normal.y < 0.0)]

bmesh.ops.delete(bm, geom=faces, context=5)

# Finish up, write the bmesh back to the mesh
bm.free()  # free and prevent further access

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.