# Creating a Shape Using Shrinkwrap Modifier

I would like to create a simple 3d shape from a list of vertices, so I wrote a Python script which subdivides a cube and uses the Shrinkwrap modifier.

After the shape is created, I would like to be able to select the faces and/or edges of the new shape. If I go into edit mode in the 3d view, I can select an entire face on the object I called "Final". However, if I look at the number of edges or faces in the Python console, I get a large number (in the case of my example, it says 96 faces). I am including an example using vertex points from a triangular prism, but I would like to do this with a polygon with an arbitrary number of vertices. I would like to be able to find the entire face for each of the sides of my object in Python.

import bpy
import bmesh
from mathutils import Vector,Euler

w = 2
h = 3
length = 4

verts = [
Vector((w/2,0,0)),Vector((-w/2,0,0)),Vector((-w/2,0,-h)),
Vector((0,length,0)),Vector((w/2,0,-h)),Vector((0,length,-h))]

mesh = bpy.data.meshes.new(name="New Object Mesh")
mesh.from_pydata(verts, [], [])
objsize=objpoints.dimensions
objmod=bpy.context.active_object
objmod.dimensions=[1.3*objsize.x,1.3*objsize.y,1.3*objsize.z]
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.subdivide(number_cuts=3)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)

wrapmod = objmod.modifiers.new(name='shapefrompoints', type='SHRINKWRAP')
wrapmod.target = objpoints
wrapmod.wrap_method = 'NEAREST_VERTEX'
# apply the modifier so we have a real object
depsgraph = bpy.context.evaluated_depsgraph_get()
# apply modifier using depsgraph (dependency graph
# https://blender.stackexchange.com/questions/146559/how-do-i-get-a-mesh-data-block-with-modifiers-and-shape-keys-applied-in-blender
object_eval = objmod.evaluated_get(depsgraph)
obj=bpy.data.objects.new("Final",object_eval.data.copy())


1.The object which is created "Final" has to be selected before applying the modifier. Hence added the following: objf=bpy.data.objects.new("Final",object_eval.data.copy()) bpy.context.collection.objects.link(objf) bpy.context.view_layer.objects.active = objf objf.select_set(True)

1. To remove doubles the following lines are added: bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.remove_doubles() bpy.ops.object.mode_set(mode='OBJECT')

2. Modifier has to me named for it to effect: bpy.ops.object.modifier_apply(modifier='shapefrompoints')

3. To verify the result: print("No of vertices",len(objf.data.vertices)," No of edges =",len(objf.data.edges),"No of polygons",len(objf.data.polygons))

the above after running the full code gives: Info: Removed 50 vertice(s) No of vertices 6 No of edges = 9 No of polygons 5 which is correct for the triangular prism.

=============================== Full code given below:

 import bpy
import bmesh
from mathutils import Vector,Euler

w = 2
h = 3
length = 4
verts = [
Vector((w/2,0,0)),Vector((-w/2,0,0)),Vector((-w/2,0,-h)),
Vector((0,length,0)),Vector((w/2,0,-h)),Vector((0,length,-h))]

mesh = bpy.data.meshes.new(name="New Object Mesh")
mesh.from_pydata(verts, [], [])
objsize=objpoints.dimensions

objmod=bpy.context.active_object
objmod.dimensions=[1.3*objsize.x,1.3*objsize.y,1.3*objsize.z]
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.subdivide(number_cuts=2)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)

wrapmod = objmod.modifiers.new(name='shapefrompoints', type='SHRINKWRAP')
wrapmod.target = objpoints
wrapmod.wrap_method = 'NEAREST_VERTEX'
# apply the modifier so we have a real object
depsgraph = bpy.context.evaluated_depsgraph_get()
# apply modifier using depsgraph (dependency graph
# https://blender.stackexchange.com/questions/146559/how-do-i-get-a-mesh-data-
block-with-modifiers-and-shape-keys-applied-in-blender
object_eval = objmod.evaluated_get(depsgraph)
objf=bpy.data.objects.new("Final",object_eval.data.copy())
bpy.context.view_layer.objects.active = objf
objf.select_set(True)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.remove_doubles()
bpy.ops.object.mode_set(mode='OBJECT')

bpy.ops.object.modifier_apply(modifier='shapefrompoints')

print("no of vertices",len(objf.data.vertices)," no of edges
=",len(objf.data.edges),"no of polygons",len(objf.data.polygons))

• Thank you. Your correction allows me to identify each of the sides of an arbitrary shape. Correctly using remove_doubles is the main part. However, if I understand modifiers correctly, I don't need to use both the dependency graph and modifier_apply., and the depsgraph method is more efficient.
– SJK
Commented Aug 30, 2021 at 15:20