def save_vertex_position(target): # active when 1, or close by 0 addProps(target, 'vic_active', True) # no nagetive number, the higher value the more detail addProps(target, 'vic_detail', 1.0) # 0.0~1.0 will be best! addProps(target, 'vic_effective', 1.0) # using vertex color addProps(target, 'vic_using_vertex_color_map', False) # using vertex color for effective value addProps(target, 'vic_effective_by_vertex_color', 'Col') detail = target['vic_detail'] map_vertex_color = target['vic_effective_by_vertex_color'] addProps(target, 'vic_init_vertex_position', [v.co.copy() for v in target.data.vertices], True) addProps(target, 'vic_proxy_vertex_position', [target.matrix_world @ v.co.copy() for v in target.data.vertices], True) if map_vertex_color in target.data.vertex_colors: collect_color = collectVertexColor( target.data, target.data.vertex_colors[map_vertex_color]) map_vertexs = [avg_col(v).hsv[2] for k, v in collect_color.items()] addProps(target, 'vic_force_for_each_vertex_by_vertex_color', map_vertexs, True) else: addProps(target, 'vic_force_for_each_vertex_by_vertex_color', [.2 for v in target.data.vertices], True) addProps(target, 'vic_force_for_each_vertex', [((noise.noise(Vector(v) * detail)) + 1) / 2 for v in target['vic_init_vertex_position']], True)
def iter_grow(self, param): # container for points on contour contour_points = [] # create empty bmesh to store vertices of circle bm = bmesh.new() # divide circle in segments circle_segments = np.linspace(0, 2 * np.pi, param["n_segments"]) for segment in circle_segments: # generate point on a cricle as argument to perlin noise xoff = np.interp(np.cos(segment), [-1, 1], param["noise_range"]) yoff = np.interp(np.sin(segment), [-1, 1], param["noise_range"]) zoff = param["zoff"] pos = np.array([xoff, yoff, zoff]) # generate noise value noise_val = noise.noise(pos) # NB: noise elem [-1,1] noise_val = np.interp(noise_val, [-1, 1], param["noise_amp"]) # add to radius radius_curr = param["radius"] + noise_val # create circle point on nosy radius from center x = self.center[0] + radius_curr * np.cos(segment) y = self.center[1] + radius_curr * np.sin(segment) z = self.center[2] # add point to bmesh and container bm.verts.new(np.array([x, y, z])) contour_points.append([x, y, z]) # add faces bm.faces.new(bm.verts) # add a new mesh data layer_mesh_data = bpy.data.meshes.new(param["layer_name"] + "_data") # add a new empty mesh object using the mesh data layer_mesh_object = bpy.data.objects.new( param["layer_name"] + "_object", layer_mesh_data) # make the bmesh the object's mesh # transfer bmesh data do mesh data which is connected to empty mesh object bm.to_mesh(layer_mesh_data) bm.free() # add color material = bpy.data.materials.new(param["layer_name"] + "_material") material.diffuse_color = param["color"] layer_mesh_object.active_material = material # return object, data for object can be extracted via eden_layer_mesh_object.data return layer_mesh_object, contour_points
def export_ter(filepath): start_time = time.process_time() filename = filepath + '.ter' # start to set all the tags and values needed for the .ter file ter_header = 'TERRAGENTERRAIN ' size_tag = 'SIZE' size = 64 scal_tag = 'SCAL' scalx = 30.0 scaly = 30.0 scalz = 30.0 altw_tag = 'ALTW' HeightScale = 80 BaseHeight = 0 totalpoints = (size + 1) * (size + 1) # set seed for noise.random() noise.seed_set(123) # values are packed as short (i.e = integers max 32767) so we map them in the right range values = [] # values = [int(map_range(noise.random(), 0.0, 1.0, 0.0, 32767.0)) for i in range(totalpoints)] for x in range(size + 1): for y in range(size + 1): vec = Vector((x, y, 0.0)) out = int(map_range(noise.noise(vec, 3), -1.0, 1.0, 0.0, 32767.0)) values.append(out) print(values) eof_tag = 'EOF' # end of file tag with open(filename, "wb") as file: # write the header file.write(ter_header.encode('ascii')) # write the size of the terrain file.write(size_tag.encode('ascii')) file.write(struct.pack('h', size)) # padding byte needed after SIZE file.write(struct.pack('xx')) # padding -> b'\x00\x00' # write the scale tag = SCAL file.write(scal_tag.encode('ascii')) # pack the scaling values as floats file.write(struct.pack('fff', scalx, scaly, scalz)) # write the altitude ALTW tag file.write(altw_tag.encode('ascii')) # pack heightScale and baseHeight file.write(struct.pack('h', HeightScale)) file.write(struct.pack('h', BaseHeight)) # pack as shorts the elvetions values for v in values: file.write(struct.pack('h', v)) # EOF = end of file file.write(eof_tag.encode('ascii')) file.close() print('Terrain exported in %.4f sec.' % (time.process_time() - start_time))
def grow(self, n_iter): for i in range(n_iter): vertex_idx = np.random.choice(len(self.vertices), 1)[0] pos = np.array([np.cos(self.vertices[vertex_idx].phi), np.sin(self.vertices[vertex_idx].phi), np.pi]) noise_val = noise.noise(pos) self.vertices[vertex_idx].r += np.abs(noise_val) self.construct_mesh(self.vertices)
def turbulence(vec,oct,freq,rseed): #we choose a noise type noise_type = noise.types.STDPERLIN #set the seed but won't work with blender noise noise.seed_set(rseed) sndata = [] value = 0.0 for o in range(oct): freq *= 2.0 vVec = Vector(vec) multVec = vVec * freq #print(multVec) #print(f) value += abs(noise.noise(multVec,noise_type))/freq #value += (noise.noise(multVec,noise_type))/f #value += amplitude*(noise.noise(multVec,noise_type)) return value
SvSetSocketAnyType, SvGetSocketAnyType) ''' using slice [:] to generate 3-tuple instead of .to_tuple() because it tests slightly faster on larger data. ''' scalar_out = { "DOT": (lambda u, v: Vector(u).dot(v), 2), "DISTANCE": (lambda u, v: (Vector(u) - Vector(v)).length, 2), "ANGLE RAD": (lambda u, v: Vector(u).angle(v, 0), 2), "ANGLE DEG": (lambda u, v: degrees(Vector(u).angle(v, 0)), 2), "LEN": (lambda u: Vector(u).length, 1), "NOISE-S": (lambda u: noise(Vector(u)), 1), "CELL-S": (lambda u: cell(Vector(u)), 1) } vector_out = { "CROSS": (lambda u, v: Vector(u).cross(v)[:], 2), "ADD": (lambda u, v: (u[0]+v[0], u[1]+v[1], u[2]+v[2]), 2), "SUB": (lambda u, v: (u[0]-v[0], u[1]-v[1], u[2]-v[2]), 2), "REFLECT": (lambda u, v: Vector(u).reflect(v)[:], 2), "PROJECT": (lambda u, v: Vector(u).project(v)[:], 2), "SCALAR": (lambda u, s: (Vector(u) * s)[:], 2), "1/SCALAR": (lambda u, s: (Vector(u) * (1 / s))[:], 2), "ROUND": (lambda u, s: Vector(u).to_tuple(s), 2), "NORMALIZE": (lambda u: Vector(u).normalized()[:], 1), "NEG": (lambda u: (-Vector(u))[:], 1),
def create_perlin_points(num_points, x_scale=scale, z_scale=z_scale): return [ Vector((i * x_scale, 0, z_scale * noise(Vector((i * x_scale, 0, 0))))) for i in range(N) ]
def Effect_Basis_Function(coords, type, bias): bias = int(bias) type = int(type) x, y, z = coords iscale = 1.0 offset = 0.0 ## gradient: if type == 1: effect = offset + iscale * (Bias_Types[bias](x + y)) ## waves / bumps: elif type == 2: effect = offset + iscale * 0.5 * (Bias_Types[bias] (x * pi) + Bias_Types[bias](y * pi)) ## zigzag: elif type == 3: effect = offset + iscale * Bias_Types[bias](offset + iscale * sin(x * pi + sin(y * pi))) ## wavy: elif type == 4: effect = offset + iscale * (Bias_Types[bias]( cos(x) + sin(y) + cos(x * 2 + y * 2) - sin(-x * 4 + y * 4))) ## sine bump: elif type == 5: effect = offset + iscale * 1 - Bias_Types[bias]( (sin(x * pi) + sin(y * pi))) ## dots: elif type == 6: effect = offset + iscale * (Bias_Types[bias](x * pi * 2) * Bias_Types[bias](y * pi * 2)) - 0.5 ## rings: elif type == 7: effect = offset + iscale * (Bias_Types[bias](1.0 - (x * x + y * y))) ## spiral: elif type == 8: effect = offset + iscale * Bias_Types[bias]( (x * sin(x * x + y * y) + y * cos(x * x + y * y)) / (x**2 + y**2 + 0.5)) * 2 ## square / piramide: elif type == 9: effect = offset + iscale * Bias_Types[bias](1.0 - sqrt( (x * x)**10 + (y * y)**10)**0.1) ## blocks: elif type == 10: effect = (0.5 - max(Bias_Types[bias](x * pi), Bias_Types[bias](y * pi))) if effect > 0.0: effect = 1.0 effect = offset + iscale * effect ## grid: elif type == 11: effect = (0.025 - min(Bias_Types[bias](x * pi), Bias_Types[bias](y * pi))) if effect > 0.0: effect = 1.0 effect = offset + iscale * effect ## tech: elif type == 12: a = max(Bias_Types[bias](x * pi), Bias_Types[bias](y * pi)) b = max(Bias_Types[bias](x * pi * 2 + 2), Bias_Types[bias](y * pi * 2 + 2)) effect = min(Bias_Types[bias](a), Bias_Types[bias](b)) * 3.0 - 2.0 if effect > 0.5: effect = 1.0 effect = offset + iscale * effect ## crackle: elif type == 13: t = turbulence((x, y, 0), 6, 0, noise_basis="BLENDER") * 0.25 effect = variable_lacunarity((x, y, t), 0.25, noise_type2='VORONOI_CRACKLE') if effect > 0.5: effect = 0.5 effect = offset + iscale * effect ## sparse cracks noise: elif type == 14: effect = 2.5 * abs(noise( (x, y, 0), noise_basis="PERLIN_ORIGINAL")) - 0.1 if effect > 0.25: effect = 0.25 effect = offset + iscale * (effect * 2.5) ## shattered rock noise: elif type == 15: effect = 0.5 + noise((x, y, 0), noise_basis="VORONOI_F2F1") if effect > 0.75: effect = 0.75 effect = offset + iscale * effect ## lunar noise: elif type == 16: effect = 0.25 + 1.5 * voronoi( (x, y, 0), distance_metric='DISTANCE_SQUARED')[0][0] if effect > 0.5: effect = 0.5 effect = offset + iscale * effect * 2 ## cosine noise: elif type == 17: effect = cos(5 * noise((x, y, 0), noise_basis="BLENDER")) effect = offset + iscale * (effect * 0.5) ## spikey noise: elif type == 18: n = 0.5 + 0.5 * turbulence( (x * 5, y * 5, 0), 8, 0, noise_basis="BLENDER") effect = ((n * n)**5) effect = offset + iscale * effect ## stone noise: elif type == 19: effect = offset + iscale * (noise( (x * 2, y * 2, 0), noise_basis="BLENDER") * 1.5 - 0.75) ## Flat Turb: elif type == 20: t = turbulence((x, y, 0), 6, 0, noise_basis="BLENDER") effect = t * 2.0 if effect > 0.25: effect = 0.25 effect = offset + iscale * effect ## Flat Voronoi: elif type == 21: t = 1 - voronoi((x, y, 0), distance_metric='DISTANCE_SQUARED')[0][0] effect = t * 2 - 1.5 if effect > 0.25: effect = 0.25 effect = offset + iscale * effect else: effect = 0.0 if effect < 0.0: effect = 0.0 return effect
def execute(self, context): seed(self.seed) bpy.ops.mesh.primitive_grid_add(x_subdivisions=self.xsub, y_subdivisions=self.ysub, enter_editmode=True) # TODO make spacing of horizontal rows somewhat variable obj = bpy.context.edit_object me = obj.data bm = bmesh.from_edit_mesh(me) bm.faces.active = None for i in range(self.nv): verts = get_internal_verts(bm) if len(verts): vert = choice(verts) bmesh.ops.dissolve_faces(bm, faces=vert.link_faces, use_verts=False) for i in range(self.ne): edges = get_internal_edges(bm) if len(edges): edge = choice(edges) bmesh.ops.dissolve_faces(bm, faces=edge.link_faces, use_verts=False) for edge in get_movable_edges(bm): x = (random() * 2 - 1) * self.randomedge * (2.0 / self.xsub) * 0.5 edge.verts[0].co.x += x edge.verts[1].co.x += x for vert in bm.verts: x = (noise(vert.co) * 2 - 1) * self.randomvert * (2.0 / self.xsub) * 0.5 y = (noise(vert.co + Vector((11.1, 13.12, 17.14))) * 2 - 1) * self.randomvert * (2.0 / self.ysub) * 0.5 vert.co.x += x vert.co.y += y extruded_faces = bmesh.ops.extrude_discrete_faces( bm, faces=bm.faces)['faces'] bm.verts.index_update() for face in extruded_faces: vindices = [v.index for v in face.verts] for vert in face.verts: for e in vert.link_edges: overt = e.other_vert(vert) if overt.index not in vindices: overt.tag = True bmesh.ops.delete(bm, geom=[v for v in bm.verts if v.tag], context=1) for face in bm.faces: z = (random() * 2 - 1) * self.zrandom for vert in face.verts: vert.co.z += z bmesh.update_edit_mesh(me, True) bpy.ops.object.editmode_toggle() obj.scale.x = self.xsub / 10.0 obj.scale.y = self.ysub / 10.0 # add random uv and vcolor me.uv_textures.new() uv_layer = me.uv_layers.active.data vertex_colors = me.vertex_colors.new().data for poly in me.polygons: offset = Vector( (random(), random(), 0)) if obj.randomuv else Vector((0, 0, 0)) color = [random(), random(), random()] for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total): coords = me.vertices[me.loops[loop_index].vertex_index].co uv_layer[loop_index].uv = (coords + offset).xy vertex_colors[loop_index].color = color bpy.ops.object.modifier_add(type='SOLIDIFY') bpy.context.object.modifiers["Solidify"].offset = 1 bpy.context.object.modifiers["Solidify"].thickness = 0.1 bpy.ops.object.modifier_add(type='BEVEL') bpy.context.object.modifiers["Bevel"].width = 0.01 bpy.context.object.modifiers["Bevel"].segments = 2 return {'FINISHED'}
import json cont = logic.getCurrentController() owner = cont.owner init_pos = [] detail = owner['detail'] def push_init_pos( add_point ): global init_pos need_add = True for p in init_pos: if p[0] == add_point[0] and p[1] == add_point[1] and p[2] == add_point[2]: need_add = False p[3].append( add_point[3][0] ) if need_add: init_pos.append( add_point ) for mesh_index, mesh in enumerate( owner.meshes, 0 ): for m_index in range(len(mesh.materials)): for v_index in range(mesh.getVertexArrayLength(m_index)): vertex = mesh.getVertex(m_index, v_index) push_init_pos( [vertex.x,vertex.y,vertex.z, [[mesh_index, m_index, v_index]]] ) force_pos = [ ( noise.noise( Vector([p[0],p[1],p[2]]) * detail ) + 1 ) / 2 for p in init_pos ] proxy_pos_vec = [ owner.worldTransform * Vector([p[0],p[1],p[2]]) for p in init_pos ] proxy_pos = [[p[0],p[1],p[2]] for p in proxy_pos_vec ] owner['init_pos'] = json.dumps( init_pos ) owner['proxy_pos'] = json.dumps( proxy_pos ) owner['force_pos'] = json.dumps( force_pos )
def Effect_Basis_Function(coords, type, bias): bias = int(bias) type = int(type) x, y, z = coords iscale = 1.0 offset = 0.0 ## gradient: if type == 1: effect = offset + iscale * (Bias_Types[bias](x + y)) ## waves / bumps: elif type == 2: effect = offset + iscale * 0.5 * (Bias_Types[bias](x * pi) + Bias_Types[bias](y * pi)) ## zigzag: elif type == 3: effect = offset + iscale * Bias_Types[bias](offset + iscale * sin(x * pi + sin(y * pi))) ## wavy: elif type == 4: effect = offset + iscale * (Bias_Types[bias](cos(x) + sin(y) + cos(x * 2 + y * 2) - sin(-x * 4 + y * 4))) ## sine bump: elif type == 5: effect = offset + iscale * 1 - Bias_Types[bias]((sin(x * pi) + sin(y * pi))) ## dots: elif type == 6: effect = offset + iscale * (Bias_Types[bias](x * pi * 2) * Bias_Types[bias](y * pi * 2)) - 0.5 ## rings: elif type == 7: effect = offset + iscale * (Bias_Types[bias ](1.0 - (x * x + y * y))) ## spiral: elif type == 8: effect = offset + iscale * Bias_Types[bias]( (x * sin(x * x + y * y) + y * cos(x * x + y * y)) / (x**2 + y**2 + 0.5)) * 2 ## square / piramide: elif type == 9: effect = offset + iscale * Bias_Types[bias](1.0 - sqrt((x * x)**10 + (y * y)**10)**0.1) ## blocks: elif type == 10: effect = (0.5 - max(Bias_Types[bias](x * pi) , Bias_Types[bias](y * pi))) if effect > 0.0: effect = 1.0 effect = offset + iscale * effect ## grid: elif type == 11: effect = (0.025 - min(Bias_Types[bias](x * pi), Bias_Types[bias](y * pi))) if effect > 0.0: effect = 1.0 effect = offset + iscale * effect ## tech: elif type == 12: a = max(Bias_Types[bias](x * pi), Bias_Types[bias](y * pi)) b = max(Bias_Types[bias](x * pi * 2 + 2), Bias_Types[bias](y * pi * 2 + 2)) effect = min(Bias_Types[bias](a), Bias_Types[bias](b)) * 3.0 - 2.0 if effect > 0.5: effect = 1.0 effect = offset + iscale * effect ## crackle: elif type == 13: t = turbulence((x, y, 0), 6, 0, 0) * 0.25 effect = variable_lacunarity((x, y, t), 0.25, 0, 8) if effect > 0.5: effect = 0.5 effect = offset + iscale * effect ## sparse cracks noise: elif type == 14: effect = 2.5 * abs(noise((x, y, 0), 1)) - 0.1 if effect > 0.25: effect = 0.25 effect = offset + iscale * (effect * 2.5) ## shattered rock noise: elif type == 15: effect = 0.5 + noise((x, y, 0), 7) if effect > 0.75: effect = 0.75 effect = offset + iscale * effect ## lunar noise: elif type == 16: effect = 0.25 + 1.5 * voronoi((x, y, 0), 1)[0][0] if effect > 0.5: effect = 0.5 effect = offset + iscale * effect * 2 ## cosine noise: elif type == 17: effect = cos(5 * noise((x, y, 0), 0)) effect = offset + iscale * (effect * 0.5) ## spikey noise: elif type == 18: n = 0.5 + 0.5 * turbulence((x * 5, y * 5, 0), 8, 0, 0) effect = ((n * n)**5) effect = offset + iscale * effect ## stone noise: elif type == 19: effect = offset + iscale * (noise((x * 2, y * 2, 0), 0) * 1.5 - 0.75) ## Flat Turb: elif type == 20: t = turbulence((x, y, 0), 6, 0, 0) effect = t * 2.0 if effect > 0.25: effect = 0.25 effect = offset + iscale * effect ## Flat Voronoi: elif type == 21: t = 1 - voronoi((x, y, 0), 1)[0][0] effect = t * 2 - 1.5 if effect > 0.25: effect = 0.25 effect = offset + iscale * effect else: effect = 0.0 if effect < 0.0: effect = 0.0 return effect
bm = bmesh.new() # divide circle in segments circle_segments = np.linspace(0, 2 * np.pi, 50) for segment in circle_segments: # generate point on a cricle as argument to perlin noise xoff = np.interp(np.cos(segment), [-1, 1], [0.1, 0.9]) yoff = np.interp(np.sin(segment), [-1, 1], [0.1, 0.9]) zoff = 4.12 pos = np.array([xoff, yoff, zoff]) # generate noise value noise_val = noise.noise(pos) # NB: noise elem [-1,1] # add to radius radius_curr_x = 10 + noise_val radius_curr_y = 10 + noise_val # create circle point on nosy radius from center x = 0 + radius_curr_x * np.cos(segment) y = 0 + radius_curr_y * np.sin(segment) z = 0 # add point to bmesh bm.verts.new(np.array([x, y, z])) bm.faces.new(bm.verts) """
SvSetSocketAnyType, SvGetSocketAnyType) ''' using slice [:] to generate 3-tuple instead of .to_tuple() because it tests slightly faster on larger data. ''' scalar_out = { "DOT": (lambda u, v: Vector(u).dot(v), 2), "DISTANCE": (lambda u, v: (Vector(u) - Vector(v)).length, 2), "ANGLE RAD": (lambda u, v: Vector(u).angle(v, 0), 2), "ANGLE DEG": (lambda u, v: degrees(Vector(u).angle(v, 0)), 2), "LEN": (lambda u: Vector(u).length, 1), "NOISE-S": (lambda u: noise(Vector(u)), 1), "CELL-S": (lambda u: cell(Vector(u)), 1) } vector_out = { "CROSS": (lambda u, v: Vector(u).cross(v)[:], 2), "ADD": (lambda u, v: (u[0]+v[0],u[1]+v[1],u[2]+v[2]), 2), "SUB": (lambda u, v: (u[0]-v[0],u[1]-v[1],u[2]-v[2]), 2), "REFLECT": (lambda u, v: Vector(u).reflect(v)[:], 2), "PROJECT": (lambda u, v: Vector(u).project(v)[:], 2), "SCALAR": (lambda u, s: (Vector(u) * s)[:], 2), "1/SCALAR": (lambda u, s: (Vector(u) * (1 / s))[:], 2), "ROUND": (lambda u, s: Vector(u).to_tuple(s), 2), "NORMALIZE": (lambda u: Vector(u).normalized()[:], 1), "NEG": (lambda u: -Vector(u)[:], 1),
import bpy import numpy as np from mathutils import noise # add plane mesh bpy.ops.mesh.primitive_plane_add() plane = bpy.context.object plane.name = 'air_plane' # select plane plane = bpy.data.objects['air_plane'] # enter edit mode bpy.ops.object.mode_set(mode='EDIT') # subdivide bpy.ops.mesh.subdivide(number_cuts=10) # get vertices bpy.ops.mesh.select_mode(type='VERT') bpy.ops.mesh.select_all(action='SELECT') bpy.ops.object.mode_set(mode='OBJECT') # pazi!! verts = plane.data.vertices print("N", len(verts)) for v in verts: v.co[2] = noise.noise(v.co)
def iter_grow(self, param): # container for points on contour contour_points = [] # create empty bmesh to store vertices of circle bm = bmesh.new() # divide circle in segments circle_segments = np.linspace(0, 2 * np.pi, param["n_segments"]) for segment in circle_segments: # generate point on a cricle as argument to perlin noise xoff = np.interp(np.cos(segment), [-1, 1], param["noise_range"]) yoff = np.interp(np.sin(segment), [-1, 1], param["noise_range"]) zoff = param["zoff"] pos = np.array([xoff, yoff, zoff]) # generate noise value noise_val = noise.noise(pos) # NB: noise elem [-1,1] #noise_val = np.random.rand() # add to radius radius_curr_x = param["radius_xy"][0] + noise_val radius_curr_y = param["radius_xy"][1] + noise_val # create circle point on nosy radius from center x = self.center[0] + radius_curr_x * np.cos(segment) y = self.center[1] + radius_curr_y * np.sin(segment) z = self.center[2] # add point to bmesh and container bm.verts.new(np.array([x, y, z])) contour_points.append([x, y, z]) # add faces and extrude # https://blender.stackexchange.com/questions/65359/how-to-create-and-extrude-a-bmesh-face # think of this new vertices as bottom of the extruded shape bottom_face = bm.faces.new(bm.verts) # next we create top via extrude operator, note it doesn't move the new face # we make our 1 face into a list so it can be accepted to geom #top_face = bmesh.ops.extrude_face_region(bm, geom=[bottom_face]) # here we move all vertices returned by the previous extrusion # filter the "geom" list for vertices using list constructor #bmesh.ops.translate(bm, vec=param["extrude"], verts=[v for v in top_face["geom"] if isinstance(v,bmesh.types.BMVert)]) #bm.normal_update() # add a new mesh data layer_mesh_data = bpy.data.meshes.new(param["layer_name"] + "_data") # add a new empty mesh object using the mesh data layer_mesh_object = bpy.data.objects.new( param["layer_name"] + "_object", layer_mesh_data) # make the bmesh the object's mesh # transfer bmesh data do mesh data which is connected to empty mesh object bm.to_mesh(layer_mesh_data) bm.free() # add color material = bpy.data.materials.new(param["layer_name"] + "_material") material.diffuse_color = param["color"] layer_mesh_object.active_material = material # return object, data for object can be extracted via eden_layer_mesh_object.data return layer_mesh_object, contour_points
def __iter_grow(self, param): """ Creates one perturbed circle Given the parameters, this method is creating one perturbed circle. That is it performs one iteration of growth. Args: param (dict): parameters for creating the perturbed circle. Yields: Blender mesh object: representation of perturbed circle. list: contour points. """ # List of points that will be created on the contour. contour_points = [] # Create empty bmesh to store vertices of circle. bm = bmesh.new() circle_segments = np.linspace(start=0, stop=2 * np.pi, num=param["n_segments"]) # For every segment in circle create a perturbed vertex. for segment in circle_segments: xoff = np.interp(x=np.cos(segment), xp=[-1, 1], fp=param["noise_range"]) yoff = np.interp(x=np.sin(segment), xp=[-1, 1], fp=param["noise_range"]) zoff = param["zoff"] pos = np.array([xoff, yoff, zoff]) noise_val = noise.noise(pos) # NB: noise elem [-1,1] noise_val = np.interp(x=noise_val, xp=[-1, 1], fp=param["noise_amp"]) radius_curr = param["radius"] + noise_val x = self.center[0] + radius_curr * np.cos(segment) y = self.center[1] + radius_curr * np.sin(segment) z = self.center[2] bm.verts.new(np.array([x, y, z])) contour_points.append([x, y, z]) # Create face from existing vertices. bm.faces.new(bm.verts) # Add a new mesh data. layer_mesh_data = bpy.data.meshes.new(param["layer_name"] + "_data") # add a new empty mesh object using the mesh data. layer_mesh_object = bpy.data.objects.new( param["layer_name"] + "_object", layer_mesh_data) # Transform bmesh to mesh. bm.to_mesh(layer_mesh_data) bm.free() # Add material and color. material = bpy.data.materials.new(param["layer_name"] + "_material") material.diffuse_color = param["color"] layer_mesh_object.active_material = material return layer_mesh_object, contour_points
def execute(self, context): seed(self.seed) bpy.ops.mesh.primitive_grid_add(x_subdivisions=self.xsub, y_subdivisions=self.ysub, enter_editmode=True) # TODO make spacing of horizontal rows somewhat variable obj = bpy.context.edit_object me = obj.data bm = bmesh.from_edit_mesh(me) bm.faces.active = None for i in range(self.nv): verts = get_internal_verts(bm) if len(verts): vert = choice(verts) bmesh.ops.dissolve_faces(bm, faces=vert.link_faces, use_verts=False) for i in range(self.ne): edges = get_internal_edges(bm) if len(edges): edge = choice(edges) bmesh.ops.dissolve_faces(bm, faces=edge.link_faces, use_verts=False) for edge in get_movable_edges(bm): x = (random()*2-1)*self.randomedge*(2.0/self.xsub)*0.5 edge.verts[0].co.x += x edge.verts[1].co.x += x for vert in bm.verts: x = (noise(vert.co)*2-1)*self.randomvert*(2.0/self.xsub)*0.5 y = (noise(vert.co+Vector((11.1,13.12,17.14)))*2-1)*self.randomvert*(2.0/self.ysub)*0.5 vert.co.x += x vert.co.y += y extruded_faces = bmesh.ops.extrude_discrete_faces(bm, faces=bm.faces)['faces'] bm.verts.index_update() for face in extruded_faces: vindices = [v.index for v in face.verts] for vert in face.verts: for e in vert.link_edges: overt = e.other_vert(vert) if overt.index not in vindices: overt.tag = True bmesh.ops.delete(bm, geom=[v for v in bm.verts if v.tag], context=1) for face in bm.faces: z = (random()*2-1) * self.zrandom for vert in face.verts: vert.co.z += z bmesh.update_edit_mesh(me, True) bpy.ops.object.editmode_toggle() obj.scale.x = self.xsub/10.0 obj.scale.y = self.ysub/10.0 # add random uv and vcolor me.uv_textures.new() uv_layer = me.uv_layers.active.data vertex_colors = me.vertex_colors.new().data for poly in me.polygons: offset = Vector((random(), random(), 0)) if self.randomuv else Vector((0, 0, 0)) color = [random(), random(), random()] for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total): coords = me.vertices[me.loops[loop_index].vertex_index].co uv_layer[loop_index].uv = (coords + offset).xy vertex_colors[loop_index].color = color bpy.ops.object.modifier_add(type='SOLIDIFY') bpy.context.object.modifiers["Solidify"].offset = 1 bpy.context.object.modifiers["Solidify"].thickness = 0.1 bpy.ops.object.modifier_add(type='BEVEL') bpy.context.object.modifiers["Bevel"].width = 0.01 bpy.context.object.modifiers["Bevel"].segments = 2 return {'FINISHED'}
from mathutils import noise import numpy as np import bpy segment = np.pi + 0.1 xoff = np.interp(np.cos(segment), [-1, 1], [2, 7]) yoff = np.interp(np.sin(segment), [-1, 1], [2, 7]) zoff = 0.4 pos = np.array([xoff, yoff, zoff]) val = noise.noise(pos) radius = np.interp(val, [0, 1], [2, 7]) print(xoff, yoff, zoff) print(val, radius) """ from mathutils import noise import numpy as np import bpy import bmesh class PerlinCircle: def __init def perlin_circle(bm, param): circle_segments = np.linspace(0, 2*np.pi, param["n_segments"]) center = np.array([-1,-1,0]) radius = 2