def island_check(bm): selFaces = bmesh_extras.get_selected_faces(bm) if len(selFaces): checkFaces = bmesh_extras.get_selected_faces(bm) biggestLen = False biggestCon = False # For each face check how many are connected to it for f in selFaces: if len(checkFaces) and f in checkFaces: conFaces, checkFaces = get_connected([], checkFaces, f) cnt = len(conFaces) if cnt > biggestLen or biggestLen is False: biggestLen = cnt biggestCon = conFaces # Deslect all selected faces that arent part of the biggest island. if not biggestLen is False: for f in bm.faces: if f.select and not f in biggestCon: f.select_set(False) return bm
def inner(bm, invert=False): selFaces = bmesh_extras.get_selected_faces(bm) # no need to continue if there are no selected faces if len(selFaces): outerFaces = [] outerVerts = [] while len(outerFaces) < len(selFaces): # Deselect the outer faces if there are any if len(outerFaces): for f in outerFaces: f.select_set(False) # Reset the list outerFaces = [] outerVerts = [] # Select the faces connected to unselected faces for f1 in selFaces: found = False for v in f1.verts: # If we know this vert is on the outside... no need to loop through the linked faces if v.index in outerVerts: outerFaces.append(f1) break # Loop through the connected faces to see if they're unselected for f2 in v.link_faces: if not f2.select: outerVerts.append(v.index) outerFaces.append(f1) found = True break if found: break # Invert the selection! if invert: for f in selFaces: if f.select: f.select_set(False) else: f.select_set(True) return bm
def outer(bm, invert=False): #print('x outer start') selFaces = bmesh_extras.get_selected_faces(bm) selLen = len(selFaces) # no use continueing if there's no selection if not selLen: return bm outerFaces = [] outerVerts = [] # Find faces connected to unselected faces for f1 in selFaces: out = False for v in f1.verts: # No need to loop through connected faces if this vert is on the outside if v.index in outerVerts: outerFaces.append(f1) break # Loop through the faces connected to this vert for f2 in v.link_faces: if not f2.select: outerFaces.append(f1) outerVerts.append(v.index) out = True break if out: break # Unselect those that don't need to be kept if len(outerFaces) < selLen: for f in selFaces: if invert and f in outerFaces: f.select_set(False) elif not invert and not f in outerFaces: f.select_set(False) #print('y outer end') return bm
def cast(bme=None, corners=0, falloff_scale=1.0, falloff_shape='STR',corner_group=None,redraw=False): if not bme: bm = bmesh_extras.get_bmesh() else: bm = bme print(corners, falloff_scale, falloff_shape) # Get a heap of lists to work with later! selFaces = bmesh_extras.get_selected_faces(bm) selVerts = bmesh_extras.get_selected_verts(bm) outVerts = bmesh_extras.get_outer_verts(selFaces) outEdges = bmesh_extras.get_outer_edges(selFaces) cent = bmesh_extras.get_vert_center(selVerts ) normal = bmesh_extras.get_normal(selFaces) inVerts = [] if len(outVerts): # Let's quickly make a list of inner verts for v in selVerts: if not v in outVerts: inVerts.append(v) # make a quaternion and a matrix representing this "plane" quat = normal.to_track_quat('-Z', 'Y') mat = quat.to_matrix() # Put all the verts in the plane... # And.. find out for each vert how far it is along the normal # Ang get the average distance from the center point midDist = 0.0 for v in selVerts: relPos = (v.co - cent) relDot = normal.dot(relPos) v.co += (normal * (-relDot)) # If this is an outerVert... then we keep track of it's distance from the center if v in outVerts: midDist += relPos.length # The medium distance from the center point midDist /= len(outVerts) # now lets put them all the right distance from the center top = False topVert = False for i,v in enumerate(outVerts): relPos = v.co - cent relPos = relPos.normalized() * midDist v.co = relPos + cent # Find the top vert for nice alignment of the shape (start the steploop here) if top is False or v.co[2] > top: top = v.co[2] topVert = i # As a final step... we want them to be rotated neatly around the center... step = math.radians(360) / (len(outEdges)) # Now that we found the top vert we can start looping through to put them in the right position loopVerts = [outVerts[topVert]] outEdges, loopVerts = loop_step(outVerts[topVert],loopVerts,step,outEdges,cent,False) # Set corner group weight to 0.0 because the shape is a circle (will be reset to 1.0 later for the actual corners) if corner_group: bm, group_index = add_to_group(bme=bm,verts=outVerts, newGroup=False, groupName=corner_group, weight=0.0) if corners: # Initiate a list of all corner verts so we can set the weight accordingly later (best done in one move) cornerVerts = [] c = round((360.0 / corners),2) a = (180.0 - c) * 0.5 stepLen = math.ceil(len(outVerts) / corners) #print('stepLen', stepLen) aLine = False currentX = 0.0 vec = falloff_scale factor = 1.0 curve = falloff_curve.curve(falloff_shape, 'mult') loopCnt = len(loopVerts) cornerCnt = math.floor(loopCnt / corners) #print('\n',loopCnt,cornerCnt) for i, v in enumerate(loopVerts): #if(i>9): # return stepPos = i % stepLen #print(i,'stepPos',stepPos) # Get a normalized version of the current relative position line = mathutils.Vector(v.co - cent).normalized() # Get the starting line as a reference (is also a corner if not aLine: aLine = line currentX = 0.0 factor = 1.0 #if corner_group: corner_group.add([v.index], 1.0, 'REPLACE') if corner_group: cornerVerts.append(v) else: # Find the angle from the current starting line cAng = round(math.degrees(aLine.angle(line)),2) #print('ang',cAng,c,(cAng >= c)) # If the angle is bigger than a step, we make this the new start if cAng >= c: #print('found corner') #if corner_group: corner_group.add([v.index], 1.0, 'REPLACE') if corner_group: cornerVerts.append(v) # Make sure the angle is correct! line = misc.rotate_vector_to_vector(line, aLine, math.radians(c)) v.co = (line * midDist) + cent aLine = line currentX = 0.0 factor = 1.0 # These should all be midpoints along the line! # make sure we don't do the last one... because it's the first one! else: # Remove non corner items from the corner group #if corner_group: corner_group.remove([v.index]) # Only if we have to scale and the line isn't straight! if falloff_scale != 1.0 and falloff_shape != 'STR': # Find out how far we are from the start as a factor (fraction of one?) angFac = cAng / c newX = angFac # Create a nice curve object to represent the falloff curve.update(1.0, 0.0, vec, currentX, newX) fac = abs(curve.currentVal) factor *= fac currentX = newX # Find the corner of the new triangle b = 180 - (a+cAng) # find the distance from the midpoint A = math.sin(math.radians(a)) / (math.sin(math.radians(b))/midDist) bLine = line * A bLine *= factor v.co = bLine + cent if redraw: scene_update.go(False, 'RED') if len(cornerVerts): bm, group_index = add_to_group(bme=bm,verts=cornerVerts, newGroup=False, groupName=corner_group, weight=1.0) # I want to make sure these verts are inside the loop! # So we move all verts halfway towards the center before smoothing (neat results in entoforms) for v in inVerts: relPos = cent - v.co v.co += (relPos * 0.5) #for i in range(100): # SMOOTH THE VERTS MAN!!! bmesh_extras.smooth_verts(verts=inVerts,loops=10) #bmesh.ops.smooth_vert(bm, verts=inVerts,use_axis_x=True, use_axis_y=True, use_axis_z=True) if not bme: bmesh_extras.put_bmesh(bm) else: return bm