do a nice retopo with Bmesh

i got a problem with long lines when using retopo
and this creates distortions after retopo

so is there a way to subdivide long lines or edges
without adding more edges
just subdivide long edges with Bmesh

i can see

bmesh.ops.subdivide_edges(
bmesh.ops.split_edges

thanks

how would you subdive an edge without creating two from it? Geometrically impossible…

I did a test with subdivide and it add a vert which seems to be disconnected form faces!
not certain how this works now !

but for retopo simply needs to add verts to retopo to get a smoother faces without too much distortion

problem comes from the fact that some edges length are way tool long
so I think it would be possible to subdivide 1 or 2 to get
edge length average as the other one

can this be done when going into edit mode then find the long edges and subdivide may be

thanks

Maybe something like this

import bpy
import bmesh

me = bpy.context.object.data
bm = bmesh.from_edit_mesh(me)

edge_lengths = [e.calc_length() for e in bm.edges]
avg_edge_length = sum(edge_lengths) / len(edge_lengths)

for length, e in zip(edge_lengths, bm.edges):
    num_splits = round(length / avg_edge_length) + 1
    for fac in range(num_splits, 1, -1):
        bmesh.utils.edge_split(e, e.verts[0], 1/fac)
        
bmesh.update_edit_mesh(me)

I modified it to do only long edges

I did a retopo test and seems to work
and even if faces are not subdivided it retopo much better
no more faces or long edges distortion and shading seems to work better too

thanks

A quick question - is this iterator safe? As edges are split, do they disappear and new ones appear thereby changing the list we are iterating on? I am not saying it is or it isn’t, I really want to know if it is because I’d like to do something similar, namely build a knife tool programmatically. Thanks!

DLR

it appears to not be safe. as far as I can tell, when an edge is split, one half replaces the original in the list, and the other half is appended to the list. for this application, it should work fine since the new edges should all be smaller than the desired maximum length.

DLR

I believe that’s right, although I should test what goes one exactly…

You can avoid double processing etc. by looking at the returned dicts, all bmesh operations should give you the required sets of geometry elements, see e.g.

http://www.blender.org/documentation/blender_python_api_2_69_10/bmesh.utils.html#bmesh.utils.edge_split

http://www.blender.org/documentation/blender_python_api_2_69_10/bmesh.ops.html#bmesh.ops.convex_hull

You might need to use some set theory (union, difference, intersection) to figure out what you have to in some cases.

My workaround was to use the tag member of the edges to avoid double processing. I initialized all the edge tags to False. Then as I processed edges that were split, I tagged the returned pair of edges for each edge_split() at True. Then I simply had an if statement preventing processing of edges tagged as True. Seemed to work for me.