diff options
author | meta-androcto <meta.androcto1@gmail.com> | 2019-12-11 08:13:25 +0300 |
---|---|---|
committer | meta-androcto <meta.androcto1@gmail.com> | 2019-12-11 08:13:25 +0300 |
commit | 7347930a0fa14e752929e28c9b48adf74597b018 (patch) | |
tree | b6c4f5acd3b984cf404a1526f5b77fd92d9d4bdf /add_mesh_extra_objects | |
parent | 2fcb2241e98a409021ab427b36a3efd0b49e8f4d (diff) |
extra_objects: add rock gen: T71560
Diffstat (limited to 'add_mesh_extra_objects')
-rw-r--r-- | add_mesh_extra_objects/__init__.py | 7 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_rocks/__init__.py | 67 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_rocks/add_mesh_rocks.xml | 403 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_rocks/factory.xml | 403 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_rocks/randomize_texture.py | 157 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_rocks/rockgen.py | 1175 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_rocks/settings.py | 163 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_rocks/utils.py | 160 |
8 files changed, 2535 insertions, 0 deletions
diff --git a/add_mesh_extra_objects/__init__.py b/add_mesh_extra_objects/__init__.py index d6f25f43..ff1d3037 100644 --- a/add_mesh_extra_objects/__init__.py +++ b/add_mesh_extra_objects/__init__.py @@ -85,6 +85,9 @@ else: from . import Wallfactory from . import add_mesh_triangles + from .add_mesh_rocks import __init__ + from .add_mesh_rocks import rockgen + import bpy from bpy.types import Menu @@ -366,6 +369,8 @@ def register(): for cls in classes: register_class(cls) + add_mesh_rocks.register() + # Add "Extras" menu to the "Add Mesh" menu and context menu. bpy.types.VIEW3D_MT_mesh_add.append(menu_func) bpy.types.VIEW3D_MT_object_context_menu.prepend(Extras_contex_menu) @@ -380,5 +385,7 @@ def unregister(): for cls in reversed(classes): unregister_class(cls) + add_mesh_rocks.unregister() + if __name__ == "__main__": register() diff --git a/add_mesh_extra_objects/add_mesh_rocks/__init__.py b/add_mesh_extra_objects/add_mesh_rocks/__init__.py new file mode 100644 index 00000000..6b0218dd --- /dev/null +++ b/add_mesh_extra_objects/add_mesh_rocks/__init__.py @@ -0,0 +1,67 @@ +# Paul "BrikBot" Marshall +# Created: July 1, 2011 +# Last Modified: September 26, 2013 +# Homepage (blog): http://post.darkarsenic.com/ +# //blog.darkarsenic.com/ +# Thanks to Meta-Androco, RickyBlender, Ace Dragon, and PKHG for ideas +# and testing. +# +# Coded in IDLE, tested in Blender 2.68a. NumPy Recommended. +# Search for "@todo" to quickly find sections that need work. +# +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# The Blender Rock Creation tool is for rapid generation of +# mesh rocks in Blender. +# Copyright (C) 2011 Paul Marshall +# +# 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 3 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, see <http://www.gnu.org/licenses/>. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + +bl_info = { + "name": "Rock Generator", + "author": "Paul Marshall (brikbot)", + "version": (1, 4), + "blender": (2, 80, 0), + "location": "View3D > Add > Rock Generator", + "description": "Adds a mesh rock to the Add Mesh menu", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" + "Scripts/Add_Mesh/Rock_Generator", + "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/", + "category": "Add Mesh"} + +if "bpy" in locals(): + import importlib + importlib.reload(rockgen) + +else: + from . import rockgen + +import bpy + + +# Register: +def register(): + rockgen.register() + + +def unregister(): + rockgen.unregister() + + +if __name__ == "__main__": + register() diff --git a/add_mesh_extra_objects/add_mesh_rocks/add_mesh_rocks.xml b/add_mesh_extra_objects/add_mesh_rocks/add_mesh_rocks.xml new file mode 100644 index 00000000..08eb22e6 --- /dev/null +++ b/add_mesh_extra_objects/add_mesh_rocks/add_mesh_rocks.xml @@ -0,0 +1,403 @@ +<?xml version="1.0" ?> +<!DOCTYPE settings [ +<!ELEMENT settings (default,preset*)> +<!ELEMENT default (title,size,shape,material,random)> +<!ELEMENT preset (title,size,shape,material,random)> +<!ELEMENT title (#PCDATA)> +<!ELEMENT size (scale+,skew+,use_scale_dis,scale_fac)> +<!ELEMENT scale (axis,lower,upper)> +<!ELEMENT axis (#PCDATA)> +<!ELEMENT lower (#PCDATA)> +<!ELEMENT upper (#PCDATA)> +<!ELEMENT skew (axis,value)> +<!ELEMENT value (#PCDATA)> +<!ELEMENT use_scale_dis (#PCDATA)> +<!ELEMENT scale_fac (#PCDATA)> +<!ELEMENT shape (deform,rough,detail,display_detail,smooth_fac,smooth_it)> +<!ELEMENT deform (#PCDATA)> +<!ELEMENT rough (#PCDATA)> +<!ELEMENT detail (#PCDATA)> +<!ELEMENT display_detail (#PCDATA)> +<!ELEMENT smooth_fac (#PCDATA)> +<!ELEMENT smooth_it (#PCDATA)> +<!ELEMENT material (mat_enable,mat_color,mat_bright,mat_rough,mat_spec,mat_hard,mat_use_trans,mat_alpha,mat_cloudy,mat_IOR,mat_mossy)> +<!ELEMENT mat_enable (#PCDATA)> +<!ELEMENT mat_color (#PCDATA)> +<!ELEMENT mat_bright (#PCDATA)> +<!ELEMENT mat_rough (#PCDATA)> +<!ELEMENT mat_spec (#PCDATA)> +<!ELEMENT mat_hard (#PCDATA)> +<!ELEMENT mat_use_trans (#PCDATA)> +<!ELEMENT mat_alpha (#PCDATA)> +<!ELEMENT mat_cloudy (#PCDATA)> +<!ELEMENT mat_IOR (#PCDATA)> +<!ELEMENT mat_mossy (#PCDATA)> +<!ELEMENT random (use_random_seed,user_seed)> +<!ELEMENT use_generate (#PCDATA)> +<!ELEMENT use_random_seed (#PCDATA)> +<!ELEMENT user_seed (#PCDATA)> + +<!ATTLIST preset id ID #REQUIRED> +]> +<settings> + <default> + <title>Default</title> + <size> + <scale> + <axis>X</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <skew> + <axis>X</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Y</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Z</axis> + <value>0.0</value> + </skew> + <use_scale_dis>False</use_scale_dis> + <scale_fac>[1.0, 1.0, 1.0]</scale_fac> + </size> + <shape> + <deform>5.0</deform> + <rough>2.5</rough> + <detail>3</detail> + <display_detail>2</display_detail> + <smooth_fac>0.0</smooth_fac> + <smooth_it>0</smooth_it> + </shape> + <material> + <mat_enable>False</mat_enable> + <mat_color>[0.5, 0.5, 0.5]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>1.0</mat_rough> + <mat_spec>0.2</mat_spec> + <mat_hard>50</mat_hard> + <mat_use_trans>False</mat_use_trans> + <mat_alpha>0.0</mat_alpha> + <mat_cloudy>0.0</mat_cloudy> + <mat_IOR>1.0</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </default> + <preset id="1"> + <title>River Rock</title> + <size> + <scale> + <axis>X</axis> + <lower>0.5</lower> + <upper>1.25</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>0.5</lower> + <upper>1.25</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>0.5</lower> + <upper>1.25</upper> + </scale> + <skew> + <axis>X</axis> + <value>-0.5</value> + </skew> + <skew> + <axis>Y</axis> + <value>-0.5</value> + </skew> + <skew> + <axis>Z</axis> + <value>-0.5</value> + </skew> + <use_scale_dis>False</use_scale_dis> + <scale_fac>[1.0, 1.0, 1.0]</scale_fac> + </size> + <shape> + <deform>3.0</deform> + <rough>2.0</rough> + <detail>2</detail> + <display_detail>2</display_detail> + <smooth_fac>2.0</smooth_fac> + <smooth_it>2</smooth_it> + </shape> + <material> + <mat_enable>True</mat_enable> + <mat_color>[0.5, 0.5, 0.5]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>0.125</mat_rough> + <mat_spec>0.5</mat_spec> + <mat_hard>50</mat_hard> + <mat_use_trans>False</mat_use_trans> + <mat_alpha>0.0</mat_alpha> + <mat_cloudy>0.0</mat_cloudy> + <mat_IOR>1.0</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </preset> + <preset id="2"> + <title>Asteroid</title> + <size> + <scale> + <axis>X</axis> + <lower>1.0</lower> + <upper>5.0</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>1.0</lower> + <upper>5.0</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>1.0</lower> + <upper>5.0</upper> + </scale> + <skew> + <axis>X</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Y</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Z</axis> + <value>0.0</value> + </skew> + <use_scale_dis>False</use_scale_dis> + <scale_fac>[1.0, 1.0, 1.0]</scale_fac> + </size> + <shape> + <deform>7.5</deform> + <rough>3.0</rough> + <detail>4</detail> + <display_detail>3</display_detail> + <smooth_fac>0.0</smooth_fac> + <smooth_it>0</smooth_it> + </shape> + <material> + <mat_enable>True</mat_enable> + <mat_color>[0.3, 0.25, 0.2]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>1.5</mat_rough> + <mat_spec>0.25</mat_spec> + <mat_hard>30</mat_hard> + <mat_use_trans>False</mat_use_trans> + <mat_alpha>0.0</mat_alpha> + <mat_cloudy>0.0</mat_cloudy> + <mat_IOR>1.0</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </preset> + <preset id="3"> + <title>Sandstone</title> + <size> + <scale> + <axis>X</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <skew> + <axis>X</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Y</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Z</axis> + <value>0.0</value> + </skew> + <use_scale_dis>True</use_scale_dis> + <scale_fac>[5.0, 5.0, 0.1]</scale_fac> + </size> + <shape> + <deform>0.5</deform> + <rough>1.0</rough> + <detail>3</detail> + <display_detail>3</display_detail> + <smooth_fac>2.0</smooth_fac> + <smooth_it>2</smooth_it> + </shape> + <material> + <mat_enable>True</mat_enable> + <mat_color>[0.5, 0.4, 0.35]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>0.1</mat_rough> + <mat_spec>0.2</mat_spec> + <mat_hard>50</mat_hard> + <mat_use_trans>False</mat_use_trans> + <mat_alpha>0.0</mat_alpha> + <mat_cloudy>0.0</mat_cloudy> + <mat_IOR>1.0</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </preset> + <preset id="4"> + <title>Ice</title> + <size> + <scale> + <axis>X</axis> + <lower>0.0</lower> + <upper>2.0</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>0.0</lower> + <upper>2.0</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>0.0</lower> + <upper>2.0</upper> + </scale> + <skew> + <axis>X</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Y</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Z</axis> + <value>0.0</value> + </skew> + <use_scale_dis>False</use_scale_dis> + <scale_fac>[1.0, 1.0, 1.0]</scale_fac> + </size> + <shape> + <deform>5.0</deform> + <rough>1.0</rough> + <detail>3</detail> + <display_detail>2</display_detail> + <smooth_fac>2.0</smooth_fac> + <smooth_it>1</smooth_it> + </shape> + <material> + <mat_enable>True</mat_enable> + <mat_color>[0.9, 0.95, 1.0]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>0.25</mat_rough> + <mat_spec>0.2</mat_spec> + <mat_hard>50</mat_hard> + <mat_use_trans>True</mat_use_trans> + <mat_alpha>0.9</mat_alpha> + <mat_cloudy>0.1</mat_cloudy> + <mat_IOR>1.31</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </preset> + <preset id="5"> + <title>Fake Ocean</title> + <size> + <scale> + <axis>X</axis> + <lower>10.0</lower> + <upper>10.0</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>10.0</lower> + <upper>10.0</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>0.0</lower> + <upper>0.0</upper> + </scale> + <skew> + <axis>X</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Y</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Z</axis> + <value>0.0</value> + </skew> + <use_scale_dis>False</use_scale_dis> + <scale_fac>[1.0, 1.0, 1.0]</scale_fac> + </size> + <shape> + <deform>7.5</deform> + <rough>3.0</rough> + <detail>4</detail> + <display_detail>3</display_detail> + <smooth_fac>0.0</smooth_fac> + <smooth_it>0</smooth_it> + </shape> + <material> + <mat_enable>True</mat_enable> + <mat_color>[0.1, 0.12, 0.125]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>1.5</mat_rough> + <mat_spec>0.25</mat_spec> + <mat_hard>30</mat_hard> + <mat_use_trans>True</mat_use_trans> + <mat_alpha>0.5</mat_alpha> + <mat_cloudy>0.5</mat_cloudy> + <mat_IOR>1.333</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </preset> +</settings> diff --git a/add_mesh_extra_objects/add_mesh_rocks/factory.xml b/add_mesh_extra_objects/add_mesh_rocks/factory.xml new file mode 100644 index 00000000..08eb22e6 --- /dev/null +++ b/add_mesh_extra_objects/add_mesh_rocks/factory.xml @@ -0,0 +1,403 @@ +<?xml version="1.0" ?> +<!DOCTYPE settings [ +<!ELEMENT settings (default,preset*)> +<!ELEMENT default (title,size,shape,material,random)> +<!ELEMENT preset (title,size,shape,material,random)> +<!ELEMENT title (#PCDATA)> +<!ELEMENT size (scale+,skew+,use_scale_dis,scale_fac)> +<!ELEMENT scale (axis,lower,upper)> +<!ELEMENT axis (#PCDATA)> +<!ELEMENT lower (#PCDATA)> +<!ELEMENT upper (#PCDATA)> +<!ELEMENT skew (axis,value)> +<!ELEMENT value (#PCDATA)> +<!ELEMENT use_scale_dis (#PCDATA)> +<!ELEMENT scale_fac (#PCDATA)> +<!ELEMENT shape (deform,rough,detail,display_detail,smooth_fac,smooth_it)> +<!ELEMENT deform (#PCDATA)> +<!ELEMENT rough (#PCDATA)> +<!ELEMENT detail (#PCDATA)> +<!ELEMENT display_detail (#PCDATA)> +<!ELEMENT smooth_fac (#PCDATA)> +<!ELEMENT smooth_it (#PCDATA)> +<!ELEMENT material (mat_enable,mat_color,mat_bright,mat_rough,mat_spec,mat_hard,mat_use_trans,mat_alpha,mat_cloudy,mat_IOR,mat_mossy)> +<!ELEMENT mat_enable (#PCDATA)> +<!ELEMENT mat_color (#PCDATA)> +<!ELEMENT mat_bright (#PCDATA)> +<!ELEMENT mat_rough (#PCDATA)> +<!ELEMENT mat_spec (#PCDATA)> +<!ELEMENT mat_hard (#PCDATA)> +<!ELEMENT mat_use_trans (#PCDATA)> +<!ELEMENT mat_alpha (#PCDATA)> +<!ELEMENT mat_cloudy (#PCDATA)> +<!ELEMENT mat_IOR (#PCDATA)> +<!ELEMENT mat_mossy (#PCDATA)> +<!ELEMENT random (use_random_seed,user_seed)> +<!ELEMENT use_generate (#PCDATA)> +<!ELEMENT use_random_seed (#PCDATA)> +<!ELEMENT user_seed (#PCDATA)> + +<!ATTLIST preset id ID #REQUIRED> +]> +<settings> + <default> + <title>Default</title> + <size> + <scale> + <axis>X</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <skew> + <axis>X</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Y</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Z</axis> + <value>0.0</value> + </skew> + <use_scale_dis>False</use_scale_dis> + <scale_fac>[1.0, 1.0, 1.0]</scale_fac> + </size> + <shape> + <deform>5.0</deform> + <rough>2.5</rough> + <detail>3</detail> + <display_detail>2</display_detail> + <smooth_fac>0.0</smooth_fac> + <smooth_it>0</smooth_it> + </shape> + <material> + <mat_enable>False</mat_enable> + <mat_color>[0.5, 0.5, 0.5]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>1.0</mat_rough> + <mat_spec>0.2</mat_spec> + <mat_hard>50</mat_hard> + <mat_use_trans>False</mat_use_trans> + <mat_alpha>0.0</mat_alpha> + <mat_cloudy>0.0</mat_cloudy> + <mat_IOR>1.0</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </default> + <preset id="1"> + <title>River Rock</title> + <size> + <scale> + <axis>X</axis> + <lower>0.5</lower> + <upper>1.25</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>0.5</lower> + <upper>1.25</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>0.5</lower> + <upper>1.25</upper> + </scale> + <skew> + <axis>X</axis> + <value>-0.5</value> + </skew> + <skew> + <axis>Y</axis> + <value>-0.5</value> + </skew> + <skew> + <axis>Z</axis> + <value>-0.5</value> + </skew> + <use_scale_dis>False</use_scale_dis> + <scale_fac>[1.0, 1.0, 1.0]</scale_fac> + </size> + <shape> + <deform>3.0</deform> + <rough>2.0</rough> + <detail>2</detail> + <display_detail>2</display_detail> + <smooth_fac>2.0</smooth_fac> + <smooth_it>2</smooth_it> + </shape> + <material> + <mat_enable>True</mat_enable> + <mat_color>[0.5, 0.5, 0.5]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>0.125</mat_rough> + <mat_spec>0.5</mat_spec> + <mat_hard>50</mat_hard> + <mat_use_trans>False</mat_use_trans> + <mat_alpha>0.0</mat_alpha> + <mat_cloudy>0.0</mat_cloudy> + <mat_IOR>1.0</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </preset> + <preset id="2"> + <title>Asteroid</title> + <size> + <scale> + <axis>X</axis> + <lower>1.0</lower> + <upper>5.0</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>1.0</lower> + <upper>5.0</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>1.0</lower> + <upper>5.0</upper> + </scale> + <skew> + <axis>X</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Y</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Z</axis> + <value>0.0</value> + </skew> + <use_scale_dis>False</use_scale_dis> + <scale_fac>[1.0, 1.0, 1.0]</scale_fac> + </size> + <shape> + <deform>7.5</deform> + <rough>3.0</rough> + <detail>4</detail> + <display_detail>3</display_detail> + <smooth_fac>0.0</smooth_fac> + <smooth_it>0</smooth_it> + </shape> + <material> + <mat_enable>True</mat_enable> + <mat_color>[0.3, 0.25, 0.2]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>1.5</mat_rough> + <mat_spec>0.25</mat_spec> + <mat_hard>30</mat_hard> + <mat_use_trans>False</mat_use_trans> + <mat_alpha>0.0</mat_alpha> + <mat_cloudy>0.0</mat_cloudy> + <mat_IOR>1.0</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </preset> + <preset id="3"> + <title>Sandstone</title> + <size> + <scale> + <axis>X</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>1.0</lower> + <upper>1.0</upper> + </scale> + <skew> + <axis>X</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Y</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Z</axis> + <value>0.0</value> + </skew> + <use_scale_dis>True</use_scale_dis> + <scale_fac>[5.0, 5.0, 0.1]</scale_fac> + </size> + <shape> + <deform>0.5</deform> + <rough>1.0</rough> + <detail>3</detail> + <display_detail>3</display_detail> + <smooth_fac>2.0</smooth_fac> + <smooth_it>2</smooth_it> + </shape> + <material> + <mat_enable>True</mat_enable> + <mat_color>[0.5, 0.4, 0.35]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>0.1</mat_rough> + <mat_spec>0.2</mat_spec> + <mat_hard>50</mat_hard> + <mat_use_trans>False</mat_use_trans> + <mat_alpha>0.0</mat_alpha> + <mat_cloudy>0.0</mat_cloudy> + <mat_IOR>1.0</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </preset> + <preset id="4"> + <title>Ice</title> + <size> + <scale> + <axis>X</axis> + <lower>0.0</lower> + <upper>2.0</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>0.0</lower> + <upper>2.0</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>0.0</lower> + <upper>2.0</upper> + </scale> + <skew> + <axis>X</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Y</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Z</axis> + <value>0.0</value> + </skew> + <use_scale_dis>False</use_scale_dis> + <scale_fac>[1.0, 1.0, 1.0]</scale_fac> + </size> + <shape> + <deform>5.0</deform> + <rough>1.0</rough> + <detail>3</detail> + <display_detail>2</display_detail> + <smooth_fac>2.0</smooth_fac> + <smooth_it>1</smooth_it> + </shape> + <material> + <mat_enable>True</mat_enable> + <mat_color>[0.9, 0.95, 1.0]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>0.25</mat_rough> + <mat_spec>0.2</mat_spec> + <mat_hard>50</mat_hard> + <mat_use_trans>True</mat_use_trans> + <mat_alpha>0.9</mat_alpha> + <mat_cloudy>0.1</mat_cloudy> + <mat_IOR>1.31</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </preset> + <preset id="5"> + <title>Fake Ocean</title> + <size> + <scale> + <axis>X</axis> + <lower>10.0</lower> + <upper>10.0</upper> + </scale> + <scale> + <axis>Y</axis> + <lower>10.0</lower> + <upper>10.0</upper> + </scale> + <scale> + <axis>Z</axis> + <lower>0.0</lower> + <upper>0.0</upper> + </scale> + <skew> + <axis>X</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Y</axis> + <value>0.0</value> + </skew> + <skew> + <axis>Z</axis> + <value>0.0</value> + </skew> + <use_scale_dis>False</use_scale_dis> + <scale_fac>[1.0, 1.0, 1.0]</scale_fac> + </size> + <shape> + <deform>7.5</deform> + <rough>3.0</rough> + <detail>4</detail> + <display_detail>3</display_detail> + <smooth_fac>0.0</smooth_fac> + <smooth_it>0</smooth_it> + </shape> + <material> + <mat_enable>True</mat_enable> + <mat_color>[0.1, 0.12, 0.125]</mat_color> + <mat_bright>0.85</mat_bright> + <mat_rough>1.5</mat_rough> + <mat_spec>0.25</mat_spec> + <mat_hard>30</mat_hard> + <mat_use_trans>True</mat_use_trans> + <mat_alpha>0.5</mat_alpha> + <mat_cloudy>0.5</mat_cloudy> + <mat_IOR>1.333</mat_IOR> + <mat_mossy>0.0</mat_mossy> + </material> + <random> + <use_generate>True</use_generate> + <use_random_seed>True</use_random_seed> + <user_seed>1</user_seed> + </random> + </preset> +</settings> diff --git a/add_mesh_extra_objects/add_mesh_rocks/randomize_texture.py b/add_mesh_extra_objects/add_mesh_rocks/randomize_texture.py new file mode 100644 index 00000000..d492c4e5 --- /dev/null +++ b/add_mesh_extra_objects/add_mesh_rocks/randomize_texture.py @@ -0,0 +1,157 @@ +# This try block allows for the script to psudo-intelligently select the +# appropriate random to use. If Numpy's random is present it will use that. +# If Numpy's random is not present, it will through a "module not found" +# exception and instead use the slower built-in random that Python has. +try: + from numpy.random import random_integers as randint + from numpy.random import normal as gauss + from numpy.random import ( + beta, + uniform, + ) +except: + from random import ( + randint, + gauss, + uniform, + ) + from random import betavariate as beta + +from .utils import skewedGauss + + +def randomizeTexture(texture, level=1): + ''' + Set the values for a texture from parameters. + + param: texture - bpy.data.texture to modify. + level - designated tweaked settings to use + -> Below 10 is a displacment texture + -> Between 10 and 20 is a base material texture + ''' + noises = ['BLENDER_ORIGINAL', 'ORIGINAL_PERLIN', 'IMPROVED_PERLIN', + 'VORONOI_F1', 'VORONOI_F2', 'VORONOI_F3', 'VORONOI_F4', + 'VORONOI_F2_F1', 'VORONOI_CRACKLE'] + if texture.type == 'CLOUDS': + if randint(0, 1) == 0: + texture.noise_type = 'SOFT_NOISE' + else: + texture.noise_type = 'HARD_NOISE' + if level != 11: + tempInt = randint(0, 6) + else: + tempInt = randint(0, 8) + texture.noise_basis = noises[tempInt] + texture.noise_depth = 8 + + if level == 0: + texture.noise_scale = gauss(0.625, 1 / 24) + elif level == 2: + texture.noise_scale = 0.15 + elif level == 11: + texture.noise_scale = gauss(0.5, 1 / 24) + + if texture.noise_basis in ['BLENDER_ORIGINAL', 'ORIGINAL_PERLIN', + 'IMPROVED_PERLIN', 'VORONOI_F1']: + texture.intensity = gauss(1, 1 / 6) + texture.contrast = gauss(4, 1 / 3) + elif texture.noise_basis in ['VORONOI_F2', 'VORONOI_F3', 'VORONOI_F4']: + texture.intensity = gauss(0.25, 1 / 12) + texture.contrast = gauss(2, 1 / 6) + elif texture.noise_basis == 'VORONOI_F2_F1': + texture.intensity = gauss(0.5, 1 / 6) + texture.contrast = gauss(2, 1 / 6) + elif texture.noise_basis == 'VORONOI_CRACKLE': + texture.intensity = gauss(0.5, 1 / 6) + texture.contrast = gauss(2, 1 / 6) + elif texture.type == 'MUSGRAVE': + # musgraveType = ['MULTIFRACTAL', 'RIDGED_MULTIFRACTAL', + # 'HYBRID_MULTIFRACTAL', 'FBM', 'HETERO_TERRAIN'] + texture.musgrave_type = 'MULTIFRACTAL' + texture.dimension_max = abs(gauss(0, 0.6)) + 0.2 + texture.lacunarity = beta(3, 8) * 8.2 + 1.8 + + if level == 0: + texture.noise_scale = gauss(0.625, 1 / 24) + texture.noise_intensity = 0.2 + texture.octaves = 1.0 + elif level == 2: + texture.intensity = gauss(1, 1 / 6) + texture.contrast = 0.2 + texture.noise_scale = 0.15 + texture.octaves = 8.0 + elif level == 10: + texture.intensity = gauss(0.25, 1 / 12) + texture.contrast = gauss(1.5, 1 / 6) + texture.noise_scale = 0.5 + texture.octaves = 8.0 + elif level == 12: + texture.octaves = uniform(1, 3) + elif level > 12: + texture.octaves = uniform(2, 8) + else: + texture.intensity = gauss(1, 1 / 6) + texture.contrast = 0.2 + texture.octaves = 8.0 + elif texture.type == 'DISTORTED_NOISE': + tempInt = randint(0, 8) + texture.noise_distortion = noises[tempInt] + tempInt = randint(0, 8) + texture.noise_basis = noises[tempInt] + texture.distortion = skewedGauss(2.0, 2.6666, (0.0, 10.0), False) + + if level == 0: + texture.noise_scale = gauss(0.625, 1 / 24) + elif level == 2: + texture.noise_scale = 0.15 + elif level >= 12: + texture.noise_scale = gauss(0.2, 1 / 48) + elif texture.type == 'STUCCI': + stucciTypes = ['PLASTIC', 'WALL_IN', 'WALL_OUT'] + if randint(0, 1) == 0: + texture.noise_type = 'SOFT_NOISE' + else: + texture.noise_type = 'HARD_NOISE' + tempInt = randint(0, 2) + texture.stucci_type = stucciTypes[tempInt] + + if level == 0: + tempInt = randint(0, 6) + texture.noise_basis = noises[tempInt] + texture.noise_scale = gauss(0.625, 1 / 24) + elif level == 2: + tempInt = randint(0, 6) + texture.noise_basis = noises[tempInt] + texture.noise_scale = 0.15 + elif level >= 12: + tempInt = randint(0, 6) + texture.noise_basis = noises[tempInt] + texture.noise_scale = gauss(0.2, 1 / 30) + else: + tempInt = randint(0, 6) + texture.noise_basis = noises[tempInt] + elif texture.type == 'VORONOI': + metrics = ['DISTANCE', 'DISTANCE_SQUARED', 'MANHATTAN', 'CHEBYCHEV', + 'MINKOVSKY_HALF', 'MINKOVSKY_FOUR', 'MINKOVSKY'] + # Settings for first dispalcement level: + if level == 0: + tempInt = randint(0, 1) + texture.distance_metric = metrics[tempInt] + texture.noise_scale = gauss(0.625, 1 / 24) + texture.contrast = 0.5 + texture.intensity = 0.7 + elif level == 2: + texture.noise_scale = 0.15 + tempInt = randint(0, 6) + texture.distance_metric = metrics[tempInt] + elif level >= 12: + tempInt = randint(0, 1) + texture.distance_metric = metrics[tempInt] + texture.noise_scale = gauss(0.125, 1 / 48) + texture.contrast = 0.5 + texture.intensity = 0.7 + else: + tempInt = randint(0, 6) + texture.distance_metric = metrics[tempInt] + + return diff --git a/add_mesh_extra_objects/add_mesh_rocks/rockgen.py b/add_mesh_extra_objects/add_mesh_rocks/rockgen.py new file mode 100644 index 00000000..46819093 --- /dev/null +++ b/add_mesh_extra_objects/add_mesh_rocks/rockgen.py @@ -0,0 +1,1175 @@ +# Blender rock creation tool +# +# Based on BlenderGuru's asteroid tutorial and personal experimentation. +# Tutorial: http://www.blenderguru.com/how-to-make-a-realistic-asteroid/ +# Update with another tutorial shared by "rusted" of BlenderArtists: +# Tutorial: http://saschahenrichs.blogspot.com/2010/03/3dsmax-environment-modeling-1.html +# +# Uses the NumPy Gaussian random number generator to generate a +# a rock within a given range and give some randomness to the displacement +# texture values. NumPy's gaussian generator was chosen as, based on +# profiling I performed, it runs in about half the time as the built in +# Python gaussian equivalent. I would like to shift the script to use the +# NumPy beta distribution as it ran in about half the time as the NumPy +# gaussian once the skew calculations are added. +# +# Set lower and upper bounds to the same for no randomness. +# +# Tasks: +# Generate meshes with random scaling between given values. +# - Allow for a skewed distribution +# *** Completed on 4/17/2011 *** +# - Create a set of meshes that can be used +# Give the user the ability to set the subsurf level (detail level) +# *** Completed on 4/29/2011 *** +# - Set subsurf modifiers to default at view:3, render:3. +# *** Completed on 4/17/2011 *** +# - Set crease values to allow for hard edges on first subsurf. +# *** Completed on 4/29/2011 *** +# Be able to generate and add a texture to the displacement modifiers. +# *** Completed 5/17/2011 *** +# - Generate three displacement modifiers. +# - The first only uses a Musgrave for initial intentations. +# *** Now generating four displacement modifiers *** +# *** Completed on 5/17/2011 *** +# - Set a randomness for the type and values of the displacement texture. +# *** Completed 5/9/2011 *** +# - Allow the user to set a value for the range of displacement. +# -> Modification: have user set "roughness" and "roughness range". +# *** Compleded on 4/23/2011 *** +# Set material settings and assign material textures +# *** Completed 6/9/2011 *** +# - Mossiness of the rocks. +# *** Completed 6/9/2011 *** +# - Color of the rocks. +# *** Completed 5/16/2011 *** +# - Wetness/shinyness of the rock. +# *** Completed 5/6/2011 *** +# - For all the user provides a mean value for a skewed distribution. +# *** Removed to lessen usage complexity *** +# Add some presets (mesh) to make it easier to use +# - Examples: river rock, asteroid, quaried rock, etc +# *** Completed 7/12/2011 *** +# +# Code Optimization: +# Remove all "bpy.ops" operations with "bpy.data" base operations. +# Remove material/texture cataloging with building a list of +# returned values from bpy.data.*.new() operations. +# *** Completed on 9/6/2011 *** +# Search for places where list comprehensions can be used. +# Look for alternate methods +# - Possible alternate and more efficient data structures +# - Possible alternate algorithms may realize greater performance +# - Look again at multi-processing. Without bpy.ops is might +# be viable. +# +# Future tasks: +# Multi-thread the script +# *** Will not be implemented. Multi-processing is adding to much +# overhead to realize a performance increase *** +# - Learn basic multi-threading in Python (multiprocessing) +# - Break material generation into separate threads (processes) +# - Break mesh generation into separate threads (processes) +# - Move name generation, texture ID generation, etc to process first +# - Roll version to 2.0 on completion +# +# Paul "BrikBot" Marshall +# Created: April 17, 2011 +# Last Modified: November 17, 2011 +# Homepage (blog): http://post.darkarsenic.com/ +# //blog.darkarsenic.com/ +# Thanks to Meta-Androco, RickyBlender, Ace Dragon, and PKHG for ideas +# and testing. +# +# Coded in IDLE, tested in Blender 2.59. NumPy Recommended. +# Search for "@todo" to quickly find sections that need work. +# +# Remeber - +# Functional code comes before fast code. Once it works, then worry about +# making it faster/more efficient. +# +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# The Blender Rock Creation tool is for rapid generation of mesh rocks. +# Copyright (C) 2011 Paul Marshall +# +# 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 3 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, see <http://www.gnu.org/licenses/>. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + +import bpy +import time +from . import ( + settings, + utils +) +from .utils import skewedGauss +from .randomize_texture import randomizeTexture +from bpy_extras import object_utils +from mathutils import ( + Vector +) +from bpy.props import ( + BoolProperty, + IntProperty, + FloatProperty, + FloatVectorProperty, + EnumProperty +) + +# This try block allows for the script to psudo-intelligently select the +# appropriate random to use. If Numpy's random is present it will use that. +# If Numpy's random is not present, it will through a "module not found" +# exception and instead use the slower built-in random that Python has. +try: + from numpy.random import random_integers as randint + from numpy.random import normal as gauss + from numpy.random import ( + seed, + weibull) + print("Rock Generator: Numpy found.") + numpy = True +except: + from random import ( + randint, + gauss, + seed) + from random import weibullvariate as weibull + print("Rock Generator: Numpy not found. Using Python's random.") + numpy = False + +# Global variables: +LASTROCK = 0 + + +# Creates a new mesh: +# +# param: verts - Vector of vertices for the mesh. +# edges - Edges for the mesh. Can be "[]". +# faces - Face tuples corresponding to vertices. +# name - Name of the mesh. +def createMeshObject(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) + + # Set mesh to use auto smoothing: + mesh.use_auto_smooth = True + + # Update mesh geometry after adding stuff. + mesh.update() + + return object_utils.object_data_add(context, mesh, operator=None) + + +# Generates an object based on one of several different mesh types. +# All meshes have exactly eight vertices, and may be built from either +# tri's or quads. +# +# param: muX - mean X offset value +# sigmaX - X offset standard deviation +# scaleX - X upper and lower bounds +# upperSkewX - Is the distribution upperskewed? +# muY - mean Y offset value +# sigmaY - Y offset standard deviation +# scaleY - Y upper and lower bounds +# upperSkewY - Is the distribution upperskewed? +# muZ - mean Z offset value +# sigmaZ - Z offset standard deviation +# scaleZ - Z upper and lower bounds +# upperSkewY - Is the distribution upperskewed? +# base - base number on the end of the object name +# shift - Addition to the base number for multiple runs. +# scaleDisplace - Scale the displacement maps +# +# return: name - the built name of the object +def generateObject(context, muX, sigmaX, scaleX, upperSkewX, muY, sigmaY, + scaleY, upperSkewY, muZ, sigmaZ, scaleZ, upperSkewZ, base, + shift, scaleDisplace, scale_fac): + x = [] + y = [] + z = [] + shape = randint(0, 11) + + # Cube + # Use parameters to re-scale cube: + # Reversed if/for nesting. Should be a little faster. + if shape == 0: + for j in range(8): + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif shape == 1: + for j in range(8): + if j in [0, 1, 3, 4]: + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif j in [2, 5]: + if sigmaX == 0: + x.append(0) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif j in [6, 7]: + if sigmaX == 0: + x.append(0) + else: + x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 4) + if sigmaY == 0: + y.append(0) + else: + y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif shape == 2: + for j in range(8): + if j in [0, 2, 5, 7]: + if sigmaX == 0: + x.append(scaleX[0] / 4) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4) + if sigmaY == 0: + y.append(0) + else: + y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 4) + elif j in [1, 3, 4, 6]: + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif shape == 3: + for j in range(8): + if j > 0: + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + else: + if sigmaX == 0: + x.append(0) + else: + x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 8) + if sigmaY == 0: + y.append(0) + else: + y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 8) + if sigmaZ == 0: + z.append(0) + else: + z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 8) + elif shape == 4: + for j in range(10): + if j in [0, 9]: + if sigmaX == 0: + x.append(0) + else: + x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(0) + else: + y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif j in [1, 2, 3, 4]: + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif j in [5, 7]: + if sigmaX == 0: + x.append(0) + else: + x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 3) + if sigmaY == 0: + y.append(scaleY[0] / 3) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 3) + if sigmaZ == 0: + z.append(0) + else: + z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 6) + elif j in [6, 8]: + if sigmaX == 0: + x.append(scaleX[0] / 3) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 3) + if sigmaY == 0: + y.append(0) + else: + y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 3) + if sigmaZ == 0: + z.append(0) + else: + z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 6) + elif shape == 5: + for j in range(10): + if j == 0: + if sigmaX == 0: + x.append(0) + else: + x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 8) + if sigmaY == 0: + y.append(0) + else: + y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 8) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif j in [1, 2]: + if sigmaX == 0: + x.append(scaleZ[0] * .125) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) * 0.125) + if sigmaY == 0: + y.append(scaleZ[0] * 0.2165) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) * 0.2165) + if sigmaZ == 0: + z.append(0) + else: + z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 4) + elif j == 3: + if sigmaX == 0: + x.append(scaleX[0] / 4) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4) + if sigmaY == 0: + y.append(0) + else: + y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4) + if sigmaZ == 0: + z.append(0) + else: + z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 4) + elif j in [4, 6]: + if sigmaX == 0: + x.append(scaleX[0] * 0.25) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) * 0.25) + if sigmaY == 0: + y.append(scaleY[0] * 0.433) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) * 0.433) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif j == 5: + if sigmaX == 0: + x.append(scaleX[0] / 4) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4) + if sigmaY == 0: + y.append(0) + else: + y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif j in [7, 9]: + if sigmaX == 0: + x.append(scaleX[0] * 0.10825) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) * 0.10825) + if sigmaY == 0: + y.append(scaleY[0] * 0.2165) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) * 0.2165) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif j == 8: + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(0) + else: + y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif shape == 6: + for j in range(7): + if j > 0: + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + else: + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(0) + else: + y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif shape == 7: + for j in range(10): + if j in [1, 3, 4, 5, 8, 9]: + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + else: + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(0) + else: + y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif shape == 8: + for j in range(7): + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif shape == 9: + for j in range(8): + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif shape == 10: + for j in range(7): + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + elif shape == 11: + for j in range(7): + if sigmaX == 0: + x.append(scaleX[0] / 2) + else: + x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2) + if sigmaY == 0: + y.append(scaleY[0] / 2) + else: + y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2) + if sigmaZ == 0: + z.append(scaleZ[0] / 2) + else: + z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2) + + # This is for scaling the displacement textures. + # Scale the vertices so that their average is equal to 1 * scale factor. + if scaleDisplace: + averageX = (sum(x) / len(x)) * scale_fac[0] + for i in range(len(x)): + x[i] /= averageX + averageY = (sum(y) / len(y)) * scale_fac[1] + for i in range(len(y)): + y[i] /= averageY + averageZ = (sum(z) / len(z)) * scale_fac[2] + for i in range(len(z)): + z[i] /= averageZ + + # Build vertex and face arrays: + if shape == 1: + verts = [(-x[0], -y[0], -z[0]), (x[1], -y[1], -z[1]), (x[2], -y[2], z[2]), + (-x[3], y[3], -z[3]), (x[4], y[4], -z[4]), (x[5], y[5], z[5]), + (x[6], y[6], z[6]), (x[7], y[7], -z[7])] + faces = [[0, 1, 2], [0, 1, 7], [3, 0, 7], [3, 4, 7], [1, 4, 7], [3, 4, 5], [1, 2, 6], + [1, 4, 6], [4, 5, 6], [0, 2, 6], [0, 3, 6], [3, 5, 6]] + elif shape == 2: + verts = [(-x[0], y[0], -z[0]), (x[1], -y[1], -z[1]), (x[2], y[2], -z[2]), + (-x[3], y[3], -z[3]), (-x[4], -y[4], z[4]), (x[5], y[5], z[5]), + (x[6], y[6], z[6]), (-x[7], y[7], z[7])] + faces = [[0, 1, 2], [0, 2, 3], [0, 3, 7], [0, 7, 4], [1, 4, 5], [0, 1, 4], [5, 1, 2], + [5, 2, 6], [3, 2, 6], [3, 6, 7], [5, 4, 7], [5, 6, 7]] + elif shape == 3: + verts = [(x[0], y[0], z[0]), (x[1], -y[1], -z[1]), (x[2], y[2], -z[2]), + (-x[3], y[3], -z[3]), (x[4], -y[4], z[4]), (x[5], y[5], z[5]), + (-x[6], y[6], z[6]), (-x[7], -y[7], z[7])] + faces = [[0, 1, 2], [0, 2, 3], [0, 3, 6], [0, 6, 7], [0, 7, 4], [0, 4, 1], [5, 4, 1, 2], + [5, 6, 3, 2], [5, 4, 7, 6]] + elif shape == 4: + verts = [(x[0], y[0], z[0]), (x[1], -y[1], -z[1]), (x[2], y[2], -z[2]), + (-x[3], y[3], -z[3]), (-x[4], -y[4], -z[4]), (x[5], -y[5], -z[5]), + (x[6], y[6], -z[6]), (x[7], y[7], -z[7]), (-x[8], y[8], -z[8]), + (x[9], y[9], -z[9])] + faces = [[0, 1, 6], [0, 6, 2], [0, 2, 7], [0, 7, 3], [0, 3, 8], [0, 8, 4], [0, 4, 5], + [0, 5, 1], [1, 9, 2], [2, 9, 3], [3, 9, 4], [4, 9, 1], [1, 6, 2], [2, 7, 3], + [3, 8, 4], [4, 5, 1]] + elif shape == 5: + verts = [(x[0], y[0], z[0]), (x[1], -y[1], z[1]), (x[2], y[2], z[2]), + (-x[3], y[3], z[3]), (x[4], -y[4], -z[4]), (x[5], y[5], -z[5]), + (x[6], y[6], -z[6]), (-x[7], y[7], -z[7]), (-x[8], y[8], -z[8]), + (-x[9], -y[9], -z[9])] + faces = [[0, 1, 2], [0, 2, 3], [0, 3, 1], [1, 4, 5], [1, 5, 2], [2, 5, 6], [2, 6, 7], + [2, 7, 3], [3, 7, 8], [3, 8, 9], [3, 9, 1], [1, 9, 4], [4, 5, 9], [5, 6, 7], + [7, 8, 9], [9, 5, 7]] + elif shape == 6: + verts = [(x[0], y[0], z[0]), (x[1], -y[1], -z[1]), (x[2], y[2], -z[2]), + (-x[3], y[3], -z[3]), (-x[4], y[4], z[4]), (-x[5], -y[5], z[5]), + (-x[6], -y[6], -z[6])] + faces = [[0, 1, 2], [0, 2, 3, 4], [0, 1, 6, 5], [0, 4, 5], [1, 2, 3, 6], [3, 4, 5, 6]] + elif shape == 7: + verts = [(x[0], y[0], z[0]), (x[1], -y[1], -z[1]), (x[2], y[2], -z[2]), + (x[3], y[3], -z[3]), (-x[4], y[4], -z[4]), (-x[5], y[5], z[5]), + (-x[6], y[6], z[6]), (-x[7], y[7], -z[7]), (-x[8], -y[8], -z[8]), + (-x[9], -y[9], z[9])] + faces = [[0, 1, 2], [0, 2, 3], [0, 5, 6], [0, 6, 9], [0, 1, 8, 9], [0, 3, 4, 5], + [1, 2, 7, 8], [2, 3, 4, 7], [4, 5, 6, 7], [6, 7, 8, 9]] + elif shape == 8: + verts = [(x[0], y[0], z[0]), (x[1], -y[1], -z[1]), (x[2], y[2], -z[2]), + (-x[3], y[3], -z[3]), (-x[4], -y[4], -z[4]), (-x[5], -y[5], z[5]), + (-x[6], y[6], z[6])] + faces = [[0, 2, 1], [0, 1, 4], [0, 4, 5], [0, 5, 6], [0, 6, 3, 2], [2, 1, 4, 3], + [3, 6, 5, 4]] + elif shape == 9: + verts = [(-x[0], -y[0], -z[0]), (-x[1], y[1], -z[1]), (-x[2], y[2], z[2]), + (-x[3], -y[3], z[3]), (x[4], -y[4], -z[4]), (x[5], y[5], -z[5]), + (x[6], y[6], z[6]), (x[7], -y[7], z[7])] + faces = [[0, 1, 6, 2], [1, 5, 7, 6], [5, 4, 3, 7], [4, 0, 2, 3], [0, 1, 5, 4], [3, 2, 6, 7]] + elif shape == 10: + verts = [(-x[0], -y[0], -z[0]), (-x[1], y[1], -z[1]), (-x[2], y[2], z[2]), + (x[3], -y[3], z[3]), (x[4], y[4], z[4]), (x[5], y[5], -z[5]), + (x[6], -y[6], -z[6])] + faces = [[0, 2, 3], [0, 3, 6], [0, 1, 5, 6], [2, 3, 4], [0, 1, 2], [1, 2, 4, 5], [3, 4, 5, 6]] + elif shape == 11: + verts = [(-x[0], -y[0], -z[0]), (-x[1], y[1], -z[1]), (-x[2], y[2], z[2]), + (x[3], -y[3], z[3]), (x[4], y[4], z[4]), (x[5], y[5], -z[5]), + (x[6], -y[6], -z[6])] + faces = [[0, 2, 3], [0, 3, 6], [0, 1, 5, 6], [2, 3, 4], [5, 6, 3], [1, 5, 3, 4], [0, 1, 4, 2]] + else: + verts = [(-x[0], -y[0], -z[0]), (-x[1], y[1], -z[1]), (-x[2], -y[2], z[2]), + (-x[3], y[3], z[3]), (x[4], -y[4], -z[4]), (x[5], y[5], -z[5]), + (x[6], -y[6], z[6]), (x[7], y[7], z[7])] + faces = [[0, 1, 3, 2], [0, 1, 5, 4], [0, 4, 6, 2], [7, 5, 4, 6], [7, 3, 2, 6], [7, 5, 1, 3]] + + # name = "Rock." + str(base + shift).zfill(3) + name = "rock" + + # Make object: + obj = createMeshObject(context, verts, [], faces, name) + + if scaleDisplace: + # bpy.data.objects[name].scale = Vector((averageX, averageY, averageZ)) + obj.scale = Vector((averageX, averageY, averageZ)) + + # For a slight speed bump / Readability: + # mesh = bpy.data.meshes[name] + mesh = obj.data + + # Apply creasing: + if shape == 0: + for i in range(12): + # todo: "0.375 / 3"? WTF? That = 0.125. . . . + # *** Completed 7/15/2011: Changed second one *** + mesh.edges[i].crease = gauss(0.125, 0.125) + elif shape == 1: + for i in [0, 2]: + mesh.edges[i].crease = gauss(0.5, 0.125) + for i in [6, 9, 11, 12]: + mesh.edges[i].crease = gauss(0.25, 0.05) + for i in [5, 7, 15, 16]: + mesh.edges[i].crease = gauss(0.125, 0.025) + elif shape == 2: + for i in range(18): + mesh.edges[i].crease = gauss(0.125, 0.025) + elif shape == 3: + for i in [0, 1, 6, 10, 13]: + mesh.edges[i].crease = gauss(0.25, 0.05) + mesh.edges[8].crease = gauss(0.5, 0.125) + elif shape == 4: + for i in [5, 6, 7, 10, 14, 16, 19, 21]: + mesh.edges[i].crease = gauss(0.5, 0.125) + elif shape == 7: + for i in range(18): + if i in [0, 1, 2, 3, 6, 7, 8, 9, 13, 16]: + mesh.edges[i].crease = gauss(0.5, 0.125) + elif i in [11, 17]: + mesh.edges[i].crease = gauss(0.25, 0.05) + else: + mesh.edges[i].crease = gauss(0.125, 0.025) + elif shape == 8: + for i in range(12): + if i in [0, 3, 8, 9, 10]: + mesh.edges[i].crease = gauss(0.5, 0.125) + elif i == 11: + mesh.edges[i].crease = gauss(0.25, 0.05) + else: + mesh.edges[i].crease = gauss(0.125, 0.025) + elif shape == 9: + for i in range(12): + if i in [0, 3, 4, 11]: + mesh.edges[i].crease = gauss(0.5, 0.125) + else: + mesh.edges[i].crease = gauss(0.25, 0.05) + elif shape == 10: + for i in range(12): + if i in [0, 2, 3, 4, 8, 11]: + mesh.edges[i].crease = gauss(0.5, 0.125) + elif i in [1, 5, 7]: + mesh.edges[i].crease = gauss(0.25, 0.05) + else: + mesh.edges[i].crease = gauss(0.125, 0.025) + elif shape == 11: + for i in range(11): + if i in [1, 2, 3, 4, 8, 11]: + mesh.edges[i].crease = gauss(0.25, 0.05) + else: + mesh.edges[i].crease = gauss(0.125, 0.025) + + return obj + + +# Creates rock objects: +def generateRocks(context, scaleX, skewX, scaleY, skewY, scaleZ, skewZ, + scale_fac, detail, display_detail, deform, rough, + smooth_fac, smooth_it, + numOfRocks=1, userSeed=1.0, + scaleDisplace=False, randomSeed=True): + global LASTROCK + sigmaX = 0 + sigmaY = 0 + sigmaZ = 0 + upperSkewX = False + upperSkewY = False + upperSkewZ = False + shift = 0 + # vertexScaling = [] + + # Seed the random Gaussian value generator: + if randomSeed: + seed(int(time.time())) + else: + seed(userSeed) + + # These values need to be really small to look good. + # So the user does not have to use such ridiculously small values: + deform /= 10 + rough /= 100 + + # Verify that the min really is the min: + if scaleX[1] < scaleX[0]: + scaleX[0], scaleX[1] = scaleX[1], scaleX[0] + if scaleY[1] < scaleY[0]: + scaleY[0], scaleY[1] = scaleY[1], scaleY[0] + if scaleZ[1] < scaleZ[0]: + scaleZ[0], scaleZ[1] = scaleZ[1], scaleZ[0] + + # todo: edit below to allow for skewing the distribution + # *** todo completed 4/22/2011 *** + # *** Code now generating "int not scriptable error" in Blender *** + # + # Calculate mu and sigma for a Gaussian distributed random number + # generation: + # If the lower and upper bounds are the same, skip the math. + # + # sigma is the standard deviation of the values. The 95% interval is three + # standard deviations, which is what we want most generated values to fall + # in. Since it might be skewed we are going to use half the difference + # betwee the mean and the furthest bound and scale the other side down + # post-number generation. + if scaleX[0] != scaleX[1]: + skewX = (skewX + 1) / 2 + muX = scaleX[0] + ((scaleX[1] - scaleX[0]) * skewX) + if skewX < 0.5: + sigmaX = (scaleX[1] - muX) / 3 + else: + sigmaX = (muX - scaleX[0]) / 3 + upperSkewX = True + else: + muX = scaleX[0] + if scaleY[0] != scaleY[1]: + skewY = (skewY + 1) / 2 + muY = scaleY[0] + ((scaleY[1] - scaleY[0]) * skewY) + if skewY < 0.5: + sigmaY = (scaleY[1] - muY) / 3 + else: + sigmaY = (muY - scaleY[0]) / 3 + upperSkewY = True + else: + muY = scaleY[0] + if scaleZ[0] != scaleZ[1]: + skewZ = (skewZ + 1) / 2 + muZ = scaleZ[0] + ((scaleZ[1] - scaleZ[0]) * skewZ) + if skewZ < 0.5: + sigmaZ = (scaleZ[1] - muZ) / 3 + else: + sigmaZ = (muZ - scaleZ[0]) / 3 + upperSkewZ = True + else: + muZ = scaleZ + + for i in range(numOfRocks): + # todo: enable different random values for each (x,y,z) corrdinate for + # each vertex. This will add additional randomness to the shape of the + # generated rocks. + # *** todo completed 4/19/2011 *** + # *** Code is notably slower at high rock counts *** + + # name = generateObject(context, muX, sigmaX, scaleX, upperSkewX, muY, + rock = generateObject( + context, muX, sigmaX, scaleX, upperSkewX, muY, + sigmaY, scaleY, upperSkewY, muZ, sigmaZ, scaleZ, + upperSkewZ, i, LASTROCK, scaleDisplace, scale_fac) + + # rock = bpy.data.objects[name] + + # todo Map what the two new textures will be: + # This is not working. It works on paper so . . . ??? + # *** todo completed on 4/23/2011 *** + # *** todo re-added as the first rock is getting + # 'Texture.001' twice. *** + # *** todo completed on 4/25/2011 *** + # *** Script no longer needs to map new texture names 9/6/2011 *** + + # Create the four new textures: + # todo Set displacement texture parameters: + # *** todo completed on 5/31/2011 *** + # Voronoi has been removed from being an option for the fine detail + # texture. + texTypes = ['CLOUDS', 'MUSGRAVE', 'DISTORTED_NOISE', 'STUCCI', 'VORONOI'] + newTex = [] + # The first texture is to give a more ranodm base shape appearance: + newTex.append(bpy.data.textures.new( + name='rock_displacement', + type=texTypes[1])) + randomizeTexture(newTex[0], 0) + newTex.append(bpy.data.textures.new( + name='rock_displacement', + type=texTypes[4])) + randomizeTexture(newTex[1], 0) + if numpy: + newTex.append(bpy.data.textures.new( + name='rock_displacement', + type=texTypes[int(round(weibull(1, 1)[0] / 2.125))])) + randomizeTexture(newTex[2], 1) + newTex.append(bpy.data.textures.new( + name='rock_displacement', + type=texTypes[int(round(weibull(1, 1)[0] / 2.125))])) + randomizeTexture(newTex[3], 2) + else: + newTex.append(bpy.data.textures.new( + name='rock_displacement', + type=texTypes[int(round(weibull(1, 1) / 2.125))])) + randomizeTexture(newTex[2], 1) + newTex.append(bpy.data.textures.new( + name='rock_displacement', + type=texTypes[int(round(weibull(1, 1) / 2.125))])) + randomizeTexture(newTex[3], 2) + + # Add modifiers: + rock.modifiers.new(name="Subsurf", type='SUBSURF') + rock.modifiers.new(name="Subsurf", type='SUBSURF') + rock.modifiers.new(name="Displace", type='DISPLACE') + rock.modifiers.new(name="Displace", type='DISPLACE') + rock.modifiers.new(name="Displace", type='DISPLACE') + rock.modifiers.new(name="Displace", type='DISPLACE') + + # If smoothing is enabled, allow a little randomness into the + # smoothing factor. Then add the smoothing modifier. + if smooth_fac > 0.0 and smooth_it > 0: + rock.modifiers.new(name="Smooth", type='SMOOTH') + rock.modifiers[6].factor = gauss(smooth_fac, (smooth_fac ** 0.5) / 12) + rock.modifiers[6].iterations = smooth_it + # Make a call to random to keep things consistant: + else: + gauss(0, 1) + + # Set subsurf modifier parameters: + rock.modifiers[0].levels = display_detail + rock.modifiers[0].render_levels = detail + rock.modifiers[1].levels = display_detail + rock.modifiers[1].render_levels = detail + + # todo Set displacement modifier parameters: + # *** todo completed on 4/23/2011 *** + # *** toned down the variance on 4/26/2011 *** + # *** added third modifier on 4/28/2011 *** + # *** texture access changed on 9/6/2011 *** + rock.modifiers[2].texture = newTex[0] + rock.modifiers[2].strength = gauss(deform / 100, (1 / 300) * deform) + rock.modifiers[2].mid_level = 0 + rock.modifiers[3].texture = newTex[1] + rock.modifiers[3].strength = gauss(deform, (1 / 3) * deform) + rock.modifiers[3].mid_level = 0 + rock.modifiers[4].texture = newTex[2] + rock.modifiers[4].strength = gauss(rough * 2, (1 / 3) * rough) + rock.modifiers[5].texture = newTex[3] + rock.modifiers[5].strength = gauss(rough, (1 / 3) * rough) + + # Set mesh to be smooth and fix the normals: + utils.smooth(rock.data) + # utils.smooth(bpy.data.meshes[name]) + bpy.ops.object.editmode_toggle() + bpy.ops.mesh.normals_make_consistent() + bpy.ops.object.editmode_toggle() + + # Store the last value of i: + shift = i + + # Add the shift to LASTROCK: + LASTROCK += shift + 1 + + return + + +# Much of the code below is more-or-less imitation of other addons and as such +# I have left it undocumented. + +class OBJECT_OT_add_mesh_rock(bpy.types.Operator): + """Add rock objects""" + bl_idname = "mesh.add_mesh_rock" + bl_label = "Add Rocks" + bl_options = {'REGISTER', 'UNDO'} + bl_description = "Add rocks" + + # Get the preset values from the XML file. + # -> The script was morphed into a Python module + # to support this. + # Tell settings.py to parse the XML file with the settings. + # Then get the default values resulting from the parsing. + # Make a list containing the default values and append to that + # the presets specified in the same XML file. This list will + # be used to load preset values. + settings.parse() + defaults = settings.getDefault() + presetsList = [defaults] + presetsList += settings.getPresetLists() + presets = [] + lastPreset = 0 + + # Build the presets list for the enum property. + # This needs to be a for loop as the user might add presets to + # the XML file and those should show here: + for i, preset in enumerate(presetsList): + presets.append((str(i), preset[0], preset[0] + " preset values")) + + preset_values: EnumProperty( + name="Presets", + items=presets, + description="Preset values for some rock types") + + num_of_rocks: IntProperty( + name="Number of rocks", + description="Number of rocks to generate. WARNING: Slow at high values!", + min=1, max=1048576, + soft_max=20, + default=1) + + scale_X: FloatVectorProperty( + name="X scale", + description="X axis scaling range", + min=0.0, max=256.0, step=1, + default=defaults[1], size=2) + skew_X: FloatProperty( + name="X skew", + description="X Skew ratio. 0.5 is no skew", + min=-1.0, max=1.0, default=defaults[4]) + scale_Y: FloatVectorProperty( + name="Y scale", + description="Y axis scaling range", + min=.0, max=256.0, step=1, + default=defaults[2], size=2) + skew_Y: FloatProperty( + name="Y skew", + description="Y Skew ratio. 0.5 is no skew", + min=-1.0, max=1.0, default=defaults[5]) + scale_Z: FloatVectorProperty( + name="Z scale", + description="Z axis scaling range", + min=0.0, max=256.0, step=1, + default=defaults[3], size=2) + skew_Z: FloatProperty( + name="Z skew", + description="Z Skew ratio. 0.5 is no skew", + min=-1.0, max=1.0, default=defaults[6]) + use_scale_dis: BoolProperty( + name="Scale displace textures", + description="Scale displacement textures with dimensions. May cause streched textures", + default=defaults[7]) + scale_fac: FloatVectorProperty( + name="Scaling Factor", + description="XYZ scaling factor. 1: no scaling", + min=0.0001, max=256.0, step=0.1, + default=defaults[8], size=3) + + # @todo Possible to title this section "Physical Properties:"? + deform: FloatProperty( + name="Deformation", + description="Rock deformation", + min=0.0, soft_max=50, max=1024.0, default=defaults[9]) + rough: FloatProperty( + name="Roughness", + description="Rock roughness", + min=0.0, soft_max=50, max=1024.0, default=defaults[10]) + detail: IntProperty( + name="Detail level", + description="Detail level. WARNING: Slow at high values!", + min=1, soft_max=4, max=10, default=defaults[11]) + display_detail: IntProperty( + name="Display Detail", + description="Display detail. Use a lower value for high numbers of rocks", + min=1, soft_max=4, max=10, default=defaults[12]) + smooth_fac: FloatProperty( + name="Smooth Factor", + description="Smoothing factor. A value of 0 disables", + min=0.0, max=128.0, default=defaults[13]) + smooth_it: IntProperty( + name="Smooth Iterations", + description="Smoothing iterations. A value of 0 disables", + min=0, max=50, default=defaults[14]) + + use_generate: BoolProperty( + name="Generate Rocks", + description="Enable actual generation", + default=defaults[15]) + use_random_seed: BoolProperty( + name="Use a random seed", + description="Create a seed based on time. Causes user seed to be ignored", + default=defaults[16]) + user_seed: IntProperty( + name="User seed", + description="Use a specific seed for the generator", + min=0, max=1048576, default=defaults[17]) + + def draw(self, context): + layout = self.layout + box = layout.box() + box.prop(self, 'num_of_rocks') + box = layout.box() + box.prop(self, 'scale_X') + box.prop(self, 'skew_X') + box.prop(self, 'scale_Y') + box.prop(self, 'skew_Y') + box.prop(self, 'scale_Z') + box.prop(self, 'skew_Z') + box.prop(self, 'use_scale_dis') + if self.use_scale_dis: + box.prop(self, 'scale_fac') + else: + self.scale_fac = utils.toFloats(self.defaults[8]) + box = layout.box() + box.prop(self, 'deform') + box.prop(self, 'rough') + box.prop(self, 'detail') + box.prop(self, 'display_detail') + box.prop(self, 'smooth_fac') + box.prop(self, 'smooth_it') + + box = layout.box() + box.prop(self, 'use_generate') + box.prop(self, 'use_random_seed') + if not self.use_random_seed: + box.prop(self, 'user_seed') + box.prop(self, 'preset_values') + + @classmethod + def poll(cls, context): + return context.mode == 'OBJECT' + # return (context.object is not None and context.object.mode == 'OBJECT') + + def execute(self, context): + + # The following "if" block loads preset values: + if self.lastPreset != int(self.preset_values): + self.scale_X = utils.toFloats(self.presetsList[int(self.preset_values)][1]) + self.scale_Y = utils.toFloats(self.presetsList[int(self.preset_values)][2]) + self.scale_Z = utils.toFloats(self.presetsList[int(self.preset_values)][3]) + self.skew_X = float(self.presetsList[int(self.preset_values)][4]) + self.skew_Y = float(self.presetsList[int(self.preset_values)][5]) + self.skew_Z = float(self.presetsList[int(self.preset_values)][6]) + self.use_scale_dis = bool(self.presetsList[int(self.preset_values)][7]) + self.scale_fac = utils.toFloats(self.presetsList[int(self.preset_values)][8]) + self.deform = float(self.presetsList[int(self.preset_values)][9]) + self.rough = float(self.presetsList[int(self.preset_values)][10]) + self.detail = int(self.presetsList[int(self.preset_values)][11]) + self.display_detail = int(self.presetsList[int(self.preset_values)][12]) + self.smooth_fac = float(self.presetsList[int(self.preset_values)][13]) + self.smooth_it = int(self.presetsList[int(self.preset_values)][14]) + self.use_generate = bool(self.presetsList[int(self.preset_values)][15]) + self.use_random_seed = bool(self.presetsList[int(self.preset_values)][16]) + self.user_seed = int(self.presetsList[int(self.preset_values)][17]) + self.lastPreset = int(self.preset_values) + + # todo Add deform, deform_Var, rough, and rough_Var: + # *** todo completed 4/23/2011 *** + # *** Eliminated "deform_Var" and "rough_Var" so the script is not + # as complex to use. May add in again as advanced features. *** + if self.use_generate: + generateRocks(context, + self.scale_X, + self.skew_X, + self.scale_Y, + self.skew_Y, + self.scale_Z, + self.skew_Z, + self.scale_fac, + self.detail, + self.display_detail, + self.deform, + self.rough, + self.smooth_fac, + self.smooth_it, + self.num_of_rocks, + self.user_seed, + self.use_scale_dis, + self.use_random_seed) + + return {'FINISHED'} + + +# Register: +def menu_func_rocks(self, context): + layout = self.layout + layout.separator() + layout.operator( + OBJECT_OT_add_mesh_rock.bl_idname, + text="Rock Generator", + icon="MESH_ICOSPHERE") + + +classes = ( + OBJECT_OT_add_mesh_rock, +) + + +def register(): + from bpy.utils import register_class + for cls in classes: + register_class(cls) + bpy.types.VIEW3D_MT_mesh_add.append(menu_func_rocks) + + +def unregister(): + from bpy.utils import unregister_class + for cls in reversed(classes): + unregister_class(cls) + bpy.types.VIEW3D_MT_mesh_add.remove(menu_func_rocks) + + +if __name__ == "__main__": + register() diff --git a/add_mesh_extra_objects/add_mesh_rocks/settings.py b/add_mesh_extra_objects/add_mesh_rocks/settings.py new file mode 100644 index 00000000..3e6a8df2 --- /dev/null +++ b/add_mesh_extra_objects/add_mesh_rocks/settings.py @@ -0,0 +1,163 @@ +# Paul "BrikBot" Marshall +# Created: July 1, 2011 +# Last Modified: November 17, 2011 +# Homepage (blog): http://post.darkarsenic.com/ +# //blog.darkarsenic.com/ +# Thanks to Meta-Androco, RickyBlender, Ace Dragon, and PKHG for ideas +# and testing. +# +# Coded in IDLE, tested in Blender 2.59. NumPy Recommended. +# Search for "@todo" to quickly find sections that need work. +# +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# The Blender Rock Creation tool is for rapid generation of +# mesh rocks in Blender. +# Copyright (C) 2011 Paul Marshall +# +# 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 3 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, see <http://www.gnu.org/licenses/>. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + +import inspect +import shutil +from . import utils +from xml.dom import minidom + +basePath = inspect.getfile(inspect.currentframe())[0:-len("settings.py")] +path = basePath + "add_mesh_rocks.xml" + +try: + source = minidom.parse(path) + print("Rock generator settings file found:\n" + path) +except: + print("Rock generator settings file not found. Creating settings file.") + shutil.copy(basePath + "factory.xml", path) + source = minidom.parse(path) + +xmlDefault = source.getElementsByTagName('default')[0] +xmlPresets = source.getElementsByTagName('preset') +default = [] +presets = [] + +# ----- Gets and Sets -----# + + +def getDefault(): + global default + return default + + +def getPresetLists(): + global presets + return presets + + +def getPreset(ID=0): + global presets + return presets[ID] + +# ---------- Core ----------# + + +def parse(): + global xmlDefault + global xmlPresets + global default + global presets + + # Parse default values + default = parseNode(xmlDefault) + + # Parse preset values + for setting in xmlPresets: + presets.append(parseNode(setting)) + + return '{FINISHED}' + + +# Takes a node and parses it for data. Relies on that setting.xml has +# a valid format as specified by the DTD. +# For some reason minidom places an empty child node for every other node. +def parseNode(setting, title=True): + loc = 1 + + if title: + # Preset name (xmlPreset.childNodes[1]): + title = setting.childNodes[loc].childNodes[0].data + loc += 2 + + # Preset size values (xmlPreset.childNodes[3]): + scaleX = [float(setting.childNodes[loc].childNodes[1].childNodes[3].childNodes[0].data), + float(setting.childNodes[loc].childNodes[1].childNodes[5].childNodes[0].data)] + scaleY = [float(setting.childNodes[loc].childNodes[3].childNodes[3].childNodes[0].data), + float(setting.childNodes[loc].childNodes[3].childNodes[5].childNodes[0].data)] + scaleZ = [float(setting.childNodes[loc].childNodes[5].childNodes[3].childNodes[0].data), + float(setting.childNodes[loc].childNodes[5].childNodes[5].childNodes[0].data)] + skewX = float(setting.childNodes[loc].childNodes[7].childNodes[3].childNodes[0].data) + skewY = float(setting.childNodes[loc].childNodes[9].childNodes[3].childNodes[0].data) + skewZ = float(setting.childNodes[loc].childNodes[11].childNodes[3].childNodes[0].data) + if setting.childNodes[loc].childNodes[13].childNodes[0].data == 'False': + use_scale_dis = False + else: + use_scale_dis = True + scale_fac = utils.toList(setting.childNodes[loc].childNodes[15].childNodes[0].data) + loc += 2 + + # Presst shape values (xmlPreset.childNodes[5]): + deform = float(setting.childNodes[loc].childNodes[1].childNodes[0].data) + rough = float(setting.childNodes[loc].childNodes[3].childNodes[0].data) + detail = int(setting.childNodes[loc].childNodes[5].childNodes[0].data) + display_detail = int(setting.childNodes[loc].childNodes[7].childNodes[0].data) + smooth_fac = float(setting.childNodes[loc].childNodes[9].childNodes[0].data) + smooth_it = int(setting.childNodes[loc].childNodes[11].childNodes[0].data) + loc += 2 + + # Preset material values (xmlPreset.childNodes[7]): + loc += 2 + + # Preset random values (xmlPreset.childNodes[9]): + if setting.childNodes[loc].childNodes[1].childNodes[0].data == 'True': + use_generate = True + else: + use_generate = False + if setting.childNodes[loc].childNodes[3].childNodes[0].data == 'False': + use_random_seed = False + else: + use_random_seed = True + user_seed = int(setting.childNodes[loc].childNodes[5].childNodes[0].data) + + if title: + parsed = [title, scaleX, scaleY, scaleZ, skewX, skewY, skewZ, + use_scale_dis, scale_fac, deform, rough, detail, + display_detail, smooth_fac, smooth_it, + use_generate, use_random_seed, user_seed] + else: + parsed = [scaleX, scaleY, scaleZ, skewX, skewY, skewZ, use_scale_dis, + scale_fac, deform, rough, detail, display_detail, smooth_fac, + smooth_it, use_generate, use_random_seed, user_seed] + + return parsed + + +def save(): + return '{FINISHED}' + + +def _print(): + for i in presets: + print(i) + return '{FINISHED}' diff --git a/add_mesh_extra_objects/add_mesh_rocks/utils.py b/add_mesh_extra_objects/add_mesh_rocks/utils.py new file mode 100644 index 00000000..64e2daf4 --- /dev/null +++ b/add_mesh_extra_objects/add_mesh_rocks/utils.py @@ -0,0 +1,160 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# The Blender Rock Creation tool is for rapid generation of mesh rocks. +# Copyright (C) 2011 Paul Marshall +# +# 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 3 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, see <http://www.gnu.org/licenses/>. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + + +# Converts a formated string to a float tuple: +# IN - '(0.5, 0.2)' -> CONVERT -> OUT - (0.5, 0.2) +def toTuple(stringIn): + sTemp = str(stringIn)[1:len(str(stringIn)) - 1].split(', ') + fTemp = [] + for i in sTemp: + fTemp.append(float(i)) + return tuple(fTemp) + + +# Converts a formated string to a float tuple: +# IN - '[0.5, 0.2]' -> CONVERT -> OUT - [0.5, 0.2] +def toList(stringIn): + sTemp = str(stringIn)[1:len(str(stringIn)) - 1].split(', ') + fTemp = [] + for i in sTemp: + fTemp.append(float(i)) + return fTemp + + +# Converts each item of a list into a float: +def toFloats(inList): + outList = [] + for i in inList: + outList.append(float(i)) + return outList + + +# Converts each item of a list into an integer: +def toInts(inList): + outList = [] + for i in inList: + outList.append(int(i)) + return outList + + +# Sets all faces smooth. Done this way since I can't +# find a simple way without using bpy.ops: +def smooth(mesh): + import bmesh + bm = bmesh.new() + bm.from_mesh(mesh) + for f in bm.faces: + f.smooth = True + bm.to_mesh(mesh) + return mesh + + +# This try block allows for the script to psudo-intelligently select the +# appropriate random to use. If Numpy's random is present it will use that. +# If Numpy's random is not present, it will through a "module not found" +# exception and instead use the slower built-in random that Python has. +try: + # from numpy.random import random_integers as randint + from numpy.random import normal as gauss + # from numpy.random import (beta, + # uniform, + # seed, + # weibull) + # print("Rock Generator: Numpy found.") + numpy = True +except: + from random import ( + # randint, + gauss, + # uniform, + # seed + ) + # from random import betavariate as beta + # from random import weibullvariate as weibull + print("Rock Generator: Numpy not found. Using Python's random.") + numpy = False +# Artifically skews a normal (gaussian) distribution. This will not create +# a continuous distribution curve but instead acts as a piecewise finction. +# This linearly scales the output on one side to fit the bounds. +# +# Example output historgrams: +# +# Upper skewed: Lower skewed: +# | ▄ | _ +# | █ | █ +# | █_ | █ +# | ██ | _█ +# | _██ | ██ +# | _▄███_ | ██ _ +# | ▄██████ | ▄██▄█▄_ +# | _█▄███████ | ███████ +# | _██████████_ | ████████▄▄█_ _ +# | _▄▄████████████ | ████████████▄█_ +# | _▄_ ▄███████████████▄_ | _▄███████████████▄▄_ +# ------------------------- ----------------------- +# |mu |mu +# Historgrams were generated in R (http://www.r-project.org/) based on the +# calculations below and manually duplicated here. +# +# param: mu - mu is the mean of the distribution. +# sigma - sigma is the standard deviation of the distribution. +# bounds - bounds[0] is the lower bound and bounds[1] +# is the upper bound. +# upperSkewed - if the distribution is upper skewed. +# return: out - Rondomly generated value from the skewed distribution. +# +# @todo: Because NumPy's random value generators are faster when called +# a bunch of times at once, maybe allow this to generate and return +# multiple values at once? + + +def skewedGauss(mu, sigma, bounds, upperSkewed=True): + raw = gauss(mu, sigma) + + # Quicker to check an extra condition than do unnecessary math. . . . + if raw < mu and not upperSkewed: + out = ((mu - bounds[0]) / (3 * sigma)) * raw + ((mu * (bounds[0] - (mu - 3 * sigma))) / (3 * sigma)) + elif raw > mu and upperSkewed: + out = ((mu - bounds[1]) / (3 * -sigma)) * raw + ((mu * (bounds[1] - (mu + 3 * sigma))) / (3 * -sigma)) + else: + out = raw + + return out + + +# @todo create a def for generating an alpha and beta for a beta distribution +# given a mu, sigma, and an upper and lower bound. This proved faster in +# profiling in addition to providing a much better distribution curve +# provided multiple iterations happen within this function; otherwise it was +# slower. +# This might be a scratch because of the bounds placed on mu and sigma: +# +# For alpha > 1 and beta > 1: +# mu^2 - mu^3 mu^3 - mu^2 + mu +# ----------- < sigma < ---------------- +# 1 + mu 2 - mu +# +# def generateBeta(mu, sigma, scale, repitions=1): + # results = [] +# + # return results |