Blender ANT Landscape Add-On Python


SUBMITTED BY: Guest

DATE: July 21, 2014, 11:44 p.m.

FORMAT: Text only

SIZE: 31.1 kB

HITS: 1000

  1. # ##### BEGIN GPL LICENSE BLOCK #####
  2. #
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the terms of the GNU General Public License
  5. # as published by the Free Software Foundation; either version 2
  6. # of the License, or (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software Foundation,
  15. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. #
  17. # ##### END GPL LICENSE BLOCK #####
  18. bl_info = {
  19. "name": "ANT Landscape",
  20. "author": "Jimmy Hazevoet",
  21. "version": (0,1,2),
  22. "blender": (2, 61, 0),
  23. "location": "View3D > Add > Mesh",
  24. "description": "Add a landscape primitive",
  25. "warning": "", # used for warning icon and text in addons panel
  26. "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
  27. "Scripts/Add_Mesh/ANT_Landscape",
  28. "tracker_url": "https://projects.blender.org/tracker/index.php?"\
  29. "func=detail&aid=23130",
  30. "category": "Add Mesh"}
  31. """
  32. Another Noise Tool: Landscape mesh generator
  33. MESH OPTIONS:
  34. Mesh update: Turn this on for interactive mesh update.
  35. Sphere: Generate sphere or a grid mesh. (Turn height falloff off for sphere mesh)
  36. Smooth: Generate smooth shaded mesh.
  37. Subdivision: Number of mesh subdivisions, higher numbers gives more detail but also slows down the script.
  38. Mesh size: X,Y size of the grid mesh (in blender units).
  39. NOISE OPTIONS: ( Most of these options are the same as in blender textures. )
  40. Random seed: Use this to randomise the origin of the noise function.
  41. Noise size: Size of the noise.
  42. Noise type: Available noise types: multiFractal, ridgedMFractal, hybridMFractal, heteroTerrain, Turbulence, Distorted Noise, Cellnoise, Shattered_hTerrain, Marble
  43. Noise basis: Blender, Perlin, NewPerlin, Voronoi_F1, Voronoi_F2, Voronoi_F3, Voronoi_F4, Voronoi_F2-F1, Voronoi Crackle, Cellnoise
  44. VLNoise basis: Blender, Perlin, NewPerlin, Voronoi_F1, Voronoi_F2, Voronoi_F3, Voronoi_F4, Voronoi_F2-F1, Voronoi Crackle, Cellnoise
  45. Distortion: Distortion amount.
  46. Hard: Hard/Soft turbulence noise.
  47. Depth: Noise depth, number of frequencies in the fBm.
  48. Dimension: Musgrave: Fractal dimension of the roughest areas.
  49. Lacunarity: Musgrave: Gap between successive frequencies.
  50. Offset: Musgrave: Raises the terrain from sea level.
  51. Gain: Musgrave: Scale factor.
  52. Marble Bias: Sin, Tri, Saw
  53. Marble Sharpnes: Soft, Sharp, Sharper
  54. Marble Shape: Shape of the marble function: Default, Ring, Swirl, X, Y
  55. HEIGHT OPTIONS:
  56. Invert: Invert terrain height.
  57. Height: Scale terrain height.
  58. Offset: Terrain height offset.
  59. Falloff: Terrain height falloff: Type 1, Type 2, X, Y
  60. Sealevel: Flattens terrain below sealevel.
  61. Platlevel: Flattens terrain above plateau level.
  62. Strata: Strata amount, number of strata/terrace layers.
  63. Strata type: Strata types, Smooth, Sharp-sub, Sharp-add
  64. """
  65. # import modules
  66. import bpy
  67. from bpy.props import *
  68. from mathutils import *
  69. from mathutils.noise import *
  70. from math import *
  71. # Create a new mesh (object) from verts/edges/faces.
  72. # verts/edges/faces ... List of vertices/edges/faces for the
  73. # new mesh (as used in from_pydata).
  74. # name ... Name of the new mesh (& object).
  75. def create_mesh_object(context, verts, edges, faces, name):
  76. # Create new mesh
  77. mesh = bpy.data.meshes.new(name)
  78. # Make a mesh from a list of verts/edges/faces.
  79. mesh.from_pydata(verts, edges, faces)
  80. # Update mesh geometry after adding stuff.
  81. mesh.update()
  82. from bpy_extras import object_utils
  83. return object_utils.object_data_add(context, mesh, operator=None)
  84. # A very simple "bridge" tool.
  85. # Connects two equally long vertex rows with faces.
  86. # Returns a list of the new faces (list of lists)
  87. #
  88. # vertIdx1 ... First vertex list (list of vertex indices).
  89. # vertIdx2 ... Second vertex list (list of vertex indices).
  90. # closed ... Creates a loop (first & last are closed).
  91. # flipped ... Invert the normal of the face(s).
  92. #
  93. # Note: You can set vertIdx1 to a single vertex index to create
  94. # a fan/star of faces.
  95. # Note: If both vertex idx list are the same length they have
  96. # to have at least 2 vertices.
  97. def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False):
  98. faces = []
  99. if not vertIdx1 or not vertIdx2:
  100. return None
  101. if len(vertIdx1) < 2 and len(vertIdx2) < 2:
  102. return None
  103. fan = False
  104. if (len(vertIdx1) != len(vertIdx2)):
  105. if (len(vertIdx1) == 1 and len(vertIdx2) > 1):
  106. fan = True
  107. else:
  108. return None
  109. total = len(vertIdx2)
  110. if closed:
  111. # Bridge the start with the end.
  112. if flipped:
  113. face = [
  114. vertIdx1[0],
  115. vertIdx2[0],
  116. vertIdx2[total - 1]]
  117. if not fan:
  118. face.append(vertIdx1[total - 1])
  119. faces.append(face)
  120. else:
  121. face = [vertIdx2[0], vertIdx1[0]]
  122. if not fan:
  123. face.append(vertIdx1[total - 1])
  124. face.append(vertIdx2[total - 1])
  125. faces.append(face)
  126. # Bridge the rest of the faces.
  127. for num in range(total - 1):
  128. if flipped:
  129. if fan:
  130. face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]]
  131. else:
  132. face = [vertIdx2[num], vertIdx1[num],
  133. vertIdx1[num + 1], vertIdx2[num + 1]]
  134. faces.append(face)
  135. else:
  136. if fan:
  137. face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]]
  138. else:
  139. face = [vertIdx1[num], vertIdx2[num],
  140. vertIdx2[num + 1], vertIdx1[num + 1]]
  141. faces.append(face)
  142. return faces
  143. ###------------------------------------------------------------
  144. ###------------------------------------------------------------
  145. # some functions for marble_noise
  146. def sin_bias(a):
  147. return 0.5 + 0.5 * sin(a)
  148. def tri_bias(a):
  149. b = 2 * pi
  150. a = 1 - 2 * abs(floor((a * (1/b))+0.5) - (a*(1/b)))
  151. return a
  152. def saw_bias(a):
  153. b = 2 * pi
  154. n = int(a/b)
  155. a -= n * b
  156. if a < 0: a += b
  157. return a / b
  158. def soft(a):
  159. return a
  160. def sharp(a):
  161. return a**0.5
  162. def sharper(a):
  163. return sharp(sharp(a))
  164. def shapes(x,y,shape=0):
  165. if shape == 1:
  166. # ring
  167. x = x*2
  168. y = y*2
  169. s = (-cos(x**2+y**2)/(x**2+y**2+0.5))
  170. elif shape == 2:
  171. # swirl
  172. x = x*2
  173. y = y*2
  174. s = (( x*sin( x*x+y*y ) + y*cos( x*x+y*y ) ) / (x**2+y**2+0.5))
  175. elif shape == 3:
  176. # bumps
  177. x = x*2
  178. y = y*2
  179. s = ((cos( x*pi ) + cos( y*pi ))-0.5)
  180. elif shape == 4:
  181. # y grad.
  182. s = (y*pi)
  183. elif shape == 5:
  184. # x grad.
  185. s = (x*pi)
  186. else:
  187. # marble
  188. s = ((x+y)*5)
  189. return s
  190. # marble_noise
  191. def marble_noise(x,y,z, origin, size, shape, bias, sharpnes, turb, depth, hard, basis ):
  192. x = x / size
  193. y = y / size
  194. z = z / size
  195. s = shapes(x,y,shape)
  196. x += origin[0]
  197. y += origin[1]
  198. z += origin[2]
  199. value = s + turb * turbulence_vector((x,y,z), depth, hard, basis )[0]
  200. if bias == 1:
  201. value = tri_bias( value )
  202. elif bias == 2:
  203. value = saw_bias( value )
  204. else:
  205. value = sin_bias( value )
  206. if sharpnes == 1:
  207. value = sharp( value )
  208. elif sharpnes == 2:
  209. value = sharper( value )
  210. else:
  211. value = soft( value )
  212. return value
  213. ###------------------------------------------------------------
  214. # custom noise types
  215. # shattered_hterrain:
  216. def shattered_hterrain( x,y,z, H, lacunarity, octaves, offset, distort, basis ):
  217. d = ( turbulence_vector( ( x, y, z ), 6, 0, 0 )[0] * 0.5 + 0.5 )*distort*0.5
  218. t1 = ( turbulence_vector( ( x+d, y+d, z ), 0, 0, 7 )[0] + 0.5 )
  219. t2 = ( hetero_terrain(( x*2, y*2, z*2 ), H, lacunarity, octaves, offset, basis )*0.5 )
  220. return (( t1*t2 )+t2*0.5) * 0.5
  221. # strata_hterrain
  222. def strata_hterrain( x,y,z, H, lacunarity, octaves, offset, distort, basis ):
  223. value = hetero_terrain(( x, y, z ), H, lacunarity, octaves, offset, basis )*0.5
  224. steps = ( sin( value*(distort*5)*pi ) * ( 0.1/(distort*5)*pi ) )
  225. return ( value * (1.0-0.5) + steps*0.5 )
  226. ###------------------------------------------------------------
  227. # landscape_gen
  228. 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]):
  229. # options
  230. rseed = options[0]
  231. nsize = options[1]
  232. ntype = int( options[2][0] )
  233. nbasis = int( options[3][0] )
  234. vlbasis = int( options[4][0] )
  235. distortion = options[5]
  236. hardnoise = options[6]
  237. depth = options[7]
  238. dimension = options[8]
  239. lacunarity = options[9]
  240. offset = options[10]
  241. gain = options[11]
  242. marblebias = int( options[12][0] )
  243. marblesharpnes = int( options[13][0] )
  244. marbleshape = int( options[14][0] )
  245. invert = options[15]
  246. height = options[16]
  247. heightoffset = options[17]
  248. falloff = int( options[18][0] )
  249. sealevel = options[19]
  250. platlevel = options[20]
  251. strata = options[21]
  252. stratatype = options[22]
  253. sphere = options[23]
  254. # origin
  255. if rseed == 0:
  256. origin = 0.0,0.0,0.0
  257. origin_x = 0.0
  258. origin_y = 0.0
  259. origin_z = 0.0
  260. else:
  261. # randomise origin
  262. seed_set( rseed )
  263. origin = random_unit_vector()
  264. origin_x = ( 0.5 - origin[0] ) * 1000.0
  265. origin_y = ( 0.5 - origin[1] ) * 1000.0
  266. origin_z = ( 0.5 - origin[2] ) * 1000.0
  267. # adjust noise size and origin
  268. ncoords = ( x / nsize + origin_x, y / nsize + origin_y, z / nsize + origin_z )
  269. # noise basis type's
  270. if nbasis == 9: nbasis = 14 # to get cellnoise basis you must set 14 instead of 9
  271. if vlbasis ==9: vlbasis = 14
  272. # noise type's
  273. if ntype == 0: value = multi_fractal( ncoords, dimension, lacunarity, depth, nbasis ) * 0.5
  274. elif ntype == 1: value = ridged_multi_fractal( ncoords, dimension, lacunarity, depth, offset, gain, nbasis ) * 0.5
  275. elif ntype == 2: value = hybrid_multi_fractal( ncoords, dimension, lacunarity, depth, offset, gain, nbasis ) * 0.5
  276. elif ntype == 3: value = hetero_terrain( ncoords, dimension, lacunarity, depth, offset, nbasis ) * 0.25
  277. elif ntype == 4: value = fractal( ncoords, dimension, lacunarity, depth, nbasis )
  278. elif ntype == 5: value = turbulence_vector( ncoords, depth, hardnoise, nbasis )[0]
  279. elif ntype == 6: value = variable_lacunarity( ncoords, distortion, nbasis, vlbasis ) + 0.5
  280. 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 )
  281. elif ntype == 8: value = shattered_hterrain( ncoords[0], ncoords[1], ncoords[2], dimension, lacunarity, depth, offset, distortion, nbasis )
  282. elif ntype == 9: value = strata_hterrain( ncoords[0], ncoords[1], ncoords[2], dimension, lacunarity, depth, offset, distortion, nbasis )
  283. else:
  284. value = 0.0
  285. # adjust height
  286. if invert !=0:
  287. value = (1-value) * height + heightoffset
  288. else:
  289. value = value * height + heightoffset
  290. # edge falloff
  291. if sphere == 0: # no edge falloff if spherical
  292. if falloff != 0:
  293. fallofftypes = [ 0, sqrt((x*x)**2+(y*y)**2), sqrt(x*x+y*y), sqrt(y*y), sqrt(x*x) ]
  294. dist = fallofftypes[ falloff]
  295. if falloff ==1:
  296. radius = (falloffsize/2)**2
  297. else:
  298. radius = falloffsize/2
  299. value = value - sealevel
  300. if( dist < radius ):
  301. dist = dist / radius
  302. dist = ( (dist) * (dist) * ( 3-2*(dist) ) )
  303. value = ( value - value * dist ) + sealevel
  304. else:
  305. value = sealevel
  306. # strata / terrace / layered
  307. if stratatype !='0':
  308. strata = strata / height
  309. if stratatype == '1':
  310. strata *= 2
  311. steps = ( sin( value*strata*pi ) * ( 0.1/strata*pi ) )
  312. value = ( value * (1.0-0.5) + steps*0.5 ) * 2.0
  313. elif stratatype == '2':
  314. steps = -abs( sin( value*(strata)*pi ) * ( 0.1/(strata)*pi ) )
  315. value =( value * (1.0-0.5) + steps*0.5 ) * 2.0
  316. elif stratatype == '3':
  317. steps = abs( sin( value*(strata)*pi ) * ( 0.1/(strata)*pi ) )
  318. value =( value * (1.0-0.5) + steps*0.5 ) * 2.0
  319. else:
  320. value = value
  321. # clamp height
  322. if ( value < sealevel ): value = sealevel
  323. if ( value > platlevel ): value = platlevel
  324. return value
  325. # generate grid
  326. def grid_gen( sub_d, size_me, options ):
  327. verts = []
  328. faces = []
  329. edgeloop_prev = []
  330. delta = size_me / float(sub_d - 1)
  331. start = -(size_me / 2.0)
  332. for row_x in range(sub_d):
  333. edgeloop_cur = []
  334. x = start + row_x * delta
  335. for row_y in range(sub_d):
  336. y = start + row_y * delta
  337. z = landscape_gen(x,y,0.0,size_me,options)
  338. edgeloop_cur.append(len(verts))
  339. verts.append((x,y,z))
  340. if len(edgeloop_prev) > 0:
  341. faces_row = createFaces(edgeloop_prev, edgeloop_cur)
  342. faces.extend(faces_row)
  343. edgeloop_prev = edgeloop_cur
  344. return verts, faces
  345. # generate sphere
  346. def sphere_gen( sub_d, size_me, options ):
  347. verts = []
  348. faces = []
  349. edgeloop_prev = []
  350. for row_x in range(sub_d):
  351. edgeloop_cur = []
  352. for row_y in range(sub_d):
  353. u = sin(row_y*pi*2/(sub_d-1)) * cos(-pi/2+row_x*pi/(sub_d-1)) * size_me/2
  354. v = cos(row_y*pi*2/(sub_d-1)) * cos(-pi/2+row_x*pi/(sub_d-1)) * size_me/2
  355. w = sin(-pi/2+row_x*pi/(sub_d-1)) * size_me/2
  356. h = landscape_gen(u,v,w,size_me,options) / size_me
  357. u,v,w = u+u*h, v+v*h, w+w*h
  358. edgeloop_cur.append(len(verts))
  359. verts.append((u, v, w))
  360. if len(edgeloop_prev) > 0:
  361. faces_row = createFaces(edgeloop_prev, edgeloop_cur)
  362. faces.extend(faces_row)
  363. edgeloop_prev = edgeloop_cur
  364. return verts, faces
  365. ###------------------------------------------------------------
  366. # Add landscape
  367. class landscape_add(bpy.types.Operator):
  368. """Add a landscape mesh"""
  369. bl_idname = "mesh.landscape_add"
  370. bl_label = "Landscape"
  371. bl_options = {'REGISTER', 'UNDO', 'PRESET'}
  372. bl_description = "Add landscape mesh"
  373. # properties
  374. AutoUpdate = BoolProperty(name="Mesh update",
  375. default=True,
  376. description="Update mesh")
  377. SphereMesh = BoolProperty(name="Sphere",
  378. default=False,
  379. description="Generate Sphere mesh")
  380. SmoothMesh = BoolProperty(name="Smooth",
  381. default=True,
  382. description="Shade smooth")
  383. Subdivision = IntProperty(name="Subdivisions",
  384. min=4,
  385. max=6400,
  386. default=64,
  387. description="Mesh x y subdivisions")
  388. MeshSize = FloatProperty(name="Mesh Size",
  389. min=0.01,
  390. max=100000.0,
  391. default=2.0,
  392. description="Mesh size")
  393. RandomSeed = IntProperty(name="Random Seed",
  394. min=0,
  395. max=9999,
  396. default=0,
  397. description="Randomize noise origin")
  398. NoiseSize = FloatProperty(name="Noise Size",
  399. min=0.01,
  400. max=10000.0,
  401. default=1.0,
  402. description="Noise size")
  403. NoiseTypes = [
  404. ("0","multiFractal","multiFractal"),
  405. ("1","ridgedMFractal","ridgedMFractal"),
  406. ("2","hybridMFractal","hybridMFractal"),
  407. ("3","heteroTerrain","heteroTerrain"),
  408. ("4","fBm","fBm"),
  409. ("5","Turbulence","Turbulence"),
  410. ("6","Distorted Noise","Distorted Noise"),
  411. ("7","Marble","Marble"),
  412. ("8","Shattered_hTerrain","Shattered_hTerrain"),
  413. ("9","Strata_hTerrain","Strata_hTerrain")]
  414. NoiseType = EnumProperty(name="Type",
  415. description="Noise type",
  416. items=NoiseTypes)
  417. BasisTypes = [
  418. ("0","Blender","Blender"),
  419. ("1","Perlin","Perlin"),
  420. ("2","NewPerlin","NewPerlin"),
  421. ("3","Voronoi_F1","Voronoi_F1"),
  422. ("4","Voronoi_F2","Voronoi_F2"),
  423. ("5","Voronoi_F3","Voronoi_F3"),
  424. ("6","Voronoi_F4","Voronoi_F4"),
  425. ("7","Voronoi_F2-F1","Voronoi_F2-F1"),
  426. ("8","Voronoi Crackle","Voronoi Crackle"),
  427. ("9","Cellnoise","Cellnoise")]
  428. BasisType = EnumProperty(name="Basis",
  429. description="Noise basis",
  430. items=BasisTypes)
  431. VLBasisTypes = [
  432. ("0","Blender","Blender"),
  433. ("1","Perlin","Perlin"),
  434. ("2","NewPerlin","NewPerlin"),
  435. ("3","Voronoi_F1","Voronoi_F1"),
  436. ("4","Voronoi_F2","Voronoi_F2"),
  437. ("5","Voronoi_F3","Voronoi_F3"),
  438. ("6","Voronoi_F4","Voronoi_F4"),
  439. ("7","Voronoi_F2-F1","Voronoi_F2-F1"),
  440. ("8","Voronoi Crackle","Voronoi Crackle"),
  441. ("9","Cellnoise","Cellnoise")]
  442. VLBasisType = EnumProperty(name="VLBasis",
  443. description="VLNoise basis",
  444. items=VLBasisTypes)
  445. Distortion = FloatProperty(name="Distortion",
  446. min=0.01,
  447. max=1000.0,
  448. default=1.0,
  449. description="Distortion amount")
  450. HardNoise = BoolProperty(name="Hard",
  451. default=True,
  452. description="Hard noise")
  453. NoiseDepth = IntProperty(name="Depth",
  454. min=1,
  455. max=16,
  456. default=6,
  457. description="Noise Depth - number of frequencies in the fBm")
  458. mDimension = FloatProperty(name="Dimension",
  459. min=0.01,
  460. max=2.0,
  461. default=1.0,
  462. description="H - fractal dimension of the roughest areas")
  463. mLacunarity = FloatProperty(name="Lacunarity",
  464. min=0.01,
  465. max=6.0,
  466. default=2.0,
  467. description="Lacunarity - gap between successive frequencies")
  468. mOffset = FloatProperty(name="Offset",
  469. min=0.01,
  470. max=6.0,
  471. default=1.0,
  472. description="Offset - raises the terrain from sea level")
  473. mGain = FloatProperty(name="Gain",
  474. min=0.01,
  475. max=6.0,
  476. default=1.0,
  477. description="Gain - scale factor")
  478. BiasTypes = [
  479. ("0","Sin","Sin"),
  480. ("1","Tri","Tri"),
  481. ("2","Saw","Saw")]
  482. MarbleBias = EnumProperty(name="Bias",
  483. description="Marble bias",
  484. items=BiasTypes)
  485. SharpTypes = [
  486. ("0","Soft","Soft"),
  487. ("1","Sharp","Sharp"),
  488. ("2","Sharper","Sharper")]
  489. MarbleSharp = EnumProperty(name="Sharp",
  490. description="Marble sharp",
  491. items=SharpTypes)
  492. ShapeTypes = [
  493. ("0","Default","Default"),
  494. ("1","Ring","Ring"),
  495. ("2","Swirl","Swirl"),
  496. ("3","Bump","Bump"),
  497. ("4","Y","Y"),
  498. ("5","X","X")]
  499. MarbleShape = EnumProperty(name="Shape",
  500. description="Marble shape",
  501. items=ShapeTypes)
  502. Invert = BoolProperty(name="Invert",
  503. default=False,
  504. description="Invert noise input")
  505. Height = FloatProperty(name="Height",
  506. min=0.01,
  507. max=10000.0,
  508. default=0.5,
  509. description="Height scale")
  510. Offset = FloatProperty(name="Offset",
  511. min=-10000.0,
  512. max=10000.0,
  513. default=0.0,
  514. description="Height offset")
  515. fallTypes = [
  516. ("0","None","None"),
  517. ("1","Type 1","Type 1"),
  518. ("2","Type 2","Type 2"),
  519. ("3","Y","Y"),
  520. ("4","X","X")]
  521. Falloff = EnumProperty(name="Falloff",
  522. description="Edge falloff",
  523. default="1",
  524. items=fallTypes)
  525. Sealevel = FloatProperty(name="Sealevel",
  526. min=-10000.0,
  527. max=10000.0,
  528. default=0.0,
  529. description="Sealevel")
  530. Plateaulevel = FloatProperty(name="Plateau",
  531. min=-10000.0,
  532. max=10000.0,
  533. default=1.0,
  534. description="Plateau level")
  535. Strata = FloatProperty(name="Strata",
  536. min=0.01,
  537. max=1000.0,
  538. default=3.0,
  539. description="Strata amount")
  540. StrataTypes = [
  541. ("0","None","None"),
  542. ("1","Type 1","Type 1"),
  543. ("2","Type 2","Type 2"),
  544. ("3","Type 3","Type 3")]
  545. StrataType = EnumProperty(name="Strata",
  546. description="Strata type",
  547. default="0",
  548. items=StrataTypes)
  549. ###------------------------------------------------------------
  550. # Draw
  551. def draw(self, context):
  552. layout = self.layout
  553. box = layout.box()
  554. box.prop(self, 'AutoUpdate')
  555. box.prop(self, 'SphereMesh')
  556. box.prop(self, 'SmoothMesh')
  557. box.prop(self, 'Subdivision')
  558. box.prop(self, 'MeshSize')
  559. box = layout.box()
  560. box.prop(self, 'NoiseType')
  561. if self.NoiseType != '7':
  562. box.prop(self, 'BasisType')
  563. box.prop(self, 'RandomSeed')
  564. box.prop(self, 'NoiseSize')
  565. if self.NoiseType == '0':
  566. box.prop(self, 'NoiseDepth')
  567. box.prop(self, 'mDimension')
  568. box.prop(self, 'mLacunarity')
  569. elif self.NoiseType == '1':
  570. box.prop(self, 'NoiseDepth')
  571. box.prop(self, 'mDimension')
  572. box.prop(self, 'mLacunarity')
  573. box.prop(self, 'mOffset')
  574. box.prop(self, 'mGain')
  575. elif self.NoiseType == '2':
  576. box.prop(self, 'NoiseDepth')
  577. box.prop(self, 'mDimension')
  578. box.prop(self, 'mLacunarity')
  579. box.prop(self, 'mOffset')
  580. box.prop(self, 'mGain')
  581. elif self.NoiseType == '3':
  582. box.prop(self, 'NoiseDepth')
  583. box.prop(self, 'mDimension')
  584. box.prop(self, 'mLacunarity')
  585. box.prop(self, 'mOffset')
  586. elif self.NoiseType == '4':
  587. box.prop(self, 'NoiseDepth')
  588. box.prop(self, 'mDimension')
  589. box.prop(self, 'mLacunarity')
  590. elif self.NoiseType == '5':
  591. box.prop(self, 'NoiseDepth')
  592. box.prop(self, 'HardNoise')
  593. elif self.NoiseType == '6':
  594. box.prop(self, 'VLBasisType')
  595. box.prop(self, 'Distortion')
  596. elif self.NoiseType == '7':
  597. box.prop(self, 'MarbleShape')
  598. box.prop(self, 'MarbleBias')
  599. box.prop(self, 'MarbleSharp')
  600. box.prop(self, 'Distortion')
  601. box.prop(self, 'NoiseDepth')
  602. box.prop(self, 'HardNoise')
  603. elif self.NoiseType == '8':
  604. box.prop(self, 'NoiseDepth')
  605. box.prop(self, 'mDimension')
  606. box.prop(self, 'mLacunarity')
  607. box.prop(self, 'mOffset')
  608. box.prop(self, 'Distortion')
  609. elif self.NoiseType == '9':
  610. box.prop(self, 'NoiseDepth')
  611. box.prop(self, 'mDimension')
  612. box.prop(self, 'mLacunarity')
  613. box.prop(self, 'mOffset')
  614. box.prop(self, 'Distortion')
  615. box = layout.box()
  616. box.prop(self, 'Invert')
  617. box.prop(self, 'Height')
  618. box.prop(self, 'Offset')
  619. box.prop(self, 'Plateaulevel')
  620. box.prop(self, 'Sealevel')
  621. if self.SphereMesh == False:
  622. box.prop(self, 'Falloff')
  623. box.prop(self, 'StrataType')
  624. if self.StrataType != '0':
  625. box.prop(self, 'Strata')
  626. ###------------------------------------------------------------
  627. # Execute
  628. def execute(self, context):
  629. #mesh update
  630. if self.AutoUpdate != 0:
  631. # turn off undo
  632. undo = bpy.context.user_preferences.edit.use_global_undo
  633. bpy.context.user_preferences.edit.use_global_undo = False
  634. # deselect all objects when in object mode
  635. if bpy.ops.object.select_all.poll():
  636. bpy.ops.object.select_all(action='DESELECT')
  637. # options
  638. options = [
  639. self.RandomSeed, #0
  640. self.NoiseSize, #1
  641. self.NoiseType, #2
  642. self.BasisType, #3
  643. self.VLBasisType, #4
  644. self.Distortion, #5
  645. self.HardNoise, #6
  646. self.NoiseDepth, #7
  647. self.mDimension, #8
  648. self.mLacunarity, #9
  649. self.mOffset, #10
  650. self.mGain, #11
  651. self.MarbleBias, #12
  652. self.MarbleSharp, #13
  653. self.MarbleShape, #14
  654. self.Invert, #15
  655. self.Height, #16
  656. self.Offset, #17
  657. self.Falloff, #18
  658. self.Sealevel, #19
  659. self.Plateaulevel, #20
  660. self.Strata, #21
  661. self.StrataType, #22
  662. self.SphereMesh #23
  663. ]
  664. # Main function
  665. if self.SphereMesh !=0:
  666. # sphere
  667. verts, faces = sphere_gen( self.Subdivision, self.MeshSize, options )
  668. else:
  669. # grid
  670. verts, faces = grid_gen( self.Subdivision, self.MeshSize, options )
  671. # create mesh object
  672. obj = create_mesh_object(context, verts, [], faces, "Landscape")
  673. bpy.ops.object.mode_set(mode='EDIT')
  674. bpy.ops.mesh.normals_make_consistent(inside=False)
  675. bpy.ops.object.mode_set(mode='OBJECT')
  676. # sphere, remove doubles
  677. if self.SphereMesh !=0:
  678. bpy.ops.object.mode_set(mode='EDIT')
  679. bpy.ops.mesh.remove_doubles(threshold=0.0001)
  680. bpy.ops.object.mode_set(mode='OBJECT')
  681. # Shade smooth
  682. if self.SmoothMesh !=0:
  683. if bpy.ops.object.shade_smooth.poll():
  684. bpy.ops.object.shade_smooth()
  685. else: # edit mode
  686. bpy.ops.mesh.faces_shade_smooth()
  687. # restore pre operator undo state
  688. bpy.context.user_preferences.edit.use_global_undo = undo
  689. return {'FINISHED'}
  690. else:
  691. return {'PASS_THROUGH'}
  692. ###------------------------------------------------------------
  693. # Register
  694. # Define "Landscape" menu
  695. def menu_func_landscape(self, context):
  696. self.layout.operator(landscape_add.bl_idname, text="Landscape", icon="PLUGIN")
  697. def register():
  698. bpy.utils.register_module(__name__)
  699. bpy.types.INFO_MT_mesh_add.append(menu_func_landscape)
  700. def unregister():
  701. bpy.utils.unregister_module(__name__)
  702. bpy.types.INFO_MT_mesh_add.remove(menu_func_landscape)
  703. if __name__ == "__main__":
  704. register()

comments powered by Disqus