mesh_wire.py

* Support for fgons (dont make wire on fgon edges)
* added new wire type (extra sharp)
* also fixed editnmesh problem

* mistake in previous commit log (mesh_solidifym meant mesh_wire)
This commit is contained in:
Campbell Barton 2007-04-09 01:43:33 +00:00
parent ec52983146
commit 55d0bf6b33
2 changed files with 120 additions and 76 deletions

@ -97,7 +97,7 @@ def copy_facedata_multilayer(me, from_faces, to_faces):
Ang= Mathutils.AngleBetweenVecs
SMALL_NUM=0.00001
def solidify(me, PREF_THICK, PREF_SKIN_SIDES=True, PREF_REM_ORIG=False):
def solidify(me, PREF_THICK, PREF_SKIN_SIDES=True, PREF_REM_ORIG=False, PREF_COLLAPSE_SIDES=False):
# Main code function
me_faces = me.faces
@ -178,7 +178,7 @@ def solidify(me, PREF_THICK, PREF_SKIN_SIDES=True, PREF_REM_ORIG=False):
"""
copy_facedata_multilayer(me, faces_sel, [me_faces[len_faces + i] for i in xrange(len(faces_sel))])
if PREF_SKIN_SIDES:
if PREF_SKIN_SIDES or PREF_COLLAPSE_SIDES:
skin_side_faces= []
skin_side_faces_orig= []
# Get edges of faces that only have 1 user - so we can make walls
@ -200,77 +200,97 @@ def solidify(me, PREF_THICK, PREF_SKIN_SIDES=True, PREF_REM_ORIG=False):
edges[edgekey] = f, f_v, i, ROT_QUAD_INDEX[i+1]
del ROT_QUAD_INDEX, ROT_TRI_INDEX
# So we can remove doubles with edges only.
if PREF_COLLAPSE_SIDES:
me.sel = False
# Edges are done. extrude the single user edges.
for edge_face_data in edges.itervalues():
if edge_face_data: # != None
f, f_v, i1, i2 = edge_face_data
v1i,v2i= f_v[i1].index, f_v[i2].index
# Now make a new Face
# skin_side_faces.append( (v1i, v2i, vert_mapping[v2i], vert_mapping[v1i]) )
skin_side_faces.append( (v2i, v1i, vert_mapping[v1i], vert_mapping[v2i]) )
skin_side_faces_orig.append((f, len(me_faces) + len(skin_side_faces_orig), i1, i2))
if PREF_COLLAPSE_SIDES:
# Collapse
cv1 = me.verts[v1i]
cv2 = me.verts[vert_mapping[v1i]]
cv3 = me.verts[v2i]
cv4 = me.verts[vert_mapping[v2i]]
cv1.co = cv2.co = (cv1.co+cv2.co)/2
cv3.co = cv4.co = (cv3.co+cv4.co)/2
cv1.sel=cv2.sel=cv3.sel=cv4.sel=True
else:
# Now make a new Face
# skin_side_faces.append( (v1i, v2i, vert_mapping[v2i], vert_mapping[v1i]) )
skin_side_faces.append( (v2i, v1i, vert_mapping[v1i], vert_mapping[v2i]) )
skin_side_faces_orig.append((f, len(me_faces) + len(skin_side_faces_orig), i1, i2))
me_faces.extend(skin_side_faces)
# Now assign properties.
"""
# Before MultiUVs
for i, origfData in enumerate(skin_side_faces_orig):
orig_f, new_f_idx, i1, i2 = origfData
new_f= me_faces[new_f_idx]
if PREF_COLLAPSE_SIDES:
me.remDoubles(0.0001)
else:
me_faces.extend(skin_side_faces)
# Now assign properties.
"""
# Before MultiUVs
for i, origfData in enumerate(skin_side_faces_orig):
orig_f, new_f_idx, i1, i2 = origfData
new_f= me_faces[new_f_idx]
new_f.mat= orig_f.mat
new_f.smooth= orig_f.smooth
if has_uv:
new_f.mode= orig_f.mode
new_f.flag= orig_f.flag
if orig_f.image:
new_f.image= orig_f.image
uv1= orig_f.uv[i1]
uv2= orig_f.uv[i2]
new_f.uv= (uv1, uv2, uv2, uv1)
if has_vcol:
col1= orig_f.col[i1]
col2= orig_f.col[i2]
new_f.col= (col1, col2, col2, col1)
"""
new_f.mat= orig_f.mat
new_f.smooth= orig_f.smooth
if has_uv:
new_f.mode= orig_f.mode
new_f.flag= orig_f.flag
if orig_f.image:
for i, origfData in enumerate(skin_side_faces_orig):
orig_f, new_f_idx, i2, i1 = origfData
new_f= me_faces[new_f_idx]
new_f.mat= orig_f.mat
new_f.smooth= orig_f.smooth
for uvlayer in me.getUVLayerNames():
me.activeUVLayer = uvlayer
for i, origfData in enumerate(skin_side_faces_orig):
orig_f, new_f_idx, i2, i1 = origfData
new_f= me_faces[new_f_idx]
new_f.mode= orig_f.mode
new_f.flag= orig_f.flag
new_f.image= orig_f.image
uv1= orig_f.uv[i1]
uv2= orig_f.uv[i2]
new_f.uv= (uv1, uv2, uv2, uv1)
uv1= orig_f.uv[i1]
uv2= orig_f.uv[i2]
new_f.uv= (uv1, uv2, uv2, uv1)
if has_vcol:
col1= orig_f.col[i1]
col2= orig_f.col[i2]
new_f.col= (col1, col2, col2, col1)
"""
for collayer in me.getColorLayerNames():
me.activeColorLayer = collayer
for i, origfData in enumerate(skin_side_faces_orig):
orig_f, new_f_idx, i2, i1 = origfData
new_f= me_faces[new_f_idx]
col1= orig_f.col[i1]
col2= orig_f.col[i2]
new_f.col= (col1, col2, col2, col1)
for i, origfData in enumerate(skin_side_faces_orig):
orig_f, new_f_idx, i2, i1 = origfData
new_f= me_faces[new_f_idx]
new_f.mat= orig_f.mat
new_f.smooth= orig_f.smooth
for uvlayer in me.getUVLayerNames():
me.activeUVLayer = uvlayer
for i, origfData in enumerate(skin_side_faces_orig):
orig_f, new_f_idx, i2, i1 = origfData
new_f= me_faces[new_f_idx]
new_f.mode= orig_f.mode
new_f.flag= orig_f.flag
new_f.image= orig_f.image
uv1= orig_f.uv[i1]
uv2= orig_f.uv[i2]
new_f.uv= (uv1, uv2, uv2, uv1)
for collayer in me.getColorLayerNames():
me.activeColorLayer = collayer
for i, origfData in enumerate(skin_side_faces_orig):
orig_f, new_f_idx, i2, i1 = origfData
new_f= me_faces[new_f_idx]
col1= orig_f.col[i1]
col2= orig_f.col[i2]
new_f.col= (col1, col2, col2, col1)
if PREF_REM_ORIG:
me_faces.delete(0, faces_sel)
@ -294,11 +314,13 @@ def main():
# Create the variables.
PREF_THICK = Draw.Create(-0.1)
PREF_SKIN_SIDES= Draw.Create(1)
PREF_COLLAPSE_SIDES= Draw.Create(0)
PREF_REM_ORIG= Draw.Create(0)
pup_block = [\
('Thick:', PREF_THICK, -10, 10, 'Skin thickness in mesh space.'),\
('Skin Sides', PREF_SKIN_SIDES, 'Skin between the original and new faces.'),\
('Collapse Sides', PREF_COLLAPSE_SIDES, 'Skin between the original and new faces.'),\
('Remove Original', PREF_REM_ORIG, 'Remove the selected faces after skinning.'),\
]
@ -311,7 +333,7 @@ def main():
Window.WaitCursor(1)
me = ob.getData(mesh=1)
solidify(me, PREF_THICK.val, PREF_SKIN_SIDES.val, PREF_REM_ORIG.val)
solidify(me, PREF_THICK.val, PREF_SKIN_SIDES.val, PREF_REM_ORIG.val, PREF_COLLAPSE_SIDES.val)
Window.WaitCursor(0)

@ -47,7 +47,10 @@ import BPyMessages
import bpy
def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_DOUBLE_STRIPS):
def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_SHARP, PREF_XSHARP):
if not PREF_SHARP and PREF_XSHARP:
PREF_XSHARP = False
# This function runs out of editmode with a mesh
# error cases are alredy checked for
@ -62,7 +65,13 @@ def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_DOUBLE_ST
ob.sel = True
sce.objects.active = ob
# Modify the object
# Modify the object, should be a set
FGON= Mesh.EdgeFlags.FGON
edges_fgon = dict([(ed.key,None) for ed in me.edges if ed.flag & FGON])
# edges_fgon.fromkeys([ed.key for ed in me.edges if ed.flag & FGON])
del FGON
# each face needs its own verts
@ -72,7 +81,7 @@ def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_DOUBLE_ST
if len(f) == 3:
new_vert_count -= 1
if PREF_DOUBLE_STRIPS == 0:
if PREF_SHARP == 0:
new_faces_edge= {}
def add_edge(i1,i2, ni1, ni2):
@ -135,10 +144,20 @@ def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_DOUBLE_ST
]
if PREF_DOUBLE_STRIPS == 1:
new_faces.extend(faces)
if PREF_SHARP == 1:
if not edges_fgon:
new_faces.extend(faces)
else:
for nf in faces:
i1,i2 = nf[0], nf[1]
if i1>i2: i1,i2 = i2,i1
if edges_fgon and (i1,i2) not in edges_fgon:
new_faces.append(nf)
elif PREF_DOUBLE_STRIPS == 0:
elif PREF_SHARP == 0:
for nf in faces:
add_edge(*nf)
@ -146,7 +165,7 @@ def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_DOUBLE_ST
me.verts.extend(new_verts)
if PREF_DOUBLE_STRIPS == 0:
if PREF_SHARP == 0:
def add_tri_flipped(i1,i2,i3):
if AngleBetweenVecs(me.verts[i1].no, TriangleNormal(me.verts[i1].co, me.verts[i2].co, me.verts[i3].co)) < 90:
return i3,i2,i1
@ -162,7 +181,8 @@ def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_DOUBLE_ST
if len(nf) == 2:
# Add the main face
new_faces.append((nf[0][0], nf[0][1], nf[1][0], nf[1][1]))
if edges_fgon and (i1,i2) not in edges_fgon:
new_faces.append((nf[0][0], nf[0][1], nf[1][0], nf[1][1]))
if nf[0][2]: key1 = nf[0][1],nf[0][0]
@ -174,7 +194,6 @@ def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_DOUBLE_ST
###new_faces.append((i2, key1[0], key2[0])) # NO FLIPPING, WORKS THOUGH
###new_faces.append((i1, key1[1], key2[1]))
new_faces.append(add_tri_flipped(i2, key1[0], key2[0]))
new_faces.append(add_tri_flipped(i1, key1[1], key2[1]))
@ -207,7 +226,7 @@ def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_DOUBLE_ST
# External function, solidify
me.sel = True
if PREF_SOLID:
mesh_solidify.solidify(me, -inset_half*2)
mesh_solidify.solidify(me, -inset_half*2, True, False, PREF_XSHARP)
def main():
@ -226,12 +245,14 @@ def main():
# Create the variables.
PREF_THICK = Blender.Draw.Create(0.005)
PREF_SOLID = Blender.Draw.Create(1)
PREF_DOUBLE_STRIPS = Blender.Draw.Create(1)
PREF_SHARP = Blender.Draw.Create(1)
PREF_XSHARP = Blender.Draw.Create(0)
pup_block = [\
('Thick:', PREF_THICK, 0.0001, 2.0, 'Skin thickness in mesh space.'),\
('Solid Wire', PREF_SOLID, 'If Disabled, will use 6 sided wire segments'),\
('Double Strips', PREF_DOUBLE_STRIPS, 'Use 2 strips for each wire segment before making solid'),\
('Sharp Wire', PREF_SHARP, 'Use the original mesh topology for more accurate sharp wire.'),\
('Extra Sharp', PREF_XSHARP, 'Use less geometry to create a sharper looking wire'),\
]
if not Blender.Draw.PupBlock('Solid Wireframe', pup_block):
@ -241,13 +262,14 @@ def main():
# editmode if its enabled, we cant make
# changes to the mesh data while in editmode.
is_editmode = Window.EditMode()
Window.EditMode(0)
Window.WaitCursor(1)
me = ob_act.getData(mesh=1) # old NMesh api is default
t = sys.time()
# Run the mesh editing function
solid_wire(ob_act, me, sce, PREF_THICK.val, PREF_SOLID.val, PREF_DOUBLE_STRIPS.val)
solid_wire(ob_act, me, sce, PREF_THICK.val, PREF_SOLID.val, PREF_SHARP.val, PREF_XSHARP.val)
# Timing the script is a good way to be aware on any speed hits when scripting
print 'Solid Wireframe finished in %.2f seconds' % (sys.time()-t)