Script to remove faces with significantly different normals

I have a mesh imported from a Structure Scanner that has some dirty mesh sections. I have a script that imports, orients and simplifies the mesh to this:

However, looking from the inside shows that some faces are facing inwards, causing problems for another program along to process:

The scanner seems to double up some faces causing these problems. I can get away with deleting the erroneous faces/vertices (leaving holes to be filled in blender or the next stage), but I can't figure a way to detect these areas and remove them.

This solution from another question looked promising, but, firstly, I can't get the script to work and, secondly, it takes an average of the whole selection which wouldn't work on this nearly hemispherical shape.

Is there perhaps a simpler way of removing and correcting these erroneous points, CATIA has "clean non manifold triangles"?

Close up of one of the problems:

• Answered based on title and script part. For cleaning suggest looking at Related Oct 25, 2017 at 15:22
• Just wanted to add that there is an operator bpy.ops.mesh.select_non_manifold() Oct 25, 2017 at 20:15

A script to select verts based on the angle between normal and radial vector.

An alternative script than the one shown in question link.

In the case where the object is spherical, , after changing the object origin to the centre of the base ring if hemisphere (or where sphere centre would be), can then check the angle between vert normal and vert coordinate (since vert.co is also the vector from (0, 0, 0) origin). If it was a perfect sphere, all these angles would be zero.

Test script to run in edit mode. (In vertex selection mode) Change the 90 degree value of angle_check = radians(90) to suit. The script only selects verts with an angle of norm to radial outside angle_check.

import bpy
import bmesh
from math import radians
context = bpy.context
obj = context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)
for v in bm.verts:
v.select = v.normal.angle(v.co) > angle_check

'''
# or by faces
for f in bm.faces:
f.select = f.normal.angle(f.calc_center_median()) > angle_check

'''
bm.select_flush(False)
me.update()


You could try using the 3D Printing Toolbox add-on.

It checks your mesh for any bad geometry that would prevent proper printing, which includes intersecting faces, non-manifold edges, bad contiguous edges and so on.