I’m using bpy.ops.mesh.primitive_circle_add() to create a circle with 32 verts. I know how to index a meshes vertices by number, however, the numbers seem to be in some kind of interleaved order. I’d like to be able to index the circle’s vertices in radial order (it doesn’t matter what the starting vertex is). Does anyone know of a simple way to do this? I know manual sorting and my friend atan2, but I don’t want to have to go there.
bpy.ops.mesh.vertices_sort doesn’t seem to change anything, here.
They are in order in 2.70 for me, no matter how many vertices. If you need to loop over them in order and they aren’t ordered by index, you should use the bmesh module I guess:
import bpy
import bmesh
from random import shuffle
from bpy_extras.object_utils import object_data_add
def main():
circle = bmesh.new()
bmesh.ops.create_circle(circle, segments=32, diameter=2)
# Randomize vertex indices
random_indices = list(range(len(circle.verts)))
shuffle(random_indices)
for v, i in zip(circle.verts, random_indices):
v.index = i
circle.verts.sort()
circle_walk = circle.copy()
bmesh.ops.translate(circle_walk, vec=(5,0,0), verts=circle_walk.verts)
iterate_circle(circle, circle.verts[0])
walk_circle(circle_walk, circle_walk.verts[0])
me = bpy.data.meshes.new("Circle iterated")
circle.to_mesh(me)
object_data_add(bpy.context, me)
me = bpy.data.meshes.new("Circle walked")
circle_walk.to_mesh(me)
object_data_add(bpy.context, me)
def iterate_circle(bm, start):
vert_count = len(bm.verts)
vert_offset = start.index
for i, j in enumerate(range(vert_count)):
index = (j + vert_offset) % vert_count
bm.verts[index].co.z += i / 10
def walk_circle(bm, start):
v = start
edges = []
i = 0
while v is not None:
for edge in v.link_edges:
if edge not in edges:
edges.append(edge)
v = edge.other_vert(v)
print(v)
# Do something to the verts
v.co.z += i / 10
i += 1
break
if v == start:
v = None
break
main()
with Bmesh, I use this function. Written with help of BA Community. I need to go back and check my sources for this script. It doesn’t look like something by brain would have written
def edge_loops_from_bmedges(bmesh, bm_edges):
"""
Edge loops defined by edges
Takes [mesh edge indices] and returns the edge loops
as lists of vertex indices.
[ [1, 6, 7, 2], ...]
closed loops have matching start and end values.
"""
line_polys = []
edges = bm_edges.copy() #so as not to mutate the input list
while edges:
current_edge = bmesh.edges[edges.pop()]
vert_e, vert_st = current_edge.verts[:]
vert_end, vert_start = vert_e.index, vert_st.index
line_poly = [vert_start, vert_end]
ok = True #just to get started
while ok:
ok = False
#for i, ed in enumerate(edges):
i = len(edges)
while i:
i -= 1
ed = bmesh.edges[edges[i]]
v_1, v_2 = ed.verts
v1, v2 = v_1.index, v_2.index
if v1 == vert_end:
line_poly.append(v2)
vert_end = line_poly[-1]
ok = 1
del edges[i]
# break
elif v2 == vert_end:
line_poly.append(v1)
vert_end = line_poly[-1]
ok = 1
del edges[i]
#break
elif v1 == vert_start:
line_poly.insert(0, v2)
vert_start = line_poly[0]
ok = 1
del edges[i]
# break
elif v2 == vert_start:
line_poly.insert(0, v1)
vert_start = line_poly[0]
ok = 1
del edges[i]
#break
line_polys.append(line_poly)
return line_polys
As it turns out, the vertices were already in the right order. It was a different problem in my code that was throwing me off. lol, I need to learn to proofread my code before posting. Thanks anyays.