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 executeDNA(self, string, baseGroups, baseWeight):
		
		'''
		if string['number'] >= 1:
			#if string['number'] in [0,1,3]:
			return
		
		elif string['number'] == 5 or string['number'] == 6:
			return	
		'''
		# Redraw hack to see what is happening
		# bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
		
		newGroups, formmatrix, growmatrices = self.makeAffectedGroups(string, baseGroups)
		groupLen = len(newGroups)\
		
		pad = str(' ').rjust(string['level'], ' ')
		
		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('  - 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
				select_faces.none()
				select_faces.in_group(group)
				
				# No need to continue if we have no selected faces
				if not mesh_extras.contains_selected_item(self.me.faces):
					print(pad,'skip ',stepText,'no selection',string['action']['name'])
					
				else:
					
					a = string['action']
					
					if a['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((-a['rotation'][0],a['rotation'][1],-a['rotation'][2]))
						else:
							rot = a['rotation']
					
						# Add relative intensity here (half the original + half the weight)
						weight = baseWeight * self.getWeight(groupLen, a['scalin'])
						
						trans = a['translation']
						#trans = self.applyIntensity(a['translation'], weight, 'float')
						#rot = self.applyIntensity(rot, weight, 'inc')
					
					if a['type'] == 'grow' and trans == 0.0:
					
						print(pad,'skip ',stepText,'too short',trans,'from',a['translation'])
					
					else:
					
						print(pad,'step ',stepText,a['name'])
						#print(self.applyIntensity(a['push'], weight, 'float'))
						
						bpy.ops.object.mode_set(mode='EDIT')
						
						if a['type'] == 'bump':
						
							bpy.ops.mesh.bump(
								type=a['bumptype'],
								scale=a['bumpscale'],
								steps=True,
								)
								
						else:
						
							bpy.ops.mesh.grow(
								translation=trans,
								rotation=rot,
								rotation_falloff=a['rotation_falloff'],
								scale=a['scale'],
								scale_falloff=a['scale_falloff'],
								retain=True,
								steps=True,
								debug=False,
								)
							
						bpy.ops.object.mode_set(mode='OBJECT')
							
						
						select_faces.none()
						select_faces.in_group(group)
						
						self.applyGrowthColor(a)
						if a['type'] == 'grow':
							self.applyGrowthCrease(a)
						
						# Remove new stuff from all but the current group
						self.cleanGroup(group)
						
						# Keep track of how much steps we've taken
						self.dnaStep += 1
						
						# If there's a sub
						if len(string['strings']):
							for s in string['strings']:
								#print('going sub', string['name'], s['name'])
								self.executeDNA(s, [group], weight)
Exemple #3
0
	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
Exemple #4
0
	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
Exemple #5
0
	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
Exemple #6
0
	def executeDNA(self, string, baseGroups, baseWeight, subCount):
		
		''''
		if string['number'] >= 1:
			#if string['number'] in [0,1,3]:
			return
	
		elif string['number'] == 5 or string['number'] == 6:
			return	
		'''
		# Redraw hack
		#bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
		
		newGroups, formmatrix, growmatrices = self.makeAffectedGroups(string, baseGroups, subCount)
		groupLen = len(newGroups)
		
		pad = str(' ').rjust(string['level'], ' ')
		
		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('  - 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 trunk or body
				if string['name'] == 'trunk' 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'] == 'trunk':
					growmatrix = mathutils.Matrix(((1.0,0.0,0.0),(0.0,-1.0,0.0),(0.0,0.0,1.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
				select_faces.none()
				select_faces.in_group(group)
				
				# No need to continue if we have no selected faces
				if not mesh_extras.contains_selected_item(self.me.faces):
					print(pad,'skip ',stepText,'no selection',string['action']['name'])
					
				else:
					
					a = string['action']
					
					if a['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((-a['rotation'][0],a['rotation'][1],-a['rotation'][2]))
						else:
							rot = a['rotation']
					
						# Add relative intensity here (half the original + half the weight)
						weight = baseWeight * self.getWeight(groupLen, a['scalin'])
						
						trans = a['translation']
					
					if a['type'] == 'grow' and trans == 0.0:
					
						print(pad,'skip ',stepText,'too short',trans,'from',a['translation'])
					
					else:
					
						print(pad,'step ',stepText,a['name'])
						
						bpy.ops.object.mode_set(mode='EDIT')
						
						if a['type'] == 'bump':
						
							bpy.ops.mesh.bump(
								type=a['bumptype'],
								scale=a['bumpscale'],
								steps=True,
								)
								
						else:
						
							bpy.ops.mesh.grow(
								translation=trans,
								rotation=rot,
								rotation_falloff=a['rotation_falloff'],
								scale=a['scale'],
								scale_falloff=a['scale_falloff'],
								retain=True,
								steps=True,
								debug=False,
								)
							
						bpy.ops.object.mode_set(mode='OBJECT')
							
						
						select_faces.none()
						select_faces.in_group(group)
						
						self.applyGrowthColor(a)
						if a['type'] == 'grow':
							self.applyGrowthCrease(a)
						
						# Remove new stuff from all but the current group
						self.cleanGroup(group)
						
						# Keep track of how much steps we've taken
						self.dnaStep += 1
						
						# If there's a sub
						if len(string['strings']):
							for sc, s in enumerate(string['strings']):
								#print('going sub', string['name'], s['name'])
								self.executeDNA(s, [group], weight, sc)