Mesh Terrain Cutter Script for Blender (Python) v2

Archive of Mesh Files and Information related to Mesh, specifically Blender and Collada for OpenSimulator
Post Reply
User avatar
nebadon
Site Admin
Posts: 107
Joined: Mon Feb 11, 2008 5:46 pm

Wed Jan 29, 2014 9:39 am

Requires Blender 2.66

Code: Select all

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()


Post Reply
  • Information
  • Who is online

    Users browsing this forum: No registered users and 1 guest