def deselectGrouped(self, baseGroups): # Get the faces (and go into object mode) faces = mesh_extras.get_selected_faces() if len(faces): # First lets make sure the faces are in the current base groups for g in baseGroups: # Check all selected faces for f in faces: if f.select: inGroup = True # See all the verts (all should be in the group!) for v in f.vertices: found = False vert = self.ob.data.vertices[v] vertGroups = vert.groups for vg in vert.groups: if vg.group == g.index: found = True if not found: inGroup = False if not inGroup: f.select = False faces = mesh_extras.get_selected_faces() if len(faces): for g in self.newGroups: if not g in baseGroups: # Check all selected faces for f in faces: if f.select: inGroup = True # See all the verts (all should be in the group!) for v in f.vertices: found = False vert = self.ob.data.vertices[v] vertGroups = vert.groups for vg in vert.groups: if vg.group == g.index: found = True if not found: inGroup = False if inGroup: f.select = False
def applyGrowthCrease(self, a): # LETS LOOK AT CREASES! vec = a['crease'] # Now we want to find out how many steps we made steps = self.ob['growsteps'] if steps: # Loop through all the steps for i in range(int(steps)): select_faces.outermost(True) # Find all the selected vertices selFaces = mesh_extras.get_selected_faces() selVerts = [] for f in selFaces: selVerts.extend(f.vertices) # Loop through all edges for e in self.me.edges: eVerts = e.vertices # If an edge has only 1 selected vert... it's "long" and on the outside of the selection intersection = [v for v in e.vertices if v in selVerts] if len(intersection) == 1 and e.crease < 1.0: e.crease = vec
def deselectUnGrouped(self): # Get the faces (and go into object mode) faces = mesh_extras.get_selected_faces() if len(faces): for f in faces: if f.select: inGroup = True # See all the verts (all should be in the group!) for v in f.vertices: found = False vert = self.ob.data.vertices[v] vertGroups = vert.groups for g in vert.groups: if g.weight: found = True if not found: inGroup = False if not inGroup: f.select = False
def limit(limit=1, key=''): from macouno import liberty lib = liberty.liberty('string', key) nuFaces = lib.makeDict(mesh_extras.get_selected_faces()) nuLen = len(nuFaces) while nuLen > limit: deFace = lib.Choose('select',nuFaces) deFace.select = False nuFaces = lib.makeDict(mesh_extras.get_selected_faces()) nuLen = len(nuFaces)
def limit(limit=1, key=''): from macouno import liberty lib = liberty.liberty('string', key) nuFaces = lib.makeDict(mesh_extras.get_selected_faces()) nuLen = len(nuFaces) while nuLen > limit: deFace = lib.Choose('select', nuFaces) deFace.select = False nuFaces = lib.makeDict(mesh_extras.get_selected_faces()) nuLen = len(nuFaces)
def addToNewGroups(self, string, newGroups, growmatrices=[]): selection = string['selection'] self.doubleCheckSelection(selection) faces = mesh_extras.get_selected_faces() formmatrix = mathutils.Matrix() growmatrices = [] if len(faces): verts = [] inds = [] for f in faces: for v in f.vertices: if not v in inds: inds.append(v) verts.append(self.me.vertices[v]) # NOW WE GO MAKE THE GROUPS if len(verts): weights = self.makeWeights(verts) formmatrix = mesh_extras.get_selection_matrix(faces) # If we do this per area, we want the entire area to be part of one group if selection['area'] == 'area': growmatrices.append(formmatrix) newGroup = self.ob.vertex_groups.new(string['name']+'.'+selection['type']) newGroups.append(newGroup) self.newGroups.append(newGroup) for v in verts: newGroup.add([v.index], 1.0, 'REPLACE') # If we have it per face, we need sepparate weights and groups elif selection['area'] == 'faces': if len(faces): for i, f in enumerate(faces): growmatrices.append(mesh_extras.get_selection_matrix([f])) newGroup = self.ob.vertex_groups.new(string['name']+'.'+selection['type']+'.'+misc.nr4(i)) newGroups.append(newGroup) self.newGroups.append(newGroup) vertList = f.vertices for i,v in enumerate(verts): ind = v.index if ind in vertList: newGroup.add([v.index], weights[i], 'REPLACE') return newGroups, formmatrix, growmatrices
def checkForIslands(self, vector): faces = mesh_extras.get_selected_faces() # Find the face furthest along the vector max = 0.0 closestFace = 0 closestVerts = 0 for i,f in enumerate(faces): dist = vector.dot(f.center) if dist > max or not i: max = dist closestFace = f closestVerts = f.vertices # Find the faces connected to this one! connectedFaces = [closestFace] connectedVerts = list(closestVerts) foundNew = True # As long as we can find connected faces we continue while foundNew: foundNew = False for f in faces: addThis = False # If we haven't done this one yet if not f in connectedFaces: intersection = [v for v in f.vertices if v in connectedVerts] if len(intersection): addThis = True if addThis: foundNew = True connectedFaces.append(f) connectedVerts.extend(f.vertices) # Deselect disconnected faces for f in faces: if not f in connectedFaces: f.select = False
def __init__(self, context, invert): me = context.active_object.data bpy.ops.object.mode_set(mode='OBJECT') oList = [f.index for f in mesh_extras.get_selected_faces()] oLen = len(oList) # If no faces are selected, we just return if not oLen: bpy.ops.object.mode_set(mode='EDIT') return # If all faces are selected, select nothing and return if oLen == len(me.faces): bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_all(action='DESELECT') return fList = False # If we invert, we just want to select less once, and then we're done if invert: bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_less() bpy.ops.object.mode_set(mode='OBJECT') fList = [f.index for f in mesh_extras.get_selected_faces()] # Only if there's now less selected do we change anything if len(fList) < oLen: for f in me.faces: fIn = f.index if fIn in oList and not fIn in fList: f.select = True else: f.select = False bpy.ops.object.mode_set(mode='EDIT') return # So now we can start and see what's up while mesh_extras.contains_selected_item(me.faces): if fList is False: fList = oList else: fList = [f.index for f in mesh_extras.get_selected_faces()] bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_less() bpy.ops.object.mode_set(mode='OBJECT') if len(fList) < oLen: for f in me.faces: if f.index in fList: f.select = True else: f.select = False bpy.ops.object.mode_set(mode='EDIT')
def makeAffectedGroups(self, string, baseGroups): selection = string['selection'] newGroups = [] formmatrix = mathutils.Matrix() growmatrices = [] # Deselect all faces to start clean! select_faces.none() # Select everything in the base groups for g in baseGroups: select_faces.in_group(g,True) #print('in_group',len(mesh_extras.get_selected_faces())) # If nothing is selected there's nothing to do if mesh_extras.contains_selected_item(self.me.faces): # Select the faces at the tip in a certain direction if selection['type'] == 'joint' or selection['type'] == 'tip': select_faces.innermost() if mesh_extras.contains_selected_item(self.me.faces): if selection['type'] == 'joint': select_faces.connected(True) selCnt = len(mesh_extras.get_selected_faces()) nuCnt = selCnt div = selection['divergence'] # If the nr of faces selected isn't diminished... we select less! while selCnt and selCnt == nuCnt and div > 0.1: select_faces.by_direction(selection['vector'],div) div = div * 0.75 selFaces = mesh_extras.get_selected_faces() nuCnt = len(selFaces) # Check for opposing normals.. .cause they should not be there! for f1 in selFaces: if f1.select: f1No = f1.normal for f2 in selFaces: if f2.select and not f1 is f2: f2No = f2.normal ang = f2No.angle(f1No) if ang > math.radians(120): f1.select = False break selFaces = mesh_extras.get_selected_faces() nuCnt = len(selFaces) if nuCnt == selCnt: select_faces.none() # If we have selected faces... we can add em to a new group newGroups, formmatrix, growmatrices = self.addToNewGroups(string, newGroups, growmatrices) # Select by pi (fake random) elif selection['type'] == 'liberal': select_faces.liberal(self.dnaString) # If we have selected faces... we can add em to a new group newGroups, formmatrix, growmatrices = self.addToNewGroups(string, newGroups, growmatrices) # Select all loops in the group elif selection['type'] == 'loops': select_faces.connected() self.deselectUnGrouped() step = 0 # As long as something is selected, we can continue while mesh_extras.contains_selected_item(self.ob.data.faces): select_faces.connected() self.deselectGrouped(baseGroups) # Skip selection just in case if not step % selection['frequency']: # If we have selected faces... we can add em to a new group newGroups, formmatrix, grw = self.addToNewGroups(string, newGroups, growmatrices) growmatrices.extend(grw) step += 1 print(step) # Select by direction elif selection['type'] == 'direction': select_faces.by_direction(selection['vector'],selection['divergence']) newGroups, formmatrix, growmatrices = self.addToNewGroups(string, newGroups, growmatrices) # All! else: newGroups, formmatrix, growmatrices = self.addToNewGroups(string, newGroups, growmatrices) return newGroups, formmatrix, growmatrices
def __init__(self, context, translation, rotation, rotation_falloff, scale, scale_falloff, retain, steps, debug): self.startTime = time.time() self.markTime = self.startTime self.debug = debug self.context = context self.ob = context.active_object self.selectNr = len(mesh_extras.get_selected_faces()) if not self.selectNr: print('Grow error no faces selected') return if steps: self.ob['growsteps'] = 0 self.factor = 0.0 self.iteration = 0 self.reachedGoal = False self.translated = 0.0 self.currentX = 0.0 self.averagelength = 0.0 # Go into object mode for the initial stages bpy.ops.object.mode_set(mode='OBJECT') self.averageLength = mesh_extras.get_average_outer_edge_length() translation *= self.averageLength # Now this is an added bit only for use with entoform.py # This matrix may already be set by a previous grow function running making this shape (just being consistent) try: self.transformMatrix = mathutils.Matrix( (self.ob['growmatrix'][0], self.ob['growmatrix'][1], self.ob['growmatrix'][2])) except: self.transformMatrix = mesh_extras.get_selection_matrix() # This matrix is just there to check whether the "directions" are correct try: self.checkMatrix = mathutils.Matrix( (self.ob['formmatrix'][0], self.ob['formmatrix'][1], self.ob['formmatrix'][2])) print('GOT checkmatrix') except: self.checkMatrix = False # Make the actions actions = [] actions.append({'type': 'extrude'}) actions.append({ 'type': 'scale', 'vector': scale, 'falloff': scale_falloff }) actions.append({ 'type': 'rotate', 'vector': mathutils.Vector(rotation), 'falloff': rotation_falloff }) actions.append({'type': 'translate', 'vector': translation}) # Add the extrude at the start (doing it this way in case we'd like to invert the list) #actions.insert(0, {'type': 'extrude'}) # Loop through all the actions bpy.ops.object.mode_set(mode='EDIT') self.mark('startloop') while not self.reachedGoal: self.mark('step ' + str(self.iteration)) # Figure out how much to translate and where we are on the curves self.currentX = self.translated / translation self.translated += self.averageLength self.newX = self.translated / translation self.mark('transcal') # Lets check.. if we move beyond the wanted result in this step... we quit! if self.translated == translation: self.reachedGoal = True elif self.translated > translation: self.reachedGoal = True self.newX = 1.0 break self.mark('actions') for action in actions: self.mark(action['type'] + ' start') self.spurt(action) self.mark(action['type'] + ' end') self.iteration += 1 if steps: self.ob['growsteps'] = self.iteration # Save this matrix, in case we grow again... if retain: self.ob['growmatrix'] = self.transformMatrix else: try: del (self.ob['growmatrix']) except: pass self.mark('end')
def __init__(self, context, dnaString): self.startTime = time.time() self.markTime = self.startTime self.debug = True self.mark('start') self.offset = 0.999 self.xVec = mathutils.Vector((1.0,0.0,0.0)) self.yVec = mathutils.Vector((0.0,1.0,0.0)) self.zVec = mathutils.Vector((0.0,0.0,1.0)) # Make the liberty class random.seed(dnaString) #Figure out what hull to use hulls = bpy.data.groups['hulls'].objects hull = self.prepObject(random.choice(hulls)) select_faces.none() select_faces.in_group(hull.vertex_groups['mounts']) # Make sure there's some selected faces at least if not mesh_extras.has_selected('faces'): print('No faces found in hull'); else: attachMents = mesh_extras.get_selected_faces() if len(attachMents): group = hull.vertex_groups['mounts'] step = 0 attachCount = 1 vertLen = len(bpy.context.active_object.data.vertices) while step < attachCount and step <= 13 and vertLen < 500000: print('') self.mark('- - - - - finished step '+str(step)+' with '+str(vertLen)+' verts') print('') step += 1 #print('\n - step',step,'\n') # Deselect all faces #select_faces.none() #select_faces.in_group(group) bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_all(action='DESELECT') #bpy.ops.object.vertex_group_select() bpy.ops.object.vertex_group_select() bpy.ops.object.mode_set(mode='OBJECT') self.mark('deselected everything') #select_faces.in_group(group) #self.mark('selected mounts') hullMounts = mesh_extras.get_selected_faces() hullLen = len(hullMounts) self.mark('got mounts '+str(hullLen)) attachCount = random.randint(int(round(hullLen*0.4)), hullLen) self.mark('made attachcount '+str(attachCount)) if len(hullMounts): hullMount = random.choice(hullMounts) # PREP hullNormal = (hullMount.normal * hull.matrix_world).normalized() hullPos = hullMount.center * hull.matrix_world self.mark('prepped for attaching') self.attachPart(hull, hullMount, hullNormal, hullPos) self.mark('part attached') bpy.ops.object.modifier_add(type='EDGE_SPLIT') bpy.ops.object.modifier_apply(apply_as='DATA', modifier="EdgeSplit") self.mark('edges split') vertLen = len(bpy.context.active_object.data.vertices) self.mark('done attaching at '+str(vertLen)+' verts') ''' select_faces.none() ob = bpy.context.active_object bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_all(action='DESELECT') bpy.ops.wm.context_set_value(data_path='tool_settings.mesh_select_mode', value="(False, True, False)") bpy.ops.mesh.edges_select_sharp(sharpness=140.0) #bpy.ops.transform.edge_crease(value=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False) bpy.ops.mesh.mark_sharp(clear=False) bpy.ops.object.mode_set(mode='OBJECT') for e in bpy.context.active_object.data.edges: if e.select: e.crease = 1.0 bpy.ops.object.mode_set(mode='EDIT') bpy.ops.wm.context_set_value(data_path='tool_settings.mesh_select_mode', value="(False, False, True)") bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.modifier_add(type='SUBSURF') m = ob.modifiers[0] m.show_viewport = False bpy.ops.object.modifier_add(type='EDGE_SPLIT') m = ob.modifiers[0] m.use_edge_angle = False m.use_edge_sharp = True m.show_viewport = False ''' bpy.ops.object.modifier_add(type='EDGE_SPLIT') bpy.ops.object.modifier_apply(apply_as='DATA', modifier="EdgeSplit") #m = bpy.context.active_object.modifiers[0] #m.show_viewport = False bpy.ops.object.shade_smooth() self.mark('set edgesplit and shading') # Lets scale the object ob = bpy.context.active_object dimensions = ob.dimensions max = 0.0 for i, d in enumerate(dimensions): if (not i) or d > max: max = d if max != 0.0: ratio = 15 / max ob.scale *= ratio self.mark('found relative dimension') bpy.ops.object.scale_apply() bpy.ops.object.location_clear() bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='BOUNDS') self.mark('set scale and location') max = mathutils.Vector() min = mathutils.Vector() for i, v in enumerate(ob.data.vertices): co = v.co * ob.matrix_world for j, c in enumerate(co): if c > max[j] or not i: max[j] = c if c < min[j] or not i: min[j] = c #print('vmax',max) #print('vmin',min) loc = (max + min) * 0.5 ob.location = -loc self.mark('corrected location') #print('loc',loc) bpy.data.objects['name'].data.body = dnaString.upper() bpy.context.active_object.name = dnaString self.mark('finished') return
def attachPart(self, parent, parentMount, parentNormal, parentPos): print('') # NOW LETS FIND A PART #children = self.dna.makeDict(bpy.data.groups['parts'].objects) children = bpy.data.groups['parts'].objects if not len(children): return child = self.prepObject(random.choice(children)) #child = self.prepObject(self.dna.Choose('select', children, 'part')) self.mark('prepped object') # Select all the mounts in the child part select_faces.in_group(child.vertex_groups['mounts']) # Make sure there's some selected faces at least if not mesh_extras.has_selected('faces'): print('No faces found in part'); else: childMat = child.matrix_world childMounts = mesh_extras.get_selected_faces() # Deselect all faces select_faces.none() self.mark('finished selection') #childMounts = self.dna.makeDict(childMounts) childMount = random.choice(childMounts) #childMount = self.dna.Choose('select', childMounts, 'childMount') self.mark('chose mount') if childMount: childMount.select = True childNormal = (childMount.normal * child.matrix_world).normalized() # ROTATE THE CHILD AROUND THE GLOBAL Y AXIS TO MATCH THE PARENTMOUNT childY = mathutils.Vector((childNormal[0], 0.0, childNormal[2])).normalized() parentY = mathutils.Vector((parentNormal[0], 0.0, parentNormal[2])).normalized() if childY.length > 0.0 and parentY.length > 0.0: angY = childY.angle(parentY) print(' angY', math.degrees(angY)) if angY > 0.0 and angY < 180.0: rotY = mathutils.Matrix.Rotation((math.radians(180) - angY), 4, mathutils.Vector((0.0,1.0,0.0))).to_4x4() child.matrix_world = rotY * child.matrix_world childNormal = (childMount.normal * child.matrix_world).normalized() else: # ROTATE THE CHILD AROUND THE GLOBAL X AXIS TO MATCH THE PARENTMOUNT childX = mathutils.Vector((0.0, childNormal[1], childNormal[2])).normalized() parentX = mathutils.Vector((0.0, parentNormal[0], parentNormal[2])).normalized() if childX.length > 0.0 and parentX.length > 0.0: angX = childX.angle(parentX) print(' angX', math.degrees(angX)) if angX > 0.0 and angX < 180.0: rotX = mathutils.Matrix.Rotation((math.radians(180) - angX), 4, mathutils.Vector((-1.0,0.0,0.0))).to_4x4() child.matrix_world = rotX * child.matrix_world childNormal = (childMount.normal * child.matrix_world).normalized() # ROTATE THE CHILD AROUDN THE GLOBAL Z AXIS TO MATCH THE PARENTMOUNT childZ = mathutils.Vector((childNormal[0], childNormal[1], 0.0)).normalized() parentZ = mathutils.Vector((parentNormal[0], parentNormal[1], 0.0)).normalized() if childZ.length > 0.0 and parentZ.length > 0.0: angZ = childZ.angle(parentZ) print(' angZ', math.degrees(angZ)) if angZ > 0.0 and angZ < 180.0: rotZ = mathutils.Matrix.Rotation((math.radians(180) - angZ), 4, mathutils.Vector((0.0,0.0,-1.0))).to_4x4() child.matrix_world = rotZ * child.matrix_world elif angZ == 0.0: rotZ = mathutils.Matrix.Rotation(math.radians(180), 4, mathutils.Vector((0.0,0.0,-1.0))).to_4x4() child.matrix_world = rotZ * child.matrix_world #childNormal = (childMount.normal * child.matrix_world).normalized() self.mark('fixed rotation') # SET CHILD POSITION childPos = childMount.center * child.matrix_world child.location = parentPos - childPos bpy.ops.transform.resize(value=(self.offset,self.offset,self.offset), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=0.826446, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), texture_space=False, release_confirm=False) #child.scale *= self.offset self.offset -= 0.001 self.mark('fixed location') # MAKE THE PARENT THE PARENT! YEA parent.select = True bpy.context.scene.objects.active = parent #bpy.ops.object.parent_set(type='OBJECT') self.mirrorCheck(parent, parentMount, parentPos, child) self.mark('checked mirror') # Join the two meshes bpy.ops.object.join() #print(' post join selected',len(mesh_extras.get_selected_faces())) bpy.ops.object.mode_set(mode='EDIT') bpy.ops.object.vertex_group_remove_from(all=True) bpy.ops.object.mode_set(mode='OBJECT') self.mark('joined and cleaned') return
def __init__(self, context, translation, rotation, rotation_falloff, scale, scale_falloff, retain, steps, debug): self.startTime = time.time() self.markTime = self.startTime self.debug = debug self.context = context self.ob = context.active_object self.selectNr = len(mesh_extras.get_selected_faces()) if not self.selectNr: print('Grow error no faces selected') return if steps: self.ob['growsteps'] = 0 self.factor = 0.0 self.iteration = 0 self.reachedGoal = False self.translated = 0.0 self.currentX = 0.0 self.averagelength = 0.0 # Go into object mode for the initial stages bpy.ops.object.mode_set(mode='OBJECT') self.averageLength = mesh_extras.get_average_outer_edge_length() translation *= self.averageLength # Now this is an added bit only for use with entoform.py # This matrix may already be set by a previous grow function running making this shape (just being consistent) try: self.transformMatrix = mathutils.Matrix((self.ob['growmatrix'][0],self.ob['growmatrix'][1],self.ob['growmatrix'][2])) except: self.transformMatrix = mesh_extras.get_selection_matrix() # This matrix is just there to check whether the "directions" are correct try: self.checkMatrix = mathutils.Matrix((self.ob['formmatrix'][0],self.ob['formmatrix'][1],self.ob['formmatrix'][2])) print('GOT checkmatrix') except: self.checkMatrix = False # Make the actions actions = [] actions.append({'type': 'extrude'}) actions.append({'type': 'scale', 'vector': scale, 'falloff': scale_falloff}) actions.append({'type': 'rotate', 'vector': mathutils.Vector(rotation), 'falloff': rotation_falloff}) actions.append({'type': 'translate', 'vector': translation}) # Add the extrude at the start (doing it this way in case we'd like to invert the list) #actions.insert(0, {'type': 'extrude'}) # Loop through all the actions bpy.ops.object.mode_set(mode='EDIT') self.mark('startloop') while not self.reachedGoal: self.mark('step '+str(self.iteration)) # Figure out how much to translate and where we are on the curves self.currentX = self.translated / translation self.translated += self.averageLength self.newX = self.translated / translation self.mark('transcal') # Lets check.. if we move beyond the wanted result in this step... we quit! if self.translated == translation: self.reachedGoal = True elif self.translated > translation: self.reachedGoal = True self.newX = 1.0 break self.mark('actions') for action in actions: self.mark(action['type']+' start') self.spurt(action) self.mark(action['type']+' end') self.iteration += 1 if steps: self.ob['growsteps'] = self.iteration # Save this matrix, in case we grow again... if retain: self.ob['growmatrix'] = self.transformMatrix else: try: del(self.ob['growmatrix']) except: pass self.mark('end')
def makeAffectedGroups(self, string, baseGroups, subCount): print('subcnt', subCount) selection = string['selection'] newGroups = [] formmatrix = mathutils.Matrix() growmatrices = [] # Deselect all faces to start clean! select_faces.none() # Select everything in the base groups for g in baseGroups: select_faces.in_group(g,True) #print('in_group',len(mesh_extras.get_selected_faces())) # If nothing is selected there's nothing to do if mesh_extras.contains_selected_item(self.me.faces): if selection['type'] == 'twig': # Lets find the middle... selFaces = mesh_extras.get_selected_faces() midPoint = mathutils.Vector(); for f1 in selFaces: midPoint += f1.center midPoint /= len(selFaces) midDist = 0.0 nearest = 0 for fc, f1 in enumerate(selFaces): dist = midPoint - f1.center dist = dist.length if not fc or dist < midDist: nearest = f1 midDist = dist select_faces.none() nearest.select = True print('found at distance',len(mesh_extras.get_selected_faces(self.me.faces))) # If we have selected faces... we can add em to a new group newGroups, formmatrix, growmatrices = self.addToNewGroups(string, newGroups, growmatrices) # Select the faces at the tip in a certain direction elif selection['type'] == 'joint' or selection['type'] == 'tip' : select_faces.innermost() if mesh_extras.contains_selected_item(self.me.faces): if selection['type'] == 'joint': select_faces.connected(True) selCnt = len(mesh_extras.get_selected_faces()) nuCnt = selCnt div = selection['divergence'] # If the nr of faces selected isn't diminished... we select less! while selCnt and selCnt == nuCnt and div > 0.1: select_faces.by_direction(selection['vector'],div) div = div * 0.75 selFaces = mesh_extras.get_selected_faces() nuCnt = len(selFaces) # Check for opposing normals.. .cause they should not be there! for f1 in selFaces: if f1.select: f1No = f1.normal for f2 in selFaces: if f2.select and not f1 is f2: f2No = f2.normal ang = f2No.angle(f1No) if ang > math.radians(120): f1.select = False break selFaces = mesh_extras.get_selected_faces() nuCnt = len(selFaces) if nuCnt == selCnt: select_faces.none() # If we have selected faces... we can add em to a new group newGroups, formmatrix, growmatrices = self.addToNewGroups(string, newGroups, growmatrices) # Select by pi (fake random) elif selection['type'] == 'liberal': select_faces.liberal(self.dnaString) # If we have selected faces... we can add em to a new group newGroups, formmatrix, growmatrices = self.addToNewGroups(string, newGroups, growmatrices) # Select all loops in the group elif selection['type'] == 'loops': select_faces.connected() self.deselectUnGrouped() step = 0 # As long as something is selected, we can continue while mesh_extras.contains_selected_item(self.ob.data.faces): select_faces.connected() self.deselectGrouped(baseGroups) # Skip selection just in case if not step % selection['frequency']: # If we have selected faces... we can add em to a new group newGroups, formmatrix, grw = self.addToNewGroups(string, newGroups, growmatrices) growmatrices.extend(grw) step += 1 print(step) # Select by direction elif selection['type'] == 'direction': select_faces.by_direction(selection['vector'],selection['divergence']) newGroups, formmatrix, growmatrices = self.addToNewGroups(string, newGroups, growmatrices) # All! else: newGroups, formmatrix, growmatrices = self.addToNewGroups(string, newGroups, growmatrices) return newGroups, formmatrix, growmatrices