Mesh Terrain Cutter.py
De DigiWiki.
v1 for Blender 2.65 and <
import bpy ### # # INPUT PARAMETERS # ### POINTS_PER_REGION = 256 N_REGIONS_X = 4 N_REGIONS_Y = 8 MAX_HEIGHT = 48 HEIGHTMAP_PATH = 'C:/Users/crista/tmp/uppsala_2_terrain_geometry_master.bmp' NAME = 'uppsala' ### # # MAIN ACTIONS # ### # delete all objects from the scene def reset_scene(): print('Reseting scene...') bpy.ops.object.select_all(action='DESELECT') for o in bpy.data.objects: # leave the camera and the lamp if o.name != 'Lamp' and o.name != 'Camera': o.select= True # delete them bpy.ops.object.delete() # delete the meshes for item in bpy.data.meshes: bpy.data.meshes.remove(item) def create_unit_plane(): print('Creating unit plane...') # Define the coordinates of the vertices. Each vertex is defined by 3 consecutive floats. vertices=[(-1.0, -1.0, 0), (1.0, -1.0, 0), (1.0, 1.0 , 0), (-1.0, 1.0, 0)] # Define the faces by index numbers. Each faces is defined by 4 consecutive integers. # For triangles you need to repeat the first vertex also in the fourth position. faces=[ (0,1,2,3)] me = bpy.data.meshes.new("PlaneMesh") # create a new mesh ob = bpy.data.objects.new("Plane", me) # create an object with that mesh ob.location = (0, 0, 0) #bpy.context.scene.cursor_location # position object at 3d-cursor bpy.context.scene.objects.link(ob) # Link object to scene # Fill the mesh with verts, edges, faces me.from_pydata(vertices,[],faces) # edges or faces should be [], or you ask for problems me.update(calc_edges=True) # Update mesh with new data def subdivide(): print('Subdividing...') bpy.data.objects['Plane'].select = True bpy.context.scene.objects.active = bpy.data.objects['Plane'] bpy.ops.object.mode_set(mode='EDIT', toggle=False) bpy.ops.mesh.subdivide(number_cuts=256) bpy.ops.object.mode_set(mode='OBJECT', toggle=False) def add_array_modifiers(): print('Adding array modifiers...') bpy.ops.object.modifier_add(type='ARRAY') bpy.context.object.modifiers['Array'].name = 'ARRAY_X' bpy.context.object.modifiers['ARRAY_X'].relative_offset_displace = [1, 0, 0] bpy.context.object.modifiers['ARRAY_X'].count=4 bpy.ops.object.modifier_add(type='ARRAY') bpy.context.object.modifiers['Array'].name = 'ARRAY_Y' bpy.context.object.modifiers['ARRAY_Y'].relative_offset_displace = [0, 1, 0] bpy.context.object.modifiers['ARRAY_Y'].count=8 def load_heightmap(): print('Loading heightmap...') try: heightmap = bpy.data.images.load(HEIGHTMAP_PATH) except: raise NameError("Cannot load image %s" % HEIGHTMAP_PATH) cTex = bpy.data.textures.new('Heightmap', type = 'IMAGE') cTex.image = heightmap cTex.extension = 'EXTEND' cTex.crop_max_x = 1/N_REGIONS_X cTex.crop_max_y = 1/N_REGIONS_Y def add_displace_modifier(): print('Adding displace modifier...') bpy.ops.object.modifier_add(type='DISPLACE') bpy.context.object.modifiers['Displace'].name = 'DISPLACEMENT' bpy.context.object.modifiers['DISPLACEMENT'].texture = bpy.data.textures['Heightmap'] bpy.context.object.modifiers['DISPLACEMENT'].strength = MAX_HEIGHT/POINTS_PER_REGION bpy.ops.object.shade_smooth() bpy.data.objects['Plane'].location = (0, 0, 0) def apply_modifiers(): print('Applying all modifiers') bpy.ops.object.modifier_apply(modifier='ARRAY_X') bpy.ops.object.modifier_apply(modifier='ARRAY_Y') bpy.ops.object.modifier_apply(modifier='DISPLACEMENT') def split(): print('Spliting the mesh into individual regions...') bpy.ops.object.mode_set(mode='EDIT', toggle=False) bpy.ops.mesh.separate(type='LOOSE') bpy.ops.object.mode_set(mode='OBJECT', toggle=False) # Give the right name to the last one bpy.data.objects['Plane'].name = 'Plane.%03d' % (N_REGIONS_X*N_REGIONS_Y) bpy.data.meshes['PlaneMesh'].name = 'PlaneMesh.%03d' % (N_REGIONS_X*N_REGIONS_Y) # Set the origin for all objects and rename them bpy.ops.object.select_all(action='DESELECT') for o in bpy.data.objects: if o.name.startswith('Plane'): o.select = True bpy.context.scene.objects.active = o bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY') bpy.context.scene.cursor_location = o.location bpy.context.scene.cursor_location[2] = -0.5 # z = -0.5 bpy.ops.object.origin_set(type='ORIGIN_CURSOR') o.name = o.name.replace('Plane', NAME) o.select = False reset_scene() create_unit_plane() subdivide() add_array_modifiers() load_heightmap() add_displace_modifier() apply_modifiers() split()
v2 for Blender 2.66 and >
import bpy import mathutils ### # # INPUT PARAMETERS # ### POINTS_PER_REGION = 256 N_REGIONS_X = 10 N_REGIONS_Y = 10 MAX_HEIGHT = 152.4 HEIGHTMAP_PATH = 'E:/Encitra/SanJose_Oakridge-Collada/SanJose_Oakridge-Cropped3-Terrain_Heightmap3.bmp' #TEXTURE_PATH = 'D:/encitra terrain/test3/uppsala_{0}_{1}.tga' COLLADA_PATH = 'E:/Encitra/SanJose_Oakridge-Collada/test1/sanjose_{0}_{1}.dae' NAME = 'sanjose' ### # # MAIN ACTIONS # ### # delete all objects from the scene def reset_scene(): print('Reseting scene...') bpy.ops.object.select_all(action='DESELECT') for o in bpy.data.objects: # leave the camera and the lamp if o.name != 'Lamp' and o.name != 'Camera': o.select= True # delete them bpy.ops.object.delete() # delete the meshes for item in bpy.data.meshes: bpy.data.meshes.remove(item) def create_unit_plane(): print('Creating unit plane...') # Define the coordinates of the vertices. Each vertex is defined by 3 consecutive floats. vertices=[(-1.0, -1.0, 0), (1.0, -1.0, 0), (1.0, 1.0 , 0), (-1.0, 1.0, 0)] # Define the faces by index numbers. Each faces is defined by 4 consecutive integers. # For triangles you need to repeat the first vertex also in the fourth position. faces=[ (0,1,2,3)] me = bpy.data.meshes.new("PlaneMesh") # create a new mesh ob = bpy.data.objects.new("Plane", me) # create an object with that mesh ob.location = (0, 0, 0) #bpy.context.scene.cursor_location # position object at 3d-cursor bpy.context.scene.objects.link(ob) # Link object to scene # Fill the mesh with verts, edges, faces me.from_pydata(vertices,[],faces) # edges or faces should be [], or you ask for problems me.update(calc_edges=True) # Update mesh with new data def subdivide(): print('Subdividing...') bpy.data.objects['Plane'].select = True bpy.context.scene.objects.active = bpy.data.objects['Plane'] bpy.ops.object.mode_set(mode='EDIT', toggle=False) bpy.ops.mesh.subdivide(number_cuts=256) bpy.ops.object.mode_set(mode='OBJECT', toggle=False) def add_array_modifiers(): print('Adding array modifiers...') bpy.ops.object.modifier_add(type='ARRAY') bpy.context.object.modifiers['Array'].name = 'ARRAY_X' bpy.context.object.modifiers['ARRAY_X'].relative_offset_displace = [1, 0, 0] bpy.context.object.modifiers['ARRAY_X'].count=10 bpy.ops.object.modifier_add(type='ARRAY') bpy.context.object.modifiers['Array'].name = 'ARRAY_Y' bpy.context.object.modifiers['ARRAY_Y'].relative_offset_displace = [0, 1, 0] bpy.context.object.modifiers['ARRAY_Y'].count=10 def load_heightmap(): print('Loading heightmap...') try: heightmap = bpy.data.images.load(HEIGHTMAP_PATH) except: raise NameError("Cannot load image %s" % HEIGHTMAP_PATH) cTex = bpy.data.textures.new('Heightmap', type = 'IMAGE') cTex.image = heightmap cTex.extension = 'EXTEND' cTex.crop_max_x = 1/N_REGIONS_X cTex.crop_max_y = 1/N_REGIONS_Y def add_displace_modifier(): print('Adding displace modifier...') bpy.ops.object.modifier_add(type='DISPLACE') bpy.context.object.modifiers['Displace'].name = 'DISPLACEMENT' bpy.context.object.modifiers['DISPLACEMENT'].texture = bpy.data.textures['Heightmap'] bpy.context.object.modifiers['DISPLACEMENT'].strength = MAX_HEIGHT/POINTS_PER_REGION bpy.ops.object.shade_smooth() bpy.data.objects['Plane'].location = (0, 0, 0) def apply_modifiers(): print('Applying all modifiers') bpy.ops.object.modifier_apply(modifier='ARRAY_X') bpy.ops.object.modifier_apply(modifier='ARRAY_Y') bpy.ops.object.modifier_apply(modifier='DISPLACEMENT') def split(): print('Spliting the mesh into individual regions...') bpy.ops.object.mode_set(mode='EDIT', toggle=False) bpy.ops.mesh.separate(type='LOOSE') bpy.ops.object.mode_set(mode='OBJECT', toggle=False) # Give the right name to the last one bpy.data.objects['Plane'].name = 'Plane.%03d' % (N_REGIONS_X*N_REGIONS_Y) bpy.data.meshes['PlaneMesh'].name = 'PlaneMesh.%03d' % (N_REGIONS_X*N_REGIONS_Y) # Set the origin for all objects bpy.ops.object.select_all(action='DESELECT') for o in bpy.data.objects: if o.name.startswith('Plane'): o.select = True bpy.context.scene.objects.active = o bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY') bpy.context.scene.cursor_location = o.location bpy.context.scene.cursor_location[2] = -(MAX_HEIGHT/256) # -(MAX_HEIGHT/256) bpy.ops.object.origin_set(type='ORIGIN_CURSOR') o.select = False # Change the names of the objects and meshes for i in range(N_REGIONS_X*N_REGIONS_Y): y = int(i / N_REGIONS_X) x = i % N_REGIONS_X name = 'Plane.%03d' % (i+1) bpy.data.objects[name].name = NAME + '_' + str(x) + '_' + str(y) name = 'PlaneMesh.%03d' % (i+1) bpy.data.meshes[name].name = NAME + 'Mesh_' + str(x) + '_' + str(y) def uvmap_and_export(): for x in range(N_REGIONS_X): for y in range(N_REGIONS_Y): ## load the image from the file #img_name = TEXTURE_PATH.format(x, y) #img = bpy.data.images.load(img_name) ## create a new texture #tex = bpy.data.textures.new(img_name, type='IMAGE') #tex.image = img # select the object and create the UV Map that allows it to be textured name = NAME + '_' + str(x) + '_' + str(y) bpy.data.objects[name].select = True bpy.context.scene.objects.active = bpy.data.objects[name] bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_all(action='SELECT') bpy.ops.uv.cube_project(clip_to_bounds=True) bpy.ops.object.mode_set(mode='OBJECT') # create the material mat = bpy.data.materials.new('aerial_{0}_{1}'.format(x, y)) mat.diffuse_intensity = 1 mat.diffuse_color = mathutils.Vector((1, 1, 1)) mat_entry = mat.texture_slots.add() mat_entry.texture = bpy.data.textures['Tex'] mat_entry.texture_coords = 'UV' # link the material to the object bpy.context.object.data.materials.append(mat) # export filename = COLLADA_PATH.format(x, y) bpy.ops.wm.collada_export(filepath=filename, selected=True, include_uv_textures=True, include_material_textures=True) bpy.data.objects[name].select = False reset_scene() create_unit_plane() subdivide() add_array_modifiers() load_heightmap() add_displace_modifier() apply_modifiers() split() uvmap_and_export()