Made BPyMesh's ngon a lot better- handels polylines that loop back on themselves, vert length edges and removes doubles (also slower :/ )

Lightwave importer uses this and also makes FGons from imported ngons.
This commit is contained in:
Campbell Barton
2006-06-30 15:41:20 +00:00
parent 6a5f637338
commit b0a3566409
2 changed files with 159 additions and 177 deletions

View File

@@ -571,13 +571,15 @@ def getUvPixelLoc(face, pxLoc, img_size = None, uvArea = None):
type_tuple= type( (0,) )
type_list= type( [] )
def ngon(from_data, indices):
def ngon(from_data, indices, PREF_FIX_LOOPS= True):
'''
takes a polyline of indices (fgon)
and returns a list of face indicie lists.
Designed to be used for importers that need indices for an fgon to create from existing verts.
from_data is either a mesh, or a list/tuple of vectors.
from_data: either a mesh, or a list/tuple of vectors.
indices: a list of indicies to use this list is the ordered closed polyline to fill, and can be a subset of the data given.
PREF_FIX_LOOPS: If this is enabled polylines that use loops to make ultiple polylines are delt with correctly.
'''
Mesh= Blender.Mesh
Window= Blender.Window
@@ -600,22 +602,128 @@ def ngon(from_data, indices):
if type(from_data) in (type_tuple, type_list):
# From a list/tuple of vectors
temp_mesh.verts.extend( [from_data[i] for i in indices] )
temp_mesh.edges.extend( [(temp_mesh.verts[i], temp_mesh.verts[i-1]) for i in xrange(len(temp_mesh.verts))] )
#temp_mesh.edges.extend( [(temp_mesh.verts[i], temp_mesh.verts[i-1]) for i in xrange(len(temp_mesh.verts))] )
edges= [(i, i-1) for i in xrange(len(temp_mesh.verts))]
else:
# From a mesh
temp_mesh.verts.extend( [from_data.verts[i].co for i in indices] )
temp_mesh.edges.extend( [(temp_mesh.verts[i], temp_mesh.verts[i-1]) for i in xrange(len(temp_mesh.verts))] )
#temp_mesh.edges.extend( [(temp_mesh.verts[i], temp_mesh.verts[i-1]) for i in xrange(len(temp_mesh.verts))] )
edges= [(i, i-1) for i in xrange(len(temp_mesh.verts))]
if edges:
edges[0]= (0,len(temp_mesh.verts)-1)
def rvec(co): return round(co.x, 6), round(co.y, 6), round(co.z, 6)
def mlen(co): return co[0]+co[1]+co[2] # manhatten length of a vector
if PREF_FIX_LOOPS:
edge_used_count= {}
rounded_verts= [rvec(v.co) for v in temp_mesh.verts] # rounded verts we can use as dict keys.
# We need to check if any edges are used twice location based.
for ed_idx, ed in enumerate(edges):
ed_v1= rounded_verts[ed[0]]
ed_v2= rounded_verts[ed[1]]
if ed_v1==ed_v2: # Same locations, remove the edge.
edges[ed_idx]= None
else:
if mlen(ed_v1) < mlen(ed_v2):
edkey= ed_v1, ed_v2
else:
edkey= ed_v2, ed_v1
try:
edge_user_list= edge_used_count[edkey]
edge_user_list.append(ed_idx)
# remove edges if there are doubles.
if len(edge_user_list) > 1:
for edidx in edge_user_list:\
edges[edidx]= None
except:
edge_used_count[edkey]= [ed_idx]
# Now remove double verts
vert_doubles= {}
for edidx, ed in enumerate(edges):
if ed != None:
ed_v1= rounded_verts[ed[0]]
ed_v2= rounded_verts[ed[1]]
if ed_v1==ed_v2:
edges[edidx]= None # will clear later, edge is zero length.
#print 'REMOVING DOUBLES'
else:
# Try and replace with an existing vert or add teh one we use.
try: edges[edidx]= vert_doubles[ed_v1], ed[1]
except:
vert_doubles[ed_v1]= ed[0]
#print 'REMOVING DOUBLES'
try: edges[edidx]= ed[0], vert_doubles[ed_v2]
except:
vert_doubles[ed_v2]= ed[1]
#print 'REMOVING DOUBLES'
edges= [ed for ed in edges if ed != None] # != None
# Done removing double edges!
# DONE DEALING WITH LOOP FIXING
temp_mesh.edges.extend(edges)
# Move verts to middle and normalize.
# For a good fill we need to normalize and scale the vert location.
xmax=ymax=zmax= -1<<30
xmin=ymin=zmin= 1<<30
for v in temp_mesh.verts:
co= v.co
x= co.x
y= co.y
z= co.z
if x<xmin: xmin=x
if y<ymin: ymin=y
if z<zmin: zmin=z
if x>xmax: xmax=x
if y>ymax: ymax=y
if z>zmax: zmax=z
# get the bounds on the largist axis
size= xmax-xmin
size= max(size, ymax-ymin)
size= max(size, zmax-zmin)
xmid= (xmin+xmax)/2
ymid= (ymin+ymax)/2
zmid= (zmin+zmax)/2
x=x/len(temp_mesh.verts)
y=y/len(temp_mesh.verts)
z=z/len(temp_mesh.verts)
for v in temp_mesh.verts:
co= v.co
co.x= (co.x-xmid)/size
co.y= (co.y-ymid)/size
co.z= (co.z-zmid)/size
# finished resizing the verts.
oldmode = Mesh.Mode()
Mesh.Mode(Mesh.SelectModes['VERTEX'])
temp_mesh.sel= 1 # Select all verst
temp_mesh.sel= 1 # Select all verst
# Must link to scene
scn= Scene.GetCurrent()
temp_ob= Object.New('Mesh')
temp_ob.link(temp_mesh)
scn.link(temp_ob)
temp_mesh.fill()
scn.unlink(temp_ob)
Mesh.Mode(oldmode)