Thanks for the thread liero, I missed this one and it seems pretty interesting, I’ll dig into it.
PKHG : In fact, I want to build vertex groups for a mesh from its intersections with other meshes. So I’m really only interested with vertices for the first mesh, therefore its topology can be anything, but for the other meshes, I try to keep them hole free and convex (and if it has to be mandatory for the script to work, I can deal with it).
EDIT : It appears that Dynamic Paint with Weight surface type gives me exactly what I need (thanks to its vertex group output). But for the info, the “closest_point_on_mesh” technique gave me good results too.
EDIT 2 : I’ve adapted the point in mesh script found here for Blender 2.6 :
def pointInsideMesh(pt, ob):
Intersect = mathutils.geometry.intersect_ray_tri # less dict lookups.
def ptInFaceXYBounds(f, pt):
co= obvert[f.vertices[0]].co
xmax= xmin= co.x
ymax= ymin= co.y
co= obvert[f.vertices[1]].co
xmax= max(xmax, co.x)
xmin= min(xmin, co.x)
ymax= max(ymax, co.y)
ymin= min(ymin, co.y)
co= obvert[f.vertices[2]].co
xmax= max(xmax, co.x)
xmin= min(xmin, co.x)
ymax= max(ymax, co.y)
ymin= min(ymin, co.y)
if len(f.vertices)==4:
co= obvert[f.vertices[3]].co
xmax= max(xmax, co.x)
xmin= min(xmin, co.x)
ymax= max(ymax, co.y)
ymin= min(ymin, co.y)
# Now we have the bounds, see if the point is in it.
return xmin <= pt.x <= xmax and ymin <= pt.y <= ymax
def faceIntersect(f):
isect = Intersect(obvert[f.vertices[0]].co, obvert[f.vertices[1]].co, obvert[f.vertices[2]].co, ray, obSpacePt, 1) # Clipped.
if not isect and len(f.vertices) == 4:
isect = Intersect(obvert[f.vertices[0]].co, obvert[f.vertices[2]].co, obvert[f.vertices[3]].co, ray, obSpacePt, 1) # Clipped.
return bool(isect and isect.z > obSpacePt.z) # This is so the ray only counts if its above the point.
obImvMat = mathutils.Matrix(ob.matrix_world)
obImvMat.invert()
pt.resize_4d()
obSpacePt = obImvMat * pt
pt.resize_3d()
obSpacePt.resize_3d()
ray = mathutils.Vector()
ray.x = 0
ray.y = 0
ray.z = 1
me= ob.data
obvert = ob.data.vertices
# Here we find the number on intersecting faces, return true if an odd number (inside), false (outside) if its true.
return len([None for f in me.faces if ptInFaceXYBounds(f, obSpacePt) if faceIntersect(f)]) % 2
From my tests, it gives a more robust result but is slower. Hope it helps !