ant landscape: bug fix stable release

This commit is contained in:
Brendon Murphy 2017-06-20 18:14:18 +10:00
parent fb45d3cdf8
commit 764d4e21e6
9 changed files with 437 additions and 292 deletions

View File

@ -1,2 +1,3 @@
http://blog.michelanders.nl/search/label/erosion
https://github.com/nerk987/ErosionR
https://github.com/nerk987/ErosionR
https://blenderartists.org/forum/showthread.php?323808-Simulating-erosion-in-Blender

View File

@ -22,7 +22,7 @@
bl_info = {
"name": "A.N.T.Landscape",
"author": "Jim Hazevoet",
"version": (0, 1, 6),
"version": (0, 1, 7),
"blender": (2, 77, 0),
"location": "View3D > Tool Shelf",
"description": "Another Noise Tool: Landscape and Displace",
@ -67,7 +67,7 @@ from .ant_functions import (
# Menu's and panels
def menu_func_eroder(self, context):
self.layout.operator('mesh.eroder', text="Eroder", icon='RNDCURVE')
self.layout.operator('mesh.eroder', text="Landscape Eroder", icon='SMOOTHCURVE')
def menu_func_landscape(self, context):
@ -105,14 +105,10 @@ class AntLandscapeToolsPanel(bpy.types.Panel):
def draw(self, context):
layout = self.layout
ob = context.active_object
if ob and ob.type == 'MESH':
col = layout.column()
col.operator('mesh.ant_displace', text="Mesh Displace", icon="RNDCURVE")
col.operator('mesh.eroder', text="Landscape Eroder", icon='SMOOTHCURVE')
col.operator('mesh.ant_slope_map', icon='GROUP_VERTEX')
else:
box = layout.box()
box.label("Select a Mesh!", icon='ERROR')
col = layout.column()
col.operator('mesh.ant_displace', text="Mesh Displace", icon="RNDCURVE")
col.operator('mesh.eroder', text="Landscape Eroder", icon='SMOOTHCURVE')
col.operator('mesh.ant_slope_map', icon='GROUP_VERTEX')
# Landscape Settings / Properties:
@ -133,33 +129,28 @@ class AntMainSettingsPanel(bpy.types.Panel):
layout = self.layout
scene = context.scene
ob = bpy.context.active_object
if ob and ob.ant_landscape.keys():
ant = ob.ant_landscape
box = layout.box()
col = box.column(align=False)
col.scale_y = 1.5
col.operator('mesh.ant_landscape_regenerate', text="Regenerate", icon="LOOP_FORWARDS")
row = box.row(align=True)
split = row.split(align=True)
split.prop(ant, "smooth_mesh", toggle=True, text="Smooth", icon='SOLID')
split.prop(ant, "tri_face", toggle=True, text="Triangulate", icon='MESH_DATA')
if ant.sphere_mesh:
split.prop(ant, "remove_double", toggle=True, text="Remove Doubles", icon='MESH_DATA')
box.prop(ant, "ant_terrain_name")
box.prop_search(ant, "land_material", bpy.data, "materials")
col = box.column(align=True)
col.prop(ant, "subdivision_x")
col.prop(ant, "subdivision_y")
col = box.column(align=True)
if ant.sphere_mesh:
col.prop(ant, "mesh_size")
else:
col.prop(ant, "mesh_size_x")
col.prop(ant, "mesh_size_y")
ant = ob.ant_landscape
box = layout.box()
col = box.column(align=False)
col.scale_y = 1.5
col.operator('mesh.ant_landscape_regenerate', text="Regenerate", icon="LOOP_FORWARDS")
row = box.row(align=True)
split = row.split(align=True)
split.prop(ant, "smooth_mesh", toggle=True, text="Smooth", icon='SOLID')
split.prop(ant, "tri_face", toggle=True, text="Triangulate", icon='MESH_DATA')
if ant.sphere_mesh:
split.prop(ant, "remove_double", toggle=True, text="Remove Doubles", icon='MESH_DATA')
box.prop(ant, "ant_terrain_name")
box.prop_search(ant, "land_material", bpy.data, "materials")
col = box.column(align=True)
col.prop(ant, "subdivision_x")
col.prop(ant, "subdivision_y")
col = box.column(align=True)
if ant.sphere_mesh:
col.prop(ant, "mesh_size")
else:
box = layout.box()
box.label("Select a Landscape Object!", icon='ERROR')
col.prop(ant, "mesh_size_x")
col.prop(ant, "mesh_size_y")
# Landscape Settings / Properties:
@ -180,154 +171,148 @@ class AntNoiseSettingsPanel(bpy.types.Panel):
layout = self.layout
scene = context.scene
ob = bpy.context.active_object
ant = ob.ant_landscape
box = layout.box()
col = box.column(align=True)
col.scale_y = 1.5
if ant.sphere_mesh:
col.operator('mesh.ant_landscape_regenerate', text="Regenerate", icon="LOOP_FORWARDS")
else:
col.operator('mesh.ant_landscape_refresh', text="Refresh", icon="FILE_REFRESH")
if ob and ob.ant_landscape.keys():
ant = ob.ant_landscape
box = layout.box()
col = box.column(align=True)
col.scale_y = 1.5
if ant.sphere_mesh:
col.operator('mesh.ant_landscape_regenerate', text="Regenerate", icon="LOOP_FORWARDS")
else:
col.operator('mesh.ant_landscape_refresh', text="Refresh", icon="FILE_REFRESH")
box.prop(ant, "noise_type")
if ant.noise_type == "blender_texture":
box.prop_search(ant, "texture_block", bpy.data, "textures")
else:
box.prop(ant, "basis_type")
col = box.column(align=True)
col.prop(ant, "random_seed")
col = box.column(align=True)
col.prop(ant, "noise_offset_x")
col.prop(ant, "noise_offset_y")
col.prop(ant, "noise_offset_z")
col.prop(ant, "noise_size_x")
col.prop(ant, "noise_size_y")
if ant.sphere_mesh:
col.prop(ant, "noise_size_z")
col = box.column(align=True)
col.prop(ant, "noise_size")
col = box.column(align=True)
if ant.noise_type == "multi_fractal":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
elif ant.noise_type == "ridged_multi_fractal":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "gain")
elif ant.noise_type == "hybrid_multi_fractal":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "gain")
elif ant.noise_type == "hetero_terrain":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
elif ant.noise_type == "fractal":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
elif ant.noise_type == "turbulence_vector":
col.prop(ant, "noise_depth")
col.prop(ant, "amplitude")
col.prop(ant, "frequency")
col.separator()
row = col.row(align=True)
row.prop(ant, "hard_noise", expand=True)
elif ant.noise_type == "variable_lacunarity":
box.prop(ant, "vl_basis_type")
box.prop(ant, "distortion")
elif ant.noise_type == "marble_noise":
box.prop(ant, "marble_shape")
box.prop(ant, "marble_bias")
box.prop(ant, "marble_sharp")
col = box.column(align=True)
col.prop(ant, "distortion")
col.prop(ant, "noise_depth")
col.separator()
row = col.row(align=True)
row.prop(ant, "hard_noise", expand=True)
elif ant.noise_type == "shattered_hterrain":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "distortion")
elif ant.noise_type == "strata_hterrain":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "distortion", text="Strata")
elif ant.noise_type == "ant_turbulence":
col.prop(ant, "noise_depth")
col.prop(ant, "amplitude")
col.prop(ant, "frequency")
col.prop(ant, "distortion")
col.separator()
row = col.row(align=True)
row.prop(ant, "hard_noise", expand=True)
elif ant.noise_type == "vl_noise_turbulence":
col.prop(ant, "noise_depth")
col.prop(ant, "amplitude")
col.prop(ant, "frequency")
col.prop(ant, "distortion")
col.separator()
col.prop(ant, "vl_basis_type")
col.separator()
row = col.row(align=True)
row.prop(ant, "hard_noise", expand=True)
elif ant.noise_type == "vl_hTerrain":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "distortion")
col.separator()
col.prop(ant, "vl_basis_type")
elif ant.noise_type == "distorted_heteroTerrain":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "distortion")
col.separator()
col.prop(ant, "vl_basis_type")
elif ant.noise_type == "double_multiFractal":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "gain")
col.separator()
col.prop(ant, "vl_basis_type")
elif ant.noise_type == "slick_rock":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "gain")
col.prop(ant, "offset")
col.prop(ant, "distortion")
col.separator()
col.prop(ant, "vl_basis_type")
elif ant.noise_type == "planet_noise":
col.prop(ant, "noise_depth")
col.separator()
row = col.row(align=True)
row.prop(ant, "hard_noise", expand=True)
box.prop(ant, "noise_type")
if ant.noise_type == "blender_texture":
box.prop_search(ant, "texture_block", bpy.data, "textures")
else:
box = layout.box()
box.label("Select a Landscape Object!", icon='ERROR')
box.prop(ant, "basis_type")
col = box.column(align=True)
col.prop(ant, "random_seed")
col = box.column(align=True)
col.prop(ant, "noise_offset_x")
col.prop(ant, "noise_offset_y")
col.prop(ant, "noise_offset_z")
col.prop(ant, "noise_size_x")
col.prop(ant, "noise_size_y")
if ant.sphere_mesh:
col.prop(ant, "noise_size_z")
col = box.column(align=True)
col.prop(ant, "noise_size")
col = box.column(align=True)
if ant.noise_type == "multi_fractal":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
elif ant.noise_type == "ridged_multi_fractal":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "gain")
elif ant.noise_type == "hybrid_multi_fractal":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "gain")
elif ant.noise_type == "hetero_terrain":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
elif ant.noise_type == "fractal":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
elif ant.noise_type == "turbulence_vector":
col.prop(ant, "noise_depth")
col.prop(ant, "amplitude")
col.prop(ant, "frequency")
col.separator()
row = col.row(align=True)
row.prop(ant, "hard_noise", expand=True)
elif ant.noise_type == "variable_lacunarity":
box.prop(ant, "vl_basis_type")
box.prop(ant, "distortion")
elif ant.noise_type == "marble_noise":
box.prop(ant, "marble_shape")
box.prop(ant, "marble_bias")
box.prop(ant, "marble_sharp")
col = box.column(align=True)
col.prop(ant, "distortion")
col.prop(ant, "noise_depth")
col.separator()
row = col.row(align=True)
row.prop(ant, "hard_noise", expand=True)
elif ant.noise_type == "shattered_hterrain":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "distortion")
elif ant.noise_type == "strata_hterrain":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "distortion", text="Strata")
elif ant.noise_type == "ant_turbulence":
col.prop(ant, "noise_depth")
col.prop(ant, "amplitude")
col.prop(ant, "frequency")
col.prop(ant, "distortion")
col.separator()
row = col.row(align=True)
row.prop(ant, "hard_noise", expand=True)
elif ant.noise_type == "vl_noise_turbulence":
col.prop(ant, "noise_depth")
col.prop(ant, "amplitude")
col.prop(ant, "frequency")
col.prop(ant, "distortion")
col.separator()
col.prop(ant, "vl_basis_type")
col.separator()
row = col.row(align=True)
row.prop(ant, "hard_noise", expand=True)
elif ant.noise_type == "vl_hTerrain":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "distortion")
col.separator()
col.prop(ant, "vl_basis_type")
elif ant.noise_type == "distorted_heteroTerrain":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "distortion")
col.separator()
col.prop(ant, "vl_basis_type")
elif ant.noise_type == "double_multiFractal":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "offset")
col.prop(ant, "gain")
col.separator()
col.prop(ant, "vl_basis_type")
elif ant.noise_type == "slick_rock":
col.prop(ant, "noise_depth")
col.prop(ant, "dimension")
col.prop(ant, "lacunarity")
col.prop(ant, "gain")
col.prop(ant, "offset")
col.prop(ant, "distortion")
col.separator()
col.prop(ant, "vl_basis_type")
elif ant.noise_type == "planet_noise":
col.prop(ant, "noise_depth")
col.separator()
row = col.row(align=True)
row.prop(ant, "hard_noise", expand=True)
# Landscape Settings / Properties:
@ -348,45 +333,40 @@ class AntDisplaceSettingsPanel(bpy.types.Panel):
layout = self.layout
scene = context.scene
ob = bpy.context.active_object
ant = ob.ant_landscape
box = layout.box()
col = box.column(align=True)
col.scale_y = 1.5
if ant.sphere_mesh:
col.operator('mesh.ant_landscape_regenerate', text="Regenerate", icon="LOOP_FORWARDS")
else:
col.operator('mesh.ant_landscape_refresh', text="Refresh", icon="FILE_REFRESH")
if ob and ob.ant_landscape.keys():
ant = ob.ant_landscape
box = layout.box()
col = box.column(align=True)
col.scale_y = 1.5
if ant.sphere_mesh:
col.operator('mesh.ant_landscape_regenerate', text="Regenerate", icon="LOOP_FORWARDS")
else:
col.operator('mesh.ant_landscape_refresh', text="Refresh", icon="FILE_REFRESH")
col = box.column(align=True)
row = col.row(align=True).split(0.92, align=True)
row.prop(ant, "height")
row.prop(ant, "height_invert", toggle=True, text="", icon='ARROW_LEFTRIGHT')
col.prop(ant, "height_offset")
col.prop(ant, "maximum")
col.prop(ant, "minimum")
if not ant.sphere_mesh:
col = box.column()
col.prop(ant, "edge_falloff")
if ant.edge_falloff is not "0":
col = box.column(align=True)
col.prop(ant, "edge_level")
if ant.edge_falloff in ["2", "3"]:
col.prop(ant, "falloff_x")
if ant.edge_falloff in ["1", "3"]:
col.prop(ant, "falloff_y")
col = box.column(align=True)
row = col.row(align=True).split(0.92, align=True)
row.prop(ant, "height")
row.prop(ant, "height_invert", toggle=True, text="", icon='ARROW_LEFTRIGHT')
col.prop(ant, "height_offset")
col.prop(ant, "maximum")
col.prop(ant, "minimum")
if not ant.sphere_mesh:
col = box.column()
col.prop(ant, "strata_type")
if ant.strata_type is not "0":
col = box.column()
col.prop(ant, "strata")
col.prop(ant, "edge_falloff")
if ant.edge_falloff is not "0":
col = box.column(align=True)
col.prop(ant, "edge_level")
if ant.edge_falloff in ["2", "3"]:
col.prop(ant, "falloff_x")
if ant.edge_falloff in ["1", "3"]:
col.prop(ant, "falloff_y")
col = box.column()
col.prop(ant, "strata_type")
if ant.strata_type is not "0":
col = box.column()
col.prop(ant, "use_vgroup", toggle=True)
else:
box = layout.box()
box.label("Select a Landscape Object!", icon='ERROR')
col.prop(ant, "strata")
col = box.column()
col.prop(ant, "use_vgroup", toggle=True)
# ------------------------------------------------------------
@ -529,8 +509,8 @@ class AntLandscapePropertiesGroup(bpy.types.PropertyGroup):
('marble_noise', "Marble", "A.N.T.: Marble Noise", 7),
('shattered_hterrain', "Shattered hTerrain", "A.N.T.: Shattered hTerrain", 8),
('strata_hterrain', "Strata hTerrain", "A.N.T: Strata hTerrain", 9),
('ant_turbulence', "Another Turbulence", "A.N.T: Turbulence variation", 10),
('vl_noise_turbulence', "vlNoise turbulence", "A.N.T: vlNoise turbulence", 11),
('ant_turbulence', "Another Noise", "A.N.T: Turbulence variation", 10),
('vl_noise_turbulence', "vlNoise turbulence", "A.N.T: Real vlNoise turbulence", 11),
('vl_hTerrain', "vlNoise hTerrain", "A.N.T: vlNoise hTerrain", 12),
('distorted_heteroTerrain', "Distorted hTerrain", "A.N.T distorted hTerrain", 13),
('double_multiFractal', "Double MultiFractal", "A.N.T: double multiFractal", 14),

View File

@ -186,8 +186,8 @@ class AntAddLandscape(bpy.types.Operator):
('marble_noise', "Marble", "A.N.T.: Marble Noise", 7),
('shattered_hterrain', "Shattered hTerrain", "A.N.T.: Shattered hTerrain", 8),
('strata_hterrain', "Strata hTerrain", "A.N.T: Strata hTerrain", 9),
('ant_turbulence', "Another Turbulence", "A.N.T: Turbulence variation", 10),
('vl_noise_turbulence', "vlNoise turbulence", "A.N.T: vlNoise turbulence", 11),
('ant_turbulence', "Another Noise", "A.N.T: Turbulence variation", 10),
('vl_noise_turbulence', "vlNoise turbulence", "A.N.T: Real vlNoise turbulence", 11),
('vl_hTerrain', "vlNoise hTerrain", "A.N.T: vlNoise hTerrain", 12),
('distorted_heteroTerrain', "Distorted hTerrain", "A.N.T distorted hTerrain", 13),
('double_multiFractal', "Double MultiFractal", "A.N.T: double multiFractal", 14),

View File

@ -694,7 +694,7 @@ def draw_ant_main(self, context, generate=True):
col.prop(self, "mesh_size_y")
def draw_ant_noise(self, context):
def draw_ant_noise(self, context, generate=True):
layout = self.layout
box = layout.box()
box.prop(self, "show_noise_settings", toggle=True)
@ -713,8 +713,9 @@ def draw_ant_noise(self, context):
col.prop(self, "noise_offset_z")
col.prop(self, "noise_size_x")
col.prop(self, "noise_size_y")
if self.sphere_mesh:
if self.sphere_mesh == True or generate == False:
col.prop(self, "noise_size_z")
col = box.column(align=True)
col.prop(self, "noise_size")
@ -960,7 +961,7 @@ def availableVertexGroupsOrNone(self, context):
class Eroder(bpy.types.Operator):
bl_idname = "mesh.eroder"
bl_label = "ErosionR"
bl_description = "Apply various kinds of erosion to a landscape mesh"
bl_description = "Apply various kinds of erosion to a landscape mesh. Also available in Weight Paint mode > Weights menu"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
Iterations = IntProperty(
@ -1122,22 +1123,12 @@ class Eroder(bpy.types.Operator):
default=False
)
weight_mode = BoolProperty(
name="Weight Paint Mode",
default=False,
description="Enter weightpaint mode"
)
stats = Stats()
counts= {}
# add poll function to restrict action to mesh object in object mode
def execute(self, context):
# Enter WeightPaintMode
if self.weight_mode:
bpy.ops.paint.weight_paint_toggle()
def execute(self, context):
ob = context.active_object
#obwater = bpy.data.objects["water"]
@ -1190,7 +1181,7 @@ class Eroder(bpy.types.Operator):
except:
vgcapacity=ob.vertex_groups.new("capacity")
g = Grid.fromBlenderMesh(me, vg, self.Ef)
me = bpy.data.meshes.new(me.name)
#mewater = bpy.data.meshes.new(mewater.name)
@ -1201,7 +1192,7 @@ class Eroder(bpy.types.Operator):
if self.IterRiver > 0:
for i in range(self.IterRiver):
g.rivergeneration(self.Kr, self.Kv, self.userainmap, self.Kc, self.Ks, self.Kdep, self.Ka, self.Kev/100, 0,0,0,0, self.numexpr)
if self.Kd > 0.0:
for k in range(self.IterDiffuse):
g.diffuse(self.Kd / 5, self.IterDiffuse, self.numexpr)
@ -1333,8 +1324,6 @@ class Eroder(bpy.types.Operator):
layout.prop(self,'smooth')
layout.prop(self,'weight_mode')
#if numexpr_available:
# layout.prop(self, 'numexpr')
#else:

View File

@ -115,18 +115,18 @@ class Grid:
def raw(self,format="%.3f"):
fstr=format+" "+ format+" "+ format+" "
a=self.center / self.zscale
minx=0.0 if self.minx is None else self.minx
miny=0.0 if self.miny is None else self.miny
maxx=1.0 if self.maxx is None else self.maxx
maxy=1.0 if self.maxy is None else self.maxy
dx=(maxx-minx)/(a.shape[0]-1)
dy=(maxy-miny)/(a.shape[1]-1)
for row in range(a.shape[0]-1):
row0=miny+row*dy
row1=row0+dy
for col in range(a.shape[1]-1):
col0=minx+col*dx
col1=col0+dx
minx = 0.0 if self.minx is None else self.minx
miny = 0.0 if self.miny is None else self.miny
maxx = 1.0 if self.maxx is None else self.maxx
maxy = 1.0 if self.maxy is None else self.maxy
dx = (maxx - minx) / (a.shape[0] - 1)
dy = (maxy - miny) / (a.shape[1] - 1)
for row in range(a.shape[0] - 1):
row0 = miny + row * dy
row1 = row0 + dy
for col in range(a.shape[1] - 1):
col0 = minx + col * dx
col1 = col0 + dx
yield (fstr%(row0 ,col0 ,a[row ][col ])+
fstr%(row0 ,col1 ,a[row ][col+1])+
fstr%(row1 ,col0 ,a[row+1][col ])+"\n")
@ -140,7 +140,7 @@ class Grid:
if infomap:
with open(os.path.splitext(filename)[0]+".inf" if type(filename) == str else sys.stdout.fileno() , "w") as f:
f.writelines("\n".join("%-15s: %s"%t for t in sorted(infomap.items())))
@staticmethod
def fromRaw(filename):
"""initialize a grid from a Blender .raw file.
@ -171,7 +171,7 @@ class Grid:
self.zscale=1.0
if abs(yscale) > 1e-6 :
self.zscale=1.0/yscale
# keep just the z-values and null any ofsset
# we might catch a reshape error that will occur if nx*ny != # of vertices (if we are not dealing with a heightfield but with a mesh with duplicate x,y coords, like an axis aligned cube
self.center=np.array([c[2] for c in verts],dtype=np.single).reshape(nx,ny)
@ -182,7 +182,7 @@ class Grid:
rmscale = np.max(self.center)
#self.rainmap = (self.center/rmscale) * np.exp(expfact*((self.center/rmscale)-1))
self.rainmap = expfact + (1-expfact)*(self.center/rmscale)
@staticmethod
def fromBlenderMesh(me, vg, expfact):
g=Grid()
@ -201,12 +201,11 @@ class Grid:
# def rainmapcolor(me, vg):
# if vg is not None:
# for v in me.vertices:
def setrainmap(self, rainmap):
self.rainmap = rainmap
def _verts(self, surface):
a=surface / self.zscale
minx=0.0 if self.minx is None else self.minx
@ -228,15 +227,15 @@ class Grid:
vi = row * ncol + col
yield (vi, vi+ncol, vi+1)
yield (vi+1, vi+ncol, vi+ncol+1)
def toBlenderMesh(self, me): # pass me as argument so that we don't need to import bpy and create a dependency
# the docs state that from_pydata takes iterators as arguments but it will fail with generators because it does len(arg)
me.from_pydata(list(self._verts(self.center)),[],list(self._faces()))
def toWaterMesh(self, me): # pass me as argument so that we don't need to import bpy and create a dependency
# the docs state that from_pydata takes iterators as arguments but it will fail with generators because it does len(arg)
me.from_pydata(list(self._verts(self.water)),[],list(self._faces()))
def peak(self, value=1):
nx,ny = self.center.shape
self.center[int(nx/2),int(ny/2)] += value
@ -283,14 +282,14 @@ class Grid:
def avalanche(self, delta, iterava, prob, numexpr):
self.zeroedge()
#print(self.center)
c = self.center[1:-1,1:-1]
up = self.center[ :-2,1:-1]
down = self.center[2: ,1:-1]
left = self.center[1:-1, :-2]
right = self.center[1:-1,2: ]
where = np.where
if(numexpr and numexpr_available):
self.center[1:-1,1:-1] = ne.evaluate('c + where((up -c) > delta ,(up -c -delta)/2, 0) \
+ where((down -c) > delta ,(down -c -delta)/2, 0) \
@ -317,14 +316,14 @@ class Grid:
sa = where(randarray < prob, sa, 0)
self.avalanced[1:-1,1:-1] = self.avalanced[1:-1,1:-1] + sa/iterava
self.center[1:-1,1:-1] = c + sa/iterava
#print(self.center)
self.maxrss = max(getmemsize(), self.maxrss)
return self.center
def rain(self, amount=1, variance=0, userainmap=False):
self.water += (1.0 - np.random.random(self.water.shape) * variance) * (amount if ((self.rainmap is None) or (not userainmap)) else self.rainmap * amount)
def spring(self, amount, px, py, radius): # px, py and radius are all fractions
nx, ny = self.center.shape
rx = max(int(nx*radius),1)
@ -332,7 +331,7 @@ class Grid:
px = int(nx*px)
py = int(ny*py)
self.water[px-rx:px+rx+1,py-ry:py+ry+1] += amount
def river(self, Kc, Ks, Kdep, Ka, Kev, numexpr):
zeros = np.zeros
@ -342,14 +341,14 @@ class Grid:
abs = np.absolute
arctan = np.arctan
sin = np.sin
center = (slice( 1, -1,None),slice( 1, -1,None))
#print("CentreSlice\n", np.array_str(center,precision=3), file=sys.stderr)
up = (slice(None, -2,None),slice( 1, -1,None))
down = (slice( 2, None,None),slice( 1, -1,None))
left = (slice( 1, -1,None),slice(None, -2,None))
right = (slice( 1, -1,None),slice( 2,None,None))
water = self.water
rock = self.center
sediment = self.sediment
@ -385,7 +384,7 @@ class Grid:
sds = sds + dw * where(inflow, sc[d], sc[center])
svdw = svdw + abs(dw)
angle= angle + np.arctan(abs(rock[d]-rock[center]))
if(numexpr and numexpr_available):
wcc = water[center]
scc = sediment[center]
@ -417,7 +416,7 @@ class Grid:
#rock[center] = where(rcc<0,0,rcc) # there isn't really a bottom to the rock but negative values look ugly
sediment[center] = scc + ds + sds
#print("sdw", sdw[10,15])
def flow(self, Kc, Ks, Kz, Ka, numexpr):
zeros = np.zeros
@ -427,14 +426,14 @@ class Grid:
abs = np.absolute
arctan = np.arctan
sin = np.sin
center = (slice( 1, -1,None),slice( 1, -1,None))
#print("CentreSlice\n", np.array_str(center,precision=3), file=sys.stderr)
#up = (slice(None, -2,None),slice( 1, -1,None))
#down = (slice( 2, None,None),slice( 1, -1,None))
#left = (slice( 1, -1,None),slice(None, -2,None))
#right = (slice( 1, -1,None),slice( 2,None,None))
#water = self.water
rock = self.center
#sediment = self.sediment
@ -471,7 +470,7 @@ class Grid:
#sds = sds + dw * where(inflow, sc[d], sc[center])
#svdw = svdw + abs(dw)
#angle= angle + np.arctan(abs(rock[d]-rock[center]))
#if(numexpr and numexpr_available):
#wcc = water[center]
#scc = sediment[center]
@ -519,7 +518,7 @@ class Grid:
self.scourmin = np.min(self.scour)
self.sedmax = np.max(self.sediment)
print("DSMinMax", np.min(self.scour), np.max(self.scour))
def analyze(self):
self.neighborgrid()
# just looking at up and left to avoid needless doubel calculations
@ -611,7 +610,7 @@ if __name__ == "__main__":
if args.unittest:
unittest.main(argv=[sys.argv[0]])
sys.exit(0)
if args.useinputfile:
if args.rawin:
grid = Grid.fromRaw(args.infile)

View File

@ -182,8 +182,8 @@ class AntMeshDisplace(bpy.types.Operator):
('marble_noise', "Marble", "A.N.T.: Marble Noise", 7),
('shattered_hterrain', "Shattered hTerrain", "A.N.T.: Shattered hTerrain", 8),
('strata_hterrain', "Strata hTerrain", "A.N.T: Strata hTerrain", 9),
('ant_turbulence', "Another Turbulence", "A.N.T: Turbulence variation", 10),
('vl_noise_turbulence', "vlNoise turbulence", "A.N.T: vlNoise turbulence", 11),
('ant_turbulence', "Another Noise", "A.N.T: Turbulence variation", 10),
('vl_noise_turbulence', "vlNoise turbulence", "A.N.T: Real vlNoise turbulence", 11),
('vl_hTerrain', "vlNoise hTerrain", "A.N.T: vlNoise hTerrain", 12),
('distorted_heteroTerrain', "Distorted hTerrain", "A.N.T distorted hTerrain", 13),
('double_multiFractal', "Double MultiFractal", "A.N.T: double multiFractal", 14),
@ -467,7 +467,7 @@ class AntMeshDisplace(bpy.types.Operator):
def draw(self, context):
draw_ant_refresh(self, context)
draw_ant_noise(self, context)
draw_ant_noise(self, context, generate=False)
draw_ant_displace(self, context, generate=False)

View File

@ -14,25 +14,25 @@ class Stats:
self.process=psutil.Process()
self.memstats_available = True
self.reset()
def reset(self):
self.lasttime=self._gettime()
self.lastmem=self._getmem()
self.lasttime = self._gettime()
self.lastmem = self._getmem()
self.basemem = self.lastmem
self.maxmem=0
self.elapsedtime=0
self.maxmem = 0
self.elapsedtime = 0
def _gettime(self):
"""return the time in seconds used by the current process."""
if psutil_available:
m=self.process.get_cpu_times()
return m.user+m.system
return m.user + m.system
return time()
def _getmem(self):
"""return the resident set size in bytes used by the current process."""
if psutil_available:
m=self.process.get_memory_info()
m = self.process.get_memory_info()
return m.rss
return 0
@ -40,9 +40,9 @@ class Stats:
"""return the time since the last call in seconds used by the current process."""
old = self.lasttime
self.lasttime = self._gettime()
self.elapsedtime = self.lasttime-old
self.elapsedtime = self.lasttime - old
return self.elapsedtime
def memory(self):
"""return the maximum resident set size since the first call in bytes used by the current process."""
self.lastmem = self._getmem()
@ -50,6 +50,3 @@ class Stats:
if d>self.maxmem:
self.maxmem = d
return self.maxmem

View File

@ -18,4 +18,4 @@ if __name__ == '__main__':
print(stats.memory())
a = cos(a)**2+sin(a)**2
print(stats.time())
print(stats.memory())
print(stats.memory())

179
mesh_tissue/uv_to_mesh.py Normal file
View File

@ -0,0 +1,179 @@
# ##### 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 #####
#---------------------------------- UV to MESH --------------------------------#
#--------------------------------- version 0.1 --------------------------------#
# #
# Create a new Mesh based on active UV #
# #
# (c) Alessandro Zomparelli #
# (2017) #
# #
# http://www.co-de-it.com/ #
# #
################################################################################
import bpy
import bmesh, math
from mathutils import Vector
bl_info = {
"name": "UV to Mesh",
"author": "Alessandro Zomparelli (Co-de-iT)",
"version": (0, 1),
"blender": (2, 7, 9),
"location": "",
"description": "Create a new Mesh based on active UV",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Mesh"}
class uv_to_mesh(bpy.types.Operator):
bl_idname = "object.uv_to_mesh"
bl_label = "UV to Mesh"
bl_options = {'REGISTER', 'UNDO'}
bl_description = ("Create a new Mesh based on active UV")
apply_modifiers = bpy.props.BoolProperty(
name="Apply Modifiers", default=False,
description="Apply object's modifiers")
vertex_groups = bpy.props.BoolProperty(
name="Keep Vertex Groups", default=False,
description="Transfer all the Vertex Groups")
materials = bpy.props.BoolProperty(
name="Keep Materials", default=True,
description="Transfer all the Materials")
auto_scale = bpy.props.BoolProperty(
name="Resize", default=True,
description="Scale the new object in order to preserve the average surface area")
def execute(self, context):
bpy.ops.object.mode_set(mode='OBJECT')
for o in bpy.data.objects: o.select = False
bpy.context.object.select = True
if self.apply_modifiers:
bpy.ops.object.duplicate_move()
bpy.ops.object.convert(target='MESH')
ob0 = bpy.context.object
me0 = ob0.to_mesh(bpy.context.scene,
apply_modifiers=self.apply_modifiers, settings = 'PREVIEW')
area = 0
verts = []
faces = []
face_materials = []
for face in me0.polygons:
area += face.area
uv_face = []
store = False
try:
for loop in face.loop_indices:
uv = me0.uv_layers.active.data[loop].uv
if uv.x != 0 and uv.y != 0: store = True
new_vert = Vector((uv.x,uv.y,0))
verts.append(new_vert)
uv_face.append(loop)
if store:
faces.append(uv_face)
face_materials.append(face.material_index)
except:
self.report({'ERROR'}, "Missing UV Map")
return {'CANCELLED'}
name = ob0.name + 'UV'
# Create mesh and object
me = bpy.data.meshes.new(name+'Mesh')
ob = bpy.data.objects.new(name, me)
# Link object to scene and make active
scn = bpy.context.scene
scn.objects.link(ob)
scn.objects.active = ob
ob.select = True
# Create mesh from given verts, faces.
me.from_pydata(verts, [], faces)
# Update mesh with new data
me.update()
if self.auto_scale:
new_area = 0
for p in me.polygons:
new_area += p.area
if new_area == 0:
self.report({'ERROR'}, "Impossible to generate mesh from UV")
return {'CANCELLED'}
# VERTEX GROUPS
if self.vertex_groups:
try:
for group in ob0.vertex_groups:
index = group.index
ob.vertex_groups.new(group.name)
for p in me0.polygons:
for vert, loop in zip(p.vertices, p.loop_indices):
ob.vertex_groups[index].add([loop], group.weight(vert), "ADD")
except:
pass
ob0.select = False
if self.auto_scale:
scaleFactor = math.pow(area/new_area,1/2)
ob.scale = Vector((scaleFactor,scaleFactor,scaleFactor))
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
bpy.ops.mesh.remove_doubles(threshold=1e-06)
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
# MATERIALS
if self.materials:
try:
# assign old material
uv_materials = [slot.material for slot in ob0.material_slots]
for i in range(len(uv_materials)):
bpy.ops.object.material_slot_add()
bpy.context.object.material_slots[i].material = uv_materials[i]
for i in range(len(ob.data.polygons)):
ob.data.polygons[i].material_index = face_materials[i]
except:
pass
if self.apply_modifiers:
bpy.ops.object.mode_set(mode='OBJECT')
ob.select = False
ob0.select = True
bpy.ops.object.delete(use_global=False)
ob.select = True
bpy.context.scene.objects.active = ob
return {'FINISHED'}
def register():
bpy.utils.register_class(uv_to_mesh)
def unregister():
bpy.utils.unregister_class(uv_to_mesh)
if __name__ == "__main__":
register()