Actually, here try this one instead. I built a while loop (note: manually setting the allowed number of iterations because it WILL get stuck in an infinite loop otherwise). Currently I haven’t implemented any safety checks for things like mesh boundaries or non-quad faces.
My test object is a default cube, subdivided 4 times, with the normals flipped on a random selection of faces so I don’t have to worry about running into things like mesh borders while I’m testing.
Also made 1 modification in BM_edge_other_loop
at the part with if l_other.vert == loop.vert:
because passing seemed to break things in some cases and getting the link_loop_prev seemed to fix that. Sorry for the absurd number of print statements. Just trying to step my way through what’s happening.
Copy/paste to script editor, select an edge, and hit run.
import bpy
import bmesh
def BM_edge_other_loop(edge, loop):
### Pseudo-python. (there isn't an "edge.loop" in the bmesh python API so we'd need a bit more work but I'm skipping asserts for now)
# if edge.loop and edge.loop.link_loop_radial_next != edge.loop:
# if BM_vert_in_edge(edge, loop.vert) ### I can't actually find where this is defined in the source code.. just several places where it's used.
if loop.edge == edge:
l_other = loop
print("Loop's edge is input edge. Setting other loop as the starting loop.")
else:
l_other = loop.link_loop_prev
print("Setting other loop as previous loop")
print("l_other first value:", l_other)
l_other = l_other.link_loop_radial_next
print("l_other radial value:", l_other)
# if l_other.edge == edge:
# print("We would assert here.") # Skipping asserts for now.
if l_other.vert == loop.vert:
print("Loops have the same vert. Setting other loop as link_loop_prev instead of passing.")
l_other = l_other.link_loop_prev # Modified this one spot to get link_loop_prev instead of pass because that seemed to fix at least 1 broken case
# pass
elif l_other.link_loop_next.vert == loop.vert:
l_other = l_other.link_loop_next
print("Setting other loop as link_loop_next")
else:
print("Nope!") # Skipping asserts for now. We'll just print some nonsense instead.
return None
print("l_other final value:", l_other)
print("l_other's edge:", l_other.edge.index)
return l_other
def BM_vert_step_fan_loop(loop, e_step):
print("Starting loop's edge:", loop.edge.index)
print("e_step is:", e_step.index)
e_prev = e_step
if loop.edge == e_prev:
e_next = loop.link_loop_prev.edge
print("Matched on first If")
elif loop.link_loop_prev.edge == e_prev:
e_next = loop.edge
print("Matched on Elif")
else:
print("No match")
return None
print("e_next is:", e_next.index)
if e_next.is_manifold:
return BM_edge_other_loop(e_next, loop)
else:
print("Nonmanifold edge.")
return None
#####################
print("---BEGIN---")
bm = bmesh.from_edit_mesh(bpy.context.object.data)
active_edge = bm.select_history.active
e_step = active_edge
loop = e_step.link_loops[0].link_loop_next
new_sel = []
i = 0
while i <= 63:
print("---")
new_loop = BM_vert_step_fan_loop(loop, e_step)
e_step = new_loop.edge
new_sel.append(e_step.index)
cur_vert = loop.vert
oth_vert = loop.link_loop_radial_next.vert
print("cur_vert:", cur_vert.index)
print("oth_vert:", oth_vert.index)
if cur_vert != oth_vert:
print("AAAAAAAAAAAAAAAAAAAAAAAAAAAA")
loop = new_loop.link_loop_next
else:
print("CCCCCCCCCCCCCCCCCCCCCCCCCCCC")
loop = new_loop.link_loop_radial_next
bm.select_history.add(e_step)
i += 1
print("---END---")
for i in new_sel:
bm.edges[i].select = True
bm.select_flush_mode()
bpy.context.object.data.update()