# Script fails after 4th iteration

I am trying to write a basic subdivision script that does exactly the same thing as "simple subsurf modifier" does. (Subdivides triangles to 3 quads, quads to 4 quads and Ngons to n quads). I will develop it later to create different subdivision methods like Catmull-Clark.

The script below works fine on a cube mesh and the subsequently generated subdivided cubes for 4 times. When I try to run it the 5th time, the script gives error.

I'd appreciate all the help. Thanks in advance.

import bpy
import bmesh
import mathutils

# Duplicate and Get Mesh
mesh=bpy.context.object.data

# Create BMesh_Now
bm_now=bmesh.new()
bm_now.from_mesh(mesh)
vertices_now=bm_now.verts
edges_now=bm_now.edges
faces_now=bm_now.faces
loops_now=bm_now.loops

# Create BMesh_Next
bm_next=bmesh.new()
bm_next.from_mesh(mesh)
vertices_next=bm_next.verts
edges_next=bm_next.edges
faces_next=bm_next.faces
loops_next=bm_next.loops

# Number of Vertices, Edges and Faces
vertex_count=len(vertices_now)
edge_count=len(edges_now)
face_count=len(faces_now)

# Remove Edges and Faces from  BMesh_Next
for edge in edges_next:
edges_next.remove(edge)
for face in faces_next:
faces_next.remove(face)

# Add new Vertices to BMesh_Next
for edge in edges_now:
verts=edge.verts
mid=mathutils.Vector((0.0, 0.0, 0.0))
for v in verts:
mid+=v.co
mid=mid/2
vertices_next.new(mid)
for face in faces_now:
verts=face.verts
center=mathutils.Vector((0.0, 0.0, 0.0))
for v in verts:
center+=v.co
center=center/len(verts)
vertices_next.new(center)

vertices_next.index_update()

# Create new Faces
facecount=0
for face in faces_now:
verts=face.verts
count=len(verts)
vertexlist=[]
for v in verts:
vertexlist.append(v.index)
edges=face.edges
edgelist=[]
for e in edges:
edgelist.append(e.index)

for i in range(count):
newfacevertices=[]
v=vertexlist[i]
newfacevertices+=vertices_next[v:v+1]
e1=vertex_count+edgelist[i]
newfacevertices+=vertices_next[e1:e1+1]
f=vertex_count+edge_count+facecount
newfacevertices+=vertices_next[f:f+1]
e2=vertex_count+edgelist[(i+count-1)%count]
newfacevertices+=vertices_next[e2:e2+1]
print(newfacevertices)
faces_next.new(newfacevertices)
facecount+=1

# Copy to Mesh
bm_next.to_mesh(mesh)
bm_now.free()
bm_next.free()

print("Done!")

• Your script worked fine for me, i made a cube and kept running it until cube.006 I had to kill blender afterwards because the scene was too heavy , but it didn't fail after the 4th time executing it. – user2816 May 12 '16 at 2:19
• Thanks R00t . I've tried on two different computers. It always fails at 5th. Not sure what causes it.... – Bora May 12 '16 at 17:52
• Why can't this be done with a modifier or the edit mode tool? – JakeD Sep 9 '16 at 22:52

A couple of things

You are not freeing your bmesh s with

bm.free


you need to call the free method

bm_now.free()
bm_next.free()


Also consider replacing bpy.ops.object.duplicate(linked=False) with either:

newobj = bpy.context.object.copy()
newobj.data = newobj.data.copy()
bpy.context.scene.objects.active = newobj # make it context.active_object


or quite simply

mesh = bpy.context.object.data


to not have subdivided dupes.

Not using operators will avoid adding the state to the undo stack, and running out of memory.

Making these changes lets me get to 8 on default cube, (9 crashes my blender), which is passable given 6 is the max for modifier.

• Thanks you for your answer batFinger. I've added the parenthesis to call the free methods. I've tried replacing the duplication and also removing it altogether simplify but in either case I cannot get past the 4th iteration. the script always fail at the 5th time. If I apply a simple subdivision modifier to the 4th Cube and run the script again, it works for two more times and then blender crashes on the third. – Bora May 12 '16 at 16:45
• Side note: You can manually enter the number in subsurf modifier. My computer can handle up to 11 on a cube. – Bora May 12 '16 at 16:54