Skip to content

Instantly share code, notes, and snippets.

@atartanian
Created April 20, 2017 06:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atartanian/a1272125cd76094b9535f164cd6e8c76 to your computer and use it in GitHub Desktop.
Save atartanian/a1272125cd76094b9535f164cd6e8c76 to your computer and use it in GitHub Desktop.
add perlin plane to blender
import bpy
import bmesh
from mathutils import noise
def add_perlin_plane(width=1.0, length=1.0, x_res=10, y_res=10, min_z=-0.5, max_z=0.5, noise_scale=0.5, seed=0.0, x_offset=0.0, y_offset=0.0):
"""
This function takes inputs and returns vertex and face arrays.
no actual mesh data creation is done here.
"""
verts = []
faces = []
x_res = 2 if x_res < 2 else x_res
y_res = 2 if y_res < 2 else y_res
x_inc = width/x_res
y_inc = length/y_res
vi = 0
for yi in range(0, y_res):
for xi in range(0, x_res):
noise_sample = ((xi * x_inc + x_offset) * noise_scale, (yi * y_inc + y_offset) * noise_scale, seed * noise_scale)
noise_value = noise.noise(noise_sample)
normalize = noise_value
z_position = noise_value * (max_z-min_z) + min_z
coord = (xi * x_inc, yi * y_inc, z_position)
verts.append(coord)
if(xi != (x_res-1) and yi != (y_res-1)):
faces.append((int(vi),int(vi + 1), int(vi + x_res + 1), int(vi + x_res)))
vi += 1
return verts, faces
from bpy.props import (
BoolProperty,
BoolVectorProperty,
FloatProperty,
FloatVectorProperty,
IntProperty
)
class AddPerlinPlane(bpy.types.Operator):
"""Add a simple perlin plane"""
bl_idname = "mesh.perlin_plane_add"
bl_label = "Add Perlin Plane"
bl_options = {'REGISTER', 'UNDO'}
width = FloatProperty(
name="Width",
description="Plane Width",
min=0.01, max=100.0,
default=10.0,
)
length = FloatProperty(
name="Length",
description="Plane Length",
min=0.01, max=100.0,
default=10.0,
)
x_res = IntProperty(
name="X Resolution",
description="number of verticies in the x direction",
min=2, max=100,
default=100,
)
y_res = IntProperty(
name="X Resolution",
description="number of verticies in the x direction",
min=2, max=100,
default=100,
)
z_bottom = FloatProperty(
name="Floor",
description="Minimum Z Displacement",
min=-100.0, max=0.0,
default=-0.5,
)
z_top = FloatProperty(
name="Ceiling",
description="Maximum Z Displacement",
min=0.0, max=100.0,
default=0.5,
)
noise_scale = FloatProperty(
name="Noise Scale",
description="Noise Scale",
min=0.01, max=100.0,
default=1.0,
)
seed = FloatProperty(
name="Noise Z",
description="Noise Z sample position",
min=-100.0, max=100.0,
default=0.0,
)
x_offset = FloatProperty(
name="X Offset",
description="Noise X sample position",
min=-100.0, max=100.0,
default=0.0,
)
y_offset = FloatProperty(
name="Y Offset",
description="Noise Y sample position",
min=-100.0, max=100.0,
default=0.0,
)
layers = BoolVectorProperty(
name="Layers",
description="Object Layers",
size=20,
options={'HIDDEN', 'SKIP_SAVE'},
)
# generic transform props
view_align = BoolProperty(
name="Align to View",
default=False,
)
location = FloatVectorProperty(
name="Location",
subtype='TRANSLATION',
)
rotation = FloatVectorProperty(
name="Rotation",
subtype='EULER',
)
def execute(self, context):
verts_loc, faces = add_perlin_plane(self.width,
self.length,
self.x_res,
self.y_res,
self.z_bottom,
self.z_top,
self.noise_scale,
self.seed,
self.x_offset,
self.y_offset
)
mesh = bpy.data.meshes.new("Perlin_Plane")
bm = bmesh.new()
for v_co in verts_loc:
bm.verts.new(v_co)
bm.verts.ensure_lookup_table()
for f_idx in faces:
bm.faces.new([bm.verts[i] for i in f_idx])
bm.to_mesh(mesh)
mesh.update()
# add the mesh as an object into the scene with this utility module
from bpy_extras import object_utils
object_utils.object_data_add(context, mesh, operator=self)
return {'FINISHED'}
def menu_func(self, context):
self.layout.operator(AddPerlinPlane.bl_idname, icon='MESH_PLANE')
def register():
bpy.utils.register_class(AddPerlinPlane)
bpy.types.INFO_MT_mesh_add.append(menu_func)
def unregister():
bpy.utils.unregister_class(AddPerlinPlane)
bpy.types.INFO_MT_mesh_add.remove(menu_func)
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment