Mesh Terrain Cutter.py
De DigiWiki.
(Différences entre les versions)
(Page créée avec « <python> 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_te… ») |
|||
Ligne 1 : | Ligne 1 : | ||
+ | v1 for Blender 2.65 and < | ||
<python> | <python> | ||
import bpy | import bpy | ||
Ligne 129 : | Ligne 130 : | ||
apply_modifiers() | apply_modifiers() | ||
split() | split() | ||
+ | </python> | ||
+ | |||
+ | v2 for Blender 2.66 and > | ||
+ | <python> | ||
+ | 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() | ||
</python> | </python> |
Version actuelle en date du 30 mai 2014 à 14:58
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()