In the case that merging+recalculating normals is not working and in the spirit of providing what OP asked for, I have written a script that will select all the red faces for you.
import bpy
import bmesh
print("=================")
Set to object mode.
bpy.ops.object.mode_set(mode = 'OBJECT')
Get the active object
obj = bpy.context.active_object
faces=[]
if obj and obj.type == 'MESH':
mesh = bpy.context.active_object
# Get selected faces
selected_faces = [f.index for f in mesh.data.polygons if f.select]
# Loop through the selected faces.
for face_index in selected_faces:
face = mesh.data.polygons[face_index]
normal = face.normal
# Get location of the current 3d view.
area = next(area for area in bpy.context.window.screen.areas if area.type == 'VIEW_3D')
view_location = area.spaces.active.region_3d.view_matrix.inverted().translation
# modify the view location so that it is at (0,0,0) and calculate
# the dot product with the normal.
dot_product = normal.dot(view_location - face.center)
# If the dot product is negative then this is a 'red' face.
if dot_product < 0:
faces.append(face_index)
# Deselect all faces
bpy.ops.object.mode_set(mode = 'EDIT')
bpy.ops.mesh.select_all(action = 'DESELECT')
bpy.ops.object.mode_set(mode = 'OBJECT')
# Reselect only the inverted faces.
for face in faces:
obj.data.polygons[face].select = True
bpy.ops.object.mode_set(mode = 'EDIT')
else:
print("No valid mesh object in edit mode found.")
In Face Select mode, select all the faces you want to filter from and then run the script. Only the red faces will be left selected, allowing you to easily flip them. Make sure that your 3D view position is not changed between when you select the faces and run the script, as this position is used in the calculation.
