Skip to main content
new return val in closest point on mesh.
Source Link
batFINGER
  • 85.2k
  • 10
  • 114
  • 244

Came up with similar to @TLousky, test code below only selects faces without the range value.

To use closest point on mesh you need to put the reference point into the calling object's object space, if not you will get undesired results when away from the origin.

Also note: use vectors to calculate distance.

import bpy
import bmesh

L = 0.5 # distance limit
sphere = bpy.data.objects.get("Sphere")
mesh_obj = bpy.context.edit_object
me = mesh_obj.data
smwi = sphere.matrix_world.inverted()

bm = bmesh.from_edit_mesh(me)

for face in bm.faces:
    v1 = mesh_obj.matrix_world * face.calc_center_median() # global face median
    localPos = smwi * v1  # face cent in sphere local space
    
    (hit, loc, norm, face_index) = sphere.closest_point_on_mesh(localPos)
    # Edited for new hit success return val.  
    v2 = sphere.matrix_world * loc
    face.select = ((v2 - v1).length > L)

test result

enter image description here

To make it more accurate consider using the normal returned to determine which point of a face to use. If the angle between the face normal and the normal to the closest point is ~ 90 use the closest edge, ~ 180 degrees it's on the inside.

Came up with similar to @TLousky, test code below only selects faces without the range value.

To use closest point on mesh you need to put the reference point into the calling object's object space, if not you will get undesired results when away from the origin.

Also note: use vectors to calculate distance.

import bpy
import bmesh

L = 0.5 # distance limit
sphere = bpy.data.objects.get("Sphere")
mesh_obj = bpy.context.edit_object
me = mesh_obj.data
smwi = sphere.matrix_world.inverted()

bm = bmesh.from_edit_mesh(me)

for face in bm.faces:
    v1 = mesh_obj.matrix_world * face.calc_center_median() # global face median
    localPos = smwi * v1  # face cent in sphere local space
    
    (loc, norm, face_index) = sphere.closest_point_on_mesh(localPos)
    
    v2 = sphere.matrix_world * loc
    face.select = ((v2 - v1).length > L)

test result

enter image description here

To make it more accurate consider using the normal returned to determine which point of a face to use. If the angle between the face normal and the normal to the closest point is ~ 90 use the closest edge, ~ 180 degrees it's on the inside.

Came up with similar to @TLousky, test code below only selects faces without the range value.

To use closest point on mesh you need to put the reference point into the calling object's object space, if not you will get undesired results when away from the origin.

Also note: use vectors to calculate distance.

import bpy
import bmesh

L = 0.5 # distance limit
sphere = bpy.data.objects.get("Sphere")
mesh_obj = bpy.context.edit_object
me = mesh_obj.data
smwi = sphere.matrix_world.inverted()

bm = bmesh.from_edit_mesh(me)

for face in bm.faces:
    v1 = mesh_obj.matrix_world * face.calc_center_median() # global face median
    localPos = smwi * v1  # face cent in sphere local space
    
    (hit, loc, norm, face_index) = sphere.closest_point_on_mesh(localPos)
    # Edited for new hit success return val.  
    v2 = sphere.matrix_world * loc
    face.select = ((v2 - v1).length > L)

test result

enter image description here

To make it more accurate consider using the normal returned to determine which point of a face to use. If the angle between the face normal and the normal to the closest point is ~ 90 use the closest edge, ~ 180 degrees it's on the inside.

Code cleanup
Source Link
batFINGER
  • 85.2k
  • 10
  • 114
  • 244

Came up with similar to @TLousky, test code below only selects faces without the range value.

To use closest point on mesh you need to put the reference point into the calling object's object space, if not you will get undesired results when away from the origin.

Also note: use vectors to calculate distance.

import bpy
import bmesh

# Get the active mesh

L = 0.5 # distance limit
sphere = bpy.data.objects.get("Sphere")
mesh_obj = bpy.context.edit_object
me = mesh_obj.data
 
# Get asmwi BMesh= representationsphere.matrix_world.inverted()

bm = bmesh.from_edit_mesh(me) 

for face in bm.faces:
    face.select = False
    
    v1 = mesh_obj.matrix_world * face.calc_center_median() # global face median
    localPos = sphere.matrix_world.inverted()smwi * v1  # face cent in sphere local space
    
    (loc, norm, face_index) = sphere.closest_point_on_mesh(localPos)
    
    v2 = sphere.matrix_world * loc
    
    face.select if= ((v2 - v1).length > L:
        face.select = True)

test result

enter image description here

To make it more accurate consider using the normal returned to determine which point of a face to use. If the angle between the face normal and the normal to the closest point is ~ 90 use the closest edge, ~ 180 degrees it's on the inside.

Came up with similar to @TLousky, test code below only selects faces without the range value.

To use closest point on mesh you need to put the reference point into the calling object's object space, if not you will get undesired results when away from the origin.

Also note: use vectors to calculate distance.

import bpy
import bmesh

# Get the active mesh

L = 0.5 # distance limit
sphere = bpy.data.objects.get("Sphere")
mesh_obj = bpy.context.edit_object
me = mesh_obj.data
 
# Get a BMesh representation
bm = bmesh.from_edit_mesh(me)
for face in bm.faces:
    face.select = False
    
    v1 = mesh_obj.matrix_world * face.calc_center_median() # global face median
    localPos = sphere.matrix_world.inverted() * v1  # face cent in sphere local space
    
    (loc, norm, face_index) = sphere.closest_point_on_mesh(localPos)
    
    v2 = sphere.matrix_world * loc
    
     if (v2 - v1).length > L:
        face.select = True

test result

enter image description here

To make it more accurate consider using the normal returned to determine which point of a face to use. If the angle between the face normal and the normal to the closest point is ~ 90 use the closest edge, ~ 180 degrees it's on the inside.

Came up with similar to @TLousky, test code below only selects faces without the range value.

To use closest point on mesh you need to put the reference point into the calling object's object space, if not you will get undesired results when away from the origin.

Also note: use vectors to calculate distance.

import bpy
import bmesh

L = 0.5 # distance limit
sphere = bpy.data.objects.get("Sphere")
mesh_obj = bpy.context.edit_object
me = mesh_obj.data
smwi = sphere.matrix_world.inverted()

bm = bmesh.from_edit_mesh(me) 

for face in bm.faces:
    v1 = mesh_obj.matrix_world * face.calc_center_median() # global face median
    localPos = smwi * v1  # face cent in sphere local space
    
    (loc, norm, face_index) = sphere.closest_point_on_mesh(localPos)
    
    v2 = sphere.matrix_world * loc
    face.select = ((v2 - v1).length > L)

test result

enter image description here

To make it more accurate consider using the normal returned to determine which point of a face to use. If the angle between the face normal and the normal to the closest point is ~ 90 use the closest edge, ~ 180 degrees it's on the inside.

added 279 characters in body
Source Link
batFINGER
  • 85.2k
  • 10
  • 114
  • 244

Came up with similar to @TLousky, test code below only selects faces without the range value.

To use closest point on mesh you need to put the reference point into the calling object's object space, if not you will get undesired results when away from the origin.

Also note: use vectors to calculate distance.

import bpy
import bmesh

# Get the active mesh

L = 0.5 # distance limit
sphere = bpy.data.objects.get("Sphere")
mesh_obj = bpy.context.edit_object
me = mesh_obj.data

# Get a BMesh representation
bm = bmesh.from_edit_mesh(me)
for face in bm.faces:
    face.select = False
    
    v1 = mesh_obj.matrix_world * face.calc_center_median() # global face median
    localPos = sphere.matrix_world.inverted() * v1  # face cent in sphere local space
    
    (loc, norm, face_index) = sphere.closest_point_on_mesh(localPos)
    
    v2 = sphere.matrix_world * loc
    
    if (v2 - v1).length > L:
        face.select = True

test result

enter image description here

To make it more accurate consider using the normal returned to determine which point of a face to use. If the angle between the face normal and the normal to the closest point is ~ 90 use the closest edge, ~ 180 degrees it's on the inside.

Came up with similar to @TLousky, test code below only selects faces without the range value.

To use closest point on mesh you need to put the reference point into the calling object's object space, if not you will get undesired results when away from the origin.

Also note: use vectors to calculate distance.

import bpy
import bmesh

# Get the active mesh

L = 0.5 # distance limit
sphere = bpy.data.objects.get("Sphere")
mesh_obj = bpy.context.edit_object
me = mesh_obj.data

# Get a BMesh representation
bm = bmesh.from_edit_mesh(me)
for face in bm.faces:
    face.select = False
    
    v1 = mesh_obj.matrix_world * face.calc_center_median() # global face median
    localPos = sphere.matrix_world.inverted() * v1  # face cent in sphere local space
    
    (loc, norm, face_index) = sphere.closest_point_on_mesh(localPos)
    
    v2 = sphere.matrix_world * loc
    
    if (v2 - v1).length > L:
        face.select = True

test result

enter image description here

Came up with similar to @TLousky, test code below only selects faces without the range value.

To use closest point on mesh you need to put the reference point into the calling object's object space, if not you will get undesired results when away from the origin.

Also note: use vectors to calculate distance.

import bpy
import bmesh

# Get the active mesh

L = 0.5 # distance limit
sphere = bpy.data.objects.get("Sphere")
mesh_obj = bpy.context.edit_object
me = mesh_obj.data

# Get a BMesh representation
bm = bmesh.from_edit_mesh(me)
for face in bm.faces:
    face.select = False
    
    v1 = mesh_obj.matrix_world * face.calc_center_median() # global face median
    localPos = sphere.matrix_world.inverted() * v1  # face cent in sphere local space
    
    (loc, norm, face_index) = sphere.closest_point_on_mesh(localPos)
    
    v2 = sphere.matrix_world * loc
    
    if (v2 - v1).length > L:
        face.select = True

test result

enter image description here

To make it more accurate consider using the normal returned to determine which point of a face to use. If the angle between the face normal and the normal to the closest point is ~ 90 use the closest edge, ~ 180 degrees it's on the inside.

added 15 characters in body
Source Link
batFINGER
  • 85.2k
  • 10
  • 114
  • 244
Loading
Source Link
batFINGER
  • 85.2k
  • 10
  • 114
  • 244
Loading