def new_vert(fi): co = f_v_co[fi] a = angles[fi] if a > 180: vert_inset = 1 * inset_half else: vert_inset = inset_half * angleToLength( abs((180-a) / 2) ) # Calculate the inset direction co1 = f_v_co[fi-1] co2 = fi+1 # Wrap this index back to the start if co2 == len(f_v_co): co2 = 0 co2 = f_v_co[co2] co1 = co1 - co co2 = co2 - co co1.normalize() co2.normalize() d = co1+co2 # Done with inset direction d.length = vert_inset return co+d
def solidify(me, PREF_THICK, PREF_SKIN_SIDES=True, PREF_REM_ORIG=False, PREF_COLLAPSE_SIDES=False): # Main code function me_faces = me.faces faces_sel= [f for f in me_faces if f.sel] BPyMesh.meshCalcNormals(me) normals= [v.no for v in me.verts] vertFaces= [[] for i in xrange(len(me.verts))] for f in me_faces: no=f.no for v in f: vertFaces[v.index].append(no) # Scale the normals by the face angles from the vertex Normals. for i in xrange(len(me.verts)): length=0.0 if vertFaces[i]: for fno in vertFaces[i]: try: a= Ang(fno, normals[i]) except: a= 0 if a>=90: length+=1 elif a < SMALL_NUM: length+= 1 else: length+= angleToLength(a) length= length/len(vertFaces[i]) #print 'LENGTH %.6f' % length # normals[i]= (normals[i] * length) * PREF_THICK normals[i] *= length * PREF_THICK len_verts = len( me.verts ) len_faces = len( me_faces ) vert_mapping= [-1] * len(me.verts) verts= [] for f in faces_sel: for v in f: i= v.index if vert_mapping[i]==-1: vert_mapping[i]= len_verts + len(verts) verts.append(v.co + normals[i]) #verts= [v.co + normals[v.index] for v in me.verts] me.verts.extend( verts ) #faces= [tuple([ me.verts[v.index+len_verts] for v in reversed(f.v)]) for f in me_faces ] faces= [ tuple([vert_mapping[v.index] for v in reversed(f.v)]) for f in faces_sel ] me_faces.extend( faces ) # Old method before multi UVs """ has_uv = me.faceUV has_vcol = me.vertexColors for i, orig_f in enumerate(faces_sel): new_f= me_faces[len_faces + i] new_f.mat = orig_f.mat new_f.smooth = orig_f.smooth orig_f.sel=False new_f.sel= True new_f = me_faces[i+len_faces] if has_uv: new_f.uv = [c for c in reversed(orig_f.uv)] new_f.mode = orig_f.mode new_f.flag = orig_f.flag if orig_f.image: new_f.image = orig_f.image if has_vcol: new_f.col = [c for c in reversed(orig_f.col)] """ copy_facedata_multilayer(me, faces_sel, [me_faces[len_faces + i] for i in xrange(len(faces_sel))]) 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 edges = {} # So we can reference indicies that wrap back to the start. ROT_TRI_INDEX = 0,1,2,0 ROT_QUAD_INDEX = 0,1,2,3,0 for f in faces_sel: f_v= f.v for i, edgekey in enumerate(f.edge_keys): if edges.has_key(edgekey): edges[edgekey]= None else: if len(f_v) == 3: edges[edgekey] = f, f_v, i, ROT_TRI_INDEX[i+1] else: 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 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)) 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) """ 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)
def solidify(me, PREF_THICK, PREF_SKIN_SIDES=True, PREF_REM_ORIG=False, PREF_COLLAPSE_SIDES=False): # Main code function me_faces = me.faces faces_sel = [f for f in me_faces if f.sel] BPyMesh.meshCalcNormals(me) normals = [v.no for v in me.verts] vertFaces = [[] for i in xrange(len(me.verts))] for f in me_faces: no = f.no for v in f: vertFaces[v.index].append(no) # Scale the normals by the face angles from the vertex Normals. for i in xrange(len(me.verts)): length = 0.0 if vertFaces[i]: for fno in vertFaces[i]: try: a = Ang(fno, normals[i]) except: a = 0 if a >= 90: length += 1 elif a < SMALL_NUM: length += 1 else: length += angleToLength(a) length = length / len(vertFaces[i]) #print 'LENGTH %.6f' % length # normals[i]= (normals[i] * length) * PREF_THICK normals[i] *= length * PREF_THICK len_verts = len(me.verts) len_faces = len(me_faces) vert_mapping = [-1] * len(me.verts) verts = [] for f in faces_sel: for v in f: i = v.index if vert_mapping[i] == -1: vert_mapping[i] = len_verts + len(verts) verts.append(v.co + normals[i]) #verts= [v.co + normals[v.index] for v in me.verts] me.verts.extend(verts) #faces= [tuple([ me.verts[v.index+len_verts] for v in reversed(f.v)]) for f in me_faces ] faces = [ tuple([vert_mapping[v.index] for v in reversed(f.v)]) for f in faces_sel ] me_faces.extend(faces) # Old method before multi UVs """ has_uv = me.faceUV has_vcol = me.vertexColors for i, orig_f in enumerate(faces_sel): new_f= me_faces[len_faces + i] new_f.mat = orig_f.mat new_f.smooth = orig_f.smooth orig_f.sel=False new_f.sel= True new_f = me_faces[i+len_faces] if has_uv: new_f.uv = [c for c in reversed(orig_f.uv)] new_f.mode = orig_f.mode new_f.flag = orig_f.flag if orig_f.image: new_f.image = orig_f.image if has_vcol: new_f.col = [c for c in reversed(orig_f.col)] """ copy_facedata_multilayer( me, faces_sel, [me_faces[len_faces + i] for i in xrange(len(faces_sel))]) 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 edges = {} # So we can reference indicies that wrap back to the start. ROT_TRI_INDEX = 0, 1, 2, 0 ROT_QUAD_INDEX = 0, 1, 2, 3, 0 for f in faces_sel: f_v = f.v for i, edgekey in enumerate(f.edge_keys): if edges.has_key(edgekey): edges[edgekey] = None else: if len(f_v) == 3: edges[edgekey] = f, f_v, i, ROT_TRI_INDEX[i + 1] else: 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 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)) 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) """ 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)