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