-
Luca Bonavita authored
READ THIS TO AVOID A LOT OF WORK! New way of linking to tracker pages: just use the parameter "aid" (artifact ID), to avoid a lot of manual updates later in wiki and svn. Example: ========= OLD WAY TO LINK TO TRACKER ----------------------------- Complete url of a script in Upload http://projects.blender.org/tracker/index.php?func=detail&aid=25349&group_id=153&atid=467 If we move this in contrib this url will become http://projects.blender.org/tracker/index.php?func=detail&aid=25349&group_id=153&atid=468 467 becomes 468, so we have to update this in wiki page. Later on, when this moves into Trunk, the url will become http://projects.blender.org/tracker/index.php?func=detail&aid=25349&group_id=153&atid=469 468 becomes 469, so we have to update the url in wiki page and svn. Annoying! NEW WAY TO LINK TO TRACKER ----------------------------- Best way to link to tracker page is using: http://projects.blender.org/tracker/index.php?func=detail&aid=25349 Use "func=detail" Use "aid" (which is the "artifact ID") DON'T use "group_id" (which is the project ID, bf-extensions is project 153) DON'T use "atid" (which is the "artifacts tracker ID") Like this, the url is unique, and we will avoid to update wiki pages and svn after moving pages [[Split portion of a mixed commit.]]
Luca Bonavita authoredREAD THIS TO AVOID A LOT OF WORK! New way of linking to tracker pages: just use the parameter "aid" (artifact ID), to avoid a lot of manual updates later in wiki and svn. Example: ========= OLD WAY TO LINK TO TRACKER ----------------------------- Complete url of a script in Upload http://projects.blender.org/tracker/index.php?func=detail&aid=25349&group_id=153&atid=467 If we move this in contrib this url will become http://projects.blender.org/tracker/index.php?func=detail&aid=25349&group_id=153&atid=468 467 becomes 468, so we have to update this in wiki page. Later on, when this moves into Trunk, the url will become http://projects.blender.org/tracker/index.php?func=detail&aid=25349&group_id=153&atid=469 468 becomes 469, so we have to update the url in wiki page and svn. Annoying! NEW WAY TO LINK TO TRACKER ----------------------------- Best way to link to tracker page is using: http://projects.blender.org/tracker/index.php?func=detail&aid=25349 Use "func=detail" Use "aid" (which is the "artifact ID") DON'T use "group_id" (which is the project ID, bf-extensions is project 153) DON'T use "atid" (which is the "artifacts tracker ID") Like this, the url is unique, and we will avoid to update wiki pages and svn after moving pages [[Split portion of a mixed commit.]]
add_mesh_ant_landscape.py 29.68 KiB
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
bl_addon_info = {
"name": "ANT Landscape",
"author": "Jimmy Hazevoet",
"version": (0,1,0),
"blender": (2, 5, 4),
"api": 32411,
"location": "Add Mesh menu",
"description": "Adds a landscape primitive",
"warning": "", # used for warning icon and text in addons panel
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
"Scripts/Add_Mesh/ANT_Landscape",
"tracker_url": "https://projects.blender.org/tracker/index.php?"\
"func=detail&aid=23130",
"category": "Add Mesh"}
'''
Another Noise Tool: Landscape mesh generator
MESH OPTIONS:
Mesh update: Turn this on for interactive mesh update.
Sphere: Generate sphere or a grid mesh. (Turn height falloff off for sphere mesh)
Smooth: Generate smooth shaded mesh.
Subdivision: Number of mesh subdivisions, higher numbers gives more detail but also slows down the script.
Mesh size: X,Y size of the grid mesh (in blender units).
NOISE OPTIONS: ( Most of these options are the same as in blender textures. )
Random seed: Use this to randomise the origin of the noise function.
Noise size: Size of the noise.
Noise type: Available noise types: multiFractal, ridgedMFractal, hybridMFractal, heteroTerrain, Turbulence, Distorted Noise, Cellnoise, Shattered_hTerrain, Marble
Noise basis: Blender, Perlin, NewPerlin, Voronoi_F1, Voronoi_F2, Voronoi_F3, Voronoi_F4, Voronoi_F2-F1, Voronoi Crackle, Cellnoise
VLNoise basis: Blender, Perlin, NewPerlin, Voronoi_F1, Voronoi_F2, Voronoi_F3, Voronoi_F4, Voronoi_F2-F1, Voronoi Crackle, Cellnoise
Distortion: Distortion amount.
Hard: Hard/Soft turbulence noise.
Depth: Noise depth, number of frequencies in the fBm.
Dimension: Musgrave: Fractal dimension of the roughest areas.
Lacunarity: Musgrave: Gap between successive frequencies.
Offset: Musgrave: Raises the terrain from sea level.
Gain: Musgrave: Scale factor.
Marble Bias: Sin, Tri, Saw
Marble Sharpnes: Soft, Sharp, Sharper
Marble Shape: Shape of the marble function: Default, Ring, Swirl, X, Y
HEIGHT OPTIONS:
Invert: Invert terrain height.
Height: Scale terrain height.
Offset: Terrain height offset.
Falloff: Terrain height falloff: Type 1, Type 2, X, Y
Sealevel: Flattens terrain below sealevel.
Platlevel: Flattens terrain above plateau level.
Strata: Strata amount, number of strata/terrace layers.
Strata type: Strata types, Smooth, Sharp-sub, Sharp-add
'''
# import modules
import bpy
from bpy.props import *
from mathutils import *
from noise import *
from math import *
###------------------------------------------------------------
# calculates the matrix for the new object depending on user pref
def align_matrix(context):
loc = Matrix.Translation(context.scene.cursor_location)
obj_align = context.user_preferences.edit.object_align
if (context.space_data.type == 'VIEW_3D'
and obj_align == 'VIEW'):
rot = context.space_data.region_3d.view_matrix.rotation_part().invert().resize4x4()
else:
rot = Matrix()
align_matrix = loc * rot
return align_matrix
# Create a new mesh (object) from verts/edges/faces.
# verts/edges/faces ... List of vertices/edges/faces for the
# new mesh (as used in from_pydata).
# name ... Name of the new mesh (& object).
# edit ... Replace existing mesh data.
# Note: Using "edit" will destroy/delete existing mesh data.
def create_mesh_object(context, verts, edges, faces, name, edit, align_matrix):
scene = context.scene
obj_act = scene.objects.active
# Can't edit anything, unless we have an active obj.
if edit and not obj_act:
return None
# Create new mesh
mesh = bpy.data.meshes.new(name)
# Make a mesh from a list of verts/edges/faces.
mesh.from_pydata(verts, edges, faces)
# Update mesh geometry after adding stuff.
mesh.update()
# Deselect all objects.
bpy.ops.object.select_all(action='DESELECT')
if edit:
# Replace geometry of existing object
# Use the active obj and select it.
ob_new = obj_act
ob_new.select = True
if obj_act.mode == 'OBJECT':
# Get existing mesh datablock.
old_mesh = ob_new.data
# Set object data to nothing
ob_new.data = None
# Clear users of existing mesh datablock.
old_mesh.user_clear()
# Remove old mesh datablock if no users are left.
if (old_mesh.users == 0):
bpy.data.meshes.remove(old_mesh)
# Assign new mesh datablock.
ob_new.data = mesh
else:
# Create new object
ob_new = bpy.data.objects.new(name, mesh)
# Link new object to the given scene and select it.
scene.objects.link(ob_new)
ob_new.select = True
# Place the object at the 3D cursor location.
# apply viewRotaion
ob_new.matrix_world = align_matrix
if obj_act and obj_act.mode == 'EDIT':
if not edit:
# We are in EditMode, switch to ObjectMode.
bpy.ops.object.mode_set(mode='OBJECT')
# Select the active object as well.
obj_act.select = True
# Apply location of new object.
scene.update()
# Join new object into the active.
bpy.ops.object.join()
# Switching back to EditMode.
bpy.ops.object.mode_set(mode='EDIT')
ob_new = obj_act
else:
# We are in ObjectMode.
# Make the new object the active one.
scene.objects.active = ob_new
return ob_new
# A very simple "bridge" tool.
# Connects two equally long vertex rows with faces.
# Returns a list of the new faces (list of lists)
#
# vertIdx1 ... First vertex list (list of vertex indices).
# vertIdx2 ... Second vertex list (list of vertex indices).
# closed ... Creates a loop (first & last are closed).
# flipped ... Invert the normal of the face(s).
#
# Note: You can set vertIdx1 to a single vertex index to create
# a fan/star of faces.
# Note: If both vertex idx list are the same length they have
# to have at least 2 vertices.
def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False):
faces = []
if not vertIdx1 or not vertIdx2:
return None
if len(vertIdx1) < 2 and len(vertIdx2) < 2:
return None
fan = False
if (len(vertIdx1) != len(vertIdx2)):
if (len(vertIdx1) == 1 and len(vertIdx2) > 1):
fan = True
else:
return None
total = len(vertIdx2)
if closed:
# Bridge the start with the end.
if flipped:
face = [
vertIdx1[0],
vertIdx2[0],
vertIdx2[total - 1]]
if not fan:
face.append(vertIdx1[total - 1])
faces.append(face)
else:
face = [vertIdx2[0], vertIdx1[0]]
if not fan:
face.append(vertIdx1[total - 1])
face.append(vertIdx2[total - 1])
faces.append(face)
# Bridge the rest of the faces.
for num in range(total - 1):
if flipped:
if fan:
face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]]
else:
face = [vertIdx2[num], vertIdx1[num],
vertIdx1[num + 1], vertIdx2[num + 1]]
faces.append(face)
else:
if fan:
face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]]
else:
face = [vertIdx1[num], vertIdx2[num],
vertIdx2[num + 1], vertIdx1[num + 1]]
faces.append(face)
return faces
###------------------------------------------------------------
###------------------------------------------------------------
# some functions for marble_noise
def sin_bias(a):
return 0.5 + 0.5 * sin(a)
def tri_bias(a):
b = 2 * pi
a = 1 - 2 * abs(floor((a * (1/b))+0.5) - (a*(1/b)))
return a
def saw_bias(a):
b = 2 * pi
n = int(a/b)
a -= n * b
if a < 0: a += b
return a / b
def soft(a):
return a
def sharp(a):
return a**0.5
def sharper(a):
return sharp(sharp(a))
def shapes(x,y,shape=0):
if shape == 1:
# ring
x = x*2
y = y*2
s = (-cos(x**2+y**2)/(x**2+y**2+0.5))
elif shape == 2:
# swirl
x = x*2
y = y*2
s = (( x*sin( x*x+y*y ) + y*cos( x*x+y*y ) ) / (x**2+y**2+0.5))
elif shape == 3:
# bumps
x = x*2
y = y*2
s = ((cos( x*pi ) + cos( y*pi ))-0.5)
elif shape == 4:
# y grad.
s = (y*pi)
elif shape == 5:
# x grad.
s = (x*pi)
else:
# marble
s = ((x+y)*5)
return s
# marble_noise
def marble_noise(x,y,z, origin, size, shape, bias, sharpnes, turb, depth, hard, basis ):
x = x / size
y = y / size
z = z / size
s = shapes(x,y,shape)
x += origin[0]
y += origin[1]
z += origin[2]
value = s + turb * turbulence_vector((x,y,z), depth, hard, basis )[0]
if bias == 1:
value = tri_bias( value )
elif bias == 2:
value = saw_bias( value )
else:
value = sin_bias( value )
if sharpnes == 1:
value = sharp( value )
elif sharpnes == 2:
value = sharper( value )
else:
value = soft( value )
return value
###------------------------------------------------------------
# custom noise types
# shattered_hterrain:
def shattered_hterrain( x,y,z, H, lacunarity, octaves, offset, distort, basis ):
d = ( turbulence_vector( ( x, y, z ), 6, 0, 0 )[0] * 0.5 + 0.5 )*distort*0.5
t1 = ( turbulence_vector( ( x+d, y+d, z ), 0, 0, 7 )[0] + 0.5 )
t2 = ( hetero_terrain(( x*2, y*2, z*2 ), H, lacunarity, octaves, offset, basis )*0.5 )
return (( t1*t2 )+t2*0.5) * 0.5
# strata_hterrain
def strata_hterrain( x,y,z, H, lacunarity, octaves, offset, distort, basis ):
value = hetero_terrain(( x, y, z ), H, lacunarity, octaves, offset, basis )*0.5
steps = ( sin( value*(distort*5)*pi ) * ( 0.1/(distort*5)*pi ) )
return ( value * (1.0-0.5) + steps*0.5 )
###------------------------------------------------------------
# landscape_gen
def landscape_gen(x,y,z,falloffsize,options=[0,1.0,1, 0,0,1.0,0,6,1.0,2.0,1.0,2.0,0,0,0, 1.0,0.0,1,0.0,1.0,0,0,0]):
# options
rseed = options[0]
nsize = options[1]
ntype = int( options[2][0] )
nbasis = int( options[3][0] )
vlbasis = int( options[4][0] )
distortion = options[5]
hardnoise = options[6]
depth = options[7]
dimension = options[8]
lacunarity = options[9]
offset = options[10]
gain = options[11]
marblebias = int( options[12][0] )
marblesharpnes = int( options[13][0] )
marbleshape = int( options[14][0] )
invert = options[15]
height = options[16]
heightoffset = options[17]
falloff = int( options[18][0] )
sealevel = options[19]
platlevel = options[20]
strata = options[21]
stratatype = options[22]
sphere = options[23]
# origin
if rseed == 0:
origin = 0.0,0.0,0.0
origin_x = 0.0
origin_y = 0.0
origin_z = 0.0
else:
# randomise origin
seed_set( rseed )
origin = random_unit_vector()
origin_x = ( 0.5 - origin[0] ) * 1000.0
origin_y = ( 0.5 - origin[1] ) * 1000.0
origin_z = ( 0.5 - origin[2] ) * 1000.0
# adjust noise size and origin
ncoords = ( x / nsize + origin_x, y / nsize + origin_y, z / nsize + origin_z )
# noise basis type's
if nbasis == 9: nbasis = 14 # to get cellnoise basis you must set 14 instead of 9
if vlbasis ==9: vlbasis = 14
# noise type's
if ntype == 0: value = multi_fractal( ncoords, dimension, lacunarity, depth, nbasis ) * 0.5
elif ntype == 1: value = ridged_multi_fractal( ncoords, dimension, lacunarity, depth, offset, gain, nbasis ) * 0.5
elif ntype == 2: value = hybrid_multi_fractal( ncoords, dimension, lacunarity, depth, offset, gain, nbasis ) * 0.5
elif ntype == 3: value = hetero_terrain( ncoords, dimension, lacunarity, depth, offset, nbasis ) * 0.25
elif ntype == 4: value = fractal( ncoords, dimension, lacunarity, depth, nbasis )
elif ntype == 5: value = turbulence_vector( ncoords, depth, hardnoise, nbasis )[0]
elif ntype == 6: value = vl_vector( ncoords, distortion, nbasis, vlbasis ) + 0.5
elif ntype == 7: value = marble_noise( x*2.0/falloffsize,y*2.0/falloffsize,z*2/falloffsize, origin, nsize, marbleshape, marblebias, marblesharpnes, distortion, depth, hardnoise, nbasis )
elif ntype == 8: value = shattered_hterrain( ncoords[0], ncoords[1], ncoords[2], dimension, lacunarity, depth, offset, distortion, nbasis )
elif ntype == 9: value = strata_hterrain( ncoords[0], ncoords[1], ncoords[2], dimension, lacunarity, depth, offset, distortion, nbasis )
else:
value = 0.0
# adjust height
if invert !=0:
value = (1-value) * height + heightoffset
else:
value = value * height + heightoffset
# edge falloff
if sphere == 0: # no edge falloff if spherical
if falloff != 0:
fallofftypes = [ 0, sqrt((x*x)**2+(y*y)**2), sqrt(x*x+y*y), sqrt(y*y), sqrt(x*x) ]
dist = fallofftypes[ falloff]
if falloff ==1:
radius = (falloffsize/2)**2
else:
radius = falloffsize/2
value = value - sealevel
if( dist < radius ):
dist = dist / radius
dist = ( (dist) * (dist) * ( 3-2*(dist) ) )
value = ( value - value * dist ) + sealevel
else:
value = sealevel
# strata / terrace / layered
if stratatype !='0':
strata = strata / height
if stratatype == '1':
strata *= 2
steps = ( sin( value*strata*pi ) * ( 0.1/strata*pi ) )
value = ( value * (1.0-0.5) + steps*0.5 ) * 2.0
elif stratatype == '2':
steps = -abs( sin( value*(strata)*pi ) * ( 0.1/(strata)*pi ) )
value =( value * (1.0-0.5) + steps*0.5 ) * 2.0
elif stratatype == '3':
steps = abs( sin( value*(strata)*pi ) * ( 0.1/(strata)*pi ) )
value =( value * (1.0-0.5) + steps*0.5 ) * 2.0
else:
value = value
# clamp height
if ( value < sealevel ): value = sealevel
if ( value > platlevel ): value = platlevel
return value
# generate grid
def grid_gen( sub_d, size_me, options ):
verts = []
faces = []
edgeloop_prev = []
delta = size_me / float(sub_d - 1)
start = -(size_me / 2.0)
for row_x in range(sub_d):
edgeloop_cur = []
x = start + row_x * delta
for row_y in range(sub_d):
y = start + row_y * delta
z = landscape_gen(x,y,0.0,size_me,options)
edgeloop_cur.append(len(verts))
verts.append((x,y,z))
if len(edgeloop_prev) > 0:
faces_row = createFaces(edgeloop_prev, edgeloop_cur)
faces.extend(faces_row)
edgeloop_prev = edgeloop_cur
return verts, faces
# generate sphere
def sphere_gen( sub_d, size_me, options ):
verts = []
faces = []
edgeloop_prev = []
for row_x in range(sub_d):
edgeloop_cur = []
for row_y in range(sub_d):
u = sin(row_y*pi*2/(sub_d-1)) * cos(-pi/2+row_x*pi/(sub_d-1)) * size_me/2
v = cos(row_y*pi*2/(sub_d-1)) * cos(-pi/2+row_x*pi/(sub_d-1)) * size_me/2
w = sin(-pi/2+row_x*pi/(sub_d-1)) * size_me/2
h = landscape_gen(u,v,w,size_me,options) / size_me
u,v,w = u+u*h, v+v*h, w+w*h
edgeloop_cur.append(len(verts))
verts.append((u, v, w))
if len(edgeloop_prev) > 0:
faces_row = createFaces(edgeloop_prev, edgeloop_cur)
faces.extend(faces_row)
edgeloop_prev = edgeloop_cur
return verts, faces
###------------------------------------------------------------
# Add landscape
class landscape_add(bpy.types.Operator):
'''Add a landscape mesh'''
bl_idname = "Add_landscape"
bl_label = "Landscape"
bl_options = {'REGISTER', 'UNDO'}
bl_description = "Add landscape mesh"
# edit - Whether to add or update.
edit = BoolProperty(name="",
description="",
default=False,
options={'HIDDEN'})
# align_matrix for the invoke
align_matrix = Matrix()
# properties
AutoUpdate = BoolProperty(name="Mesh update",
default=True,
description="Update mesh")
SphereMesh = BoolProperty(name="Sphere",
default=False,
description="Generate Sphere mesh")
SmoothMesh = BoolProperty(name="Smooth",
default=True,
description="Shade smooth")
Subdivision = IntProperty(name="Subdivisions",
min=4,
max=6400,
default=64,
description="Mesh x y subdivisions")
MeshSize = FloatProperty(name="Mesh Size",
min=0.01,
max=100000.0,
default=2.0,
description="Mesh size")
RandomSeed = IntProperty(name="Random Seed",
min=0,
max=9999,
default=0,
description="Randomize noise origin")
NoiseSize = FloatProperty(name="Noise Size",
min=0.01,
max=10000.0,
default=1.0,
description="Noise size")
NoiseTypes = [
("0","multiFractal","multiFractal"),
("1","ridgedMFractal","ridgedMFractal"),
("2","hybridMFractal","hybridMFractal"),
("3","heteroTerrain","heteroTerrain"),
("4","fBm","fBm"),
("5","Turbulence","Turbulence"),
("6","Distorted Noise","Distorted Noise"),
("7","Marble","Marble"),
("8","Shattered_hTerrain","Shattered_hTerrain"),
("9","Strata_hTerrain","Strata_hTerrain")]
NoiseType = EnumProperty(name="Type",
description="Noise type",
items=NoiseTypes)
BasisTypes = [
("0","Blender","Blender"),
("1","Perlin","Perlin"),
("2","NewPerlin","NewPerlin"),
("3","Voronoi_F1","Voronoi_F1"),
("4","Voronoi_F2","Voronoi_F2"),
("5","Voronoi_F3","Voronoi_F3"),
("6","Voronoi_F4","Voronoi_F4"),
("7","Voronoi_F2-F1","Voronoi_F2-F1"),
("8","Voronoi Crackle","Voronoi Crackle"),
("9","Cellnoise","Cellnoise")]
BasisType = EnumProperty(name="Basis",
description="Noise basis",
items=BasisTypes)
VLBasisTypes = [
("0","Blender","Blender"),
("1","Perlin","Perlin"),
("2","NewPerlin","NewPerlin"),
("3","Voronoi_F1","Voronoi_F1"),
("4","Voronoi_F2","Voronoi_F2"),
("5","Voronoi_F3","Voronoi_F3"),
("6","Voronoi_F4","Voronoi_F4"),
("7","Voronoi_F2-F1","Voronoi_F2-F1"),
("8","Voronoi Crackle","Voronoi Crackle"),
("9","Cellnoise","Cellnoise")]
VLBasisType = EnumProperty(name="VLBasis",
description="VLNoise basis",
items=VLBasisTypes)
Distortion = FloatProperty(name="Distortion",
min=0.01,
max=1000.0,
default=1.0,
description="Distortion amount")
HardNoise = BoolProperty(name="Hard",
default=True,
description="Hard noise")
NoiseDepth = IntProperty(name="Depth",
min=1,
max=16,
default=6,
description="Noise Depth - number of frequencies in the fBm.")
mDimension = FloatProperty(name="Dimension",
min=0.01,
max=2.0,
default=1.0,
description="H - fractal dimension of the roughest areas.")
mLacunarity = FloatProperty(name="Lacunarity",
min=0.01,
max=6.0,
default=2.0,
description="Lacunarity - gap between successive frequencies.")
mOffset = FloatProperty(name="Offset",
min=0.01,
max=6.0,
default=1.0,
description="Offset - raises the terrain from sea level.")
mGain = FloatProperty(name="Gain",
min=0.01,
max=6.0,
default=1.0,
description="Gain - scale factor.")
BiasTypes = [
("0","Sin","Sin"),
("1","Tri","Tri"),
("2","Saw","Saw")]
MarbleBias = EnumProperty(name="Bias",
description="Marble bias",
items=BiasTypes)
SharpTypes = [
("0","Soft","Soft"),
("1","Sharp","Sharp"),
("2","Sharper","Sharper")]
MarbleSharp = EnumProperty(name="Sharp",
description="Marble sharp",
items=SharpTypes)
ShapeTypes = [
("0","Default","Default"),
("1","Ring","Ring"),
("2","Swirl","Swirl"),
("3","Bump","Bump"),
("4","Y","Y"),
("5","X","X")]
MarbleShape = EnumProperty(name="Shape",
description="Marble shape",
items=ShapeTypes)
Invert = BoolProperty(name="Invert",
default=False,
description="Invert noise input")
Height = FloatProperty(name="Height",
min=0.01,
max=10000.0,
default=0.5,
description="Height scale")
Offset = FloatProperty(name="Offset",
min=-10000.0,
max=10000.0,
default=0.0,
description="Height offset")
fallTypes = [
("0","None","None"),
("1","Type 1","Type 1"),
("2","Type 2","Type 2"),
("3","Y","Y"),
("4","X","X")]
Falloff = EnumProperty(name="Falloff",
description="Edge falloff",
default="1",
items=fallTypes)
Sealevel = FloatProperty(name="Sealevel",
min=-10000.0,
max=10000.0,
default=0.0,
description="Sealevel")
Plateaulevel = FloatProperty(name="Plateau",
min=-10000.0,
max=10000.0,
default=1.0,
description="Plateau level")
Strata = FloatProperty(name="Strata",
min=0.01,
max=1000.0,
default=3.0,
description="Strata amount")
StrataTypes = [
("0","None","None"),
("1","Type 1","Type 1"),
("2","Type 2","Type 2"),
("3","Type 3","Type 3")]
StrataType = EnumProperty(name="Strata",
description="Strata type",
default="0",
items=StrataTypes)
###------------------------------------------------------------
# Draw
def draw(self, context):
layout = self.layout
box = layout.box()
box.prop(self, 'AutoUpdate')
box.prop(self, 'SphereMesh')
box.prop(self, 'SmoothMesh')
box.prop(self, 'Subdivision')
box.prop(self, 'MeshSize')
box = layout.box()
box.prop(self, 'NoiseType')
if self.NoiseType != '7':
box.prop(self, 'BasisType')
box.prop(self, 'RandomSeed')
box.prop(self, 'NoiseSize')
if self.NoiseType == '0':
box.prop(self, 'NoiseDepth')
box.prop(self, 'mDimension')
box.prop(self, 'mLacunarity')
if self.NoiseType == '1':
box.prop(self, 'NoiseDepth')
box.prop(self, 'mDimension')
box.prop(self, 'mLacunarity')
box.prop(self, 'mOffset')
box.prop(self, 'mGain')
if self.NoiseType == '2':
box.prop(self, 'NoiseDepth')
box.prop(self, 'mDimension')
box.prop(self, 'mLacunarity')
box.prop(self, 'mOffset')
box.prop(self, 'mGain')
if self.NoiseType == '3':
box.prop(self, 'NoiseDepth')
box.prop(self, 'mDimension')
box.prop(self, 'mLacunarity')
box.prop(self, 'mOffset')
if self.NoiseType == '4':
box.prop(self, 'NoiseDepth')
box.prop(self, 'mDimension')
box.prop(self, 'mLacunarity')
if self.NoiseType == '5':
box.prop(self, 'NoiseDepth')
box.prop(self, 'HardNoise')
if self.NoiseType == '6':
box.prop(self, 'VLBasisType')
box.prop(self, 'Distortion')
if self.NoiseType == '7':
box.prop(self, 'MarbleShape')
box.prop(self, 'MarbleBias')
box.prop(self, 'MarbleSharp')
box.prop(self, 'Distortion')
box.prop(self, 'NoiseDepth')
box.prop(self, 'HardNoise')
if self.NoiseType == '8':
box.prop(self, 'NoiseDepth')
box.prop(self, 'mDimension')
box.prop(self, 'mLacunarity')
box.prop(self, 'mOffset')
box.prop(self, 'Distortion')
if self.NoiseType == '9':
box.prop(self, 'NoiseDepth')
box.prop(self, 'mDimension')
box.prop(self, 'mLacunarity')
box.prop(self, 'mOffset')
box.prop(self, 'Distortion')
box = layout.box()
box.prop(self, 'Invert')
box.prop(self, 'Height')
box.prop(self, 'Offset')
box.prop(self, 'Plateaulevel')
box.prop(self, 'Sealevel')
if self.SphereMesh == False:
box.prop(self, 'Falloff')
box.prop(self, 'StrataType')
if self.StrataType != '0':
box.prop(self, 'Strata')
###------------------------------------------------------------
# Execute
def execute(self, context):
edit = self.edit
#mesh update
if self.AutoUpdate != 0:
# turn off undo
undo = bpy.context.user_preferences.edit.use_global_undo
bpy.context.user_preferences.edit.use_global_undo = False
# deselect all objects
bpy.ops.object.select_all(action='DESELECT')
# options
options = [
self.RandomSeed, #0
self.NoiseSize, #1
self.NoiseType, #2
self.BasisType, #3
self.VLBasisType, #4
self.Distortion, #5
self.HardNoise, #6
self.NoiseDepth, #7
self.mDimension, #8
self.mLacunarity, #9
self.mOffset, #10
self.mGain, #11
self.MarbleBias, #12
self.MarbleSharp, #13
self.MarbleShape, #14
self.Invert, #15
self.Height, #16
self.Offset, #17
self.Falloff, #18
self.Sealevel, #19
self.Plateaulevel, #20
self.Strata, #21
self.StrataType, #22
self.SphereMesh #23
]
# Main function
if self.SphereMesh !=0:
# sphere
verts, faces = sphere_gen( self.Subdivision, self.MeshSize, options )
else:
# grid
verts, faces = grid_gen( self.Subdivision, self.MeshSize, options )
# create mesh object
obj = create_mesh_object(context, verts, [], faces, "Landscape", edit, self.align_matrix)
# sphere, remove doubles
if self.SphereMesh !=0:
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.remove_doubles(limit=0.0001)
bpy.ops.object.mode_set(mode='OBJECT')
# Shade smooth
if self.SmoothMesh !=0:
bpy.ops.object.shade_smooth()
# restore pre operator undo state
bpy.context.user_preferences.edit.use_global_undo = undo
return {'FINISHED'}
else:
return {'PASS_THROUGH'}
def invoke(self, context, event):
self.align_matrix = align_matrix(context)
self.execute(context)
return {'FINISHED'}
###------------------------------------------------------------
# Register
import space_info
# Define "Landscape" menu
def menu_func_landscape(self, context):
self.layout.operator(landscape_add.bl_idname, text="Landscape", icon="PLUGIN")
def register():
space_info.INFO_MT_mesh_add.append(menu_func_landscape)
def unregister():
space_info.INFO_MT_mesh_add.remove(menu_func_landscape)
if __name__ == "__main__":
register()