mirror of
https://github.com/blender/blender-addons.git
synced 2025-08-16 15:35:05 +00:00
796 lines
28 KiB
Python
796 lines
28 KiB
Python
# ##### 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_info = {
|
|
"name": "ANT Landscape",
|
|
"author": "Jimmy Hazevoet",
|
|
"version": (0, 1, 4),
|
|
"blender": (2, 77, 0),
|
|
"location": "View3D > Add > Mesh",
|
|
"description": "Add a landscape primitive",
|
|
"warning": "", # used for warning icon and text in addons panel
|
|
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
|
|
"Scripts/Add_Mesh/ANT_Landscape",
|
|
"tracker_url": "https://developer.blender.org/maniphest/task/create/?project=3&type=Bug",
|
|
"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.
|
|
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.
|
|
X_Offset: Noise x offset in blender units (make tiled terrain)
|
|
Y_Offset: Noise y offset 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, fBm, hybridMFractal, heteroTerrain, Turbulence, Distorted Noise, Marble, Shattered_hTerrain, Strata_hTerrain, Planet_noise
|
|
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 mathutils.noise import *
|
|
from math import *
|
|
|
|
|
|
# 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).
|
|
def create_mesh_object(context, verts, edges, faces, name):
|
|
# 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()
|
|
|
|
from bpy_extras import object_utils
|
|
return object_utils.object_data_add(context, mesh, operator=None)
|
|
|
|
###------------------------------------------------------------
|
|
###------------------------------------------------------------
|
|
# 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 )
|
|
|
|
# planet_noise by Farsthary: https://blenderartists.org/forum/showthread.php?202944-New-quot-Planet-quot-procedural-texture-by-Farsthary
|
|
def planet_noise(coords, oct=6, hard=0, noisebasis=1, nabla=0.001):
|
|
x,y,z = coords
|
|
d = 0.001
|
|
offset = nabla * 1000
|
|
x = turbulence((x, y, z), oct, hard, noisebasis)
|
|
y = turbulence((x + offset, y , z), oct, hard, noisebasis)
|
|
z = turbulence((x, y + offset, z), oct, hard, noisebasis)
|
|
xdy = x - turbulence((x, y + d, z), oct, hard, noisebasis)
|
|
xdz = x - turbulence((x, y, z + d), oct, hard, noisebasis)
|
|
ydx = y - turbulence((x + d, y, z), oct, hard, noisebasis)
|
|
ydz = y - turbulence((x, y, z + d), oct, hard, noisebasis)
|
|
zdx = z - turbulence((x + d, y, z), oct, hard, noisebasis)
|
|
zdy = z - turbulence((x, y + d, z), oct, hard, noisebasis)
|
|
return (zdy - ydz), (zdx - xdz), (ydx - xdy)
|
|
|
|
###------------------------------------------------------------
|
|
# landscape_gen
|
|
def landscape_gen(x,y,z,falloffsize,options=[0,1.0,'multi_fractal', 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,0.0,0.0]):
|
|
|
|
# options
|
|
rseed = options[0]
|
|
nsize = options[1]
|
|
ntype = options[2]
|
|
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]
|
|
x_offset = options[24]
|
|
y_offset = options[25]
|
|
|
|
# origin
|
|
if rseed == 0:
|
|
origin = 0.0,0.0,0.0
|
|
origin_x = x_offset
|
|
origin_y = y_offset
|
|
origin_z = 0.0
|
|
else:
|
|
# randomise origin
|
|
seed_set( rseed )
|
|
origin = random_unit_vector()
|
|
origin_x = (( 0.5 - origin[0] ) * 1000.0) + x_offset
|
|
origin_y = (( 0.5 - origin[1] ) * 1000.0) + y_offset
|
|
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 == 'multi_fractal': value = multi_fractal( ncoords, dimension, lacunarity, depth, nbasis ) * 0.5
|
|
elif ntype == 'ridged_multi_fractal': value = ridged_multi_fractal( ncoords, dimension, lacunarity, depth, offset, gain, nbasis ) * 0.5
|
|
elif ntype == 'hybrid_multi_fractal': value = hybrid_multi_fractal( ncoords, dimension, lacunarity, depth, offset, gain, nbasis ) * 0.5
|
|
elif ntype == 'hetero_terrain': value = hetero_terrain( ncoords, dimension, lacunarity, depth, offset, nbasis ) * 0.25
|
|
elif ntype == 'fractal': value = fractal( ncoords, dimension, lacunarity, depth, nbasis )
|
|
elif ntype == 'turbulence_vector': value = turbulence_vector( ncoords, depth, hardnoise, nbasis )[0]
|
|
elif ntype == 'variable_lacunarity': value = variable_lacunarity( ncoords, distortion, nbasis, vlbasis ) + 0.5
|
|
elif ntype == 'marble_noise': 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 == 'shattered_hterrain': value = shattered_hterrain( ncoords[0], ncoords[1], ncoords[2], dimension, lacunarity, depth, offset, distortion, nbasis )
|
|
elif ntype == 'strata_hterrain': value = strata_hterrain( ncoords[0], ncoords[1], ncoords[2], dimension, lacunarity, depth, offset, distortion, nbasis )
|
|
elif ntype == 'planet_noise': value = planet_noise(ncoords, depth, hardnoise, nbasis)[2]*0.5+0.5
|
|
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, hypot(x * x, y * y), hypot(x, y), abs(y), abs(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 ):
|
|
# mesh arrays
|
|
verts = []
|
|
faces = []
|
|
|
|
# fill verts array
|
|
for i in range (0, sub_d):
|
|
for j in range(0,sub_d):
|
|
u = (i/sub_d-1/2)
|
|
v = (j/sub_d-1/2)
|
|
x = size_me*u
|
|
y = size_me*v
|
|
z = landscape_gen(x,y,0.0,size_me,options)
|
|
vert = (x,y,z)
|
|
verts.append(vert)
|
|
|
|
# fill faces array
|
|
count = 0
|
|
for i in range (0, sub_d *(sub_d-1)):
|
|
if count < sub_d-1:
|
|
A = i+1
|
|
B = i
|
|
C = (i+sub_d)
|
|
D = (i+sub_d)+1
|
|
face = (A,B,C,D)
|
|
faces.append(face)
|
|
count = count + 1
|
|
else:
|
|
count = 0
|
|
|
|
return verts, faces
|
|
|
|
# generate sphere
|
|
def sphere_gen( sub_d, size_me, options ):
|
|
# mesh arrays
|
|
verts = []
|
|
faces = []
|
|
|
|
# fill verts array
|
|
for i in range (0, sub_d):
|
|
for j in range(0,sub_d):
|
|
u = sin(j*pi*2/(sub_d-1)) * cos(-pi/2+i*pi/(sub_d-1)) * size_me/2
|
|
v = cos(j*pi*2/(sub_d-1)) * cos(-pi/2+i*pi/(sub_d-1)) * size_me/2
|
|
w = sin(-pi/2+i*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
|
|
vert = (u,v,w)
|
|
verts.append(vert)
|
|
|
|
# fill faces array
|
|
count = 0
|
|
for i in range (0, sub_d *(sub_d-1)):
|
|
if count < sub_d-1:
|
|
A = i+1
|
|
B = i
|
|
C = (i+sub_d)
|
|
D = (i+sub_d)+1
|
|
face = (A,B,C,D)
|
|
faces.append(face)
|
|
count = count + 1
|
|
else:
|
|
count = 0
|
|
|
|
return verts, faces
|
|
|
|
###------------------------------------------------------------
|
|
# Add landscape
|
|
class landscape_add(bpy.types.Operator):
|
|
"""Add a landscape mesh"""
|
|
bl_idname = "mesh.landscape_add"
|
|
bl_label = "Landscape"
|
|
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
|
|
bl_description = "Add landscape mesh"
|
|
|
|
# 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=128,
|
|
description="Mesh x y subdivisions")
|
|
|
|
MeshSize = FloatProperty(name="Mesh Size",
|
|
min=0.01,
|
|
max=100000.0,
|
|
default=2.0,
|
|
description="Mesh size")
|
|
|
|
XOffset = FloatProperty(name="X Offset",
|
|
default=0.0,
|
|
description="X Offset")
|
|
|
|
YOffset = FloatProperty(name="Y Offset",
|
|
default=0.0,
|
|
description="Y Offset")
|
|
|
|
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 = [
|
|
('multi_fractal',"multiFractal","multiFractal"),
|
|
('ridged_multi_fractal',"ridgedMFractal","ridgedMFractal"),
|
|
('hybrid_multi_fractal',"hybridMFractal","hybridMFractal"),
|
|
('hetero_terrain',"heteroTerrain","heteroTerrain"),
|
|
('fractal',"fBm","fBm"),
|
|
('turbulence_vector',"Turbulence","Turbulence"),
|
|
('variable_lacunarity',"Distorted Noise","Distorted Noise"),
|
|
('marble_noise',"Marble","Marble"),
|
|
('shattered_hterrain',"Shattered_hTerrain","Shattered_hTerrain"),
|
|
('strata_hterrain',"Strata_hTerrain","Strata_hTerrain"),
|
|
('planet_noise',"Planet_Noise","Planet_Noise")]
|
|
|
|
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=8,
|
|
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=5.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.prop(self, 'XOffset')
|
|
box.prop(self, 'YOffset')
|
|
|
|
box = layout.box()
|
|
box.prop(self, 'NoiseType')
|
|
if self.NoiseType != 'marble_noise':
|
|
box.prop(self, 'BasisType')
|
|
box.prop(self, 'RandomSeed')
|
|
box.prop(self, 'NoiseSize')
|
|
if self.NoiseType == 'multi_fractal':
|
|
box.prop(self, 'NoiseDepth')
|
|
box.prop(self, 'mDimension')
|
|
box.prop(self, 'mLacunarity')
|
|
elif self.NoiseType == 'ridged_multi_fractal':
|
|
box.prop(self, 'NoiseDepth')
|
|
box.prop(self, 'mDimension')
|
|
box.prop(self, 'mLacunarity')
|
|
box.prop(self, 'mOffset')
|
|
box.prop(self, 'mGain')
|
|
elif self.NoiseType == 'hybrid_multi_fractal':
|
|
box.prop(self, 'NoiseDepth')
|
|
box.prop(self, 'mDimension')
|
|
box.prop(self, 'mLacunarity')
|
|
box.prop(self, 'mOffset')
|
|
box.prop(self, 'mGain')
|
|
elif self.NoiseType == 'hetero_terrain':
|
|
box.prop(self, 'NoiseDepth')
|
|
box.prop(self, 'mDimension')
|
|
box.prop(self, 'mLacunarity')
|
|
box.prop(self, 'mOffset')
|
|
elif self.NoiseType == 'fractal':
|
|
box.prop(self, 'NoiseDepth')
|
|
box.prop(self, 'mDimension')
|
|
box.prop(self, 'mLacunarity')
|
|
elif self.NoiseType == 'turbulence_vector':
|
|
box.prop(self, 'NoiseDepth')
|
|
box.prop(self, 'HardNoise')
|
|
elif self.NoiseType == 'variable_lacunarity':
|
|
box.prop(self, 'VLBasisType')
|
|
box.prop(self, 'Distortion')
|
|
elif self.NoiseType == 'marble_noise':
|
|
box.prop(self, 'MarbleShape')
|
|
box.prop(self, 'MarbleBias')
|
|
box.prop(self, 'MarbleSharp')
|
|
box.prop(self, 'Distortion')
|
|
box.prop(self, 'NoiseDepth')
|
|
box.prop(self, 'HardNoise')
|
|
elif self.NoiseType == 'shattered_hterrain':
|
|
box.prop(self, 'NoiseDepth')
|
|
box.prop(self, 'mDimension')
|
|
box.prop(self, 'mLacunarity')
|
|
box.prop(self, 'mOffset')
|
|
box.prop(self, 'Distortion')
|
|
elif self.NoiseType == 'strata_hterrain':
|
|
box.prop(self, 'NoiseDepth')
|
|
box.prop(self, 'mDimension')
|
|
box.prop(self, 'mLacunarity')
|
|
box.prop(self, 'mOffset')
|
|
box.prop(self, 'Distortion')
|
|
elif self.NoiseType == 'planet_noise':
|
|
box.prop(self, 'NoiseDepth')
|
|
box.prop(self, 'HardNoise')
|
|
|
|
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):
|
|
|
|
#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 when in object mode
|
|
if bpy.ops.object.select_all.poll():
|
|
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
|
|
self.XOffset, #24
|
|
self.YOffset #25
|
|
]
|
|
|
|
# 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")
|
|
|
|
# sphere, remove doubles
|
|
if self.SphereMesh !=0:
|
|
bpy.ops.object.mode_set(mode='EDIT')
|
|
bpy.ops.mesh.remove_doubles(threshold=0.0001)
|
|
bpy.ops.object.mode_set(mode='OBJECT')
|
|
|
|
# Shade smooth
|
|
if self.SmoothMesh !=0:
|
|
if bpy.ops.object.shade_smooth.poll():
|
|
bpy.ops.object.shade_smooth()
|
|
else: # edit mode
|
|
bpy.ops.mesh.faces_shade_smooth()
|
|
|
|
# restore pre operator undo state
|
|
bpy.context.user_preferences.edit.use_global_undo = undo
|
|
|
|
return {'FINISHED'}
|
|
else:
|
|
return {'PASS_THROUGH'}
|
|
|
|
|
|
###------------------------------------------------------------
|
|
# Register
|
|
|
|
# Define "Landscape" menu
|
|
def menu_func_landscape(self, context):
|
|
self.layout.operator(landscape_add.bl_idname, text="Landscape", icon="RNDCURVE")
|
|
|
|
def register():
|
|
bpy.utils.register_module(__name__)
|
|
|
|
bpy.types.INFO_MT_mesh_add.append(menu_func_landscape)
|
|
|
|
def unregister():
|
|
bpy.utils.unregister_module(__name__)
|
|
|
|
bpy.types.INFO_MT_mesh_add.remove(menu_func_landscape)
|
|
|
|
if __name__ == "__main__":
|
|
register()
|