def addToNewGroups(self, string, newGroups, growmatrices=[]): selection = string['selection'] formmatrix = mesh_extras.get_selection_matrix() if selection['area'] == 'area': # make sure we have one continuous island selected select_bmesh_faces.go(mode='ISLAND') addedGroup = bmesh_extras.add_to_group(newGroup=True, groupName=string['name']) addedGroups = [addedGroup] else: addedGroups = bmesh_extras.cluster_selection(limit=self.clusterSize, groupName=string['name']) #print('made',len(addedGroups),'groups') #addGroups, addMatrices = mesh_extras.group_selection(area = selection['area'], name=string['name'],chunkProduct=4, chunkLimit=selection['limit']) if len(addedGroups): addedMatrices = [] for g in addedGroups: group = bpy.context.active_object.vertex_groups[g] newGroups.append(group) self.newGroups.append(group) # Get a matrix for every group select_bmesh_faces.go(mode='GROUPED', group=g) addedMatrices.append(mesh_extras.get_selection_matrix()) for m in addedMatrices: growmatrices.append(m) return newGroups, formmatrix, growmatrices
def cleanGroup(self, group): select_bmesh_faces.go(mode='GROUPED', group=group.index) select_bmesh_faces.go(mode='OUTER', invert=True) # Make sure the entire group is selected #bpy.ops.mesh.select_all(action='DESELECT') #self.ob.vertex_groups.active_index = group.index #bpy.ops.object.vertex_group_select() # Set editing to vert mode before selecting less #bpy.ops.wm.context_set_value(data_path='tool_settings.mesh_select_mode', value="(True, False, False)") #bpy.ops.mesh.select_less() # Set editing back to face mode #bpy.ops.wm.context_set_value(data_path='tool_settings.mesh_select_mode', value="(False, False, True)") self.ob.vertex_groups.active_index = group.index bpy.ops.object.mode_set(mode='EDIT') for g in self.newGroups: if g.index != group.index and g.name != 'corner': self.ob.vertex_groups.active_index = g.index bpy.ops.object.vertex_group_remove_from(use_all_groups=False, use_all_verts=False) #bpy.ops.object.vertex_group_remove_from(all=False) self.ob.vertex_groups.active_index = group.index bpy.ops.object.mode_set(mode='OBJECT')
def makeAffectedGroups(self, string, baseGroups): selection = string['selection'] newGroups = [] formmatrix = mathutils.Matrix() growmatrices = [] # Select everything in the base groups for i, g in enumerate(baseGroups): # Deselect on the first go if not i: e = False else: e = True #print('base',g.name) select_bmesh_faces.go(mode='GROUPED', extend=e, group=g.index) #print('in_group',len(mesh_extras.get_selected_polygons())) # If nothing is selected there's nothing to do if mesh_extras.contains_selected_item(self.me.polygons): # Select the polygons at the tip in a certain direction if selection['type'] == 'joint': select_bmesh_faces.go(mode='INNER') #print('1, selected',len(mesh_extras.get_selected_polygons()),mesh_extras.contains_selected_item(self.me.polygons)) if mesh_extras.contains_selected_item(self.me.polygons): #return newGroups, formmatrix, growmatrices # Select connected twice to make sure we have enough now that selection is doubled select_bmesh_faces.go(mode='CONNECTED', extend=True) select_bmesh_faces.go(mode='CONNECTED', extend=True) #print('2, selected',len(mesh_extras.get_selected_polygons())) selCnt = len(mesh_extras.get_selected_polygons()) nuCnt = selCnt div = selection['divergence'] # If the nr of polygons selected isn't diminished... we select less! while selCnt and selCnt == nuCnt and div > 0.1: select_bmesh_faces.go(mode='DIRECTIONAL', direction=selection['vector'], limit=div) nuCnt = len(mesh_extras.get_selected_polygons()) #print('join selection at',math.degrees(div), nuCnt) div = div * 0.5 if nuCnt == selCnt: select_bmesh_faces.go(mode='NONE') # If we have selected polygons... we can add em to a new group newGroups, formmatrix, growmatrices = self.addToNewGroups(string, newGroups, growmatrices) # Select by direction elif selection['type'] == 'direction': select_bmesh_faces.go(mode='DIRECTIONAL', direction=selection['vector'],limit=selection['divergence']) #print('done selecting', len(mesh_extras.get_selected_polygons()),'polys in',selection['vector'],math.degrees(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 executeDNA(self, string, baseGroups, baseWeight): pad = str(' ').rjust(string['level'], ' ') # Stop if the limit is reached! (mostly for debugging) if self.steplimit and string['number'] >= self.steplimit: print(pad,' # Reached steplimit',self.steplimit,'>> RETURNING') return ''' if string['number'] == 5 or string['number'] == 6: return ''' #print(pad,'1 makegroups') newGroups, formmatrix, growmatrices = self.makeAffectedGroups(string, baseGroups) groupLen = len(newGroups) # Temporary halt! #return #if string['number'] == (self.steplimit-1): # print(pad,' # Reached steplimit',self.steplimit,'>> RETURNING') # return idText = 'limb '+misc.nr4(string['number'])+' '+string['name'].ljust(10, ' ') #print(pad,idText) # only if we made a group with something in it do we continue if not groupLen: print(pad,' ### No group!') else: # Loop through all the groups for i, group in enumerate(newGroups): # The step number to print out stepText = misc.nr4(i+1)+' of '+misc.nr4(groupLen) # We need a check matrix only if we're not on the head or body if string['name'] == 'head' or string['name'] == 'body' or True: try: del(self.ob['formmatrix']) except: pass # If not... then just try to get rid of it else: self.ob['formmatrix'] = formmatrix # Body gets a set matrix (so it grows nice and straight) if string['name'] == 'head': growmatrix = mathutils.Matrix(((1.0,0.0,0.0),(0.0,0.0,1.0),(0.0,-1.0,0.0))).transposed() # Head gets a set matrix (so it grows nice and straight) elif string['name'] == 'body': growmatrix = mathutils.Matrix(((-1.0,0.0,0.0),(0.0,0.0,1.0),(0.0,1.0,0.0))).transposed() # In all other cases the matrix can be dealt with by the grow addon else: growmatrix = growmatrices[i] self.ob['growmatrix'] = growmatrix # Select a group #print(pad,'2 select groups') select_bmesh_faces.go(mode='GROUPED', group=group.index) #print('sel-',len(mesh_extras.get_selected_polygons()),group.name) mesh_extras.smooth_selection() # No need to continue if we have no selected polygons if not mesh_extras.contains_selected_item(self.me.polygons): print(pad,'skip ',stepText,'no selection',string['action']['name']) else: action = string['action'] if action['type'] == 'grow': # Check for mirroring right = mathutils.Vector((1.0,0.0,0.0)) check = mathutils.Vector(growmatrix[2]) # If we're aiming left we "invert" the rotation if right.dot(check) < 0.0: rot = mathutils.Vector((-action['rotation'][0],action['rotation'][1],-action['rotation'][2])) else: rot = action['rotation'] # Add relative intensity here (half the original + half the weight) weight = baseWeight * self.getWeight(groupLen, action['scalin']) print(pad,'step ',stepText,action['name'], string['number']) # Cast the selection to the correct shape please bmesh_extras.cast_loop(corners=action['loop_corners'], falloff_scale=action['loop_scale'], falloff_shape=action['loop_shape'],corner_group='corner') bpy.ops.object.mode_set(mode='EDIT') if action['type'] == 'bump': bpy.ops.mesh.bump( type=action['bumptype'], scale=action['bumpscale'], steps=True, ) else: bpy.ops.mesh.grow( translation=action['translation'], rotation=rot, rotation_falloff=action['rotation_falloff'], scale=action['scale'], scale_falloff=action['scale_falloff'], retain=True, steps=True, debug=False, ) bpy.ops.object.mode_set(mode='OBJECT') select_bmesh_faces.go(mode='GROUPED', group=group.index) bmesh_extras.color_limb(col=action['vertexcolor'], jon=action['jointcolor'], hard=action['colorstyle']) # RESELECT GROUPED... select_bmesh_faces.go(mode='GROUPED', group=group.index) bmesh_extras.crease_edges(sharpness=action['crease'], group='corner') select_bmesh_faces.go(mode='GROUPED', group=group.index) # Remove new stuff from all but the current group self.cleanGroup(group) select_bmesh_faces.go(mode='GROUPED', group=group.index) # Keep track of how much steps we've taken self.dnaStep += 1 # Redraw hack to see what is happening #bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1) # If there's a sub string and we're allowed deeper... lets do that if len(string['strings']): for s in string['strings']: if s['number'] < self.steplimit or not self.steplimit: #print('going sub', string['name'], s['name']) self.executeDNA(s, [group], weight)