diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2017-06-16 16:56:26 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2017-06-16 16:56:26 +0300 |
commit | dc480baa613a0ef4184eec00d12c67aa5514ebd3 (patch) | |
tree | 043ec1e7a13ea25865a76e2c5d34835e9721f287 | |
parent | 0a03ed937b62c55404a4abaf89fbc11c19862bd7 (diff) | |
parent | 856c1b92841d552cd763b678d75f74c214bdb963 (diff) |
Merge branch 'master' into fbx_experiments
180 files changed, 30762 insertions, 5261 deletions
diff --git a/add_advanced_objects/delaunay_voronoi/__init__.py b/add_advanced_objects/delaunay_voronoi/__init__.py deleted file mode 100644 index c32eb374..00000000 --- a/add_advanced_objects/delaunay_voronoi/__init__.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding:utf-8 -*- - -# ##### 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 ##### - -bl_info = { - "name": "Delaunay Voronoi", - "description": "Points cloud Delaunay triangulation in 2.5D " - "(suitable for terrain modelling) or Voronoi diagram in 2D", - "author": "Domlysz, Oscurart", - "version": (1, 3), - "blender": (2, 7, 0), - "location": "View3D > Tools > GIS", - "warning": "", - "wiki_url": "https://github.com/domlysz/BlenderGIS/wiki", - "category": "" - } - -if "bpy" in locals(): - import importlib - importlib.reload(oscurart_constellation) - -else: - from . import oscurart_constellation - -import bpy -from .delaunayVoronoiBlender import ToolsPanelDelaunay - - -# Register -def register(): - bpy.utils.register_module(__name__) - - -def unregister(): - bpy.utils.unregister_module(__name__) diff --git a/add_advanced_objects/__init__.py b/add_advanced_objects_menu/__init__.py index 4a70f83d..b1d86454 100644 --- a/add_advanced_objects/__init__.py +++ b/add_advanced_objects_menu/__init__.py @@ -44,23 +44,16 @@ if "bpy" in locals(): importlib.reload(trilighting) importlib.reload(pixelate_3d) importlib.reload(object_add_chain) - importlib.reload(drop_to_ground) importlib.reload(circle_array) - importlib.reload(unfold_transition) importlib.reload(copy2) importlib.reload(make_struts) importlib.reload(random_box_structure) importlib.reload(cubester) importlib.reload(rope_alpha) importlib.reload(add_mesh_aggregate) - importlib.reload(object_mangle_tools) importlib.reload(arrange_on_curve) - importlib.reload(object_laplace_lightning) importlib.reload(mesh_easylattice) - importlib.reload(DelaunayVoronoi) - importlib.reload(delaunayVoronoiBlender) - importlib.reload(oscurart_constellation) - importlib.reload(oscurart_chain_maker) + else: from . import add_light_template @@ -70,24 +63,16 @@ else: from . import trilighting from . import pixelate_3d from . import object_add_chain - from . import oscurart_chain_maker - from . import drop_to_ground from . import circle_array - from . import unfold_transition from . import copy2 from . import make_struts from . import random_box_structure from . import cubester from . import rope_alpha from . import add_mesh_aggregate - from . import object_mangle_tools from . import arrange_on_curve - from . import object_laplace_lightning from . import mesh_easylattice - from .delaunay_voronoi import DelaunayVoronoi - from .delaunay_voronoi import delaunayVoronoiBlender - from .delaunay_voronoi import oscurart_constellation import bpy from bpy.types import ( @@ -256,6 +241,7 @@ class AdvancedObjPreferences(AddonPreferences): box.label(text="Physics Tools:", icon="LAYER_ACTIVE") box.label(text="Drop to Ground, Wrecking Ball and Cloth Rope", icon="LAYER_USED") + icon_2 = "TRIA_RIGHT" if not self.show_panel_list else "TRIA_DOWN" box = layout.box() box.prop(self, "show_panel_list", emboss=False, icon=icon_2) @@ -263,14 +249,8 @@ class AdvancedObjPreferences(AddonPreferences): if self.show_panel_list: box.label(text="Panels located in 3D View Tools Region > Create", icon="LAYER_ACTIVE") - box.label(text="Drop to Ground", icon="LAYER_USED") - box.label(text="Unfold Transition", icon="LAYER_USED") box.label(text="CubeSter", icon="LAYER_USED") - box.label(text="Mangle tools", icon="LAYER_USED") - box.label(text="Laplacian Lighting", icon="LAYER_USED") - box.label(text="Delaunay Voronoi", icon="LAYER_USED") - box.label(text="Duplicate on Curve (Shown if an Active Curve Object is it the 3D View)", - icon="LAYER_USED") + # Cubester update functions @@ -556,202 +536,6 @@ class AdvancedObjProperties(PropertyGroup): ], default='O', ) - # object_laplace_lighting props - ORIGIN = FloatVectorProperty( - name="Origin charge" - ) - GROUNDZ = IntProperty( - name="Ground Z coordinate" - ) - HORDER = IntProperty( - name="Secondary paths orders", - default=1 - ) - # object_laplace_lighting UI props - TSTEPS = IntProperty( - name="Iterations", - default=350, - description="Number of cells to create\n" - "Will end early if hits ground plane or cloud" - ) - GSCALE = FloatProperty( - name="Grid unit size", - default=0.12, - description="scale of cells, .25 = 4 cells per blenderUnit" - ) - BIGVAR = FloatProperty( - name="Straightness", - default=6.3, - description="Straightness/branchiness of bolt, \n" - "<2 is mush, >12 is staight line, 6.3 is good" - ) - GROUNDBOOL = BoolProperty( - name="Use Ground object", - description="Use ground plane or not", - default=True - ) - GROUNDC = IntProperty( - name="Ground charge", - default=-250, - description="Charge of the ground plane" - ) - CLOUDBOOL = BoolProperty( - name="Use Cloud object", - default=False, - description="Use cloud object - attracts and terminates like ground but\n" - "any obj instead of z plane\n" - "Can slow down loop if obj is large, overrides ground" - ) - CLOUDC = IntProperty( - name="Cloud charge", - default=-1, - description="Charge of a cell in cloud object\n" - "(so total charge also depends on obj size)" - ) - VMMESH = BoolProperty( - name="Multi mesh", - default=True, - description="Output to multi-meshes for different materials on main/sec/side branches" - ) - VSMESH = BoolProperty( - name="Single mesh", - default=False, - description="Output to single mesh for using build modifier and particles for effects" - ) - VCUBE = BoolProperty( - name="Cubes", - default=False, - description="CTRL-J after run to JOIN\n" - "Outputs a bunch of cube objects, mostly for testing" - ) - VVOX = BoolProperty( - name="Voxel (experimental)", - default=False, - description="Output to a voxel file to bpy.data.filepath\FSLGvoxels.raw\n" - "(doesn't work well right now)" - ) - IBOOL = BoolProperty( - name="Use Insulator object", - default=False, - description="Use insulator mesh object to prevent growth of bolt in areas" - ) - OOB = StringProperty( - name="Select", - default="", - description="Origin of bolt, can be an Empty\n" - "if object is a mesh will use all verts as charges") - GOB = StringProperty( - name="Select", - default="", - description="Object to use as ground plane, uses z coord only" - ) - COB = StringProperty( - name="Select", - default="", - description="Object to use as cloud, best to use a cube" - ) - IOB = StringProperty( - name="Select", - default="", - description="Object to use as insulator, 'voxelized'\n" - "before generating bolt (can be slow)" - ) - # object_mangle_tools properties - mangle_constraint_vector = BoolVectorProperty( - name="Mangle Constraint", - default=(True, True, True), - subtype='XYZ', - description="Constrains Mangle Direction" - ) - mangle_random_magnitude = IntProperty( - name="Mangle Severity", - default=5, - min=1, max=30, - description="Severity of mangling" - ) - mangle_name = StringProperty( - name="Shape Key Name", - default="mangle", - description="Name given for mangled shape keys" - ) - # unfold_transition properties - unfold_arm_name = StringProperty( - default="" - ) - unfold_modo = EnumProperty( - name="", - items=[("cursor", "3D Cursor", "Use the Distance to 3D Cursor"), - ("weight", "Weight Map", "Use a Painted Weight map"), - ("index", "Mesh Indices", "Use Faces and Vertices index")], - description="How to Sort Bones for animation", default="cursor" - ) - unfold_flip = BoolProperty( - name="Flipping Faces", - default=False, - description="Rotate faces around the Center and skip Scaling - " - "keep checked for both operators" - ) - unfold_fold_duration = IntProperty( - name="Total Time", - min=5, soft_min=25, - max=10000, soft_max=2500, - default=200, - description="Total animation length" - ) - unfold_sca_time = IntProperty( - name="Scale Time", - min=1, - max=5000, soft_max=500, - default=10, - description="Faces scaling time" - ) - unfold_rot_time = IntProperty( - name="Rotation Time", - min=1, soft_min=5, - max=5000, soft_max=500, - default=15, - description="Faces rotation time" - ) - unfold_rot_max = IntProperty( - name="Angle", - min=-180, - max=180, - default=135, - description="Faces rotation angle" - ) - unfold_fold_noise = IntProperty( - name="Noise", - min=0, - max=500, soft_max=50, - default=0, - description="Offset some faces animation" - ) - unfold_bounce = FloatProperty( - name="Bounce", - min=0, - max=10, soft_max=2.5, - default=0, - description="Add some bounce to rotation" - ) - unfold_from_point = BoolProperty( - name="Point", - default=False, - description="Scale faces from a Point instead of from an Edge" - ) - unfold_wiggle_rot = BoolProperty( - name="Wiggle", - default=False, - description="Use all Axis + Random Rotation instead of X Aligned" - ) - # oscurart_constellation - constellation_limit = FloatProperty( - name="Inital Threshold", - description="Edges will be created only if the distance\n" - "between vertices is smaller than this value\n" - "This is a starting value on Operator Invoke", - default=2, - min=0 - ) def register(): diff --git a/add_advanced_objects/add_light_template.py b/add_advanced_objects_menu/add_light_template.py index 9e2c139f..9e2c139f 100644 --- a/add_advanced_objects/add_light_template.py +++ b/add_advanced_objects_menu/add_light_template.py diff --git a/add_advanced_objects/add_mesh_aggregate.py b/add_advanced_objects_menu/add_mesh_aggregate.py index 6072cb9c..6072cb9c 100644 --- a/add_advanced_objects/add_mesh_aggregate.py +++ b/add_advanced_objects_menu/add_mesh_aggregate.py diff --git a/add_advanced_objects/arrange_on_curve.py b/add_advanced_objects_menu/arrange_on_curve.py index 14017480..14017480 100644 --- a/add_advanced_objects/arrange_on_curve.py +++ b/add_advanced_objects_menu/arrange_on_curve.py diff --git a/add_advanced_objects/circle_array.py b/add_advanced_objects_menu/circle_array.py index af5a6a0a..af5a6a0a 100644 --- a/add_advanced_objects/circle_array.py +++ b/add_advanced_objects_menu/circle_array.py diff --git a/add_advanced_objects/copy2.py b/add_advanced_objects_menu/copy2.py index 489f6dee..489f6dee 100644 --- a/add_advanced_objects/copy2.py +++ b/add_advanced_objects_menu/copy2.py diff --git a/add_advanced_objects/cubester.py b/add_advanced_objects_menu/cubester.py index 1a516bd0..1a516bd0 100644 --- a/add_advanced_objects/cubester.py +++ b/add_advanced_objects_menu/cubester.py diff --git a/add_advanced_objects/make_struts.py b/add_advanced_objects_menu/make_struts.py index 58e149ab..58e149ab 100644 --- a/add_advanced_objects/make_struts.py +++ b/add_advanced_objects_menu/make_struts.py diff --git a/add_advanced_objects/mesh_easylattice.py b/add_advanced_objects_menu/mesh_easylattice.py index 91a167dc..91a167dc 100644 --- a/add_advanced_objects/mesh_easylattice.py +++ b/add_advanced_objects_menu/mesh_easylattice.py diff --git a/add_advanced_objects/object_add_chain.py b/add_advanced_objects_menu/object_add_chain.py index 8b182c82..8b182c82 100644 --- a/add_advanced_objects/object_add_chain.py +++ b/add_advanced_objects_menu/object_add_chain.py diff --git a/add_advanced_objects/oscurart_chain_maker.py b/add_advanced_objects_menu/oscurart_chain_maker.py index 6dcd6f80..6dcd6f80 100644 --- a/add_advanced_objects/oscurart_chain_maker.py +++ b/add_advanced_objects_menu/oscurart_chain_maker.py diff --git a/add_advanced_objects/pixelate_3d.py b/add_advanced_objects_menu/pixelate_3d.py index d2b28971..d2b28971 100644 --- a/add_advanced_objects/pixelate_3d.py +++ b/add_advanced_objects_menu/pixelate_3d.py diff --git a/add_advanced_objects/random_box_structure.py b/add_advanced_objects_menu/random_box_structure.py index fa4b6497..fa4b6497 100644 --- a/add_advanced_objects/random_box_structure.py +++ b/add_advanced_objects_menu/random_box_structure.py diff --git a/add_advanced_objects/rope_alpha.py b/add_advanced_objects_menu/rope_alpha.py index 904168a1..904168a1 100644 --- a/add_advanced_objects/rope_alpha.py +++ b/add_advanced_objects_menu/rope_alpha.py diff --git a/add_advanced_objects/scene_objects_bi.py b/add_advanced_objects_menu/scene_objects_bi.py index f189bb11..f189bb11 100644 --- a/add_advanced_objects/scene_objects_bi.py +++ b/add_advanced_objects_menu/scene_objects_bi.py diff --git a/add_advanced_objects/scene_objects_cycles.py b/add_advanced_objects_menu/scene_objects_cycles.py index 85e85867..85e85867 100644 --- a/add_advanced_objects/scene_objects_cycles.py +++ b/add_advanced_objects_menu/scene_objects_cycles.py diff --git a/add_advanced_objects/scene_texture_render.py b/add_advanced_objects_menu/scene_texture_render.py index 02d6490b..02d6490b 100644 --- a/add_advanced_objects/scene_texture_render.py +++ b/add_advanced_objects_menu/scene_texture_render.py diff --git a/add_advanced_objects/trilighting.py b/add_advanced_objects_menu/trilighting.py index e0068e66..e0068e66 100644 --- a/add_advanced_objects/trilighting.py +++ b/add_advanced_objects_menu/trilighting.py diff --git a/add_advanced_objects/delaunay_voronoi/DelaunayVoronoi.py b/add_advanced_objects_panels/DelaunayVoronoi.py index dcce7f68..dcce7f68 100644 --- a/add_advanced_objects/delaunay_voronoi/DelaunayVoronoi.py +++ b/add_advanced_objects_panels/DelaunayVoronoi.py diff --git a/add_advanced_objects_panels/__init__.py b/add_advanced_objects_panels/__init__.py new file mode 100644 index 00000000..81950727 --- /dev/null +++ b/add_advanced_objects_panels/__init__.py @@ -0,0 +1,467 @@ +# ##### 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 ##### + +# Contributed to by: +# meta-androcto, Bill Currie, Jorge Hernandez - Melenedez Jacob Morris, Oscurart # +# Rebellion, Antonis Karvelas, Eleanor Howick, lijenstina, Daniel Schalla, Domlysz # +# Unnikrishnan(kodemax), Florian Meyer, Omar ahmed, Brian Hinton (Nichod), liero # +# Atom, Dannyboy, Mano-Wii, Kursad Karatas, teldredge, Phil Cote # + +bl_info = { + "name": "Add Advanced Object Panels", + "author": "meta-androcto,", + "version": (1, 1, 4), + "blender": (2, 7, 7), + "description": "Individual Create Panel Activation List", + "location": "Addons Preferences", + "warning": "", + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" + "Scripts/3D_interaction/viewport_pies", + "category": "Object" + } + +import bpy +from bpy.types import ( + Menu, + AddonPreferences, + PropertyGroup, + ) +from bpy.props import ( + BoolProperty, + BoolVectorProperty, + EnumProperty, + FloatProperty, + FloatVectorProperty, + IntProperty, + StringProperty, + PointerProperty, + ) + +sub_modules_names = ( + "drop_to_ground", + "object_laplace_lightning", + "object_mangle_tools", + "unfold_transition", + "delaunay_voronoi", + "oscurart_constellation", + ) + + +sub_modules = [__import__(__package__ + "." + submod, {}, {}, submod) for submod in sub_modules_names] +sub_modules.sort(key=lambda mod: (mod.bl_info['category'], mod.bl_info['name'])) + + +#Addons Preferences +def _get_pref_class(mod): + import inspect + + for obj in vars(mod).values(): + if inspect.isclass(obj) and issubclass(obj, PropertyGroup): + if hasattr(obj, 'bl_idname') and obj.bl_idname == mod.__name__: + return obj + + +def get_addon_preferences(name=''): + """Acquisition and registration""" + addons = bpy.context.user_preferences.addons + if __name__ not in addons: # wm.read_factory_settings() + return None + addon_prefs = addons[__name__].preferences + if name: + if not hasattr(addon_prefs, name): + for mod in sub_modules: + if mod.__name__.split('.')[-1] == name: + cls = _get_pref_class(mod) + if cls: + prop = PointerProperty(type=cls) + setattr(AdvancedObjPreferences1, name, prop) + bpy.utils.unregister_class(AdvancedObjPreferences1) + bpy.utils.register_class(AdvancedObjPreferences1) + return getattr(addon_prefs, name, None) + else: + return addon_prefs + + +def register_submodule(mod): + if not hasattr(mod, '__addon_enabled__'): + mod.__addon_enabled__ = False + if not mod.__addon_enabled__: + mod.register() + mod.__addon_enabled__ = True + + +def unregister_submodule(mod): + if mod.__addon_enabled__: + mod.unregister() + mod.__addon_enabled__ = False + + prefs = get_addon_preferences() + name = mod.__name__.split('.')[-1] + if hasattr(AdvancedObjPreferences1, name): + delattr(AdvancedObjPreferences1, name) + if prefs: + bpy.utils.unregister_class(AdvancedObjPreferences1) + bpy.utils.register_class(AdvancedObjPreferences1) + if name in prefs: + del prefs[name] + + +class AdvancedObjPreferences1(AddonPreferences): + bl_idname = __name__ + + def draw(self, context): + layout = self.layout + + for mod in sub_modules: + mod_name = mod.__name__.split('.')[-1] + info = mod.bl_info + column = layout.column() + box = column.box() + + # first stage + expand = getattr(self, 'show_expanded_' + mod_name) + icon = 'TRIA_DOWN' if expand else 'TRIA_RIGHT' + col = box.column() + row = col.row() + sub = row.row() + sub.context_pointer_set('addon_prefs', self) + op = sub.operator('wm.context_toggle', text='', icon=icon, + emboss=False) + op.data_path = 'addon_prefs.show_expanded_' + mod_name + sub.label('{}: {}'.format(info['category'], info['name'])) + sub = row.row() + sub.alignment = 'RIGHT' + if info.get('warning'): + sub.label('', icon='ERROR') + sub.prop(self, 'use_' + mod_name, text='') + + # The second stage + if expand: + if info.get('description'): + split = col.row().split(percentage=0.15) + split.label('Description:') + split.label(info['description']) + if info.get('location'): + split = col.row().split(percentage=0.15) + split.label('Location:') + split.label(info['location']) + if info.get('author') and info.get('author') != 'chromoly': + split = col.row().split(percentage=0.15) + split.label('Author:') + split.label(info['author']) + if info.get('version'): + split = col.row().split(percentage=0.15) + split.label('Version:') + split.label('.'.join(str(x) for x in info['version']), + translate=False) + if info.get('warning'): + split = col.row().split(percentage=0.15) + split.label('Warning:') + split.label(' ' + info['warning'], icon='ERROR') + + tot_row = int(bool(info.get('wiki_url'))) + if tot_row: + split = col.row().split(percentage=0.15) + split.label(text='Internet:') + if info.get('wiki_url'): + op = split.operator('wm.url_open', + text='Documentation', icon='HELP') + op.url = info.get('wiki_url') + for i in range(4 - tot_row): + split.separator() + + # Details and settings + if getattr(self, 'use_' + mod_name): + prefs = get_addon_preferences(mod_name) + + if prefs and hasattr(prefs, 'draw'): + box = box.column() + prefs.layout = box + try: + prefs.draw(context) + except: + traceback.print_exc() + box.label(text='Error (see console)', icon='ERROR') + del prefs.layout + + row = layout.row() + row.label("End of Panel Activations") + + +for mod in sub_modules: + info = mod.bl_info + mod_name = mod.__name__.split('.')[-1] + + def gen_update(mod): + def update(self, context): + if getattr(self, 'use_' + mod.__name__.split('.')[-1]): + if not mod.__addon_enabled__: + register_submodule(mod) + else: + if mod.__addon_enabled__: + unregister_submodule(mod) + return update + + prop = BoolProperty( + name=info['name'], + description=info.get('description', ''), + update=gen_update(mod), + ) + setattr(AdvancedObjPreferences1, 'use_' + mod_name, prop) + prop = BoolProperty() + setattr(AdvancedObjPreferences1, 'show_expanded_' + mod_name, prop) + + +class AdvancedObjProperties1(PropertyGroup): + + # main properties + + # object_laplace_lighting props + ORIGIN = FloatVectorProperty( + name="Origin charge" + ) + GROUNDZ = IntProperty( + name="Ground Z coordinate" + ) + HORDER = IntProperty( + name="Secondary paths orders", + default=1 + ) + # object_laplace_lighting UI props + TSTEPS = IntProperty( + name="Iterations", + default=350, + description="Number of cells to create\n" + "Will end early if hits ground plane or cloud" + ) + GSCALE = FloatProperty( + name="Grid unit size", + default=0.12, + description="scale of cells, .25 = 4 cells per blenderUnit" + ) + BIGVAR = FloatProperty( + name="Straightness", + default=6.3, + description="Straightness/branchiness of bolt, \n" + "<2 is mush, >12 is staight line, 6.3 is good" + ) + GROUNDBOOL = BoolProperty( + name="Use Ground object", + description="Use ground plane or not", + default=True + ) + GROUNDC = IntProperty( + name="Ground charge", + default=-250, + description="Charge of the ground plane" + ) + CLOUDBOOL = BoolProperty( + name="Use Cloud object", + default=False, + description="Use cloud object - attracts and terminates like ground but\n" + "any obj instead of z plane\n" + "Can slow down loop if obj is large, overrides ground" + ) + CLOUDC = IntProperty( + name="Cloud charge", + default=-1, + description="Charge of a cell in cloud object\n" + "(so total charge also depends on obj size)" + ) + VMMESH = BoolProperty( + name="Multi mesh", + default=True, + description="Output to multi-meshes for different materials on main/sec/side branches" + ) + VSMESH = BoolProperty( + name="Single mesh", + default=False, + description="Output to single mesh for using build modifier and particles for effects" + ) + VCUBE = BoolProperty( + name="Cubes", + default=False, + description="CTRL-J after run to JOIN\n" + "Outputs a bunch of cube objects, mostly for testing" + ) + VVOX = BoolProperty( + name="Voxel (experimental)", + default=False, + description="Output to a voxel file to bpy.data.filepath\FSLGvoxels.raw\n" + "(doesn't work well right now)" + ) + IBOOL = BoolProperty( + name="Use Insulator object", + default=False, + description="Use insulator mesh object to prevent growth of bolt in areas" + ) + OOB = StringProperty( + name="Select", + default="", + description="Origin of bolt, can be an Empty\n" + "if object is a mesh will use all verts as charges") + GOB = StringProperty( + name="Select", + default="", + description="Object to use as ground plane, uses z coord only" + ) + COB = StringProperty( + name="Select", + default="", + description="Object to use as cloud, best to use a cube" + ) + IOB = StringProperty( + name="Select", + default="", + description="Object to use as insulator, 'voxelized'\n" + "before generating bolt (can be slow)" + ) + # object_mangle_tools properties + mangle_constraint_vector = BoolVectorProperty( + name="Mangle Constraint", + default=(True, True, True), + subtype='XYZ', + description="Constrains Mangle Direction" + ) + mangle_random_magnitude = IntProperty( + name="Mangle Severity", + default=5, + min=1, max=30, + description="Severity of mangling" + ) + mangle_name = StringProperty( + name="Shape Key Name", + default="mangle", + description="Name given for mangled shape keys" + ) + # unfold_transition properties + unfold_arm_name = StringProperty( + default="" + ) + unfold_modo = EnumProperty( + name="", + items=[("cursor", "3D Cursor", "Use the Distance to 3D Cursor"), + ("weight", "Weight Map", "Use a Painted Weight map"), + ("index", "Mesh Indices", "Use Faces and Vertices index")], + description="How to Sort Bones for animation", default="cursor" + ) + unfold_flip = BoolProperty( + name="Flipping Faces", + default=False, + description="Rotate faces around the Center and skip Scaling - " + "keep checked for both operators" + ) + unfold_fold_duration = IntProperty( + name="Total Time", + min=5, soft_min=25, + max=10000, soft_max=2500, + default=200, + description="Total animation length" + ) + unfold_sca_time = IntProperty( + name="Scale Time", + min=1, + max=5000, soft_max=500, + default=10, + description="Faces scaling time" + ) + unfold_rot_time = IntProperty( + name="Rotation Time", + min=1, soft_min=5, + max=5000, soft_max=500, + default=15, + description="Faces rotation time" + ) + unfold_rot_max = IntProperty( + name="Angle", + min=-180, + max=180, + default=135, + description="Faces rotation angle" + ) + unfold_fold_noise = IntProperty( + name="Noise", + min=0, + max=500, soft_max=50, + default=0, + description="Offset some faces animation" + ) + unfold_bounce = FloatProperty( + name="Bounce", + min=0, + max=10, soft_max=2.5, + default=0, + description="Add some bounce to rotation" + ) + unfold_from_point = BoolProperty( + name="Point", + default=False, + description="Scale faces from a Point instead of from an Edge" + ) + unfold_wiggle_rot = BoolProperty( + name="Wiggle", + default=False, + description="Use all Axis + Random Rotation instead of X Aligned" + ) + # oscurart_constellation + constellation_limit = FloatProperty( + name="Inital Threshold", + description="Edges will be created only if the distance\n" + "between vertices is smaller than this value\n" + "This is a starting value on Operator Invoke", + default=2, + min=0 + ) + + +# Class list +classes = ( + AdvancedObjPreferences1, + AdvancedObjProperties1, + ) + + +def register(): + for cls in classes: + bpy.utils.register_class(cls) + + bpy.types.Scene.advanced_objects1 = PointerProperty( + type=AdvancedObjProperties1 + ) + + prefs = get_addon_preferences() + for mod in sub_modules: + if not hasattr(mod, '__addon_enabled__'): + mod.__addon_enabled__ = False + name = mod.__name__.split('.')[-1] + if getattr(prefs, 'use_' + name): + register_submodule(mod) + + +def unregister(): + for mod in sub_modules: + if mod.__addon_enabled__: + unregister_submodule(mod) + del bpy.types.Scene.advanced_objects1 + + for cls in reversed(classes): + bpy.utils.unregister_class(cls) + + +if __name__ == "__main__": + register() diff --git a/add_advanced_objects/delaunay_voronoi/delaunayVoronoiBlender.py b/add_advanced_objects_panels/delaunay_voronoi.py index 707c45b4..02768232 100644 --- a/add_advanced_objects/delaunay_voronoi/delaunayVoronoiBlender.py +++ b/add_advanced_objects_panels/delaunay_voronoi.py @@ -1,5 +1,38 @@ # -*- coding:utf-8 -*- +# ##### 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 ##### + +bl_info = { + "name": "Delaunay Voronoi", + "description": "Points cloud Delaunay triangulation in 2.5D " + "(suitable for terrain modelling) or Voronoi diagram in 2D", + "author": "Domlysz, Oscurart", + "version": (1, 3), + "blender": (2, 7, 0), + "location": "View3D > Tools > GIS", + "warning": "", + "wiki_url": "https://github.com/domlysz/BlenderGIS/wiki", + "category": "Add Mesh" + } + + + import bpy from .DelaunayVoronoi import ( computeVoronoiDiagram, @@ -67,7 +100,7 @@ class ToolsPanelDelaunay(Panel): def draw(self, context): layout = self.layout - adv_obj = context.scene.advanced_objects + adv_obj = context.scene.advanced_objects1 box = layout.box() col = box.column(align=True) @@ -75,12 +108,6 @@ class ToolsPanelDelaunay(Panel): col.operator("delaunay.triangulation") col.operator("voronoi.tesselation") - box = layout.box() - col = box.column(align=True) - col.label("Constellation:") - col.operator("mesh.constellation", text="Cross Section") - col.prop(adv_obj, "constellation_limit") - class OBJECT_OT_TriangulateButton(Operator): bl_idname = "delaunay.triangulation" @@ -266,3 +293,20 @@ class OBJECT_OT_VoronoiButton(Operator): self.report({"INFO"}, "Mesh created (" + str(len(polyIdx)) + " polygons)") return {'FINISHED'} + +# Register +def register(): + bpy.utils.register_class(OBJECT_OT_VoronoiButton) + bpy.utils.register_class(OBJECT_OT_TriangulateButton) + bpy.utils.register_class(ToolsPanelDelaunay) + + +def unregister(): + bpy.utils.unregister_class(OBJECT_OT_VoronoiButton) + bpy.utils.unregister_class(OBJECT_OT_TriangulateButton) + bpy.utils.unregister_class(ToolsPanelDelaunay) + + +if __name__ == "__main__": + register() + diff --git a/add_advanced_objects/drop_to_ground.py b/add_advanced_objects_panels/drop_to_ground.py index 744a2d6b..35020020 100644 --- a/add_advanced_objects/drop_to_ground.py +++ b/add_advanced_objects_panels/drop_to_ground.py @@ -19,13 +19,10 @@ bl_info = { "name": "Drop to Ground1", "author": "Unnikrishnan(kodemax), Florian Meyer(testscreenings)", - "version": (1, 2, 1), "blender": (2, 71, 0), "location": "3D View > Toolshelf > Tools Tab", "description": "Drop selected objects on active object", "warning": "", - "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" - "Scripts/Object/Drop_to_ground", "category": "Object"} diff --git a/add_advanced_objects/object_laplace_lightning.py b/add_advanced_objects_panels/object_laplace_lightning.py index 857682b0..3e71c29b 100644 --- a/add_advanced_objects/object_laplace_lightning.py +++ b/add_advanced_objects_panels/object_laplace_lightning.py @@ -22,12 +22,10 @@ bl_info = { "name": "Laplacian Lightning", "author": "teldredge", - "version": (0, 2, 9), "blender": (2, 78, 0), "location": "View3D > Toolshelf > Create Tab", "description": "Lightning mesh generator using laplacian growth algorithm", "warning": "", - "wiki_url": "http://www.funkboxing.com/wordpress/?p=301", "category": "Object"} # BLENDER LAPLACIAN LIGHTNING @@ -514,7 +512,7 @@ def writeStokeToSingleMesh(arr, jarr, orig, gs, mct, rpt=None): def visualizeArray(cg, oob, gs, vm, vs, vc, vv, rst): - winmgr = bpy.context.scene.advanced_objects + winmgr = bpy.context.scene.advanced_objects1 # IN: (cellgrid, origin, gridscale, # mulimesh, single mesh, cubes, voxels, report sting) origin = oob.location @@ -1077,7 +1075,7 @@ def getCandidateSites(aList, iList=[]): # Setup functions def setupObjects(): - winmgr = bpy.context.scene.advanced_objects + winmgr = bpy.context.scene.advanced_objects1 oOB = bpy.data.objects.new('ELorigin', None) oOB.location = ((0, 0, 10)) bpy.context.scene.objects.link(oOB) @@ -1115,7 +1113,7 @@ def setupObjects(): def checkSettings(): check = True - winmgr = bpy.context.scene.advanced_objects + winmgr = bpy.context.scene.advanced_objects1 message = "" if winmgr.OOB == "": message = "Error: no origin object selected" @@ -1143,7 +1141,7 @@ def checkSettings(): # Main def FSLG(): - winmgr = bpy.context.scene.advanced_objects + winmgr = bpy.context.scene.advanced_objects1 # fast simulation of laplacian growth debug_prints(func="FSLG", text="Go go gadget: fast simulation of laplacian growth") @@ -1341,7 +1339,7 @@ class OBJECT_PT_fslg(Panel): def draw(self, context): layout = self.layout - winmgr = context.scene.advanced_objects + winmgr = context.scene.advanced_objects1 col = layout.column(align=True) col.prop(winmgr, "TSTEPS") @@ -1384,7 +1382,7 @@ class OBJECT_PT_fslg(Panel): def getReportString(rtime): - winmgr = bpy.context.scene.advanced_objects + winmgr = bpy.context.scene.advanced_objects1 rSTRING1 = 't:' + str(winmgr.TSTEPS) + ',sc:' + str(winmgr.GSCALE)[0:4] + ',uv:' + str(winmgr.BIGVAR)[0:4] + ',' rSTRING2 = 'ori:' + str(winmgr. ORIGIN[0]) + '/' + str(winmgr. ORIGIN[1]) + '/' + str(winmgr. ORIGIN[2]) + ',' rSTRING3 = 'gz:' + str(winmgr.GROUNDZ) + ',gc:' + str(winmgr.GROUNDC) + ',rtime:' + str(int(rtime)) diff --git a/add_advanced_objects/object_mangle_tools.py b/add_advanced_objects_panels/object_mangle_tools.py index 9f5b44ee..60438eca 100644 --- a/add_advanced_objects/object_mangle_tools.py +++ b/add_advanced_objects_panels/object_mangle_tools.py @@ -23,7 +23,6 @@ bl_info = { "name": "Mangle Tools", "author": "Phil Cote", - "version": (0, 2, 2), "blender": (2, 71, 0), "location": "View3D > Toolshelf > Tools Tab", "description": "Set of tools to mangle curves, meshes, and shape keys", @@ -44,7 +43,7 @@ import bmesh def move_coordinate(context, co, is_curve=False): - advanced_objects = context.scene.advanced_objects + advanced_objects = context.scene.advanced_objects1 xyz_const = advanced_objects.mangle_constraint_vector random.seed(time.time()) multiplier = 1 @@ -79,7 +78,7 @@ class MeshManglerOperator(Operator): bm = bmesh.new() bm.from_mesh(mesh) verts = bm.verts - advanced_objects = context.scene.advanced_objects + advanced_objects = context.scene.advanced_objects1 randomMag = advanced_objects.mangle_random_magnitude random.seed(time.time()) @@ -117,7 +116,7 @@ class AnimanglerOperator(Operator): return ob is not None and ob.type in ['MESH', 'CURVE'] def execute(self, context): - scn = context.scene.advanced_objects + scn = context.scene.advanced_objects1 mangleName = scn.mangle_name ob = context.object shapeKey = ob.shape_key_add(name=mangleName) @@ -170,7 +169,7 @@ class MangleToolsPanel(Panel): bl_options = {'DEFAULT_CLOSED'} def draw(self, context): - scn = context.scene.advanced_objects + scn = context.scene.advanced_objects1 obj = context.object if obj and obj.type in ['MESH']: diff --git a/add_advanced_objects/delaunay_voronoi/oscurart_constellation.py b/add_advanced_objects_panels/oscurart_constellation.py index adde96c0..f2caa423 100644 --- a/add_advanced_objects/delaunay_voronoi/oscurart_constellation.py +++ b/add_advanced_objects_panels/oscurart_constellation.py @@ -19,7 +19,6 @@ bl_info = { "name": "Mesh: Constellation", "author": "Oscurart", - "version": (1, 1, 1), "blender": (2, 67, 0), "location": "Add > Mesh > Constellation", "description": "Create a new Mesh From Selected", @@ -31,10 +30,12 @@ bl_info = { # the adv_obj and advanced_objects patterns import bpy -from bpy.types import Operator from bpy.props import FloatProperty from math import sqrt - +from bpy.types import ( + Operator, + Panel, + ) def VertDis(a, b): dst = sqrt(pow(a.co.x - b.co.x, 2) + @@ -85,7 +86,7 @@ class Oscurart_Constellation(Operator): return (obj and obj.type == "MESH") def invoke(self, context, event): - adv_obj = context.scene.advanced_objects + adv_obj = context.scene.advanced_objects1 self.limit = adv_obj.constellation_limit return self.execute(context) @@ -108,16 +109,33 @@ class Oscurart_Constellation(Operator): return {'FINISHED'} +class Constellation_Operator_Panel(Panel): + bl_label = "Constellation" + bl_region_type = "TOOLS" + bl_space_type = "VIEW_3D" + bl_options = {'DEFAULT_CLOSED'} + bl_context = "objectmode" + bl_category = "Create" + + def draw(self, context): + layout = self.layout + adv_obj = context.scene.advanced_objects1 + box = layout.box() + col = box.column(align=True) + col.label("Constellation:") + col.operator("mesh.constellation", text="Cross Section") + col.prop(adv_obj, "constellation_limit") # Register def register(): bpy.utils.register_class(Oscurart_Constellation) + bpy.utils.register_class(Constellation_Operator_Panel) def unregister(): bpy.utils.unregister_class(Oscurart_Constellation) - + bpy.utils.unregister_class(Constellation_Operator_Panel) if __name__ == "__main__": register() diff --git a/add_advanced_objects/unfold_transition.py b/add_advanced_objects_panels/unfold_transition.py index 769386f5..9b196810 100644 --- a/add_advanced_objects/unfold_transition.py +++ b/add_advanced_objects_panels/unfold_transition.py @@ -3,7 +3,6 @@ bl_info = { "name": "Unfold transition", "author": "Liero, Atom", - "version": (0, 1, 2), "location": "Tool bar > Animation tab > UnFold Transition", "description": "Simple unfold transition / animation, will " "separate faces and set up an armature", @@ -40,7 +39,7 @@ class Set_Up_Fold(Operator): def execute(self, context): bpy.ops.object.mode_set() scn = bpy.context.scene - adv_obj = scn.advanced_objects + adv_obj = scn.advanced_objects1 obj = bpy.context.object dat = obj.data fac = dat.polygons @@ -184,7 +183,7 @@ class Animate_Fold(Operator): def draw(self, context): layout = self.layout - adv_obj = context.scene.advanced_objects + adv_obj = context.scene.advanced_objects1 if self.is_not_undo is True: layout.label(text="Warning:", icon="INFO") @@ -201,7 +200,7 @@ class Animate_Fold(Operator): def invoke(self, context, event): obj = bpy.context.object scn = bpy.context.scene - adv_obj = scn.advanced_objects + adv_obj = scn.advanced_objects1 if obj.name != adv_obj.unfold_arm_name: self.is_not_undo = True @@ -212,7 +211,7 @@ class Animate_Fold(Operator): def execute(self, context): obj = bpy.context.object scn = bpy.context.scene - adv_obj = scn.advanced_objects + adv_obj = scn.advanced_objects1 fra = scn.frame_current if obj.name != adv_obj.unfold_arm_name: self.report({"INFO"}, @@ -299,7 +298,7 @@ class PanelFOLD(Panel): def draw(self, context): layout = self.layout - adv_obj = context.scene.advanced_objects + adv_obj = context.scene.advanced_objects1 box = layout.box() col = box.column() @@ -327,17 +326,20 @@ class PanelFOLD(Panel): if not adv_obj.unfold_flip: row.prop(adv_obj, "unfold_from_point") +classes = ( + Set_Up_Fold, + Animate_Fold, + PanelFOLD, + ) def register(): - bpy.utils.register_class(Set_Up_Fold) - bpy.utils.register_class(Animate_Fold) - bpy.utils.register_class(PanelFOLD) + for cls in classes: + bpy.utils.register_class(cls) def unregister(): - bpy.utils.unregister_class(Set_Up_Fold) - bpy.utils.unregister_class(Animate_Fold) - bpy.utils.unregister_class(PanelFOLD) + for cls in classes: + bpy.utils.unregister_class(cls) if __name__ == "__main__": diff --git a/add_curve_ivygen.py b/add_curve_ivygen.py index 6e45d890..dd523102 100644 --- a/add_curve_ivygen.py +++ b/add_curve_ivygen.py @@ -21,31 +21,44 @@ bl_info = { "name": "IvyGen", "author": "testscreenings, PKHG, TrumanBlending", - "version": (0, 1, 1), + "version": (0, 1, 2), "blender": (2, 59, 0), "location": "View3D > Add > Curve", "description": "Adds generated ivy to a mesh object starting " "at the 3D cursor", "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" "Scripts/Curve/Ivy_Gen", "category": "Add Curve", } import bpy -from bpy.props import FloatProperty, IntProperty, BoolProperty -from mathutils import Vector, Matrix +from bpy.props import ( + FloatProperty, + IntProperty, + BoolProperty, + ) +from mathutils import ( + Vector, + Matrix, + ) from collections import deque -from math import pow, cos, pi, atan2 -from random import random as rand_val, seed as rand_seed +from math import ( + pow, cos, + pi, atan2, + ) +from random import ( + random as rand_val, + seed as rand_seed, + ) import time def createIvyGeometry(IVY, growLeaves): """Create the curve geometry for IVY""" # Compute the local size and the gauss weight filter - #local_ivyBranchSize = IVY.ivyBranchSize # * radius * IVY.ivySize + # local_ivyBranchSize = IVY.ivyBranchSize # * radius * IVY.ivySize gaussWeight = (1.0, 2.0, 4.0, 7.0, 9.0, 10.0, 9.0, 7.0, 4.0, 2.0, 1.0) # Create a new curve and intialise it @@ -65,7 +78,7 @@ def createIvyGeometry(IVY, growLeaves): ) # Get the local size - #local_ivyLeafSize = IVY.ivyLeafSize # * radius * IVY.ivySize + # local_ivyLeafSize = IVY.ivyLeafSize # * radius * IVY.ivySize # Initialise the vertex and face lists vertList = deque() @@ -86,7 +99,7 @@ def createIvyGeometry(IVY, growLeaves): radiusConstant = local_ivyBranchRadius * IVY.ivyBranchSize splineRadii = [radiusConstant * (1.3 - n.length * prevIvyLength) - for n in root.ivyNodes] + for n in root.ivyNodes] # Add the poly curve and set coords and radii newSpline = curve.splines.new(type='POLY') @@ -99,7 +112,7 @@ def createIvyGeometry(IVY, growLeaves): for k in range(len(gaussWeight)): idx = max(0, min(i + k - 5, numNodes - 1)) n.smoothAdhesionVector += (gaussWeight[k] * - root.ivyNodes[idx].adhesionVector) + root.ivyNodes[idx].adhesionVector) n.smoothAdhesionVector /= 56.0 n.adhesionLength = n.smoothAdhesionVector.length n.smoothAdhesionVector.normalize() @@ -198,6 +211,7 @@ def createIvyGeometry(IVY, growLeaves): ob.parent = newCurve + ''' def computeBoundingSphere(ob): # Get the mesh data @@ -276,10 +290,10 @@ class Ivy: self.maxLength = 0.0 # Normalize all the weights only on intialisation - sum = self.primaryWeight + self.randomWeight + self.adhesionWeight - self.primaryWeight /= sum - self.randomWeight /= sum - self.adhesionWeight /= sum + sums = self.primaryWeight + self.randomWeight + self.adhesionWeight + self.primaryWeight /= sums + self.randomWeight /= sums + self.adhesionWeight /= sums def seed(self, seedPos): # Seed the Ivy by making a new root and first node @@ -292,9 +306,9 @@ class Ivy: def grow(self, ob): # Determine the local sizes - #local_ivySize = self.ivySize # * radius - #local_maxFloatLength = self.maxFloatLength # * radius - #local_maxAdhesionDistance = self.maxAdhesionDistance # * radius + # local_ivySize = self.ivySize # * radius + # local_maxFloatLength = self.maxFloatLength # * radius + # local_maxAdhesionDistance = self.maxAdhesionDistance # * radius for root in self.ivyRoots: # Make sure the root is alive, if not, skip @@ -411,7 +425,7 @@ def adhesion(loc, ob, max_l): # Compute the direction vector between the closest point and loc adhesion_vector.normalize() adhesion_vector *= 1.0 - distance / max_l - #adhesion_vector *= getFaceWeight(ob.data, nearest_result[3]) + # adhesion_vector *= getFaceWeight(ob.data, nearest_result[3]) return adhesion_vector @@ -441,94 +455,135 @@ def collision(ob, pos, new_pos): return climbing +def check_mesh_faces(ob): + me = ob.data + if len(me.polygons) > 0: + return True + + return False + + class IvyGen(bpy.types.Operator): bl_idname = "curve.ivy_gen" bl_label = "IvyGen" + bl_description = "Generate Ivy on an Mesh Object" bl_options = {'REGISTER', 'UNDO'} - maxIvyLength = FloatProperty(name="Max Ivy Length", - description="Maximum ivy length in Blender Units", - default=1.0, - min=0.0, - soft_max=3.0, - subtype='DISTANCE', - unit='LENGTH') - primaryWeight = FloatProperty(name="Primary Weight", - description="Weighting given to the current direction", - default=0.5, - min=0.0, - soft_max=1.0) - randomWeight = FloatProperty(name="Random Weight", - description="Weighting given to the random direction", - default=0.2, - min=0.0, - soft_max=1.0) - gravityWeight = FloatProperty(name="Gravity Weight", - description="Weighting given to the gravity direction", - default=1.0, - min=0.0, - soft_max=1.0) - adhesionWeight = FloatProperty(name="Adhesion Weight", - description="Weighting given to the adhesion direction", - default=0.1, - min=0.0, - soft_max=1.0) - branchingProbability = FloatProperty(name="Branching Probability", - description="Probability of a new branch forming", - default=0.05, - min=0.0, - soft_max=1.0) - leafProbability = FloatProperty(name="Leaf Probability", - description="Probability of a leaf forming", - default=0.35, - min=0.0, - soft_max=1.0) - ivySize = FloatProperty(name="Ivy Size", - description=("The length of an ivy segment in Blender" - " Units"), - default=0.02, - min=0.0, - soft_max=1.0, - precision=3) - ivyLeafSize = FloatProperty(name="Ivy Leaf Size", - description="The size of the ivy leaves", - default=0.02, - min=0.0, - soft_max=0.5, - precision=3) - ivyBranchSize = FloatProperty(name="Ivy Branch Size", - description="The size of the ivy branches", - default=0.001, - min=0.0, - soft_max=0.1, - precision=4) - maxFloatLength = FloatProperty(name="Max Float Length", - description=("The maximum distance that a branch " - "can live while floating"), - default=0.5, - min=0.0, - soft_max=1.0) - maxAdhesionDistance = FloatProperty(name="Max Adhesion Length", - description=("The maximum distance that a branch " - "will feel the effects of adhesion"), - default=1.0, - min=0.0, - soft_max=2.0, - precision=2) - randomSeed = IntProperty(name="Random Seed", - description="The seed governing random generation", - default=0, - min=0) - maxTime = FloatProperty(name="Maximum Time", - description=("The maximum time to run the generation for " - "in seconds generation (0.0 = Disabled)"), - default=0.0, - min=0.0, - soft_max=10) - growLeaves = BoolProperty(name="Grow Leaves", - description="Grow leaves or not", - default=True) - updateIvy = BoolProperty(name="Update Ivy", default=False) + maxIvyLength = FloatProperty( + name="Max Ivy Length", + description="Maximum ivy length in Blender Units", + default=1.0, + min=0.0, + soft_max=3.0, + subtype='DISTANCE', + unit='LENGTH' + ) + primaryWeight = FloatProperty( + name="Primary Weight", + description="Weighting given to the current direction", + default=0.5, + min=0.0, + soft_max=1.0 + ) + randomWeight = FloatProperty( + name="Random Weight", + description="Weighting given to the random direction", + default=0.2, + min=0.0, + soft_max=1.0 + ) + gravityWeight = FloatProperty( + name="Gravity Weight", + description="Weighting given to the gravity direction", + default=1.0, + min=0.0, + soft_max=1.0 + ) + adhesionWeight = FloatProperty( + name="Adhesion Weight", + description="Weighting given to the adhesion direction", + default=0.1, + min=0.0, + soft_max=1.0 + ) + branchingProbability = FloatProperty( + name="Branching Probability", + description="Probability of a new branch forming", + default=0.05, + min=0.0, + soft_max=1.0 + ) + leafProbability = FloatProperty( + name="Leaf Probability", + description="Probability of a leaf forming", + default=0.35, + min=0.0, + soft_max=1.0 + ) + ivySize = FloatProperty( + name="Ivy Size", + description="The length of an ivy segment in Blender" + " Units", + default=0.02, + min=0.0, + soft_max=1.0, + precision=3 + ) + ivyLeafSize = FloatProperty( + name="Ivy Leaf Size", + description="The size of the ivy leaves", + default=0.02, + min=0.0, + soft_max=0.5, + precision=3 + ) + ivyBranchSize = FloatProperty( + name="Ivy Branch Size", + description="The size of the ivy branches", + default=0.001, + min=0.0, + soft_max=0.1, + precision=4 + ) + maxFloatLength = FloatProperty( + name="Max Float Length", + description="The maximum distance that a branch " + "can live while floating", + default=0.5, + min=0.0, + soft_max=1.0) + maxAdhesionDistance = FloatProperty( + name="Max Adhesion Length", + description="The maximum distance that a branch " + "will feel the effects of adhesion", + default=1.0, + min=0.0, + soft_max=2.0, + precision=2 + ) + randomSeed = IntProperty( + name="Random Seed", + description="The seed governing random generation", + default=0, + min=0 + ) + maxTime = FloatProperty( + name="Maximum Time", + description="The maximum time to run the generation for " + "in seconds generation (0.0 = Disabled)", + default=0.0, + min=0.0, + soft_max=10 + ) + growLeaves = BoolProperty( + name="Grow Leaves", + description="Grow leaves or not", + default=True + ) + updateIvy = BoolProperty( + name="Update Ivy", + default=False + ) @classmethod def poll(self, context): @@ -552,8 +607,17 @@ class IvyGen(bpy.types.Operator): # Get the selected object ob = context.active_object + # Check if the mesh has at least one polygon since some functions + # are expecting them in the object's data (see T51753) + check_face = check_mesh_faces(ob) + if check_face is False: + self.report({'WARNING'}, + "Mesh Object doesn't have at least one Face. " + "Operation Cancelled") + return {"CANCELLED"} + # Compute bounding sphere radius - #radius = computeBoundingSphere(ob) # Not needed anymore + # radius = computeBoundingSphere(ob) # Not needed anymore # Get the seeding point seedPoint = context.scene.cursor_location @@ -667,7 +731,7 @@ class IvyGen(bpy.types.Operator): def menu_func(self, context): self.layout.operator(IvyGen.bl_idname, text="Add Ivy to Mesh", - icon='OUTLINER_DATA_CURVE').updateIvy = True + icon='OUTLINER_DATA_CURVE').updateIvy = True def register(): diff --git a/add_mesh_ant_landscape.py b/add_mesh_ant_landscape.py deleted file mode 100644 index eaa19b54..00000000 --- a/add_mesh_ant_landscape.py +++ /dev/null @@ -1,1422 +0,0 @@ -# ##### 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 ##### - -bl_info = { - "name": "A.N.T. Landscape", - "author": "Jimmy Hazevoet", - "version": (0, 1, 6), - "blender": (2, 77, 0), - "location": "View3D > Add > Mesh", - "description": "Another Noise Tool: Add a landscape primitive", - "warning": "", - "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" - "Scripts/Add_Mesh/ANT_Landscape", - "category": "Add Mesh", -} - -""" -# ------------------------------------------------------------- -- UPDATE: A.N.T. Landscape - Version 0,1,6 (5/2017) -# ------------------------------------------------------------- - - NEW: - - - - Use Blender internal texture data block - texture nodes - - Variable X and Y grid size and variable X and Y subdivisions - - Triangulate faces - - Slope map, z normal to vertex group weight, - and optional select vertices on flat area's - - Place landscape at cursor position or at world center - - Noise variations (from old A.N.T. Blender-2.49 addon) - - Variable X and Y noise size (and X Y Offset since version 0.1.5) - - Plateau and Sealevel renamed to Maximum (plateau) and Minimum (now: seabed) - - Variable X and Y edge fallof with variable edge level (now: sealevel) - - Add water plane with variable height - - Use materials - - Some small changes and fixes - - - -# ------------------------------------------------------------- -# Another Noise Tool: Landscape mesh generator -# ------------------------------------------------------------- -MESH OPTIONS: -Mesh update: Turn this on for interactive mesh refresh. -Sphere: Generate sphere or a grid mesh. -Smooth: Generate smooth shaded mesh. -Triangulate: Triangulate faces -Subdivision X Y: Number of mesh X Y subdivisions, higher numbers gives more detail but slows down the script. -Mesh size X Y: X,Y size of the grid mesh in blender units. -X_Offset: Noise x offset in blender units (make tiled terrain) -Y_Offset: Noise y offset in blender units -Cursor: Place at cursor location -Vertex Group: Slope map, z normal value to vertex group weight, - and select vertices on flat area's - -NOISE OPTIONS: ( Many of these options are the same as in blender textures. ) -Random seed: Use this to randomise the origin of the noise function. -Noise size: Size of the noise. -Noise type: Available noise types: multiFractal, ridgedMFractal, fBm, hybridMFractal, heteroTerrain, - Turbulence, Distorted Noise, Marble, Shattered_hTerrain, Strata_hTerrain, Planet_noise -Noise basis: Blender, Perlin, NewPerlin, Voronoi_F1, Voronoi_F2, Voronoi_F3, Voronoi_F4, Voronoi_F2-F1, - Voronoi Crackle, Cellnoise -Distortion: Distortion amount. -Hard: Hard/Soft turbulence noise. -Depth: Noise depth, number of frequencies in the fBm. -Dimension: Musgrave: Fractal dimension of the roughest areas. -Lacunarity: Musgrave: Gap between successive frequencies. -Offset: Musgrave: Raises the terrain from sea level. -Gain: Musgrave: Scale factor. -Marble Bias: Sin, Tri, Saw -Marble Sharpnes: Soft, Sharp, Sharper -Marble Shape: Shape of the marble function: Default, Ring, Swirl, Bumps, Wave, X, Y - -TERRAIN OPTIONS: -Height: Scale terrain height. -Invert: Invert terrain height. -Offset: Terrain height offset. -Seabed: Flattens terrain at seabed level. -Plateau: Flattens terrain at plateau level. -Falloff: Terrain height falloff: X falloff, Y falloff, XY falloff -Edge Level: Falloff edge level, sealevel -FalloffSizeX: Scale falloff x -FalloffSizeY: Scale falloff y -Strata: Strata amount, number of strata / terrace layers. -Strata type: Strata types, Smooth, Sharp-sub, Sharp-add, Quantize - -WATER: Add water plane -Level: Adjust plane level - -MATERIAL: Use materials -""" - -# import modules -import bpy -from bpy.props import ( - BoolProperty, - EnumProperty, - FloatProperty, - IntProperty, - StringProperty, - FloatVectorProperty, - ) -from mathutils import Vector -from mathutils.noise import ( - seed_set, - turbulence, - turbulence_vector, - fractal, - hybrid_multi_fractal, - multi_fractal, - ridged_multi_fractal, - hetero_terrain, - random_unit_vector, - variable_lacunarity, - ) -from math import ( - floor, sqrt, - sin, cos, pi, - ) - - -# Create a new mesh (object) from verts/edges/faces. -# verts/edges/faces ... List of vertices/edges/faces for the -# new mesh (as used in from_pydata). -# name ... Name of the new mesh (& object). -def create_mesh_object(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) - - # Update mesh geometry after adding stuff. - mesh.update() - - from bpy_extras import object_utils - - return object_utils.object_data_add(context, mesh, operator=None) - - -# ------------------------------------------------------------ -# Generate XY Grid -def grid_gen(sub_d_x, sub_d_y, tri, meshsize_x, meshsize_y, options, water_plane, water_level): - verts = [] - faces = [] - for i in range (0, sub_d_x): - x = meshsize_x * (i / (sub_d_x - 1) - 1 / 2) - for j in range(0, sub_d_y): - y = meshsize_y * (j / (sub_d_y - 1) - 1 / 2) - if water_plane: - z = water_level - else: - z = landscape_gen(x, y, 0, meshsize_x, meshsize_y, options) - - verts.append((x,y,z)) - - count = 0 - for i in range (0, sub_d_y * (sub_d_x - 1)): - if count < sub_d_y - 1 : - A = i + 1 - B = i - C = (i + sub_d_y) - D = (i + sub_d_y) + 1 - if tri: - faces.append((A, B, D)) - faces.append((B, C, D)) - else: - faces.append((A, B, C, D)) - count = count + 1 - else: - count = 0 - - return verts, faces - - -# Generate UV Sphere -def sphere_gen(sub_d_x, sub_d_y, tri, meshsize, options, water_plane, water_level): - verts = [] - faces = [] - sub_d_x += 1 - sub_d_y += 1 - for i in range(0, sub_d_x): - for j in range(0, sub_d_y): - u = sin(j * pi * 2 / (sub_d_y - 1)) * cos(-pi / 2 + i * pi / (sub_d_x - 1)) * meshsize / 2 - v = cos(j * pi * 2 / (sub_d_y - 1)) * cos(-pi / 2 + i * pi / (sub_d_x - 1)) * meshsize / 2 - w = sin(-pi / 2 + i * pi / (sub_d_x - 1)) * meshsize / 2 - if water_plane: - h = water_level - else: - h = landscape_gen(u, v, w, meshsize, meshsize, options) / meshsize - verts.append(((u + u * h), (v + v * h), (w + w * h))) - - count = 0 - for i in range (0, sub_d_y * (sub_d_x - 1)): - if count < sub_d_y - 1 : - A = i + 1 - B = i - C = (i + sub_d_y) - D = (i + sub_d_y) + 1 - if tri: - faces.append((A, B, D)) - faces.append((B, C, D)) - else: - faces.append((A, B, C, D)) - count = count + 1 - else: - count = 0 - - return verts, faces - - -# ------------------------------------------------------------ -# Z normal value to vertex group (Slope map) -class ANTSlopeVGroup(bpy.types.Operator): - bl_idname = "mesh.ant_slope_vgroup" - bl_label = "Slope Map" - bl_description = "Slope map - z normal value to vertex group weight" - #bl_options = {'REGISTER'} - - z_method = EnumProperty( - name="Method:", - default='SLOPE_Z', - items=[ - ('SLOPE_Z', "Slope Z", "Slope for planar mesh"), - ('SLOPE_XYZ', "Slope XYZ", "Slope for spherical mesh") - ]) - group_name = StringProperty( - name="Vertex Group Name:", - default="Slope", - description="Name" - ) - select_flat = BoolProperty( - name="Vert Select:", - default=True, - description="Select vertices on flat surface" - ) - select_range = FloatProperty( - name="Vert Select Range:", - default=0.0, - min=0.0, - max=1.0, - description="Increase to select more vertices" - ) - - def invoke(self, context, event): - wm = context.window_manager - return wm.invoke_props_dialog(self) - - - def execute(self, context): - message = "Popup Values: %d, %f, %s, %s" % \ - (self.select_flat, self.select_range, self.group_name, self.z_method) - self.report({'INFO'}, message) - - ob = bpy.context.active_object - - if self.select_flat: - bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.mesh.select_all(action='DESELECT') - bpy.context.tool_settings.mesh_select_mode = [True, False, False] - bpy.ops.object.mode_set(mode='OBJECT') - - bpy.ops.object.vertex_group_add() - vg_normal = ob.vertex_groups.active - - for v in ob.data.vertices: - if self.z_method == 'SLOPE_XYZ': - zno = (v.co.normalized() * v.normal.normalized()) * 2 - 1 - else: - zno = v.normal[2] - - vg_normal.add([v.index], zno, 'REPLACE') - - if self.select_flat: - if zno >= (1.0 - self.select_range): - v.select = True - - vg_normal.name = self.group_name - - return {'FINISHED'} - -# ------------------------------------------------------------ -# ------------------------------------------------------------ -# Marble_noise: -def sin_bias(a): - return 0.5 + 0.5 * sin(a) - - -def cos_bias(a): - return 0.5 + 0.5 * cos(a) - - -def tri_bias(a): - b = 2 * pi - a = 1 - 2 * abs(floor((a * (1 / b)) + 0.5) - (a * (1 / b))) - return a - - -def saw_bias(a): - b = 2 * pi - n = int(a / b) - a -= n * b - if a < 0: - a += b - return a / b - - -def soft(a): - return a - - -def sharp(a): - return a**0.5 - - -def sharper(a): - return sharp(sharp(a)) - - -def shapes(x, y, shape=0): - p = pi - if shape is 1: - # ring - x = x * p - y = y * p - s = cos(x**2 + y**2) / (x**2 + y**2 + 0.5) - elif shape is 2: - # swirl - x = x * p - y = y * p - s = ((x * sin(x * x + y * y) + y * cos(x * x + y * y)) / (x**2 + y**2 + 0.5)) - elif shape is 3: - # bumps - x = x * p - y = y * p - s = ((cos(x * p) + cos(y * p)) - 0.5) - elif shape is 4: - # wave - x = x * p * 2 - y = y * p * 2 - s = sin(x + sin(y)) - elif shape is 5: - # y grad. - s = (y * p) - elif shape is 6: - # x grad. - s = (x * p) - else: - # marble default - s = ((x + y) * 5) - return s - - -# marble_noise -def marble_noise(x, y, z, origin, size, shape, bias, sharpnes, turb, depth, hard, basis, amp, freq): - - s = shapes(x, y, shape) - x += origin[0] - y += origin[1] - z += origin[2] - value = s + turb * turbulence_vector((x, y, z), depth, hard, basis)[1] - - if bias is 1: - value = cos_bias(value) - elif bias is 2: - value = tri_bias(value) - elif bias is 3: - value = saw_bias(value) - else: - value = sin_bias(value) - - if sharpnes is 1: - value = 1.0 - sharp(value) - elif sharpnes is 2: - value = 1.0 - sharper(value) - elif sharpnes is 3: - value = soft(value) - elif sharpnes is 4: - value = sharp(value) - elif sharpnes is 5: - value = sharper(value) - else: - value = 1.0 - soft(value) - - return value - -# A.N.T. Noise variations: - -# vl_noise_turbulence: -def vlnTurbMode(coords, distort, basis, vlbasis, hardnoise): - # hard noise - if hardnoise: - return (abs(-variable_lacunarity(coords, distort, basis, vlbasis))) - # soft noise - else: - return variable_lacunarity(coords, distort, basis, vlbasis) - - -def vl_noise_turbulence(coords, distort, depth, basis, vlbasis, hardnoise, amp, freq): - x, y, z = coords - value = vlnTurbMode(coords, distort, basis, vlbasis, hardnoise) - i=0 - for i in range(depth): - i+=1 - value += vlnTurbMode((x * (freq * i), y * (freq * i), z), distort, basis, vlbasis, hardnoise) * (amp * 0.5 / i) - return value - - -## duo_multiFractal: -def double_multiFractal(coords, H, lacunarity, octaves, offset, gain, basis, vlbasis): - x, y, z = coords - n1 = multi_fractal((x * 1.5 + 1, y * 1.5 + 1, z), 1.0, 1.0, 1.0, basis) * (offset * 0.5) - n2 = multi_fractal((x - 1, y - 1, z), H, lacunarity, octaves, vlbasis) * (gain * 0.5) - return (n1 * n1 + n2 * n2) * 0.5 - - -## distorted_heteroTerrain: -def distorted_heteroTerrain(coords, H, lacunarity, octaves, offset, distort, basis, vlbasis): - x, y, z = coords - h1 = (hetero_terrain((x, y, z), 1.0, 2.0, 1.0, 1.0, basis) * 0.5) - h2 = (hetero_terrain((x, y, h1 * distort * 2), H, lacunarity, octaves, offset, vlbasis) * 0.25) - return (h1 * h1 + h2 * h2) * 0.5 - - -## SlickRock: -def slick_rock(coords, H, lacunarity, octaves, offset, gain, distort, basis, vlbasis): - x, y, z = coords - n = multi_fractal((x,y,z), 1.0, 2.0, 2.0, basis) * distort * 0.5 - r = ridged_multi_fractal((x + n, y + n, z + n), H, lacunarity, octaves, offset + 0.1, gain * 2, vlbasis) - return (n + (n * r)) * 0.5 - - -## vlhTerrain -def vl_hTerrain(coords, H, lacunarity, octaves, offset, basis, vlbasis, distort): - x, y, z = coords - ht = hetero_terrain((x, y, z), H, lacunarity, octaves, offset, basis ) * 0.25 - vl = ht * variable_lacunarity((x, y, z), distort, basis, vlbasis) * 0.5 + 0.5 - return vl * ht - - -# another turbulence -def ant_turbulence(coords, depth, hardnoise, nbasis, amp, freq, distortion): - x, y, z = coords - tv = turbulence_vector((x + 1, y + 2, z + 3), depth, hardnoise, nbasis, amp, freq) - d = (distortion * tv[0]) * 0.25 - return (d + ((tv[0] - tv[1]) * (tv[2])**2)) - - -# shattered_hterrain: -def shattered_hterrain(coords, H, lacunarity, octaves, offset, distort, basis): - x, y, z = coords - d = (turbulence_vector(coords, 6, 0, 0)[0] * 0.5 + 0.5) * distort * 0.5 - t1 = (turbulence_vector((x + d, y + d, z), 0, 0, 7)[0] + 0.5) - t2 = (hetero_terrain((x * 2, y * 2, z * 2), H, lacunarity, octaves, offset, basis) * 0.5) - return ((t1 * t2) + t2 * 0.5) * 0.5 - - -# strata_hterrain -def strata_hterrain(coords, H, lacunarity, octaves, offset, distort, basis): - x, y, z = coords - value = hetero_terrain((x, y, z), H, lacunarity, octaves, offset, basis) * 0.5 - steps = (sin(value * (distort * 5) * pi) * (0.1 / (distort * 5) * pi)) - return (value * (1.0 - 0.5) + steps * 0.5) - - -# planet_noise by Farsthary: https://farsthary.com/2010/11/24/new-planet-procedural-texture/ -def planet_noise(coords, oct=6, hard=0, noisebasis=1, nabla=0.001): - x, y, z = coords - d = 0.001 - offset = nabla * 1000 - x = turbulence((x, y, z), oct, hard, noisebasis) - y = turbulence((x + offset, y, z), oct, hard, noisebasis) - z = turbulence((x, y + offset, z), oct, hard, noisebasis) - xdy = x - turbulence((x, y + d, z), oct, hard, noisebasis) - xdz = x - turbulence((x, y, z + d), oct, hard, noisebasis) - ydx = y - turbulence((x + d, y, z), oct, hard, noisebasis) - ydz = y - turbulence((x, y, z + d), oct, hard, noisebasis) - zdx = z - turbulence((x + d, y, z), oct, hard, noisebasis) - zdy = z - turbulence((x, y + d, z), oct, hard, noisebasis) - return (zdy - ydz), (zdx - xdz), (ydx - xdy) - - -# ------------------------------------------------------------ -# landscape_gen -def landscape_gen(x, y, z, meshsize_x, meshsize_y, props): - - rseed = props[0] - nsize = props[1] - ntype = props[2] - nbasis = int(props[3][0]) - vlbasis = int(props[4][0]) - distortion = props[5] - hardnoise = int(props[6]) - depth = props[7] - dimension = props[8] - lacunarity = props[9] - offset = props[10] - gain = props[11] - marblebias = int(props[12][0]) - marblesharpnes = int(props[13][0]) - marbleshape = int(props[14][0]) - invert = props[15] - height = props[16] - heightoffset = props[17] - falloff = int(props[18][0]) - minimum = props[19] - maximum = props[20] - strata = props[21] - stratatype = props[22] - sphere = props[23] - x_offset = props[24] - y_offset = props[25] - edge_level = props[26] - falloffsize_x = props[27] - falloffsize_y = props[28] - size_x = props[29] - size_y = props[30] - amp = props[31] - freq = props[32] - texture_name = props[33] - - # origin - if rseed is 0: - origin = x_offset, y_offset, 0 - origin_x = x_offset - origin_y = y_offset - origin_z = 0 - o_range = 1.0 - else: - # randomise origin - o_range = 10000.0 - seed_set(rseed) - origin = random_unit_vector() - ox = (origin[0] * o_range) - oy = (origin[1] * o_range) - oz = (origin[2] * o_range) - origin_x = (ox - (ox / 2)) + x_offset - origin_y = (oy - (oy / 2)) + y_offset - origin_z = (oz - (oz / 2)) - - ncoords = (x / (nsize * size_x) + origin_x, y / (nsize * size_y) + origin_y, z / nsize + origin_z) - - # noise basis type's - if nbasis == 9: - nbasis = 14 # cellnoise - if vlbasis ==9: - vlbasis = 14 - - # noise type's - if ntype == 'multi_fractal': - value = multi_fractal(ncoords, dimension, lacunarity, depth, nbasis) * 0.5 - - elif ntype == 'ridged_multi_fractal': - value = ridged_multi_fractal(ncoords, dimension, lacunarity, depth, offset, gain, nbasis) * 0.5 - - elif ntype == 'hybrid_multi_fractal': - value = hybrid_multi_fractal(ncoords, dimension, lacunarity, depth, offset, gain, nbasis) * 0.5 - - elif ntype == 'hetero_terrain': - value = hetero_terrain(ncoords, dimension, lacunarity, depth, offset, nbasis) * 0.25 - - elif ntype == 'fractal': - value = fractal(ncoords, dimension, lacunarity, depth, nbasis) - - elif ntype == 'turbulence_vector': - value = turbulence_vector(ncoords, depth, hardnoise, nbasis, amp, freq)[0] - - elif ntype == 'variable_lacunarity': - value = variable_lacunarity(ncoords, distortion, nbasis, vlbasis) - - elif ntype == 'marble_noise': - value = marble_noise( - (ncoords[0] - origin_x + x_offset), - (ncoords[1] - origin_y + y_offset), - (ncoords[2] - origin_z), - (origin[0] + x_offset, origin[1] + y_offset, 0), nsize, - marbleshape, marblebias, marblesharpnes, - distortion, depth, hardnoise, nbasis, amp, freq - ) - elif ntype == 'shattered_hterrain': - value = shattered_hterrain(ncoords, dimension, lacunarity, depth, offset, distortion, nbasis) - - elif ntype == 'strata_hterrain': - value = strata_hterrain(ncoords, dimension, lacunarity, depth, offset, distortion, nbasis) - - elif ntype == 'ant_turbulence': - value = ant_turbulence(ncoords, depth, hardnoise, nbasis, amp, freq, distortion) - - elif ntype == 'vl_noise_turbulence': - value = vl_noise_turbulence(ncoords, distortion, depth, nbasis, vlbasis, hardnoise, amp, freq) - - elif ntype == 'vl_hTerrain': - value = vl_hTerrain(ncoords, dimension, lacunarity, depth, offset, nbasis, vlbasis, distortion) - - elif ntype == 'distorted_heteroTerrain': - value = distorted_heteroTerrain(ncoords, dimension, lacunarity, depth, offset, distortion, nbasis, vlbasis) - - elif ntype == 'double_multiFractal': - value = double_multiFractal(ncoords, dimension, lacunarity, depth, offset, gain, nbasis, vlbasis) - - elif ntype == 'slick_rock': - value = slick_rock(ncoords,dimension, lacunarity, depth, offset, gain, distortion, nbasis, vlbasis) - - elif ntype == 'planet_noise': - value = planet_noise(ncoords, depth, hardnoise, nbasis)[2] * 0.5 + 0.5 - - elif ntype == 'blender_texture': - if texture_name != "" and texture_name in bpy.data.textures: - value = bpy.data.textures[texture_name].evaluate(ncoords)[3] - else: - value = 0.0 - else: - value = 0.0 - - # adjust height - if invert: - value = -value - value = value * height + heightoffset - else: - value = value * height + heightoffset - - # Edge falloff: - if not sphere: - if falloff: - ratio_x, ratio_y = abs(x) * 2 / meshsize_x, abs(y) * 2 / meshsize_y - fallofftypes = [0, - sqrt(ratio_y**falloffsize_y), - sqrt(ratio_x**falloffsize_x), - sqrt(ratio_x**falloffsize_x + ratio_y**falloffsize_y) - ] - dist = fallofftypes[falloff] - value -= edge_level - if(dist < 1.0): - dist = (dist * dist * (3 - 2 * dist)) - value = (value - value * dist) + edge_level - else: - value = edge_level - - # strata / terrace / layers - if stratatype != '0': - strata = strata / height - - if stratatype == '1': - strata *= 2 - steps = (sin(value * strata * pi) * (0.1 / strata * pi)) - value = (value * 0.5 + steps * 0.5) * 2.0 - - elif stratatype == '2': - steps = -abs(sin(value * strata * pi) * (0.1 / strata * pi)) - value = (value * 0.5 + steps * 0.5) * 2.0 - - elif stratatype == '3': - steps = abs(sin(value * strata * pi) * (0.1 / strata * pi)) - value = (value * 0.5 + steps * 0.5) * 2.0 - - elif stratatype == '4': - value = int( value * strata ) * 1.0 / strata - - elif stratatype == '5': - steps = (int( value * strata ) * 1.0 / strata) - value = (value * (1.0 - 0.5) + steps * 0.5) - - # clamp height min max - if (value < minimum): - value = minimum - if (value > maximum): - value = maximum - - return value - - -# ------------------------------------------------------------ -# Add landscape -class landscape_add(bpy.types.Operator): - bl_idname = "mesh.landscape_add" - bl_label = "Landscape" - bl_options = {'REGISTER', 'UNDO', 'PRESET'} - bl_description = "Add landscape mesh" - - # properties - at_cursor = BoolProperty( - name="Cursor", - description="Place at cursor location", - default=True - ) - smooth_mesh = BoolProperty( - name="Smooth", - default=True, - description="Shade smooth" - ) - tri_face = BoolProperty( - name="Triangulate", - default=False, - description="Triangulate faces" - ) - sphere_mesh = BoolProperty( - name="Sphere", - default=False, - description="Generate uv sphere - remove doubles when ready" - ) - subdivision_x = IntProperty( - name="Subdivisions X", - min=4, - max=6400, - default=128, - description="Mesh X subdivisions" - ) - subdivision_y = IntProperty( - name="Subdivisions Y", - min=4, - max=6400, - default=128, - description="Mesh Y subdivisions" - ) - meshsize = FloatProperty( - name="Size", - min=0.01, - max=100000.0, - default=2.0, - description="Mesh size" - ) - meshsize_x = FloatProperty( - name="Size X", - min=0.01, - default=2.0, - description="Mesh x size" - ) - meshsize_y = FloatProperty( - name="Size Y", - min=0.01, - default=2.0, - description="Mesh y size" - ) - - random_seed = IntProperty( - name="Random Seed", - min=0, - default=0, - description="Randomize noise origin" - ) - x_offset = FloatProperty( - name="Offset X", - default=0.0, - description="Noise X Offset" - ) - y_offset = FloatProperty( - name="Offset Y", - default=0.0, - description="Noise Y Offset" - ) - noise_size = FloatProperty( - name="Noise Size", - min=0.01, - max=1000.0, - default=1.0, - description="Noise size" - ) - noise_size_x = FloatProperty( - name="Size X", - min=0.01, - max=1000.0, - default=1.0, - description="Noise x size" - ) - noise_size_y = FloatProperty( - name="Size Y", - min=0.01, - max=1000.0, - default=1.0, - description="Noise y size" - ) - NoiseTypes = [ - ('multi_fractal', "Multi Fractal", "Blender: Multi Fractal algorithm"), - ('ridged_multi_fractal', "Ridged MFractal", "Blender: Ridged Multi Fractal"), - ('hybrid_multi_fractal', "Hybrid MFractal", "Blender: Hybrid Multi Fractal"), - ('hetero_terrain', "Hetero Terrain", "Blender: Hetero Terrain"), - ('fractal', "fBm Fractal", "Blender: fBm - Fractional Browninian motion"), - ('turbulence_vector', "Turbulence", "Blender: Turbulence Vector"), - ('variable_lacunarity', "Distorted Noise", "Blender: Distorted Noise"), - ('marble_noise', "Marble", "A.N.T.: Marble Noise"), - ('shattered_hterrain', "Shattered hTerrain", "A.N.T.: Shattered hTerrain"), - ('strata_hterrain', "Strata hTerrain", "A.N.T: Strata hTerrain"), - ('ant_turbulence', "Another Turbulence", "A.N.T: Turbulence variation"), - ('vl_noise_turbulence', "vlNoise turbulence", "A.N.T: vlNoise turbulence"), - ('vl_hTerrain', "vlNoise hTerrain", "A.N.T: vlNoise hTerrain"), - ('distorted_heteroTerrain', "Distorted hTerrain", "A.N.T distorted hTerrain"), - ('double_multiFractal', "Double MultiFractal", "A.N.T: double multiFractal"), - ('slick_rock', "Slick Rock", "A.N.T: slick rock"), - ('planet_noise', "Planet Noise", "Planet Noise by: Farsthary"), - ('blender_texture', "Blender Texture - Texture Nodes", "Blender texture data block") - ] - noise_type = EnumProperty( - name="Type", - description="Noise type", - default='hetero_terrain', - items=NoiseTypes - ) - BasisTypes = [ - ("0", "Blender", "Blender default noise"), - ("1", "Perlin", "Perlin noise"), - ("2", "New Perlin", "New Perlin noise"), - ("3", "Voronoi F1", "Voronoi F1"), - ("4", "Voronoi F2", "Voronoi F2"), - ("5", "Voronoi F3", "Voronoi F3"), - ("6", "Voronoi F4", "Voronoi F4"), - ("7", "Voronoi F2-F1", "Voronoi F2-F1"), - ("8", "Voronoi Crackle", "Voronoi Crackle"), - ("9", "Cell Noise", "Cell noise") - ] - basis_type = EnumProperty( - name="Basis", - description="Noise basis algorithms", - default="0", - items=BasisTypes - ) - vl_basis_type = EnumProperty( - name="VLBasis", - description="VLNoise basis algorithms", - default="0", - items=BasisTypes - ) - distortion = FloatProperty( - name="Distortion", - min=0.01, - max=100.0, - default=1.0, - description="Distortion amount" - ) - hardTypes = [ - ("0", "Soft", "Soft Noise"), - ("1", "Hard", "Hard noise") - ] - hard_noise = EnumProperty( - name="Soft Hard", - description="Soft Noise, Hard noise", - default="0", - items=hardTypes - ) - noise_depth = IntProperty( - name="Depth", - min=0, - max=16, - default=8, - description="Noise Depth - number of frequencies in the fBm" - ) - amplitude = FloatProperty( - name="Amp", - min=0.01, - max=1.0, - default=0.5, - description="Amplitude" - ) - frequency = FloatProperty( - name="Freq", - min=0.01, - max=5.0, - default=2.0, - description="Frequency" - ) - dimension = FloatProperty( - name="Dimension", - min=0.01, - max=2.0, - default=1.0, - description="H - fractal dimension of the roughest areas" - ) - lacunarity = FloatProperty( - name="Lacunarity", - min=0.01, - max=6.0, - default=2.0, - description="Lacunarity - gap between successive frequencies" - ) - moffset = FloatProperty( - name="Offset", - min=0.01, - max=6.0, - default=1.0, - description="Offset - raises the terrain from sea level" - ) - gain = FloatProperty( - name="Gain", - min=0.01, - max=6.0, - default=1.0, - description="Gain - scale factor" - ) - BiasTypes = [ - ("0", "Sin", "Sin"), - ("1", "Cos", "Cos"), - ("2", "Tri", "Tri"), - ("3", "Saw", "Saw") - ] - marble_bias = EnumProperty( - name="Bias", - description="Marble bias", - default="0", - items=BiasTypes - ) - SharpTypes = [ - ("0", "Soft", "Soft"), - ("1", "Sharp", "Sharp"), - ("2", "Sharper", "Sharper"), - ("3", "Soft inv.", "Soft"), - ("4", "Sharp inv.", "Sharp"), - ("5", "Sharper inv.", "Sharper") - ] - marble_sharp = EnumProperty( - name="Sharp", - description="Marble sharpness", - default="0", - items=SharpTypes - ) - ShapeTypes = [ - ("0", "Default", "Default"), - ("1", "Ring", "Ring"), - ("2", "Swirl", "Swirl"), - ("3", "Bump", "Bump"), - ("4", "Wave", "Wave"), - ("5", "Y", "Y"), - ("6", "X", "X") - ] - marble_shape = EnumProperty( - name="Shape", - description="Marble shape", - default="0", - items=ShapeTypes - ) - height = FloatProperty( - name="Height", - min=-10000.0, - max=10000.0, - default=0.5, - description="Noise intensity scale" - ) - invert = BoolProperty( - name="Invert", - default=False, - ) - offset = FloatProperty( - name="Offset", - min=-10000.0, - max=10000.0, - default=0.0, - description="Height offset" - ) - fallTypes = [ - ("0", "None", "None"), - ("1", "Y", "Y Falloff"), - ("2", "X", "X Falloff"), - ("3", "X Y", "X Y Falloff") - ] - edge_falloff = EnumProperty( - name="Falloff", - description="Flatten edges", - default="3", - items=fallTypes - ) - falloff_size_x = FloatProperty( - name="Falloff X", - min=0.1, - max=100.0, - default=4.0, - description="Falloff x scale" - ) - falloff_size_y = FloatProperty( - name="Falloff Y", - min=0.1, - max=100.0, - default=4.0, - description="Falloff y scale" - ) - edge_level = FloatProperty( - name="Edge Level", - min=-10000.0, - max=10000.0, - default=0.0, - description="Edge level, sealevel offset" - ) - maximum = FloatProperty( - name="Maximum", - min=-10000.0, - max=10000.0, - default=1.0, - description="Maximum, flattens terrain at plateau level" - ) - minimum = FloatProperty( - name="Minimum", - min=-10000.0, - max=10000.0, - default=-0.11, - description="Minimum, flattens terrain at seabed level" - ) - strata = FloatProperty( - name="Amount", - min=0.01, - max=1000.0, - default=5.0, - description="Strata layers / terraces" - ) - StrataTypes = [ - ("0", "None", "No strata"), - ("1", "Smooth", "Smooth transitions"), - ("2", "Sharp -", "Sharp substract transitions"), - ("3", "Sharp +", "Sharp add transitions"), - ("4", "Posterize", "Posterize"), - ("5", "Posterize Mix", "Posterize mixed with noise") - ] - strata_type = EnumProperty( - name="Strata", - description="Strata types", - default="0", - items=StrataTypes - ) - water_plane = BoolProperty( - name="Water Plane", - default=False, - description="Add water plane" - ) - water_level = FloatProperty( - name="Level", - min=-10000.0, - max=10000.0, - default=0.01, - description="Water level" - ) - use_mat = BoolProperty( - name="Material", - default=False, - description="Use material" - ) - sel_land_mat = StringProperty( - name='Terrain', - description="Terrain material" - ) - sel_water_mat = StringProperty( - name='Water', - description="Water material" - ) - show_noise_settings = BoolProperty( - name="Noise Settings", - default=True, - description="Show noise settings" - ) - show_terrain_settings = BoolProperty( - name="Terrain Settings", - default=True, - description="Show terrain settings" - ) - refresh = BoolProperty( - name="Refresh", - description="Refresh", - default=False - ) - auto_refresh = BoolProperty( - name="Auto", - description="Automatic refresh", - default=True - ) - texture_name = StringProperty( - name="Texture", - default="" - ) - - def draw(self, context): - sce = context.scene - layout = self.layout - - box = layout.box() - row = box.row(align=True) - if self.auto_refresh is False: - self.refresh = False - elif self.auto_refresh is True: - self.refresh = True - split = row.split(align=True) - split.prop(self, 'auto_refresh', toggle=True, icon_only=True, icon='AUTO') - split.prop(self, 'refresh', toggle=True, icon_only=True, icon='FILE_REFRESH') - split.prop(self, "at_cursor", toggle=True, icon_only=True, icon='CURSOR') - split.prop(self, "smooth_mesh", toggle=True, icon_only=True, icon='SOLID') - split.prop(self, "tri_face", toggle=True, icon_only=True, icon='MESH_DATA') - split.operator('mesh.ant_slope_vgroup', text="", icon='GROUP_VERTEX') - col = box.column(align=True) - col.prop(self, "sphere_mesh", toggle=True) - col = box.column(align=True) - col.prop(self, "subdivision_x") - col.prop(self, "subdivision_y") - - box = layout.box() - col = box.column(align=False) - col.prop(self, 'use_mat', toggle=True) - if self.use_mat: - col = box.column(align=True) - col.prop_search(self, "sel_land_mat", bpy.data, "materials") - col = box.column(align=True) - if self.water_plane: - col.prop_search(self, "sel_water_mat", bpy.data, "materials") - - box = layout.box() - box.prop(self, "show_noise_settings", toggle=True) - if self.show_noise_settings: - box.prop(self, "noise_type") - if self.noise_type == "blender_texture": - box.prop_search(self, "texture_name", bpy.data, "textures") - else: - box.prop(self, "basis_type") - - col = box.column(align=True) - col.prop(self, "random_seed") - col = box.column(align=True) - col.prop(self, "x_offset") - col.prop(self, "y_offset") - col.prop(self, "noise_size_x") - col.prop(self, "noise_size_y") - col = box.column(align=True) - col.prop(self, "noise_size") - - col = box.column(align=True) - if self.noise_type == "multi_fractal": - col.prop(self, "noise_depth") - col.prop(self, "dimension") - col.prop(self, "lacunarity") - elif self.noise_type == "ridged_multi_fractal": - col.prop(self, "noise_depth") - col.prop(self, "dimension") - col.prop(self, "lacunarity") - col.prop(self, "moffset") - col.prop(self, "gain") - elif self.noise_type == "hybrid_multi_fractal": - col.prop(self, "noise_depth") - col.prop(self, "dimension") - col.prop(self, "lacunarity") - col.prop(self, "moffset") - col.prop(self, "gain") - elif self.noise_type == "hetero_terrain": - col.prop(self, "noise_depth") - col.prop(self, "dimension") - col.prop(self, "lacunarity") - col.prop(self, "moffset") - elif self.noise_type == "fractal": - col.prop(self, "noise_depth") - col.prop(self, "dimension") - col.prop(self, "lacunarity") - elif self.noise_type == "turbulence_vector": - col.prop(self, "noise_depth") - col.prop(self, "amplitude") - col.prop(self, "frequency") - col.separator() - row = col.row(align=True) - row.prop(self, "hard_noise", expand=True) - elif self.noise_type == "variable_lacunarity": - box.prop(self, "vl_basis_type") - box.prop(self, "distortion") - elif self.noise_type == "marble_noise": - box.prop(self, "marble_shape") - box.prop(self, "marble_bias") - box.prop(self, "marble_sharp") - col = box.column(align=True) - col.prop(self, "distortion") - col.prop(self, "noise_depth") - col.separator() - row = col.row(align=True) - row.prop(self, "hard_noise", expand=True) - elif self.noise_type == "shattered_hterrain": - col.prop(self, "noise_depth") - col.prop(self, "dimension") - col.prop(self, "lacunarity") - col.prop(self, "moffset") - col.prop(self, "distortion") - elif self.noise_type == "strata_hterrain": - col.prop(self, "noise_depth") - col.prop(self, "dimension") - col.prop(self, "lacunarity") - col.prop(self, "moffset") - col.prop(self, "distortion", text="Strata") - elif self.noise_type == "ant_turbulence": - col.prop(self, "noise_depth") - col.prop(self, "amplitude") - col.prop(self, "frequency") - col.prop(self, "distortion") - col.separator() - row = col.row(align=True) - row.prop(self, "hard_noise", expand=True) - elif self.noise_type == "vl_noise_turbulence": - col.prop(self, "noise_depth") - col.prop(self, "amplitude") - col.prop(self, "frequency") - col.prop(self, "distortion") - col.separator() - col.prop(self, "vl_basis_type") - col.separator() - row = col.row(align=True) - row.prop(self, "hard_noise", expand=True) - elif self.noise_type == "vl_hTerrain": - col.prop(self, "noise_depth") - col.prop(self, "dimension") - col.prop(self, "lacunarity") - col.prop(self, "moffset") - col.prop(self, "distortion") - col.separator() - col.prop(self, "vl_basis_type") - elif self.noise_type == "distorted_heteroTerrain": - col.prop(self, "noise_depth") - col.prop(self, "dimension") - col.prop(self, "lacunarity") - col.prop(self, "moffset") - col.prop(self, "distortion") - col.separator() - col.prop(self, "vl_basis_type") - elif self.noise_type == "double_multiFractal": - col.prop(self, "noise_depth") - col.prop(self, "dimension") - col.prop(self, "lacunarity") - col.prop(self, "moffset") - col.prop(self, "gain") - col.separator() - col.prop(self, "vl_basis_type") - elif self.noise_type == "slick_rock": - col.prop(self, "noise_depth") - col.prop(self, "dimension") - col.prop(self, "lacunarity") - col.prop(self, "gain") - col.prop(self, "moffset") - col.prop(self, "distortion") - col.separator() - col.prop(self, "vl_basis_type") - elif self.noise_type == "planet_noise": - col.prop(self, "noise_depth") - col.separator() - row = col.row(align=True) - row.prop(self, "hard_noise", expand=True) - - box = layout.box() - box.prop(self, "show_terrain_settings", toggle=True) - if self.show_terrain_settings: - col = box.column(align=True) - if self.sphere_mesh: - col.prop(self, "meshsize") - else: - col.prop(self, "meshsize_x") - col.prop(self, "meshsize_y") - - col = box.column(align=True) - row = col.row(align=True).split(0.9, align=True) - row.prop(self, "height") - row.prop(self, "invert", toggle=True, text="", icon='ARROW_LEFTRIGHT') - col.prop(self, "offset") - col.prop(self, "maximum") - col.prop(self, "minimum") - - if not self.sphere_mesh: - col = box.column(align=False) - col.prop(self, "edge_falloff") - if self.edge_falloff is not "0": - col = box.column(align=True) - col.prop(self, "edge_level") - if self.edge_falloff in ["2", "3"]: - col.prop(self, "falloff_size_x") - if self.edge_falloff in ["1", "3"]: - col.prop(self, "falloff_size_y") - - col = box.column(align=False) - col.prop(self, "strata_type") - if self.strata_type is not "0": - col = box.column(align=False) - col.prop(self, "strata") - - col = box.column(align=False) - col.prop(self, "water_plane", toggle=True) - if self.water_plane is True: - col = box.column(align=False) - col.prop(self, "water_level") - - - def invoke(self, context, event): - self.refresh = True - return self.execute(context) - - - def execute(self, context): - if not self.refresh: - return {'PASS_THROUGH'} - - # turn off undo - undo = bpy.context.user_preferences.edit.use_global_undo - bpy.context.user_preferences.edit.use_global_undo = False - # deselect all objects when in object mode - if bpy.ops.object.select_all.poll(): - bpy.ops.object.select_all(action='DESELECT') - - scene = context.scene - # settings - props = [ - self.random_seed, - self.noise_size, - self.noise_type, - self.basis_type, - self.vl_basis_type, - self.distortion, - self.hard_noise, - self.noise_depth, - self.dimension, - self.lacunarity, - self.moffset, - self.gain, - self.marble_bias, - self.marble_sharp, - self.marble_shape, - self.invert, - self.height, - self.offset, - self.edge_falloff, - self.minimum, - self.maximum, - self.strata, - self.strata_type, - self.sphere_mesh, - self.x_offset, - self.y_offset, - self.edge_level, - self.falloff_size_x, - self.falloff_size_y, - self.noise_size_x, - self.noise_size_y, - self.amplitude, - self.frequency, - self.texture_name - ] - - # Main function, create landscape mesh object - if self.sphere_mesh: - # sphere - verts, faces = sphere_gen(self.subdivision_y, self.subdivision_x, self.tri_face, self.meshsize, props, False, 0.0) - lobj = create_mesh_object(context, verts, [], faces, "Landscape") - else: - # grid - verts, faces = grid_gen(self.subdivision_x, self.subdivision_y, self.tri_face, self.meshsize_x, self.meshsize_y, props, False, 0.0) - lobj = create_mesh_object(context, verts, [], faces, "Landscape") - - if self.smooth_mesh: - bpy.ops.object.shade_smooth() - - if not self.at_cursor: - lobj.object.location = (0.0, 0.0, 0.0) - - # Landscape Material - if self.use_mat: - if self.sel_land_mat != "" and self.sel_land_mat in bpy.data.materials: - mat = bpy.data.materials[self.sel_land_mat] - bpy.context.object.data.materials.append(mat) - - # Water plane - if self.water_plane: - if self.sphere_mesh: - # sphere - verts, faces = sphere_gen(self.subdivision_y, self.subdivision_x, self.tri_face, self.meshsize, props, self.water_plane, self.water_level) - wobj = create_mesh_object(context, verts, [], faces, "Water") - else: - # grid - verts, faces = grid_gen(2, 2, self.tri_face, self.meshsize_x, self.meshsize_y, props, self.water_plane, self.water_level) - wobj = create_mesh_object(context, verts, [], faces, "Water") - - wobj.object.select = True - if self.smooth_mesh: - bpy.ops.object.shade_smooth() - - if not self.at_cursor: - wobj.object.location = (0.0, 0.0, 0.0) - - # Water Material - if self.use_mat: - if self.sel_water_mat != "" and self.sel_water_mat in bpy.data.materials: - mat = bpy.data.materials[self.sel_water_mat] - bpy.context.object.data.materials.append(mat) - - # select landscape and make active - lobj.object.select = True - scene.objects.active = lobj.object - # - if self.auto_refresh is False: - self.refresh = False - - # restore pre operator undo state - context.user_preferences.edit.use_global_undo = undo - - return {'FINISHED'} - - -# ------------------------------------------------------------ -# Register: - -# Define "Landscape" menu -def menu_func_landscape(self, context): - self.layout.operator(landscape_add.bl_idname, text="Landscape", icon="RNDCURVE") - - -def register(): - bpy.utils.register_module(__name__) - bpy.types.INFO_MT_mesh_add.append(menu_func_landscape) - #bpy.utils.register_class(ANTSlopeVGroup) - - -def unregister(): - bpy.utils.unregister_module(__name__) - bpy.types.INFO_MT_mesh_add.remove(menu_func_landscape) - #bpy.utils.unregister_class(ANTSlopeVGroup) - - -if __name__ == "__main__": - register() diff --git a/add_mesh_extra_objects/Blocks.py b/add_mesh_extra_objects/Blocks.py index f798cf52..bade30d0 100644 --- a/add_mesh_extra_objects/Blocks.py +++ b/add_mesh_extra_objects/Blocks.py @@ -1,4 +1,4 @@ -# GPL # "author": +# GPL # "authors": dudecon, jambay # Module notes: # @@ -8,87 +8,150 @@ # auto-clip wall edge to SMALL for radial and domes. # unregister doesn't release all references. # repeat for opening doesn't distribute evenly when radialized - see wrap around -# note above. +# note above. # if opening width == indent*2 the edge blocks fail (row of blocks cross opening). # if openings overlap fills inverse with blocks - see h/v slots. # Negative grout width creates a pair of phantom blocks, seperated by grout -# width, inside the edges. -# if block width variance is 0, and edging is on, right edge blocks create a "vertical seam". +# width, inside the edges. +# if block width variance is 0, and edging is on, right edge blocks create a "vertical seam" import bpy from random import random -from math import fmod, sqrt, sin, cos, atan, pi as PI +from math import ( + fmod, sqrt, + sin, cos, atan, + pi as PI, + ) + +# Set to True to enable debug_prints +DEBUG = False # A few constants SMALL = 0.000000000001 -NOTZERO = 0.01 # for values that must be != 0; see UI options/variables - sort of a bug to be fixed. +# for values that must be != 0; see UI options/variables - sort of a bug to be fixed +NOTZERO = 0.01 -# global variables +# Global variables # General masonry Settings -settings = {'w': 1.2, 'wv': 0.3, 'h': .6, 'hv': 0.3, 'd': 0.3, 'dv': 0.1, - 'g': 0.1, 'gv': 0.07, 'gd': 0.01, 'gdv': 0.0, 'b': 0, 'bv': 0, - 'f': 0.0, 'fv': 0.0, 't': 0.0, 'sdv': 0.1, 'hwt': 0.5, 'aln': 0, - 'wm': 0.8, 'hm': 0.3, 'dm': 0.1, - 'woff': 0.0, 'woffv': 0.0, 'eoff': 0.3, 'eoffv': 0.0, 'rwhl': 1, - 'hb': 0, 'ht': 0, 'ge': 0, 'physics': 0} -# 'w':width 'wv':widthVariation -# 'h':height 'hv':heightVariation -# 'd':depth 'dv':depthVariation -# 'g':grout 'gv':groutVariation 'gd':groutDepth 'gdv':groutDepthVariation -# 'b':bevel 'bv':bevelVariation -# 'f':flawSize 'fv':flawSizeVariation 'ff':flawFraction -# 't':taper -# 'sdv':subdivision(distance or angle) -# 'hwt':row height effect on block widths in the row (0=no effect, -# 1=1:1 relationship, negative values allowed, 0.5 works well) -# 'aln':alignment(0=none, 1=rows w/features, 2=features w/rows) -# (currently un-used) -# 'wm':width minimum 'hm':height minimum 'dm':depth minimum -# 'woff':row start offset(fraction of width) -# 'woffv':width offset variation(fraction of width) -# 'eoff':edge offset 'eoffv':edge offset variation -# 'rwhl':row height lock(1 is all blocks in row have same height) -# 'hb':bottom row height 'ht': top row height 'ge': grout the edges -# 'physics': set up for physics +# ------------------------ +settings = { + 'w': 1.2, 'wv': 0.3, 'h': .6, 'hv': 0.3, 'd': 0.3, 'dv': 0.1, + 'g': 0.1, 'gv': 0.07, 'gd': 0.01, 'gdv': 0.0, 'b': 0, 'bv': 0, + 'f': 0.0, 'fv': 0.0, 't': 0.0, 'sdv': 0.1, 'hwt': 0.5, 'aln': 0, + 'wm': 0.8, 'hm': 0.3, 'dm': 0.1, + 'woff': 0.0, 'woffv': 0.0, 'eoff': 0.3, 'eoffv': 0.0, 'rwhl': 1, + 'hb': 0, 'ht': 0, 'ge': 0, 'physics': 0 + } +""" + settings DOCUMENTATION: + 'w':width 'wv':widthVariation + 'h':height 'hv':heightVariation + 'd':depth 'dv':depthVariation + 'g':grout 'gv':groutVariation 'gd':groutDepth 'gdv':groutDepthVariation + 'b':bevel 'bv':bevelVariation + 'f':flawSize 'fv':flawSizeVariation 'ff':flawFraction + 't':taper + 'sdv':subdivision(distance or angle) + 'hwt':row height effect on block widths in the row (0=no effect, + 1=1:1 relationship, negative values allowed, 0.5 works well) + 'aln':alignment(0=none, 1=rows w/features, 2=features w/rows) + (currently unused) + 'wm':width minimum 'hm':height minimum 'dm':depth minimum + 'woff':row start offset(fraction of width) + 'woffv':width offset variation(fraction of width) + 'eoff':edge offset 'eoffv':edge offset variation + 'rwhl':row height lock(1 is all blocks in row have same height) + 'hb':bottom row height 'ht': top row height 'ge': grout the edges + 'physics': set up for physics +""" # dims = area of wall (face) -dims = {'s': 0, 'e': PI * 3 / 2, 'b': 0.1, 't': 12.3} # radial -# 's':start x or theta 'e':end x or theta 'b':bottom z or r 't':top z or r -# 'w' = e-s and h = t-b; calculated to optimize for various operations/usages -# dims = {'s':-12, 'e':15, 'w':27, 'b':-15., 't':15., 'h':30} -# dims = {'s':-bayDim/2, 'e':bayDim/2, 'b':-5., 't':10.} # bay settings? - +# ------------------------ +dims = { + 's': 0, 'e': PI * 3 / 2, 'b': 0.1, 't': 12.3 + } # radial +""" + dims DOCUMENTATION: + 's':start x or theta 'e':end x or theta 'b':bottom z or r 't':top z or r + 'w' = e-s and h = t-b; calculated to optimize for various operations/usages + dims = {'s':-12, 'e':15, 'w':27, 'b':-15., 't':15., 'h':30} + dims = {'s':-bayDim/2, 'e':bayDim/2, 'b':-5., 't':10.} # bay settings? +""" + +# ------------------------ radialized = 0 # Radiating from one point - round/disc; instead of square -slope = 0 # Warp/slope; curved over like a vaulted tunnel +slope = 0 # Warp/slope; curved over like a vaulted tunnel + # 'bigblock': merge adjacent blocks into single large blocks -bigBlock = 0 # Merge blocks +bigBlock = 0 # Merge blocks -# Gaps in blocks for various apertures. + +# Gaps in blocks for various apertures +# ------------------------ # openingSpecs = [] -openingSpecs = [{'w': 0.5, 'h': 0.5, 'x': 0.8, 'z': 2.7, 'rp': 1, 'b': 0.0, - 'v': 0, 'vl': 0, 't': 0, 'tl': 0}] -# 'w': opening width, 'h': opening height, -# 'x': horizontal position, 'z': vertical position, -# 'rp': make multiple openings, with a spacing of x, -# 'b': bevel the opening, inside only, like an arrow slit. -# 'v': height of the top arch, 'vl':height of the bottom arch, -# 't': thickness of the top arch, 'tl': thickness of the bottom arch - -# Add blocks to make platforms. +openingSpecs = [ + {'w': 0.5, 'h': 0.5, 'x': 0.8, 'z': 2.7, 'rp': 1, 'b': 0.0, + 'v': 0, 'vl': 0, 't': 0, 'tl': 0} + ] +""" + openingSpecs DOCUMENTATION: + 'w': opening width, 'h': opening height, + 'x': horizontal position, 'z': vertical position, + 'rp': make multiple openings, with a spacing of x, + 'b': bevel the opening, inside only, like an arrow slit. + 'v': height of the top arch, 'vl':height of the bottom arch, + 't': thickness of the top arch, 'tl': thickness of the bottom arch +""" + +# Add blocks to make platforms +# ------------------------ shelfExt = 0 -shelfSpecs = {'w': 0.5, 'h': 0.5, 'd': 0.3, 'x': 0.8, 'z': 2.7} -# 'w': block width, 'h': block height, 'd': block depth (shelf size; offset from wall) -# 'x': horizontal start position, 'z': vertical start position -# Add blocks to make steps. +shelfSpecs = { + 'w': 0.5, 'h': 0.5, 'd': 0.3, 'x': 0.8, 'z': 2.7 + } +""" + shelfSpecs DOCUMENTATION: + 'w': block width, 'h': block height, 'd': block depth (shelf size; offset from wall) + 'x': horizontal start position, 'z': vertical start position +""" + +# Add blocks to make steps +# ------------------------ stepMod = 0 -stepSpecs = {'x': 0.0, 'z': -10, 'w': 10.0, 'h': 10.0, - 'v': 0.7, 't': 1.0, 'd': 1.0} -# 'x': horizontal start position, 'z': vertical start position, -# 'w': step area width, 'h': step area height, -# 'v': riser height, 't': tread width, 'd': block depth (step size; offset from wall) + +stepSpecs = { + 'x': 0.0, 'z': -10, 'w': 10.0, 'h': 10.0, + 'v': 0.7, 't': 1.0, 'd': 1.0 + } +""" + stepSpecs DOCUMENTATION: + 'x': horizontal start position, 'z': vertical start position, + 'w': step area width, 'h': step area height, + 'v': riser height, 't': tread width, 'd': block depth (step size; offset from wall) +""" +stepLeft = 0 +shelfBack = 0 +stepOnly = 0 +stepBack = 0 + + +# switchable prints +def debug_prints(func="", text="Message", var=None): + global DEBUG + if DEBUG: + print("\n[{}]\nmessage: {}".format(func, text)) + if var: + print("Error: ", var) + + +# pass variables just like for the regular prints +def debug_print_vars(*args, **kwargs): + global DEBUG + if DEBUG: + print(*args, **kwargs) # easier way to get to the random function @@ -126,6 +189,7 @@ def test(TestN=13): 't': float(t), 'tl': float(tl)}] return dims, openingSpecs + # dims, openingSpecs = test(15) @@ -290,7 +354,8 @@ def MakeABlock(bounds, segsize, vll=0, Offsets=None, FaceExclude=[], def MakeAKeystone(xpos, width, zpos, ztop, zbtm, thick, bevel, vll=0, FaceExclude=[], xBevScl=1): __doc__ = """\ - MakeAKeystone returns lists of points and faces to be made into a square cornered keystone, with optional bevels. + MakeAKeystone returns lists of points and faces to be made into a + square cornered keystone, with optional bevels. xpos: x position of the centerline width: x width of the keystone at the widest point (discounting bevels) zpos: z position of the widest point @@ -299,7 +364,8 @@ def MakeAKeystone(xpos, width, zpos, ztop, zbtm, thick, bevel, vll=0, FaceExclud thick: thickness bevel: the amount to raise the back vertex to account for arch beveling vll: the number of vertexes already in the mesh. len(mesh.verts) should give this number - faceExclude: list of faces to exclude from the faces list. 0:left, 1:right, 2:bottom, 3:top, 4:back, 5:front + faceExclude: list of faces to exclude from the faces list. + 0:left, 1:right, 2:bottom, 3:top, 4:back, 5:front xBevScl: how much to divide the end (+- x axis) bevel dimensions. Set to current average radius to compensate for angular distortion on curved blocks """ @@ -427,6 +493,7 @@ class opening: # ht is the z position; s is the side: 1 for right, -1 for left # if the height passed is above or below the opening, return None def edgeS(self, ht, s): + # set the row radius: 1 for standard wall (flat) if radialized: if slope: @@ -496,6 +563,7 @@ class opening: # get the top or bottom of the opening # ht is the x position; s is the side: 1 for top, -1 for bottom def edgeV(self, ht, s): + dist = abs(self.x - ht) def radialAdjust(dist, sideVal): @@ -556,9 +624,11 @@ class opening: else: return self.z - self.h / 2 - self.vl + self.rl - circVal - # and this never happens - but, leave it as failsafe :) - print("got all the way out of the edgeV! Not good!") - print("opening x = ", self.x, ", opening z = ", self.z) + # and this never happens - but, leave it as failsafe :) + debug_prints(func="opening.EdgeV", + text="Got all the way out of the edgeV! Not good!") + debug_print_vars("opening x = ", self.x, ", opening z = ", self.z) + return 0.0 def edgeBev(self, ht): @@ -618,11 +688,9 @@ class opening: # class for the whole wall boundaries; a sub-class of "opening" - -class OpeningInv(opening): +class openingInvert(opening): # this is supposed to switch the sides of the opening # so the wall will properly enclose the whole wall. - # We'll see if it works. def edgeS(self, ht, s): return opening.edgeS(self, ht, -s) @@ -776,8 +844,10 @@ def arch(ra, rt, x, z, archStart, archEnd, bevel, bevAngle, vll): else: ThisOffset = offsets - geom = MakeABlock([divs[i] + grt, divs[i + 1] - grt, ArchInner, ArchOuter, DepthBack, DepthFront], - subdivision, len(avlist) + vll, ThisOffset, [], None, ra) + geom = MakeABlock( + [divs[i] + grt, divs[i + 1] - grt, ArchInner, ArchOuter, DepthBack, DepthFront], + subdivision, len(avlist) + vll, ThisOffset, [], None, ra + ) avlist += geom[0] aflist += geom[1] @@ -929,6 +999,7 @@ def rowProcessing(row, Thesketch, WallBoundaries): # initially just the left and right edge of the wall edgetop = [[dims['s'] + row.EdgeOffset / r1 + edgrt, WallBoundaries], [dims['e'] + row.EdgeOffset / r1 - edgrt, WallBoundaries]] + # Same as edgetop, but for the bottms of the rows edgebtm = [[dims['s'] + row.EdgeOffset / r1 + edgrt, WallBoundaries], [dims['e'] + row.EdgeOffset / r1 - edgrt, WallBoundaries]] @@ -959,9 +1030,17 @@ def rowProcessing(row, Thesketch, WallBoundaries): # We want to make the walls in order, so sort the intersects. # This is where you would want to remove edge points that are out of order - # so that you don't get the "oddity where overlapping openings create blocks inversely" problem - edgetop.sort() - edgebtm.sort() + # so that you don't get the "oddity where overlapping openings + # create blocks inversely" problem + + # Note: sort ended up comparing function pointers + # if both Openings and Slots were enabled with Repeats in one of them + try: + edgetop.sort(key=lambda x: x[0]) + edgebtm.sort(key=lambda x: x[0]) + except Exception as ex: + debug_prints(func="rowProcessing", + text="Sorting has failed", var=ex) # these two loops trim the edges to the limits of the wall. # This way openings extending outside the wall don't enlarge the wall. @@ -1232,7 +1311,7 @@ def plan(Thesketch, oldrows=0): z = (dims['t'] + dims['b']) / 2 w = (dims['e'] - dims['s']) h = (dims['t'] - dims['b']) - WallBoundaries = OpeningInv(x, z, w, h) + WallBoundaries = openingInvert(x, z, w, h) # Go over each row in the list, set up edge blocks and block sections for rownum in range(len(rows)): @@ -1348,7 +1427,8 @@ def archGeneration(hole, vlist, flist, sideSign): flist += aflist # remove "debug note" once bevel is finalized. else: - print("keystone was too narrow - " + str(Wdth)) + debug_prints(func="archGeneration", + text="Keystone was too narrow - " + str(Wdth)) else: # only one arc - curve not peak. # bottom (sideSign -1) arch has poorly sized blocks... @@ -1409,8 +1489,11 @@ def archGeneration(hole, vlist, flist, sideSign): # Do some stuff to incorporate bev here bevelBlockOffsets(offsets, bev, -1) - avlist, aflist = MakeABlock([x - xstart - width, x - xstart - woffset, btmSide, topSide, - - depth / 2, depth / 2], subdivision, len(vlist), Offsets=offsets, xBevScl=1) + avlist, aflist = MakeABlock( + [x - xstart - width, x - xstart - woffset, btmSide, topSide, + -depth / 2, depth / 2], subdivision, len(vlist), + Offsets=offsets, xBevScl=1 + ) # top didn't use radialized in prev version; # just noting for clarity - may need to revise for "sideSign == 1" @@ -1439,8 +1522,11 @@ def archGeneration(hole, vlist, flist, sideSign): # Do some stuff to incorporate bev here bevelBlockOffsets(offsets, bev, 1) - avlist, aflist = MakeABlock([x + xstart + woffset, x + xstart + width, btmSide, topSide, - -depth / 2, depth / 2], subdivision, len(vlist), Offsets=offsets, xBevScl=1) + avlist, aflist = MakeABlock( + [x + xstart + woffset, x + xstart + width, btmSide, topSide, + -depth / 2, depth / 2], subdivision, len(vlist), + Offsets=offsets, xBevScl=1 + ) # top didn't use radialized in prev version; # just noting for clarity - may need to revise for "sideSign == 1" @@ -1544,11 +1630,19 @@ def build(Aplan): # - this way no gaps between platform and wall face due to wall block depth. wallDepth = settings['d'] / 2 # offset by wall depth so step depth matches UI setting :) if shelfBack: # place blocks on backside of wall - ShelfOffsets = [[0, ShelfThk / 2, 0], [0, wallDepth, 0], [0, ShelfThk / 2, 0], [0, wallDepth, 0], - [0, ShelfThk / 2, 0], [0, wallDepth, 0], [0, ShelfThk / 2, 0], [0, wallDepth, 0]] + ShelfOffsets = [ + [0, ShelfThk / 2, 0], [0, wallDepth, 0], + [0, ShelfThk / 2, 0], [0, wallDepth, 0], + [0, ShelfThk / 2, 0], [0, wallDepth, 0], + [0, ShelfThk / 2, 0], [0, wallDepth, 0] + ] else: - ShelfOffsets = [[0, -wallDepth, 0], [0, -ShelfThk / 2, 0], [0, -wallDepth, 0], [0, -ShelfThk / 2, 0], - [0, -wallDepth, 0], [0, -ShelfThk / 2, 0], [0, -wallDepth, 0], [0, -ShelfThk / 2, 0]] + ShelfOffsets = [ + [0, -wallDepth, 0], [0, -ShelfThk / 2, 0], + [0, -wallDepth, 0], [0, -ShelfThk / 2, 0], + [0, -wallDepth, 0], [0, -ShelfThk / 2, 0], + [0, -wallDepth, 0], [0, -ShelfThk / 2, 0] + ] # Add blocks for each "shelf row" in area while ShelfBtm < ShelfTop: @@ -1591,11 +1685,19 @@ def build(Aplan): # Also, will work fine as stand-alone if not used with wall (try block depth 0 and see what happens). wallDepth = settings['d'] / 2 if stepBack: # place blocks on backside of wall - StepOffsets = [[0, StepThk / 2, 0], [0, wallDepth, 0], [0, StepThk / 2, 0], [0, wallDepth, 0], - [0, StepThk / 2, 0], [0, wallDepth, 0], [0, StepThk / 2, 0], [0, wallDepth, 0]] + StepOffsets = [ + [0, StepThk / 2, 0], [0, wallDepth, 0], + [0, StepThk / 2, 0], [0, wallDepth, 0], + [0, StepThk / 2, 0], [0, wallDepth, 0], + [0, StepThk / 2, 0], [0, wallDepth, 0] + ] else: - StepOffsets = [[0, -wallDepth, 0], [0, -StepThk / 2, 0], [0, -wallDepth, 0], [0, -StepThk / 2, 0], - [0, -wallDepth, 0], [0, -StepThk / 2, 0], [0, -wallDepth, 0], [0, -StepThk / 2, 0]] + StepOffsets = [ + [0, -wallDepth, 0], [0, -StepThk / 2, 0], + [0, -wallDepth, 0], [0, -StepThk / 2, 0], + [0, -wallDepth, 0], [0, -StepThk / 2, 0], + [0, -wallDepth, 0], [0, -StepThk / 2, 0] + ] # Add steps for each "step row" in area (neg width is interesting but prevented) while StepBtm < StepTop and StepWide > 0: @@ -1645,7 +1747,8 @@ def build(Aplan): else: r1 = 1 - geom = MakeABlock([x - w / 2, x + w / 2, z - h / 2, z + h / 2, -d / 2, d / 2], settings['sdv'], len(vlist), + geom = MakeABlock([x - w / 2, x + w / 2, z - h / 2, z + h / 2, -d / 2, d / 2], + settings['sdv'], len(vlist), corners, None, settings['b'] + rndd() * settings['bv'], r1) vlist += geom[0] flist += geom[1] diff --git a/add_mesh_extra_objects/Wallfactory.py b/add_mesh_extra_objects/Wallfactory.py index a58b9f5a..41957b22 100644 --- a/add_mesh_extra_objects/Wallfactory.py +++ b/add_mesh_extra_objects/Wallfactory.py @@ -1,4 +1,4 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** +# ##### BEGIN GPL LICENSE BLOCK ##### # # This program is free software; you may redistribute it, and/or # modify it, under the terms of the GNU General Public License @@ -19,22 +19,43 @@ # # or go online at: http://www.gnu.org/licenses/ to view license options. # -# ***** END GPL LICENCE BLOCK ***** +# ##### END GPL LICENCE BLOCK ##### -# This module contains the UI definition, display, and processing (create mesh) -# functions. -# The routines to generate the vertices for the wall are found in the "Blocks" module. +# authors: dudecon, jambay + +# This module contains the UI definition, display, +# and processing (create mesh) functions. +# The routines to generate the vertices for the wall +# are found in the "Blocks" module. import bpy +from bpy.types import Operator from bpy.props import ( BoolProperty, FloatProperty, ) -from add_mesh_extra_objects.Blocks import * +from .Blocks import ( + NOTZERO, PI, + dims, + settings, + shelfSpecs, + stepSpecs, + createWall, + radialized, + slope, + openingSpecs, + bigBlock, + shelfExt, + stepMod, + stepLeft, + shelfBack, + stepOnly, + stepBack, + ) -class add_mesh_wallb(bpy.types.Operator): +class add_mesh_wallb(Operator): bl_idname = "mesh.wall_add" bl_label = "Add a Masonry Wall" bl_description = "Create a block (masonry) wall mesh" @@ -46,402 +67,407 @@ class add_mesh_wallb(bpy.types.Operator): # only create object when True # False allows modifying several parameters without creating object ConstructTog = BoolProperty( - name="Construct", - description="Generate the object", - default=True - ) - # need to modify so radial makes a tower (normal); want "flat" setting to make disk (alternate) + name="Construct", + description="Generate the object", + default=True + ) + # need to modify so radial makes a tower (normal); + # want "flat" setting to make disk (alternate) # make the wall circular - if not sloped it's a flat disc RadialTog = BoolProperty( - name="Radial", - description="Make masonry radial", - default=False - ) + name="Radial", + description="Make masonry radial", + default=False + ) # curve the wall - if radial creates dome. SlopeTog = BoolProperty( - name="Curved", - description="Make masonry sloped, or curved", - default=False - ) + name="Curved", + description="Make masonry sloped, or curved", + default=False + ) # need to review defaults and limits for all of these UI objects # wall area/size WallStart = FloatProperty( - name="Start", - description="Left side, or start angle", - default=-10.0, - min=-100, max=100.0 - ) + name="Start", + description="Left side, or start angle", + default=-10.0, + min=-100, max=100.0 + ) WallEnd = FloatProperty( - name="End", - description="Right side, or end angle", - default=10.0, - min=0.0, max=100.0 - ) + name="End", + description="Right side, or end angle", + default=10.0, + min=0.0, max=100.0 + ) WallBottom = FloatProperty( - name="Bottom", - description="Lower height or radius", - default=0.0, - min=-100, max=100 - ) + name="Bottom", + description="Lower height or radius", + default=0.0, + min=-100, max=100 + ) WallTop = FloatProperty( - name="Top", - description="Upper height or radius", - default=15.0, - min=0.0, max=100.0 - ) + name="Top", + description="Upper height or radius", + default=15.0, + min=0.0, max=100.0 + ) EdgeOffset = FloatProperty( - name="Edging", - description="Block staggering on wall sides", - default=0.6, min=0.0, max=100.0 - ) + name="Edging", + description="Block staggering on wall sides", + default=0.6, min=0.0, max=100.0 + ) # block sizing Width = FloatProperty( - name="Width", - description="Average width of each block", - default=1.5, - min=0.01, max=100.0 - ) + name="Width", + description="Average width of each block", + default=1.5, + min=0.01, max=100.0 + ) WidthVariance = FloatProperty( - name="Variance", - description="Random variance of block width", - default=0.5, - min=0.0, max=100.0 - ) + name="Variance", + description="Random variance of block width", + default=0.5, + min=0.0, max=100.0 + ) WidthMinimum = FloatProperty( - name="Minimum", - description="Absolute minimum block width", - default=0.5, - min=0.01, max=100.0 - ) + name="Minimum", + description="Absolute minimum block width", + default=0.5, + min=0.01, max=100.0 + ) Height = FloatProperty( - name="Height", - description="Average Height of each block", - default=0.7, - min=0.01, max=100.0 - ) + name="Height", + description="Average Height of each block", + default=0.7, + min=0.01, max=100.0 + ) HeightVariance = FloatProperty( - name="Variance", - description="Random variance of block Height", - default=0.3, - min=0.0, max=100.0 - ) + name="Variance", + description="Random variance of block Height", + default=0.3, + min=0.0, max=100.0 + ) HeightMinimum = FloatProperty( - name="Minimum", - description="Absolute minimum block Height", - default=0.25, - min=0.01, max=100.0 - ) + name="Minimum", + description="Absolute minimum block Height", + default=0.25, + min=0.01, max=100.0 + ) Depth = FloatProperty( - name="Depth", - description="Average Depth of each block", - default=2.0, - min=0.01, max=100.0 - ) + name="Depth", + description="Average Depth of each block", + default=2.0, + min=0.01, max=100.0 + ) DepthVariance = FloatProperty( - name="Variance", - description="Random variance of block Depth", - default=0.1, - min=0.0, max=100.0 - ) + name="Variance", + description="Random variance of block Depth", + default=0.1, + min=0.0, max=100.0 + ) DepthMinimum = FloatProperty( - name="Minimum", - description="Absolute minimum block Depth", - default=1.0, - min=0.01, max=100.0 - ) + name="Minimum", + description="Absolute minimum block Depth", + default=1.0, + min=0.01, max=100.0 + ) MergeBlock = BoolProperty( - name="Merge Blocks", - description="Make big blocks (merge closely adjoining blocks)", - default=False - ) + name="Merge Blocks", + description="Make big blocks (merge closely adjoining blocks)", + default=False + ) # edging for blocks Grout = FloatProperty( - name="Thickness", - description="Distance between blocks", - default=0.1, - min=-10.0, max=10.0 - ) + name="Thickness", + description="Distance between blocks", + default=0.1, + min=-10.0, max=10.0 + ) GroutVariance = FloatProperty( - name="Variance", - description="Random variance of block Grout", - default=0.03, - min=0.0, max=100.0) + name="Variance", + description="Random variance of block Grout", + default=0.03, + min=0.0, max=100.0 + ) GroutDepth = FloatProperty( - name="Depth", - description="Grout Depth from the face of the blocks", - default=0.1, - min=0.0001, max=10.0 - ) + name="Depth", + description="Grout Depth from the face of the blocks", + default=0.1, + min=0.0001, max=10.0 + ) GroutDepthVariance = FloatProperty( - name="Variance", - description="Random variance of block Grout Depth", - default=0.03, - min=0.0, max=100.0 - ) + name="Variance", + description="Random variance of block Grout Depth", + default=0.03, + min=0.0, max=100.0 + ) GroutEdge = BoolProperty( - name="Edging", - description="Grout perimiter", - default=False - ) + name="Edging", + description="Grout perimiter", + default=False + ) # properties for openings Opening1Tog = BoolProperty( - name="Opening(s)", - description="Make windows or doors", - default=True - ) + name="Opening(s)", + description="Make windows or doors", + default=True + ) Opening1Width = FloatProperty( - name="Width", - description="The Width of opening 1", - default=2.5, - min=0.01, max=100.0 - ) + name="Width", + description="The Width of the first opening", + default=2.5, + min=0.01, max=100.0 + ) Opening1Height = FloatProperty( - name="Height", - description="The Height of opening 1", - default=3.5, - min=0.01, max=100.0 - ) + name="Height", + description="The Height of the first opening", + default=3.5, + min=0.01, max=100.0 + ) Opening1X = FloatProperty( - name="Indent", - description="The x position or spacing of opening 1", - default=5.0, - min=-100, max=100.0 - ) + name="Indent", + description="The x position or spacing of the first opening", + default=5.0, + min=-100, max=100.0 + ) Opening1Z = FloatProperty( - name="Bottom", - description="The z position of opening 1", - default=5.0, - min=-100, max=100.0 - ) + name="Bottom", + description="The z position of the First opening", + default=5.0, + min=-100, max=100.0 + ) Opening1Repeat = BoolProperty( - name="Repeat", - description="make multiple openings, with spacing X1", - default=False - ) + name="Repeat", + description="make multiple openings, with spacing X1", + default=False + ) Opening1TopArchTog = BoolProperty( - name="Top Arch", - description="Add an arch to the top of opening 1", - default=True - ) + name="Top Arch", + description="Add an arch to the top of the first opening", + default=True + ) Opening1TopArch = FloatProperty( - name="Curve", - description="Height of the arch on the top of the opening", - default=2.5, - min=0.001, max=100.0 - ) + name="Curve", + description="Height of the arch on the top of the opening", + default=2.5, + min=0.001, max=100.0 + ) Opening1TopArchThickness = FloatProperty( - name="Thickness", - description="Thickness of the arch on the top of the opening", - default=0.75, - min=0.001, max=100.0 - ) + name="Thickness", + description="Thickness of the arch on the top of the opening", + default=0.75, + min=0.001, max=100.0 + ) Opening1BtmArchTog = BoolProperty( - name="Bottom Arch", - description="Add an arch to the bottom of opening 1", - default=False - ) + name="Bottom Arch", + description="Add an arch to the bottom of opening 1", + default=False + ) Opening1BtmArch = FloatProperty( - name="Curve", - description="Height of the arch on the bottom of the opening", - default=1.0, - min=0.01, max=100.0 - ) + name="Curve", + description="Height of the arch on the bottom of the opening", + default=1.0, + min=0.01, max=100.0 + ) Opening1BtmArchThickness = FloatProperty( - name="Thickness", - description="Thickness of the arch on the bottom of the opening", - default=0.5, - min=0.01, max=100.0 - ) + name="Thickness", + description="Thickness of the arch on the bottom of the opening", + default=0.5, + min=0.01, max=100.0 + ) Opening1Bevel = FloatProperty( - name="Bevel", - description="Angle block face", - default=0.25, - min=-10.0, max=10.0 - ) + name="Bevel", + description="Angle block face", + default=0.25, + min=-10.0, max=10.0 + ) # openings on top of wall CrenelTog = BoolProperty( - name="Crenels", - description="Make openings along top of wall", - default=False - ) + name="Crenels", + description="Make openings along top of wall", + default=False + ) CrenelXP = FloatProperty( - name="Width %", - description="Gap width in wall based % of wall width", - default=0.25, - min=0.10, max=1.0 - ) + name="Width", + description="Gap width in wall based the percentage of wall width", + default=0.25, + min=0.10, max=1.0, + subtype="PERCENTAGE" + ) CrenelZP = FloatProperty( - name="Height %", - description="Crenel Height as % of wall height", - default=0.10, - min=0.10, max=1.0 - ) + name="Height", + description="Crenel Height as the percentage of wall height", + default=0.10, + min=0.10, max=1.0, + subtype="PERCENTAGE" + ) # narrow openings in wall. # need to prevent overlap with arch openings - though inversion is an interesting effect. SlotTog = BoolProperty( - name="Slots", - description="Make narrow openings in wall", - default=False - ) - SlotRpt = BoolProperty(name="Repeat", - description="Repeat slots along wall", - default=False - ) + name="Slots", + description="Make narrow openings in wall", + default=False + ) + SlotRpt = BoolProperty( + name="Repeat", + description="Repeat slots along wall", + default=False + ) SlotWdg = BoolProperty( - name="Wedged (n/a)", - description="Bevel edges of slots", - default=False - ) + name="Wedged (n/a)", + description="Bevel edges of slots", + default=False + ) SlotX = FloatProperty( - name="Indent", - description="The x position or spacing of slots", - default=0.0, min=-100, max=100.0 - ) + name="Indent", + description="The x position or spacing of slots", + default=0.0, min=-100, max=100.0 + ) SlotGap = FloatProperty( - name="Opening", - description="The opening size of slots", - default=0.5, min=0.10, max=100.0 - ) + name="Opening", + description="The opening size of slots", + default=0.5, min=0.10, max=100.0 + ) SlotV = BoolProperty( - name="Vertical", - description="Vertical slots", - default=True - ) + name="Vertical", + description="Vertical slots", + default=True + ) SlotVH = FloatProperty( - name="Height", - description="Height of vertical slot", - default=3.5, - min=0.10, max=100.0 - ) + name="Height", + description="Height of vertical slot", + default=3.5, + min=0.10, max=100.0 + ) SlotVBtm = FloatProperty( - name="Bottom", - description="Z position for slot", - default=5.00, - min=-100.0, max=100.0 - ) + name="Bottom", + description="Z position for slot", + default=5.00, + min=-100.0, max=100.0 + ) SlotH = BoolProperty( - name="Horizontal", - description="Horizontal slots", - default=False - ) + name="Horizontal", + description="Horizontal slots", + default=False + ) SlotHW = FloatProperty( - name="Width", - description="Width of horizontal slot", - default=2.5, - min=0.10, max=100.0 - ) + name="Width", + description="Width of horizontal slot", + default=2.5, + min=0.10, max=100.0 + ) # this should offset from VBtm... maybe make a % like crenels? SlotHBtm = FloatProperty( - name="Bottom", - description="Z position for horizontal slot", - default=5.50, - min=-100.0, max=100.0 - ) + name="Bottom", + description="Z position for horizontal slot", + default=5.50, + min=-100.0, max=100.0 + ) # properties for shelf (extend blocks in area) ShelfTog = BoolProperty( - name="Shelf", - description="Add blocks in area by depth to make shelf/platform", - default=False - ) + name="Shelf", + description="Add blocks in area by depth to make shelf/platform", + default=False + ) ShelfX = FloatProperty( - name="Left", - description="The x position of Shelf", - default=-5.00, - min=-100, max=100.0 - ) + name="Left", + description="The x position of Shelf", + default=-5.00, + min=-100, max=100.0 + ) ShelfZ = FloatProperty( - name="Bottom", - description="The z position of Shelf", - default=10.0, - min=-100, max=100.0 - ) + name="Bottom", + description="The z position of Shelf", + default=10.0, + min=-100, max=100.0 + ) ShelfH = FloatProperty( - name="Height", - description="The Height of Shelf area", - default=1.0, - min=0.01, max=100.0 - ) + name="Height", + description="The Height of Shelf area", + default=1.0, + min=0.01, max=100.0 + ) ShelfW = FloatProperty( - name="Width", - description="The Width of shelf area", - default=5.0, - min=0.01, max=100.0 - ) + name="Width", + description="The Width of shelf area", + default=5.0, + min=0.01, max=100.0 + ) ShelfD = FloatProperty( - name="Depth", - description="Depth of each block for shelf (from cursor + 1/2 wall depth)", - default=2.0, - min=0.01, max=100.0 - ) + name="Depth", + description="Depth of each block for shelf (from cursor + 1/2 wall depth)", + default=2.0, + min=0.01, max=100.0 + ) ShelfBack = BoolProperty( - name="Backside", - description="Shelf on backside of wall", - default=False - ) + name="Backside", + description="Shelf on backside of wall", + default=False + ) # properties for steps (extend blocks in area, progressive width) StepTog = BoolProperty( - name="Steps", - description="Add blocks in area by depth with progressive width to make steps", - default=False - ) + name="Steps", + description="Add blocks in area by depth with progressive width to make steps", + default=False + ) StepX = FloatProperty( - name="Left", - description="The x position of steps", - default=-9.00, - min=-100, max=100.0 - ) + name="Left", + description="The x position of steps", + default=-9.00, + min=-100, max=100.0 + ) StepZ = FloatProperty( - name="Bottom", - description="The z position of steps", - default=0.0, - min=-100, max=100.0 - ) + name="Bottom", + description="The z position of steps", + default=0.0, + min=-100, max=100.0 + ) StepH = FloatProperty( - name="Height", - description="The Height of step area", - default=10.0, - min=0.01, max=100.0 - ) + name="Height", + description="The Height of step area", + default=10.0, + min=0.01, max=100.0 + ) StepW = FloatProperty( - name="Width", - description="The Width of step area", - default=8.0, - min=0.01, max=100.0 - ) + name="Width", + description="The Width of step area", + default=8.0, + min=0.01, max=100.0 + ) StepD = FloatProperty( - name="Depth", - description="Depth of each block for steps (from cursor + 1/2 wall depth)", - default=1.0, - min=0.01, max=100.0 - ) + name="Depth", + description="Depth of each block for steps (from cursor + 1/2 wall depth)", + default=1.0, + min=0.01, max=100.0 + ) StepV = FloatProperty( - name="Riser", - description="Height of each step", - default=0.70, - min=0.01, max=100.0 - ) + name="Riser", + description="Height of each step", + default=0.70, + min=0.01, max=100.0 + ) StepT = FloatProperty( - name="Tread", - description="Width of each step", - default=1.0, - min=0.01, max=100.0 - ) + name="Tread", + description="Width of each step", + default=1.0, + min=0.01, max=100.0 + ) StepLeft = BoolProperty( - name="High Left", - description="Height left; else Height right", - default=False - ) + name="Direction", + description="If checked, flip steps direction towards the -X axis", + default=False + ) StepOnly = BoolProperty( - name="No Blocks", - description="Steps only, no supporting blocks", - default=False - ) + name="Steps Only", + description="Steps only, no supporting blocks", + default=False + ) StepBack = BoolProperty( - name="Backside", - description="Steps on backside of wall", - default=False - ) + name="Backside", + description="Steps on backside of wall", + default=False + ) # Display the toolbox options def draw(self, context): @@ -453,104 +479,152 @@ class add_mesh_wallb(bpy.types.Operator): # Wall area (size/position) box = layout.box() box.label(text="Wall Size (area)") - box.prop(self, "WallStart") - box.prop(self, "WallEnd") - box.prop(self, "WallBottom") - box.prop(self, "WallTop") + + col = box.column(align=True) + col.prop(self, "WallStart") + col.prop(self, "WallEnd") + + col = box.column(align=True) + col.prop(self, "WallBottom") + col.prop(self, "WallTop") box.prop(self, "EdgeOffset") # Wall block sizing box = layout.box() - box.label(text='Block Sizing') - box.prop(self, 'MergeBlock') - # add checkbox for "fixed" sizing (ignore variance) a.k.a. bricks. - box.prop(self, "Width") - box.prop(self, "WidthVariance") - box.prop(self, "WidthMinimum") - box.prop(self, "Height") - box.prop(self, "HeightVariance") - box.prop(self, "HeightMinimum") - box.prop(self, "Depth") - box.prop(self, "DepthVariance") - box.prop(self, "DepthMinimum") + box.label(text="Block Sizing") + box.prop(self, "MergeBlock") + + # add checkbox for "fixed" sizing (ignore variance) a.k.a. bricks + col = box.column(align=True) + col.prop(self, "Width") + col.prop(self, "WidthVariance") + col.prop(self, "WidthMinimum") + + col = box.column(align=True) + col.prop(self, "Height") + col.prop(self, "HeightVariance") + col.prop(self, "HeightMinimum") + + col = box.column(align=True) + col.prop(self, "Depth") + col.prop(self, "DepthVariance") + col.prop(self, "DepthMinimum") # grout settings box = layout.box() box.label(text="Grout") - box.prop(self, "Grout") - box.prop(self, "GroutVariance") - box.prop(self, "GroutDepth") - box.prop(self, "GroutDepthVariance") + + col = box.column(align=True) + col.prop(self, "Grout") + col.prop(self, "GroutVariance") + + col = box.column(align=True) + col.prop(self, "GroutDepth") + col.prop(self, "GroutDepthVariance") # Wall shape modifiers box = layout.box() box.label(text="Wall Shape") - box.prop(self, "RadialTog") - box.prop(self, "SlopeTog") + row = box.row(align=True) + row.prop(self, "RadialTog", toggle=True) + row.prop(self, "SlopeTog", toggle=True) # Openings (doors, windows; arched) box = layout.box() box.prop(self, 'Opening1Tog') - if self.properties.Opening1Tog: - box.prop(self, "Opening1Width") - box.prop(self, "Opening1Height") - box.prop(self, "Opening1X") - box.prop(self, "Opening1Z") - box.prop(self, "Opening1Bevel") - box.prop(self, "Opening1Repeat") - box.prop(self, "Opening1TopArchTog") - box.prop(self, "Opening1TopArch") - box.prop(self, "Opening1TopArchThickness") - box.prop(self, "Opening1BtmArchTog") - box.prop(self, "Opening1BtmArch") - box.prop(self, "Opening1BtmArchThickness") + if self.Opening1Tog: + col = box.column(align=True) + col.prop(self, "Opening1Width") + col.prop(self, "Opening1Height") + col.prop(self, "Opening1X") + col.prop(self, "Opening1Z") + col.prop(self, "Opening1Bevel") + + box.prop(self, "Opening1Repeat", toggle=True) + + sub_box = box.box() + sub_box.prop(self, "Opening1TopArchTog") + if self.Opening1TopArchTog: + col = sub_box.column(align=True) + col.prop(self, "Opening1TopArch") + col.prop(self, "Opening1TopArchThickness") + + sub_box = box.box() + sub_box.prop(self, "Opening1BtmArchTog") + if self.Opening1BtmArchTog: + col = sub_box.column(align=True) + col.prop(self, "Opening1BtmArch") + col.prop(self, "Opening1BtmArchThickness") # Slots (narrow openings) box = layout.box() - box.prop(self, 'SlotTog') - if self.properties.SlotTog: - box.prop(self, "SlotX") - box.prop(self, "SlotGap") - box.prop(self, "SlotRpt") - box.prop(self, "SlotV") - box.prop(self, "SlotVH") - box.prop(self, "SlotVBtm") - box.prop(self, "SlotH") - box.prop(self, "SlotHW") - box.prop(self, "SlotHBtm") + box.prop(self, "SlotTog") + if self.SlotTog: + col = box.column(align=True) + col.prop(self, "SlotX") + col.prop(self, "SlotGap") + + box.prop(self, "SlotRpt", toggle=True) + + sub_box = box.box() + sub_box.prop(self, "SlotV") + if self.SlotV: + col = sub_box.column(align=True) + col.prop(self, "SlotVH") + col.prop(self, "SlotVBtm") + + sub_box = box.box() + sub_box.prop(self, "SlotH") + if self.SlotH: + col = sub_box.column(align=True) + col.prop(self, "SlotHW") + col.prop(self, "SlotHBtm") # Crenels, gaps in top of wall box = layout.box() box.prop(self, "CrenelTog") - if self.properties.CrenelTog: - box.prop(self, "CrenelXP") - box.prop(self, "CrenelZP") + if self.CrenelTog: + col = box.column(align=True) + col.prop(self, "CrenelXP") + col.prop(self, "CrenelZP") # Shelfing (protrusions) box = layout.box() box.prop(self, 'ShelfTog') - if self.properties.ShelfTog: - box.prop(self, "ShelfX") - box.prop(self, "ShelfZ") - box.prop(self, "ShelfH") - box.prop(self, "ShelfW") - box.prop(self, "ShelfD") + if self.ShelfTog: + col = box.column(align=True) + col.prop(self, "ShelfX") + col.prop(self, "ShelfZ") + + col = box.column(align=True) + col.prop(self, "ShelfW") + col.prop(self, "ShelfH") + col.prop(self, "ShelfD") + box.prop(self, "ShelfBack") # Steps box = layout.box() box.prop(self, 'StepTog') - if self.properties.StepTog: - box.prop(self, "StepX") - box.prop(self, "StepZ") - box.prop(self, "StepH") - box.prop(self, "StepW") - box.prop(self, "StepD") - box.prop(self, "StepV") - box.prop(self, "StepT") - box.prop(self, "StepLeft") - box.prop(self, "StepOnly") - box.prop(self, "StepBack") + if self.StepTog: + col = box.column(align=True) + col.prop(self, "StepX") + col.prop(self, "StepZ") + + col = box.column(align=True) + col.prop(self, "StepH") + col.prop(self, "StepW") + col.prop(self, "StepD") + + col = box.column(align=True) + col.prop(self, "StepV") + col.prop(self, "StepT") + + col = box.column(align=True) + row = col.row(align=True) + row.prop(self, "StepLeft", toggle=True) + row.prop(self, "StepOnly", toggle=True) + col.prop(self, "StepBack", toggle=True) # Respond to UI - get the properties set by user. # Check and process UI settings to generate masonry @@ -568,56 +642,57 @@ class add_mesh_wallb(bpy.types.Operator): global stepBack # Create the wall when enabled (skip regen iterations when off) - if not self.properties.ConstructTog: + if not self.ConstructTog: return {'FINISHED'} # enter the settings for the wall dimensions (area) # start can't be zero - min/max don't matter [if max less than end] but zero don't workie. # start can't exceed end. - if not self.properties.WallStart or self.properties.WallStart >= self.properties.WallEnd: - self.properties.WallStart = NOTZERO # Reset UI if input out of bounds... + if not self.WallStart or self.WallStart >= self.WallEnd: + self.WallStart = NOTZERO # Reset UI if input out of bounds... - dims['s'] = self.properties.WallStart - dims['e'] = self.properties.WallEnd - dims['b'] = self.properties.WallBottom - dims['t'] = self.properties.WallTop + dims['s'] = self.WallStart + dims['e'] = self.WallEnd + dims['b'] = self.WallBottom + dims['t'] = self.WallTop - settings['eoff'] = self.properties.EdgeOffset + settings['eoff'] = self.EdgeOffset # retrieve the settings for the wall block properties - settings['w'] = self.properties.Width - settings['wv'] = self.properties.WidthVariance - settings['wm'] = self.properties.WidthMinimum + settings['w'] = self.Width + settings['wv'] = self.WidthVariance + settings['wm'] = self.WidthMinimum + if not radialized: settings['sdv'] = settings['w'] else: settings['sdv'] = 0.12 - settings['h'] = self.properties.Height - settings['hv'] = self.properties.HeightVariance - settings['hm'] = self.properties.HeightMinimum + settings['h'] = self.Height + settings['hv'] = self.HeightVariance + settings['hm'] = self.HeightMinimum - settings['d'] = self.properties.Depth - settings['dv'] = self.properties.DepthVariance - settings['dm'] = self.properties.DepthMinimum + settings['d'] = self.Depth + settings['dv'] = self.DepthVariance + settings['dm'] = self.DepthMinimum - if self.properties.MergeBlock: + if self.MergeBlock: bigBlock = 1 else: bigBlock = 0 - settings['g'] = self.properties.Grout - settings['gv'] = self.properties.GroutVariance - settings['gd'] = self.properties.GroutDepth - settings['gdv'] = self.properties.GroutDepthVariance + settings['g'] = self.Grout + settings['gv'] = self.GroutVariance + settings['gd'] = self.GroutDepth + settings['gdv'] = self.GroutDepthVariance - if self.properties.GroutEdge: + if self.GroutEdge: settings['ge'] = 1 else: settings['ge'] = 0 # set wall shape modifiers - if self.properties.RadialTog: + if self.RadialTog: radialized = 1 # eliminate to allow user control for start/completion? dims['s'] = 0.0 # complete radial @@ -628,7 +703,7 @@ class add_mesh_wallb(bpy.types.Operator): else: radialized = 0 - if self.properties.SlopeTog: + if self.SlopeTog: slope = 1 else: slope = 0 @@ -636,113 +711,113 @@ class add_mesh_wallb(bpy.types.Operator): shelfExt = 0 shelfBack = 0 - # Add shelf if enabled - if self.properties.ShelfTog: + # Add shelf if enabled + if self.ShelfTog: shelfExt = 1 - shelfSpecs['h'] = self.properties.ShelfH - shelfSpecs['w'] = self.properties.ShelfW - shelfSpecs['d'] = self.properties.ShelfD - shelfSpecs['x'] = self.properties.ShelfX - shelfSpecs['z'] = self.properties.ShelfZ + shelfSpecs['h'] = self.ShelfH + shelfSpecs['w'] = self.ShelfW + shelfSpecs['d'] = self.ShelfD + shelfSpecs['x'] = self.ShelfX + shelfSpecs['z'] = self.ShelfZ - if self.properties.ShelfBack: + if self.ShelfBack: shelfBack = 1 stepMod = 0 stepLeft = 0 stepOnly = 0 stepBack = 0 - # Make steps if enabled - if self.properties.StepTog: + # Make steps if enabled + if self.StepTog: stepMod = 1 - stepSpecs['x'] = self.properties.StepX - stepSpecs['z'] = self.properties.StepZ - stepSpecs['h'] = self.properties.StepH - stepSpecs['w'] = self.properties.StepW - stepSpecs['d'] = self.properties.StepD - stepSpecs['v'] = self.properties.StepV - stepSpecs['t'] = self.properties.StepT - - if self.properties.StepLeft: + stepSpecs['x'] = self.StepX + stepSpecs['z'] = self.StepZ + stepSpecs['h'] = self.StepH + stepSpecs['w'] = self.StepW + stepSpecs['d'] = self.StepD + stepSpecs['v'] = self.StepV + stepSpecs['t'] = self.StepT + + if self.StepLeft: stepLeft = 1 - if self.properties.StepOnly: + if self.StepOnly: stepOnly = 1 - if self.properties.StepBack: + if self.StepBack: stepBack = 1 # enter the settings for the openings # when openings overlap they create inverse stonework - interesting but not the desired effect :) - # if opening width == indent*2 the edge blocks fail (row of blocks cross opening) - bug. + # if opening width == indent * 2 the edge blocks fail (row of blocks cross opening) - bug. openingSpecs = [] openingIdx = 0 # track opening array references for multiple uses # general openings with arch options - can be windows or doors. - if self.properties.Opening1Tog: + if self.Opening1Tog: # set defaults... openingSpecs += [{'w': 0.5, 'h': 0.5, 'x': 0.8, 'z': 2.7, 'rp': 1, 'b': 0.0, 'v': 0, 'vl': 0, 't': 0, 'tl': 0}] - openingSpecs[openingIdx]['w'] = self.properties.Opening1Width - openingSpecs[openingIdx]['h'] = self.properties.Opening1Height - openingSpecs[openingIdx]['x'] = self.properties.Opening1X - openingSpecs[openingIdx]['z'] = self.properties.Opening1Z - openingSpecs[openingIdx]['rp'] = self.properties.Opening1Repeat + openingSpecs[openingIdx]['w'] = self.Opening1Width + openingSpecs[openingIdx]['h'] = self.Opening1Height + openingSpecs[openingIdx]['x'] = self.Opening1X + openingSpecs[openingIdx]['z'] = self.Opening1Z + openingSpecs[openingIdx]['rp'] = self.Opening1Repeat - if self.properties.Opening1TopArchTog: - openingSpecs[openingIdx]['v'] = self.properties.Opening1TopArch - openingSpecs[openingIdx]['t'] = self.properties.Opening1TopArchThickness + if self.Opening1TopArchTog: + openingSpecs[openingIdx]['v'] = self.Opening1TopArch + openingSpecs[openingIdx]['t'] = self.Opening1TopArchThickness - if self.properties.Opening1BtmArchTog: - openingSpecs[openingIdx]['vl'] = self.properties.Opening1BtmArch - openingSpecs[openingIdx]['tl'] = self.properties.Opening1BtmArchThickness + if self.Opening1BtmArchTog: + openingSpecs[openingIdx]['vl'] = self.Opening1BtmArch + openingSpecs[openingIdx]['tl'] = self.Opening1BtmArchThickness - openingSpecs[openingIdx]['b'] = self.properties.Opening1Bevel + openingSpecs[openingIdx]['b'] = self.Opening1Bevel openingIdx += 1 # count window/door/arch openings # Slots (narrow openings) - if self.properties.SlotTog: + if self.SlotTog: - if self.properties.SlotV: # vertical slots + if self.SlotV: # vertical slots # set defaults... openingSpecs += [{'w': 0.5, 'h': 0.5, 'x': 0.0, 'z': 2.7, 'rp': 0, 'b': 0.0, 'v': 0, 'vl': 0, 't': 0, 'tl': 0}] - openingSpecs[openingIdx]['w'] = self.properties.SlotGap - openingSpecs[openingIdx]['h'] = self.properties.SlotVH - openingSpecs[openingIdx]['x'] = self.properties.SlotX - openingSpecs[openingIdx]['z'] = self.properties.SlotVBtm - openingSpecs[openingIdx]['rp'] = self.properties.SlotRpt + openingSpecs[openingIdx]['w'] = self.SlotGap + openingSpecs[openingIdx]['h'] = self.SlotVH + openingSpecs[openingIdx]['x'] = self.SlotX + openingSpecs[openingIdx]['z'] = self.SlotVBtm + openingSpecs[openingIdx]['rp'] = self.SlotRpt # make them pointy... - openingSpecs[openingIdx]['v'] = self.properties.SlotGap - openingSpecs[openingIdx]['t'] = self.properties.SlotGap / 2 - openingSpecs[openingIdx]['vl'] = self.properties.SlotGap - openingSpecs[openingIdx]['tl'] = self.properties.SlotGap / 2 + openingSpecs[openingIdx]['v'] = self.SlotGap + openingSpecs[openingIdx]['t'] = self.SlotGap / 2 + openingSpecs[openingIdx]['vl'] = self.SlotGap + openingSpecs[openingIdx]['tl'] = self.SlotGap / 2 openingIdx += 1 # count vertical slot openings # need to handle overlap of H and V slots... - if self.properties.SlotH: # Horizontal slots + if self.SlotH: # Horizontal slots # set defaults... openingSpecs += [{'w': 0.5, 'h': 0.5, 'x': 0.0, 'z': 2.7, 'rp': 0, 'b': 0.0, 'v': 0, 'vl': 0, 't': 0, 'tl': 0}] - openingSpecs[openingIdx]['w'] = self.properties.SlotHW - openingSpecs[openingIdx]['h'] = self.properties.SlotGap - openingSpecs[openingIdx]['x'] = self.properties.SlotX - openingSpecs[openingIdx]['z'] = self.properties.SlotHBtm + openingSpecs[openingIdx]['w'] = self.SlotHW + openingSpecs[openingIdx]['h'] = self.SlotGap + openingSpecs[openingIdx]['x'] = self.SlotX + openingSpecs[openingIdx]['z'] = self.SlotHBtm # horizontal repeat isn't same spacing as vertical... - openingSpecs[openingIdx]['rp'] = self.properties.SlotRpt + openingSpecs[openingIdx]['rp'] = self.SlotRpt # make them pointy... openingIdx += 1 # count horizontal slot openings # Crenellations (top row openings) - if self.properties.CrenelTog: + if self.CrenelTog: # add bottom arch option? # perhaps a repeat toggle... @@ -752,11 +827,11 @@ class add_mesh_wallb(bpy.types.Operator): openingSpecs += [{'w': 0.5, 'h': 0.5, 'x': 0.0, 'z': 2.7, 'rp': 1, 'b': 0.0, 'v': 0, 'vl': 0, 't': 0, 'tl': 0}] - wallW = self.properties.WallEnd - self.properties.WallStart - crenelW = wallW * self.properties.CrenelXP # Width % opening. + wallW = self.WallEnd - self.WallStart + crenelW = wallW * self.CrenelXP # Width % opening. - wallH = self.properties.WallTop - self.properties.WallBottom - crenelH = wallH * self.properties.CrenelZP # % proportional height. + wallH = self.WallTop - self.WallBottom + crenelH = wallH * self.CrenelZP # % proportional height. openingSpecs[openingIdx]['w'] = crenelW openingSpecs[openingIdx]['h'] = crenelH @@ -772,14 +847,17 @@ class add_mesh_wallb(bpy.types.Operator): openingSpecs[openingIdx]['x'] = 0 openingSpecs[openingIdx]['rp'] = 0 # set bottom of opening (center of hole) - openingSpecs[openingIdx]['z'] = self.properties.WallTop - (crenelH / 2) + openingSpecs[openingIdx]['z'] = self.WallTop - (crenelH / 2) openingIdx += 1 # count crenel openings # Process the user settings to generate a wall # generate the list of vertices for the wall... - verts_array, faces_array = createWall(radialized, slope, openingSpecs, bigBlock, - shelfExt, shelfBack, stepMod, stepLeft, stepOnly, stepBack) + verts_array, faces_array = createWall( + radialized, slope, openingSpecs, bigBlock, + shelfExt, shelfBack, stepMod, stepLeft, stepOnly, + stepBack + ) # Create new mesh mesh = bpy.data.meshes.new("Wall") diff --git a/add_mesh_extra_objects/__init__.py b/add_mesh_extra_objects/__init__.py index a4290b35..ecc023df 100644 --- a/add_mesh_extra_objects/__init__.py +++ b/add_mesh_extra_objects/__init__.py @@ -16,23 +16,28 @@ # # ##### END GPL LICENSE BLOCK ##### # Contributed to by: -# Pontiac, Fourmadmen, varkenvarken, tuga3d, meta-androcto, metalliandy # -# dreampainter, cotejrp1, liero, Kayo Phoenix, sugiany, dommetysk # -# Phymec, Anthony D'Agostino, Pablo Vazquez, Richard Wilks, lijenstina # -# xyz presets by elfnor +# Pontiac, Fourmadmen, varkenvarken, tuga3d, meta-androcto, metalliandy # +# dreampainter, cotejrp1, liero, Kayo Phoenix, sugiany, dommetysk, Jambay # +# Phymec, Anthony D'Agostino, Pablo Vazquez, Richard Wilks, lijenstina, # +# Sjaak-de-Draak, Phil Cote, cotejrp1, xyz presets by elfnor, revolt_randy, # + bl_info = { "name": "Extra Objects", "author": "Multiple Authors", - "version": (0, 3, 1), + "version": (0, 3, 2), "blender": (2, 74, 5), "location": "View3D > Add > Mesh", "description": "Add extra mesh object types", "warning": "", - "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Add_Mesh/Add_Extra", + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/" + "Py/Scripts/Add_Mesh/Add_Extra", "category": "Add Mesh", } +# Note: Blocks has to be loaded before the WallFactory or the script +# will not work properly after (F8) reload + if "bpy" in locals(): import importlib importlib.reload(add_mesh_star) @@ -54,8 +59,8 @@ if "bpy" in locals(): importlib.reload(add_empty_as_parent) importlib.reload(mesh_discombobulator) importlib.reload(add_mesh_beam_builder) - importlib.reload(Wallfactory) importlib.reload(Blocks) + importlib.reload(Wallfactory) importlib.reload(add_shape_geodesic) importlib.reload(forms_271) importlib.reload(geodesic_classes_271) @@ -82,8 +87,8 @@ else: from . import add_empty_as_parent from . import mesh_discombobulator from . import add_mesh_beam_builder - from . import Wallfactory from . import Blocks + from . import Wallfactory from . import add_mesh_triangles from .geodesic_domes import add_shape_geodesic @@ -164,7 +169,8 @@ class INFO_MT_mesh_math_add(Menu): layout.operator("mesh.primitive_xyz_function_surface", text="XYZ Math Surface") self.layout.operator("mesh.primitive_solid_add", text="Regular Solid") - self.layout.operator("mesh.make_triangle", icon = "MESH_DATA") + self.layout.operator("mesh.make_triangle", icon="MESH_DATA") + class INFO_MT_mesh_mech(Menu): # Define the "Math Function" menu @@ -248,97 +254,97 @@ class discombobulator_scene_props(bpy.types.PropertyGroup): DISC_doodads = [] # Protusions Buttons: repeatprot = IntProperty( - name="Repeat protusions", - description=("Make several layers of protusion \n" - "Use carefully, runs recursively the discombulator"), - default=1, min=1, max=4 # set to 4 because it's 2**n reqursive - ) + name="Repeat protusions", + description=("Make several layers of protusion \n" + "Use carefully, runs recursively the discombulator"), + default=1, min=1, max=4 # set to 4 because it's 2**n reqursive + ) doprots = BoolProperty( - name="Make protusions", - description="Check if we want to add protusions to the mesh", - default=True - ) + name="Make protusions", + description="Check if we want to add protusions to the mesh", + default=True + ) subpolygon1 = BoolProperty( - name="1", - default=True - ) + name="1", + default=True + ) subpolygon2 = BoolProperty( - name="2", - default=True - ) + name="2", + default=True + ) subpolygon3 = BoolProperty( - name="3", - default=True - ) + name="3", + default=True + ) subpolygon4 = BoolProperty( - name="4", - default=True - ) + name="4", + default=True + ) polygonschangedpercent = FloatProperty( - name="Polygon %", - description="Percentage of changed polygons", - default=1.0 - ) + name="Polygon %", + description="Percentage of changed polygons", + default=1.0 + ) minHeight = FloatProperty( - name="Min height", - description="Minimal height of the protusions", - default=0.2 - ) + name="Min height", + description="Minimal height of the protusions", + default=0.2 + ) maxHeight = FloatProperty( - name="Max height", - description="Maximal height of the protusions", - default=0.4 - ) + name="Max height", + description="Maximal height of the protusions", + default=0.4 + ) minTaper = FloatProperty( - name="Min taper", - description="Minimal height of the protusions", - default=0.15, min=0.0, max=1.0, - subtype='PERCENTAGE' - ) + name="Min taper", + description="Minimal height of the protusions", + default=0.15, min=0.0, max=1.0, + subtype='PERCENTAGE' + ) maxTaper = FloatProperty( - name="Max taper", - description="Maximal height of the protusions", - default=0.35, min=0.0, max=1.0, - subtype='PERCENTAGE' - ) + name="Max taper", + description="Maximal height of the protusions", + default=0.35, min=0.0, max=1.0, + subtype='PERCENTAGE' + ) # Doodads buttons: dodoodads = BoolProperty( - name="Make doodads", - description="Check if we want to generate doodads", - default=False - ) + name="Make doodads", + description="Check if we want to generate doodads", + default=False + ) mindoodads = IntProperty( - name="Minimum doodads number", - description="Ask for the minimum number of doodads to generate per polygon", - default=1, min=0, max=50 - ) + name="Minimum doodads number", + description="Ask for the minimum number of doodads to generate per polygon", + default=1, min=0, max=50 + ) maxdoodads = IntProperty( - name="Maximum doodads number", - description="Ask for the maximum number of doodads to generate per polygon", - default=6, min=1, max=50 - ) + name="Maximum doodads number", + description="Ask for the maximum number of doodads to generate per polygon", + default=6, min=1, max=50 + ) doodMinScale = FloatProperty( - name="Scale min", description="Minimum scaling of doodad", - default=0.5, min=0.0, max=1.0, - subtype='PERCENTAGE' - ) + name="Scale min", description="Minimum scaling of doodad", + default=0.5, min=0.0, max=1.0, + subtype='PERCENTAGE' + ) doodMaxScale = FloatProperty( - name="Scale max", - description="Maximum scaling of doodad", - default=1.0, min=0.0, max=1.0, - subtype='PERCENTAGE' - ) + name="Scale max", + description="Maximum scaling of doodad", + default=1.0, min=0.0, max=1.0, + subtype='PERCENTAGE' + ) # Materials buttons: sideProtMat = IntProperty( - name="Side's prot mat", - description="Material of protusion's sides", - default=0, min=0 - ) + name="Side's prot mat", + description="Material of protusion's sides", + default=0, min=0 + ) topProtMat = IntProperty( - name="Prot's top mat", - description="Material of protusion's top", - default=0, min=0 - ) + name="Prot's top mat", + description="Material of protusion's top", + default=0, min=0 + ) # Register all operators and panels diff --git a/add_mesh_extra_objects/add_mesh_beam_builder.py b/add_mesh_extra_objects/add_mesh_beam_builder.py index 8297f9ae..cacde06a 100644 --- a/add_mesh_extra_objects/add_mesh_beam_builder.py +++ b/add_mesh_extra_objects/add_mesh_beam_builder.py @@ -1,16 +1,16 @@ # GPL # "author": revolt_randy, Jambay -# Create "Beam" primitives. Based on original script by revolt_randy. -# @todo: track 3D cursor for location. +# Create "Beam" primitives. Based on original script by revolt_randy import bpy +from bpy.types import Operator from bpy.props import ( + BoolProperty, EnumProperty, FloatProperty, IntProperty, ) -from bpy_extras import object_utils # ##################### @@ -310,12 +310,14 @@ def create_L_beam(sRef): verts_back_temp = [] # Create front vertices by calculation - verts_front_temp = [(-x_off, -y_off, z_off), - (-(x_off - thick), -y_off, z_off), - (-(x_off - thick), -y_off, -(z_off - thick)), - (x_off, -y_off, -(z_off - thick)), - (x_off, -y_off, -z_off), - (-x_off, -y_off, -z_off)] + verts_front_temp = [ + (-x_off, -y_off, z_off), + (-(x_off - thick), -y_off, z_off), + (-(x_off - thick), -y_off, -(z_off - thick)), + (x_off, -y_off, -(z_off - thick)), + (x_off, -y_off, -z_off), + (-x_off, -y_off, -z_off) + ] # Adjust taper vert_outside = verts_front_temp[0] @@ -329,12 +331,14 @@ def create_L_beam(sRef): verts_front_temp[3] = [vert_inside[0], vert_inside[1], vert_taper] # Create back vertices by calculation - verts_back_temp = [(-x_off, y_off, z_off), - (-(x_off - thick), y_off, z_off), - (-(x_off - thick), y_off, -(z_off - thick)), - (x_off, y_off, -(z_off - thick)), - (x_off, y_off, -z_off), - (-x_off, y_off, -z_off)] + verts_back_temp = [ + (-x_off, y_off, z_off), + (-(x_off - thick), y_off, z_off), + (-(x_off - thick), y_off, -(z_off - thick)), + (x_off, y_off, -(z_off - thick)), + (x_off, y_off, -z_off), + (-x_off, y_off, -z_off) + ] # Adjust taper vert_outside = verts_back_temp[0] @@ -394,16 +398,18 @@ def create_T_beam(sRef): verts_back_temp = [] # Create front vertices - verts_front_temp = [(-x_off, -y_off, z_off), - (-thick_off, -y_off, z_off), - (thick_off, -y_off, z_off), - (x_off, -y_off, z_off), - (x_off, -y_off, z_off - thick), - (thick_off, -y_off, z_off - thick), - (thick_off, -y_off, -z_off), - (-thick_off, -y_off, -z_off), - (-thick_off, -y_off, z_off - thick), - (-x_off, -y_off, z_off - thick)] + verts_front_temp = [ + (-x_off, -y_off, z_off), + (-thick_off, -y_off, z_off), + (thick_off, -y_off, z_off), + (x_off, -y_off, z_off), + (x_off, -y_off, z_off - thick), + (thick_off, -y_off, z_off - thick), + (thick_off, -y_off, -z_off), + (-thick_off, -y_off, -z_off), + (-thick_off, -y_off, z_off - thick), + (-x_off, -y_off, z_off - thick) + ] # Adjust taper vert_outside = verts_front_temp[0] @@ -429,16 +435,18 @@ def create_T_beam(sRef): verts_front_temp[7] = [vert_taper, vert_inside[1], vert_inside[2]] # Create fack vertices by calculation - verts_back_temp = [(-x_off, y_off, z_off), - (-thick_off, y_off, z_off), - (thick_off, y_off, z_off), - (x_off, y_off, z_off), - (x_off, y_off, z_off - thick), - (thick_off, y_off, z_off - thick), - (thick_off, y_off, -z_off), - (-thick_off, y_off, -z_off), - (-thick_off, y_off, z_off - thick), - (-x_off, y_off, z_off - thick)] + verts_back_temp = [ + (-x_off, y_off, z_off), + (-thick_off, y_off, z_off), + (thick_off, y_off, z_off), + (x_off, y_off, z_off), + (x_off, y_off, z_off - thick), + (thick_off, y_off, z_off - thick), + (thick_off, y_off, -z_off), + (-thick_off, y_off, -z_off), + (-thick_off, y_off, z_off - thick), + (-x_off, y_off, z_off - thick) + ] # Adjust taper vert_outside = verts_back_temp[0] @@ -514,22 +522,24 @@ def create_I_beam(sRef): verts_back_temp = [] # Create front vertices by calculation - verts_front_temp = [(-x_off, -y_off, z_off), - (-thick_off, -y_off, z_off), - (thick_off, -y_off, z_off), - (x_off, -y_off, z_off), - (x_off, -y_off, z_off - thick), - (thick_off, -y_off, z_off - thick), - (thick_off, -y_off, -z_off + thick), - (x_off, -y_off, -z_off + thick), - (x_off, -y_off, -z_off), - (thick_off, -y_off, -z_off), - (-thick_off, -y_off, -z_off), - (-x_off, -y_off, -z_off), - (-x_off, -y_off, -z_off + thick), - (-thick_off, -y_off, -z_off + thick), - (-thick_off, -y_off, z_off - thick), - (-x_off, -y_off, z_off - thick)] + verts_front_temp = [ + (-x_off, -y_off, z_off), + (-thick_off, -y_off, z_off), + (thick_off, -y_off, z_off), + (x_off, -y_off, z_off), + (x_off, -y_off, z_off - thick), + (thick_off, -y_off, z_off - thick), + (thick_off, -y_off, -z_off + thick), + (x_off, -y_off, -z_off + thick), + (x_off, -y_off, -z_off), + (thick_off, -y_off, -z_off), + (-thick_off, -y_off, -z_off), + (-x_off, -y_off, -z_off), + (-x_off, -y_off, -z_off + thick), + (-thick_off, -y_off, -z_off + thick), + (-thick_off, -y_off, z_off - thick), + (-x_off, -y_off, z_off - thick) + ] # Adjust taper vert_outside = verts_front_temp[0] @@ -553,22 +563,24 @@ def create_I_beam(sRef): verts_front_temp[12] = [vert_inside[0], vert_inside[1], vert_taper] # Create back vertices by calculation - verts_back_temp = [(-x_off, y_off, z_off), - (-thick_off, y_off, z_off), - (thick_off, y_off, z_off), - (x_off, y_off, z_off), - (x_off, y_off, z_off - thick), - (thick_off, y_off, z_off - thick), - (thick_off, y_off, -z_off + thick), - (x_off, y_off, -z_off + thick), - (x_off, y_off, -z_off), - (thick_off, y_off, -z_off), - (-thick_off, y_off, -z_off), - (-x_off, y_off, -z_off), - (-x_off, y_off, -z_off + thick), - (-thick_off, y_off, -z_off + thick), - (-thick_off, y_off, z_off - thick), - (-x_off, y_off, z_off - thick)] + verts_back_temp = [ + (-x_off, y_off, z_off), + (-thick_off, y_off, z_off), + (thick_off, y_off, z_off), + (x_off, y_off, z_off), + (x_off, y_off, z_off - thick), + (thick_off, y_off, z_off - thick), + (thick_off, y_off, -z_off + thick), + (x_off, y_off, -z_off + thick), + (x_off, y_off, -z_off), + (thick_off, y_off, -z_off), + (-thick_off, y_off, -z_off), + (-x_off, y_off, -z_off), + (-x_off, y_off, -z_off + thick), + (-thick_off, y_off, -z_off + thick), + (-thick_off, y_off, z_off - thick), + (-x_off, y_off, z_off - thick) + ] # Adjust taper vert_outside = verts_back_temp[0] @@ -662,63 +674,77 @@ def addBeamObj(sRef, context): bpy.ops.transform.rotate(value=1.570796, constraint_axis=[False, True, False]) bpy.ops.object.transform_apply(location=False, rotation=True, scale=False) + if sRef.Cursor: + if beamObj.select is True: + # we also have to check if we're considered to be in 3D View (view3d) + if bpy.ops.view3d.snap_selected_to_cursor.poll(): + bpy.ops.view3d.snap_selected_to_cursor() + else: + sRef.Cursor = False + # ###################### # Create a beam primitive. # # UI functions and object creation. -class addBeam(bpy.types.Operator): +class addBeam(Operator): bl_idname = "mesh.add_beam" bl_label = "Beam Builder" bl_description = "Create beam meshes of various profiles" bl_options = {'REGISTER', 'UNDO'} Type = EnumProperty( - items=( - ('0', "Box", "Square Beam"), - ("1", "U", "U Beam"), - ("2", "C", "C Beam"), - ("3", "L", "L Beam"), - ("4", "I", "T Beam"), - ("5", "T", "I Beam") - ), - description="Beam form" - ) + items=( + ('0', "Box Profile", "Square Beam"), + ("1", "U Profile", "U Profile Beam"), + ("2", "C Profile", "C Profile Beam"), + ("3", "L Profile", "L Profile Beam"), + ("4", "I Profile", "I Profile Beam"), + ("5", "T Profile", "T Profile Beam") + ), + description="Beam form" + ) beamZ = FloatProperty( - name="Height", - min=0.01, max=100, - default=1 - ) + name="Height", + min=0.01, max=100, + default=1 + ) beamX = FloatProperty( - name="Width", - min=0.01, max=100, - default=.5 - ) + name="Width", + min=0.01, max=100, + default=.5 + ) beamY = FloatProperty( - name="Depth", - min=0.01, - max=100, - default=2 - ) + name="Depth", + min=0.01, + max=100, + default=2 + ) beamW = FloatProperty( - name="Thickness", - min=0.01, max=1, - default=0.1 - ) + name="Thickness", + min=0.01, max=1, + default=0.1 + ) edgeA = IntProperty( - name="Taper", - min=0, max=100, - default=0, - description="Angle beam edges" - ) + name="Taper", + min=0, max=100, + default=0, + description="Angle beam edges" + ) + Cursor = BoolProperty( + name="Use 3D Cursor", + default=False, + description="Draw the beam where the 3D Cursor is" + ) def draw(self, context): layout = self.layout box = layout.box() - row = box.row() - row.prop(self, "Type", text="") + split = box.split(percentage=0.85, align=True) + split.prop(self, "Type", text="") + split.prop(self, "Cursor", text="", icon="CURSOR") box.prop(self, "beamZ") box.prop(self, "beamX") diff --git a/add_mesh_extra_objects/add_mesh_gears.py b/add_mesh_extra_objects/add_mesh_gears.py index 7dc201d9..7eede285 100644 --- a/add_mesh_extra_objects/add_mesh_gears.py +++ b/add_mesh_extra_objects/add_mesh_gears.py @@ -2,7 +2,11 @@ import bpy from bpy.types import Operator -from math import atan, asin, cos, sin, tan, pi, radians +from math import ( + atan, asin, cos, + sin, tan, pi, + radians, + ) from bpy.props import ( FloatProperty, IntProperty, @@ -551,64 +555,74 @@ class AddGear(Operator): bl_options = {'REGISTER', 'UNDO', 'PRESET'} number_of_teeth = IntProperty(name="Number of Teeth", - description="Number of teeth on the gear", - min=2, - max=265, - default=12) + description="Number of teeth on the gear", + min=2, + max=265, + default=12 + ) radius = FloatProperty(name="Radius", - description="Radius of the gear, negative for crown gear", - min=-100.0, - max=100.0, - unit='LENGTH', - default=1.0) + description="Radius of the gear, negative for crown gear", + min=-100.0, + max=100.0, + unit='LENGTH', + default=1.0 + ) addendum = FloatProperty(name="Addendum", - description="Addendum, extent of tooth above radius", - min=0.01, - max=100.0, - unit='LENGTH', - default=0.1) + description="Addendum, extent of tooth above radius", + min=0.01, + max=100.0, + unit='LENGTH', + default=0.1 + ) dedendum = FloatProperty(name="Dedendum", - description="Dedendum, extent of tooth below radius", - min=0.0, - max=100.0, - unit='LENGTH', - default=0.1) + description="Dedendum, extent of tooth below radius", + min=0.0, + max=100.0, + unit='LENGTH', + default=0.1 + ) angle = FloatProperty(name="Pressure Angle", - description="Pressure angle, skewness of tooth tip", - min=0.0, - max=radians(45.0), - unit='ROTATION', - default=radians(20.0)) + description="Pressure angle, skewness of tooth tip", + min=0.0, + max=radians(45.0), + unit='ROTATION', + default=radians(20.0) + ) base = FloatProperty(name="Base", - description="Base, extent of gear below radius", - min=0.0, - max=100.0, - unit='LENGTH', - default=0.2) + description="Base, extent of gear below radius", + min=0.0, + max=100.0, + unit='LENGTH', + default=0.2 + ) width = FloatProperty(name="Width", - description="Width, thickness of gear", - min=0.05, - max=100.0, - unit='LENGTH', - default=0.2) + description="Width, thickness of gear", + min=0.05, + max=100.0, + unit='LENGTH', + default=0.2 + ) skew = FloatProperty(name="Skewness", - description="Skew of teeth", - min=radians(-90.0), - max=radians(90.0), - unit='ROTATION', - default=radians(0.0)) + description="Skew of teeth", + min=radians(-90.0), + max=radians(90.0), + unit='ROTATION', + default=radians(0.0) + ) conangle = FloatProperty(name="Conical angle", - description="Conical angle of gear", - min=0.0, - max=radians(90.0), - unit='ROTATION', - default=radians(0.0)) + description="Conical angle of gear", + min=0.0, + max=radians(90.0), + unit='ROTATION', + default=radians(0.0) + ) crown = FloatProperty(name="Crown", - description="Inward pointing extend of crown teeth", - min=0.0, - max=100.0, - unit='LENGTH', - default=0.0) + description="Inward pointing extend of crown teeth", + min=0.0, + max=100.0, + unit='LENGTH', + default=0.0 + ) def draw(self, context): layout = self.layout @@ -668,75 +682,75 @@ class AddWormGear(Operator): bl_options = {'REGISTER', 'UNDO', 'PRESET'} number_of_teeth = IntProperty( - name="Number of Teeth", - description="Number of teeth on the gear", - min=2, - max=265, - default=12 - ) + name="Number of Teeth", + description="Number of teeth on the gear", + min=2, + max=265, + default=12 + ) number_of_rows = IntProperty( - name="Number of Rows", - description="Number of rows on the worm gear", - min=2, - max=265, - default=32 - ) + name="Number of Rows", + description="Number of rows on the worm gear", + min=2, + max=265, + default=32 + ) radius = FloatProperty( - name="Radius", - description="Radius of the gear, negative for crown gear", - min=-100.0, - max=100.0, - unit='LENGTH', - default=1.0 - ) + name="Radius", + description="Radius of the gear, negative for crown gear", + min=-100.0, + max=100.0, + unit='LENGTH', + default=1.0 + ) addendum = FloatProperty( - name="Addendum", - description="Addendum, extent of tooth above radius", - min=0.01, - max=100.0, - unit='LENGTH', - default=0.1 - ) + name="Addendum", + description="Addendum, extent of tooth above radius", + min=0.01, + max=100.0, + unit='LENGTH', + default=0.1 + ) dedendum = FloatProperty( - name="Dedendum", - description="Dedendum, extent of tooth below radius", - min=0.0, - max=100.0, - unit='LENGTH', - default=0.1 - ) + name="Dedendum", + description="Dedendum, extent of tooth below radius", + min=0.0, + max=100.0, + unit='LENGTH', + default=0.1 + ) angle = FloatProperty( - name="Pressure Angle", - description="Pressure angle, skewness of tooth tip", - min=0.0, - max=radians(45.0), - default=radians(20.0), - unit='ROTATION' - ) + name="Pressure Angle", + description="Pressure angle, skewness of tooth tip", + min=0.0, + max=radians(45.0), + default=radians(20.0), + unit='ROTATION' + ) row_height = FloatProperty( - name="Row Height", - description="Height of each Row", - min=0.05, - max=100.0, - unit='LENGTH', - default=0.2 - ) + name="Row Height", + description="Height of each Row", + min=0.05, + max=100.0, + unit='LENGTH', + default=0.2 + ) skew = FloatProperty( - name="Skewness per Row", - description="Skew of each row", - min=radians(-90.0), - max=radians(90.0), - default=radians(11.25), - unit='ROTATION' - ) + name="Skewness per Row", + description="Skew of each row", + min=radians(-90.0), + max=radians(90.0), + default=radians(11.25), + unit='ROTATION' + ) crown = FloatProperty( - name="Crown", - description="Inward pointing extend of crown teeth", - min=0.0, - max=100.0, - unit='LENGTH', - default=0.0 - ) + name="Crown", + description="Inward pointing extend of crown teeth", + min=0.0, + max=100.0, + unit='LENGTH', + default=0.0 + ) def draw(self, context): layout = self.layout @@ -745,9 +759,11 @@ class AddWormGear(Operator): box.prop(self, "number_of_rows") box.prop(self, "radius") box.prop(self, "row_height") + box = layout.box() box.prop(self, "addendum") box.prop(self, "dedendum") + box = layout.box() box.prop(self, "angle") box.prop(self, "skew") diff --git a/add_mesh_extra_objects/add_mesh_gemstones.py b/add_mesh_extra_objects/add_mesh_gemstones.py index f99bcd43..0da6b488 100644 --- a/add_mesh_extra_objects/add_mesh_gemstones.py +++ b/add_mesh_extra_objects/add_mesh_gemstones.py @@ -2,7 +2,10 @@ import bpy from bpy.types import Operator -from mathutils import Vector, Quaternion +from mathutils import ( + Vector, + Quaternion, + ) from math import cos, sin, pi from bpy.props import ( FloatProperty, @@ -209,40 +212,40 @@ class AddDiamond(Operator): bl_options = {'REGISTER', 'UNDO', 'PRESET'} segments = IntProperty( - name="Segments", - description="Number of segments for the diamond", - min=3, - max=256, - default=32 - ) + name="Segments", + description="Number of segments for the diamond", + min=3, + max=256, + default=32 + ) girdle_radius = FloatProperty( - name="Girdle Radius", - description="Girdle radius of the diamond", - min=0.01, - max=9999.0, - default=1.0 - ) + name="Girdle Radius", + description="Girdle radius of the diamond", + min=0.01, + max=9999.0, + default=1.0 + ) table_radius = FloatProperty( - name="Table Radius", - description="Girdle radius of the diamond", - min=0.01, - max=9999.0, - default=0.6 - ) + name="Table Radius", + description="Girdle radius of the diamond", + min=0.01, + max=9999.0, + default=0.6 + ) crown_height = FloatProperty( - name="Crown Height", - description="Crown height of the diamond", - min=0.01, - max=9999.0, - default=0.35 - ) + name="Crown Height", + description="Crown height of the diamond", + min=0.01, + max=9999.0, + default=0.35 + ) pavilion_height = FloatProperty( - name="Pavilion Height", - description="Pavilion height of the diamond", - min=0.01, - max=9999.0, - default=0.8 - ) + name="Pavilion Height", + description="Pavilion height of the diamond", + min=0.01, + max=9999.0, + default=0.8 + ) def execute(self, context): verts, faces = add_diamond(self.segments, @@ -263,40 +266,40 @@ class AddGem(Operator): bl_options = {'REGISTER', 'UNDO', 'PRESET'} segments = IntProperty( - name="Segments", - description="Longitudial segmentation", - min=3, - max=265, - default=8 - ) + name="Segments", + description="Longitudial segmentation", + min=3, + max=265, + default=8 + ) pavilion_radius = FloatProperty( - name="Radius", - description="Radius of the gem", - min=0.01, - max=9999.0, - default=1.0 - ) + name="Radius", + description="Radius of the gem", + min=0.01, + max=9999.0, + default=1.0 + ) crown_radius = FloatProperty( - name="Table Radius", - description="Radius of the table(top)", - min=0.01, - max=9999.0, - default=0.6 - ) + name="Table Radius", + description="Radius of the table(top)", + min=0.01, + max=9999.0, + default=0.6 + ) crown_height = FloatProperty( - name="Table height", - description="Height of the top half", - min=0.01, - max=9999.0, - default=0.35 - ) + name="Table height", + description="Height of the top half", + min=0.01, + max=9999.0, + default=0.35 + ) pavilion_height = FloatProperty( - name="Pavilion height", - description="Height of bottom half", - min=0.01, - max=9999.0, - default=0.8 - ) + name="Pavilion height", + description="Height of bottom half", + min=0.01, + max=9999.0, + default=0.8 + ) def execute(self, context): # create mesh diff --git a/add_mesh_extra_objects/add_mesh_honeycomb.py b/add_mesh_extra_objects/add_mesh_honeycomb.py index e93b3b86..357be4cb 100644 --- a/add_mesh_extra_objects/add_mesh_honeycomb.py +++ b/add_mesh_extra_objects/add_mesh_honeycomb.py @@ -2,7 +2,10 @@ import bpy from bpy_extras import object_utils -from math import pi, sin, cos +from math import ( + pi, sin, + cos, + ) from bpy.props import ( IntProperty, BoolProperty, @@ -216,49 +219,48 @@ class add_mesh_honeycomb(bpy.types.Operator): self.edge = m rows = IntProperty( - name="Num of rows", - default=2, - min=1, max=100, - description='Number of the rows' - ) - + name="Num of rows", + default=2, + min=1, max=100, + description='Number of the rows' + ) cols = IntProperty( - name='Num of cols', - default=2, - min=1, max=100, - description='Number of the columns' - ) + name='Num of cols', + default=2, + min=1, max=100, + description='Number of the columns' + ) layers = BoolVectorProperty( - name="Layers", - size=20, - subtype='LAYER', - options={'HIDDEN', 'SKIP_SAVE'}, - ) + name="Layers", + size=20, + subtype='LAYER', + options={'HIDDEN', 'SKIP_SAVE'}, + ) diam = FloatProperty( - name='Cell Diameter', - default=1.0, - min=0.0, update=fix_edge, - description='Diameter of the cell' - ) + name='Cell Diameter', + default=1.0, + min=0.0, update=fix_edge, + description='Diameter of the cell' + ) edge = FloatProperty( - name='Edge Width', - default=0.1, - min=0.0, update=fix_edge, - description='Width of the edge' - ) + name='Edge Width', + default=0.1, + min=0.0, update=fix_edge, + description='Width of the edge' + ) # generic transform props view_align = BoolProperty( - name="Align to View", - default=False - ) + name="Align to View", + default=False + ) location = FloatVectorProperty( - name="Location", - subtype='TRANSLATION' - ) + name="Location", + subtype='TRANSLATION' + ) rotation = FloatVectorProperty( - name="Rotation", - subtype='EULER' - ) + name="Rotation", + subtype='EULER' + ) @classmethod def poll(cls, context): diff --git a/add_mesh_extra_objects/add_mesh_menger_sponge.py b/add_mesh_extra_objects/add_mesh_menger_sponge.py index 3f9ec241..088860d7 100644 --- a/add_mesh_extra_objects/add_mesh_menger_sponge.py +++ b/add_mesh_extra_objects/add_mesh_menger_sponge.py @@ -145,36 +145,36 @@ class AddMengerSponge(bpy.types.Operator): bl_options = {'REGISTER', 'UNDO'} level = IntProperty( - name="Level", - description="Sponge Level", - min=0, max=4, - default=1, - ) + name="Level", + description="Sponge Level", + min=0, max=4, + default=1, + ) radius = FloatProperty( - name="Width", - description="Sponge Radius", - min=0.01, max=100.0, - default=1.0, - ) + name="Width", + description="Sponge Radius", + min=0.01, max=100.0, + default=1.0, + ) # generic transform props view_align = BoolProperty( - name="Align to View", - default=False, - ) + name="Align to View", + default=False, + ) location = FloatVectorProperty( - name="Location", - subtype='TRANSLATION', - ) + name="Location", + subtype='TRANSLATION', + ) rotation = FloatVectorProperty( - name="Rotation", - subtype='EULER', - ) + name="Rotation", + subtype='EULER', + ) layers = BoolVectorProperty( - name="Layers", - size=20, - subtype='LAYER', - options={'HIDDEN', 'SKIP_SAVE'}, - ) + name="Layers", + size=20, + subtype='LAYER', + options={'HIDDEN', 'SKIP_SAVE'}, + ) def execute(self, context): sponger = MengerSponge(self.level) diff --git a/add_mesh_extra_objects/add_mesh_pyramid.py b/add_mesh_extra_objects/add_mesh_pyramid.py index 5c054c9f..680267cb 100644 --- a/add_mesh_extra_objects/add_mesh_pyramid.py +++ b/add_mesh_extra_objects/add_mesh_pyramid.py @@ -2,35 +2,43 @@ import bpy import bmesh +from bpy.types import Operator from bpy.props import ( FloatProperty, IntProperty, ) from math import pi -from mathutils import Quaternion, Vector -from bpy_extras.object_utils import AddObjectHelper, object_data_add +from mathutils import ( + Quaternion, + Vector, + ) +from bpy_extras.object_utils import ( + AddObjectHelper, + object_data_add, + ) def create_step(width, base_level, step_height, num_sides): - axis = [0, 0, -1] - PI2 = pi * 2 - rad = width / 2 + axis = [0, 0, -1] + PI2 = pi * 2 + rad = width / 2 + + quat_angles = [(cur_side / num_sides) * PI2 + for cur_side in range(num_sides)] - quat_angles = [(cur_side / num_sides) * PI2 - for cur_side in range(num_sides)] + quaternions = [Quaternion(axis, quat_angle) + for quat_angle in quat_angles] - quaternions = [Quaternion(axis, quat_angle) - for quat_angle in quat_angles] + init_vectors = [Vector([rad, 0, base_level])] * len(quaternions) - init_vectors = [Vector([rad, 0, base_level])] * len(quaternions) + quat_vector_pairs = list(zip(quaternions, init_vectors)) + vectors = [quaternion * vec for quaternion, vec in quat_vector_pairs] + bottom_list = [(vec.x, vec.y, vec.z) for vec in vectors] + top_list = [(vec.x, vec.y, vec.z + step_height) for vec in vectors] + full_list = bottom_list + top_list - quat_vector_pairs = list(zip(quaternions, init_vectors)) - vectors = [quaternion * vec for quaternion, vec in quat_vector_pairs] - bottom_list = [(vec.x, vec.y, vec.z) for vec in vectors] - top_list = [(vec.x, vec.y, vec.z + step_height) for vec in vectors] - full_list = bottom_list + top_list - return full_list + return full_list def split_list(l, n): @@ -52,83 +60,83 @@ def get_connector_pairs(lst, n_sides): def add_pyramid_object(self, context): - all_verts = [] + all_verts = [] - height_offset = 0 - cur_width = self.width + height_offset = 0 + cur_width = self.width - for i in range(self.num_steps): - verts_loc = create_step(cur_width, height_offset, self.height, - self.num_sides) - height_offset += self.height - cur_width -= self.reduce_by - all_verts.extend(verts_loc) + for i in range(self.num_steps): + verts_loc = create_step(cur_width, height_offset, self.height, + self.num_sides) + height_offset += self.height + cur_width -= self.reduce_by + all_verts.extend(verts_loc) - mesh = bpy.data.meshes.new("Pyramid") - bm = bmesh.new() + mesh = bpy.data.meshes.new("Pyramid") + bm = bmesh.new() - for v_co in all_verts: - bm.verts.new(v_co) + for v_co in all_verts: + bm.verts.new(v_co) - def add_faces(n, block_vert_sets): - for bvs in block_vert_sets: - for i in range(self.num_sides - 1): - bm.faces.new([bvs[i], bvs[i + n], bvs[i + n + 1], bvs[i + 1]]) - bm.faces.new([bvs[n - 1], bvs[(n * 2) - 1], bvs[n], bvs[0]]) + def add_faces(n, block_vert_sets): + for bvs in block_vert_sets: + for i in range(self.num_sides - 1): + bm.faces.new([bvs[i], bvs[i + n], bvs[i + n + 1], bvs[i + 1]]) + bm.faces.new([bvs[n - 1], bvs[(n * 2) - 1], bvs[n], bvs[0]]) - # get the base and cap faces done. - bm.faces.new(bm.verts[0:self.num_sides]) - bm.faces.new(reversed(bm.verts[-self.num_sides:])) # otherwise normal faces intern... T44619. + # get the base and cap faces done. + bm.faces.new(bm.verts[0:self.num_sides]) + bm.faces.new(reversed(bm.verts[-self.num_sides:])) # otherwise normal faces intern... T44619. - # side faces - block_vert_sets = split_list(bm.verts, self.num_sides) - add_faces(self.num_sides, block_vert_sets) + # side faces + block_vert_sets = split_list(bm.verts, self.num_sides) + add_faces(self.num_sides, block_vert_sets) - # connector faces between faces and faces of the block above it. - connector_pairs = get_connector_pairs(bm.verts, self.num_sides) - add_faces(self.num_sides, connector_pairs) + # connector faces between faces and faces of the block above it. + connector_pairs = get_connector_pairs(bm.verts, self.num_sides) + add_faces(self.num_sides, connector_pairs) - bm.to_mesh(mesh) - mesh.update() - res = object_data_add(context, mesh, operator=self) + bm.to_mesh(mesh) + mesh.update() + res = object_data_add(context, mesh, operator=self) -class AddPyramid(bpy.types.Operator, AddObjectHelper): +class AddPyramid(Operator, AddObjectHelper): bl_idname = "mesh.primitive_steppyramid_add" bl_label = "Pyramid" bl_description = "Construct a step pyramid mesh" bl_options = {'REGISTER', 'UNDO', 'PRESET'} num_sides = IntProperty( - name="Number Sides", - description="How many sides each step will have", - min=3, max=20, - default=4 - ) + name="Number Sides", + description="How many sides each step will have", + min=3, max=20, + default=4 + ) num_steps = IntProperty( - name="Number of Steps", - description="How many steps for the overall pyramid", - min=1, max=20, - default=10 - ) + name="Number of Steps", + description="How many steps for the overall pyramid", + min=1, max=20, + default=10 + ) width = FloatProperty( - name="Initial Width", - description="Initial base step width", - min=0.01, max=100.0, - default=2 - ) + name="Initial Width", + description="Initial base step width", + min=0.01, max=100.0, + default=2 + ) height = FloatProperty( - name="Height", - description="How tall each step will be", - min=0.01, max=100.0, - default=0.1 - ) + name="Height", + description="How tall each step will be", + min=0.01, max=100.0, + default=0.1 + ) reduce_by = FloatProperty( - name="Reduce Step By", - description="How much to reduce each succeeding step by", - min=.01, max=2.0, - default=.20 - ) + name="Reduce Step By", + description="How much to reduce each succeeding step by", + min=.01, max=2.0, + default=.20 + ) def execute(self, context): add_pyramid_object(self, context) diff --git a/add_mesh_extra_objects/add_mesh_round_brilliant.py b/add_mesh_extra_objects/add_mesh_round_brilliant.py index 537099b7..850421d8 100644 --- a/add_mesh_extra_objects/add_mesh_round_brilliant.py +++ b/add_mesh_extra_objects/add_mesh_round_brilliant.py @@ -1,9 +1,15 @@ # GPL "author": "Dominic Kröper, (dommetysk)" import bpy -from math import pi, sin, cos, tan +from math import ( + pi, sin, + cos, tan, + ) from bpy.types import Operator -from mathutils import Vector, Euler +from mathutils import ( + Vector, + Euler, + ) from bpy.props import ( IntProperty, FloatProperty, @@ -34,7 +40,7 @@ def addBrilliant(context, s, table_w, crown_h, girdle_t, pavi_d, bezel_f, s = s - 1 if not girdle_real: g_real_smooth = False - ang = 2 * pi / s # angle step size + ang = 2 * pi / s # angle step size Verts = [] # collect all vertices Faces = [] # collect all faces ca = cos(ang) @@ -300,85 +306,85 @@ class MESH_OT_primitive_brilliant_add(Operator): # set user options s = IntProperty( - name="Segments", - description="Longitudial segmentation", - step=1, - min=6, - max=128, - default=16, - subtype='FACTOR' - ) + name="Segments", + description="Longitudial segmentation", + step=1, + min=6, + max=128, + default=16, + subtype='FACTOR' + ) table_w = FloatProperty( - name="Table width", - description="Width of table", - min=0.001, - max=1.0, - default=0.53, - subtype='PERCENTAGE' - ) + name="Table width", + description="Width of table", + min=0.001, + max=1.0, + default=0.53, + subtype='PERCENTAGE' + ) crown_h = FloatProperty( - name="Crown height", - description="Heigth of crown", - min=0.0, - max=1.0, - default=0.162, - subtype='PERCENTAGE' - ) + name="Crown height", + description="Heigth of crown", + min=0.0, + max=1.0, + default=0.162, + subtype='PERCENTAGE' + ) girdle_t = FloatProperty( - name="Girdle height", - description="Height of girdle", - min=0.0, - max=0.5, - default=0.017, - subtype='PERCENTAGE' - ) + name="Girdle height", + description="Height of girdle", + min=0.0, + max=0.5, + default=0.017, + subtype='PERCENTAGE' + ) girdle_real = BoolProperty( - name="Real girdle", - description="More beautiful girdle; has more polygons", - default=True - ) + name="Real girdle", + description="More beautiful girdle; has more polygons", + default=True + ) g_real_smooth = BoolProperty( - name="Smooth girdle", - description="smooth shading for girdle, only available for real girdle", - default=False - ) + name="Smooth girdle", + description="smooth shading for girdle, only available for real girdle", + default=False + ) pavi_d = FloatProperty( - name="Pavilion depth", - description="Height of pavillion", - min=0.0, - max=1.0, - default=0.431, - subtype='PERCENTAGE' - ) + name="Pavilion depth", + description="Height of pavillion", + min=0.0, + max=1.0, + default=0.431, + subtype='PERCENTAGE' + ) bezel_f = FloatProperty( - name="Upper facet factor", - description="Determines the form of bezel and upper girdle facets", - min=0.0, - max=1.0, - default=0.250, - subtype='PERCENTAGE' - ) + name="Upper facet factor", + description="Determines the form of bezel and upper girdle facets", + min=0.0, + max=1.0, + default=0.250, + subtype='PERCENTAGE' + ) pavi_f = FloatProperty( - name="Lower facet factor", - description="Determines the form of pavillion and lower girdle facets", - min=0.001, - max=1.0, - default=0.400, - subtype='PERCENTAGE' - ) + name="Lower facet factor", + description="Determines the form of pavillion and lower girdle facets", + min=0.001, + max=1.0, + default=0.400, + subtype='PERCENTAGE' + ) culet = FloatProperty( - name="Culet size", - description="0: no culet (default)", - min=0.0, - max=0.999, - default=0.0, - subtype='PERCENTAGE' - ) + name="Culet size", + description="0: no culet (default)", + min=0.0, + max=0.999, + default=0.0, + subtype='PERCENTAGE' + ) keep_lga = BoolProperty( - name="Retain lower angle", - description="If culet > 0, retains angle of pavillion facets", - default=False - ) + name="Retain lower angle", + description="If culet > 0, retains angle of pavillion facets", + default=False + ) # call mesh/object generator function with user inputs def execute(self, context): diff --git a/add_mesh_extra_objects/add_mesh_round_cube.py b/add_mesh_extra_objects/add_mesh_round_cube.py index b56ac3d3..dca438ae 100644 --- a/add_mesh_extra_objects/add_mesh_round_cube.py +++ b/add_mesh_extra_objects/add_mesh_round_cube.py @@ -3,7 +3,11 @@ import bpy from bpy_extras import object_utils from itertools import permutations -from math import copysign, pi, sqrt +from math import ( + copysign, pi, + sqrt, + ) +from bpy.types import Operator from bpy.props import ( BoolProperty, EnumProperty, @@ -109,12 +113,12 @@ def round_cube(radius=1.0, arcdiv=4, lindiv=0., size=(0., 0., 0.), # Sides built left to right bottom up # xp yp zp xd yd zd - sides = ((0, 2, 1, (-1, 1, 1)), # Y+ Front - (1, 2, 0, (-1, -1, 1)), # X- Left - (0, 2, 1, ( 1, -1, 1)), # Y- Back - (1, 2, 0, ( 1, 1, 1)), # X+ Right - (0, 1, 2, (-1, 1, -1)), # Z- Bottom - (0, 1, 2, (-1, -1, 1))) # Z+ Top + sides = ((0, 2, 1, (-1, 1, 1)), # Y+ Front + (1, 2, 0, (-1, -1, 1)), # X- Left + (0, 2, 1, (1, -1, 1)), # Y- Back + (1, 2, 0, (1, 1, 1)), # X+ Right + (0, 1, 2, (-1, 1, -1)), # Z- Bottom + (0, 1, 2, (-1, -1, 1))) # Z+ Top # side vertex index table (for sphere) svit = [[[] for i in range(steps)] for i in range(6)] @@ -325,36 +329,34 @@ def round_cube(radius=1.0, arcdiv=4, lindiv=0., size=(0., 0., 0.), return verts, faces -class AddRoundCube(bpy.types.Operator, object_utils.AddObjectHelper): +class AddRoundCube(Operator, object_utils.AddObjectHelper): bl_idname = "mesh.primitive_round_cube_add" bl_label = "Add Round Cube" - bl_description = ( - "Create mesh primitives: Quadspheres, " - "Capsules, Rounded Cuboids, 3D Grids etc" - ) + bl_description = ("Create mesh primitives: Quadspheres, " + "Capsules, Rounded Cuboids, 3D Grids etc") bl_options = {"REGISTER", "UNDO", "PRESET"} sanity_check_verts = 200000 vert_count = 0 radius = FloatProperty( - name='Radius', - description='Radius of vertices for sphere, capsule or cuboid bevel', + name="Radius", + description="Radius of vertices for sphere, capsule or cuboid bevel", default=1.0, min=0.0, soft_min=0.01, step=10 ) size = FloatVectorProperty( - name='Size', - description='Size', + name="Size", + description="Size", subtype='XYZ', ) arc_div = IntProperty( - name='Arc Divisions', - description='Arc curve divisions, per quadrant; 0=derive from Linear', + name="Arc Divisions", + description="Arc curve divisions, per quadrant, 0=derive from Linear", default=4, min=1 ) lin_div = FloatProperty( - name='Linear Divisions', - description='Linear unit divisions (Edges/Faces); 0=derive from Arc', + name="Linear Divisions", + description="Linear unit divisions (Edges/Faces), 0=derive from Arc", default=0.0, min=0.0, step=100, precision=1 ) div_type = EnumProperty( @@ -378,7 +380,8 @@ class AddRoundCube(bpy.types.Operator, object_utils.AddObjectHelper): def execute(self, context): if self.arc_div <= 0 and self.lin_div <= 0: - self.report({'ERROR'}, 'Either Arc Divisions or Linear Divisions must be greater than zero!') + self.report({'ERROR'}, + "Either Arc Divisions or Linear Divisions must be greater than zero") return {'CANCELLED'} if not self.no_limit: @@ -397,8 +400,11 @@ class AddRoundCube(bpy.types.Operator, object_utils.AddObjectHelper): return {'FINISHED'} def check(self, context): - self.arcdiv, self.lindiv, self.vert_count = round_cube(self.radius, self.arc_div, self.lin_div, - self.size, self.div_type, self.odd_axis_align, True) + self.arcdiv, self.lindiv, self.vert_count = round_cube( + self.radius, self.arc_div, self.lin_div, + self.size, self.div_type, self.odd_axis_align, + True + ) return True def invoke(self, context, event): @@ -440,4 +446,3 @@ class AddRoundCube(bpy.types.Operator, object_utils.AddObjectHelper): col.prop(self, 'location', expand=True) col = layout.column(align=True) col.prop(self, 'rotation', expand=True) - diff --git a/add_mesh_extra_objects/add_mesh_star.py b/add_mesh_extra_objects/add_mesh_star.py index ae63f2c6..b7e420fe 100644 --- a/add_mesh_extra_objects/add_mesh_star.py +++ b/add_mesh_extra_objects/add_mesh_star.py @@ -1,7 +1,10 @@ # GPL Original by Fourmadmen import bpy -from mathutils import Vector, Quaternion +from mathutils import ( + Vector, + Quaternion, + ) from math import pi from bpy.props import ( IntProperty, diff --git a/add_mesh_extra_objects/add_mesh_teapot.py b/add_mesh_extra_objects/add_mesh_teapot.py index 27e7f703..23dd084f 100644 --- a/add_mesh_extra_objects/add_mesh_teapot.py +++ b/add_mesh_extra_objects/add_mesh_teapot.py @@ -5,9 +5,7 @@ from bpy.props import ( IntProperty, EnumProperty, ) - import mathutils - import io import operator import functools @@ -111,10 +109,19 @@ def patches_to_raw(patches, resolution): def make_bezier(ctrlpnts, resolution): - b1 = lambda t: t * t * t - b2 = lambda t: 3.0 * t * t * (1.0 - t) - b3 = lambda t: 3.0 * t * (1.0 - t) * (1.0 - t) - b4 = lambda t: (1.0 - t) * (1.0 - t) * (1.0 - t) + + def b1(t): + return t * t * t + + def b2(t): + return 3.0 * t * t * (1.0 - t) + + def b3(t): + return 3.0 * t * (1.0 - t) * (1.0 - t) + + def b4(t): + return (1.0 - t) * (1.0 - t) * (1.0 - t) + p1, p2, p3, p4 = map(mathutils.Vector, ctrlpnts) def makevert(t): diff --git a/add_mesh_extra_objects/add_mesh_triangles.py b/add_mesh_extra_objects/add_mesh_triangles.py index c1a57469..f5768c0a 100644 --- a/add_mesh_extra_objects/add_mesh_triangles.py +++ b/add_mesh_extra_objects/add_mesh_triangles.py @@ -1,15 +1,15 @@ +# GPL # "author": Sjaak-de-Draak + bl_info = { "name": "Triangles", - "description": "Create different types of tirangles.", + "description": "Create different types of triangles", "author": "Sjaak-de-Draak", - "version": (1, 0), + "version": (1, 0, 1), "blender": (2, 68, 0), "location": "View3D > Add > Mesh", - "warning": "First Version", # used for warning icon and text in addons panel - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" + "warning": "First Version", + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" "Scripts/Triangles", - "tracker_url": "http://projects.blender.org/tracker/index.php?" - "func=detail&aid=<number>", "category": "Add Mesh"} """ @@ -19,202 +19,219 @@ and a toolbar menu to further specify settings import math import bpy -import mathutils -import types +from mathutils import Vector +from bpy.types import Operator +from bpy.props import ( + BoolProperty, + EnumProperty, + FloatProperty, + ) -# make the mathutils Vector type accessible as Vector -Vector=mathutils.Vector def checkEditMode(): - ## Check if we are in edit mode - ## Returns: 1 if True - ## 0 if False + # Check if we are in edit mode + # Returns: 1 if True + # 0 if False if (bpy.context.active_object.mode == 'EDIT'): - return 1; - return 0; + return 1 + return 0 + def exitEditMode(): - ## Check if we are in edit mode (cuz we don't want this when creating a new Mesh) - ## If we are then toggle back to object mode + # Check if we are in edit mode (cuz we don't want this when creating a new Mesh) + # If we are then toggle back to object mode # Check if there are active objects - if (bpy.context.active_object != None ): - # Only the active object should be in edit mode + if bpy.context.active_object is not None: + # Only the active object should be in edit mode if (bpy.context.active_object.mode == 'EDIT'): bpy.ops.object.editmode_toggle() -class MakeTriangle(bpy.types.Operator): + +class MakeTriangle(Operator): bl_idname = "mesh.make_triangle" bl_label = "Triangle" + bl_description = "Construct different types of Triangle Meshes" bl_options = {"REGISTER", "UNDO"} - nothing=0 + nothing = 0 Ya = 0.0 Xb = 0.0 Xc = 0.0 - Vertices = [ ] - Faces = [ ] + Vertices = [] + Faces = [] - triangleTypeList = [('ISOSCELES', "Isosceles", "Two equal sides", 0), + triangleTypeList = [ + ('ISOSCELES', "Isosceles", "Two equal sides", 0), ('EQUILATERAL', "Equilateral", "Three equal sides and angles (60°)", 1), ('ISOSCELESRIGHTANGLE', "Isosceles right angled", "90° angle and two equal sides", 2), - ('SCALENERIGHTANGLE', "Scalene right angled", "90° angle, no equal sides", 3)] - - triangleFaceList = [('DEFAULT', "Normal", "1 Tri(angle) face", 0), + ('SCALENERIGHTANGLE', "Scalene right angled", "90° angle, no equal sides", 3) + ] + triangleFaceList = [ + ('DEFAULT', "Normal", "1 Tri(angle) face", 0), ('TRIANGLES', "3 Tri faces", "4 Verticies & 3 Tri(angle) faces", 1), ('QUADS', "3 Quad faces", "7 Verticies & 3 Quad faces", 2), - ('SAFEQUADS', "6 Quad faces", "12 Verticies & 6 Quad faces", 3)] + ('SAFEQUADS', "6 Quad faces", "12 Verticies & 6 Quad faces", 3) + ] # add definitions for some manipulation buttons - flipX = bpy.props.BoolProperty(name="Flip X sign", - description="Draw on the other side of the X axis (Mirror on Y axis)", - default = False) - flipY = bpy.props.BoolProperty(name="Flip Y sign", - description="Draw on the other side of the Y axis (Mirror on X axis)", - default = False) - scale = bpy.props.FloatProperty(name="Scale", - description="Triangle scale", - default=1.0, min=1.0) - triangleType = bpy.props.EnumProperty(items=triangleTypeList, - name="Type", - description="Triangle Type") - triangleFace = bpy.props.EnumProperty(items=triangleFaceList, - name="Face types", - description="Triangle Face Types") - at_3Dcursor = bpy.props.BoolProperty(name="At 3D Cursor", - description="Draw the triangle where the 3D cursor is", - default = False) - + flipX = BoolProperty( + name="Flip X sign", + description="Draw on the other side of the X axis (Mirror on Y axis)", + default=False + ) + flipY = BoolProperty( + name="Flip Y sign", + description="Draw on the other side of the Y axis (Mirror on X axis)", + default=False + ) + scale = FloatProperty( + name="Scale", + description="Triangle scale", + default=1.0, + min=1.0 + ) + triangleType = EnumProperty( + items=triangleTypeList, + name="Type", + description="Triangle Type" + ) + triangleFace = EnumProperty( + items=triangleFaceList, + name="Face types", + description="Triangle Face Types" + ) + at_3Dcursor = BoolProperty( + name="Use 3D Cursor", + description="Draw the triangle where the 3D cursor is", + default=False + ) def draw(self, context): layout = self.layout - row = layout.row(align=True) - row.label(text="Type: ") - - row.prop(self, "triangleType", text="") - - row = layout.row(align=True) - row.prop(self, "at_3Dcursor", text="3D Cursor") - row.prop(self, "scale") - - row = layout.row(align=True) - row.label(text="Face Type: ") - row.prop(self, "triangleFace", text="") + col = layout.column(align=True) + col.prop(self, "triangleType", text="Type") + col.prop(self, "scale") + col.prop(self, "triangleFace", text="Face") col = layout.column(align=True) - col.prop(self, "flipX") - col.prop(self, "flipY") - #end draw + col.prop(self, "at_3Dcursor", text="3D Cursor", toggle=True) + + row = col.row(align=True) + row.prop(self, "flipX", toggle=True) + row.prop(self, "flipY", toggle=True) def drawBasicTriangleShape(self): # set everything to 0 - X = Xa = Xb = Xc = 0.0 - Y = Ya = Yb = Yc = 0.0 - Z = Za = Zb = Zc = 0.0 + Xb = Xc = 0.0 + Ya = 0.0 - scale=self.scale + scale = self.scale Xsign = -1 if self.flipX else 1 Ysign = -1 if self.flipY else 1 # Isosceles (2 equal sides) - if ( self.triangleType == 'ISOSCELES' ): + if (self.triangleType == 'ISOSCELES'): # below a simple triangle containing 2 triangles with 1:2 side ratio - Ya=(1 * Ysign * scale) - A=Vector([0.0, Ya, 0.0]) - Xb=(0.5 * Xsign * scale) - B=Vector([Xb, 0.0, 0.0]) - Xc=(-0.5 * Xsign * scale) - C=Vector([Xc, 0.0, 0.0]) - - self.Ya=Ya - self.Xb=Xb - self.Xc=Xc - self.Vertices = [A, B, C,] + Ya = (1 * Ysign * scale) + A = Vector([0.0, Ya, 0.0]) + Xb = (0.5 * Xsign * scale) + B = Vector([Xb, 0.0, 0.0]) + Xc = (-0.5 * Xsign * scale) + C = Vector([Xc, 0.0, 0.0]) + + self.Ya = Ya + self.Xb = Xb + self.Xc = Xc + self.Vertices = [A, B, C, ] + return True # Equilateral (all sides equal) - if ( self.triangleType == 'EQUILATERAL' ): - Ya=(math.sqrt(0.75) * Ysign * scale) - A=Vector([0.0, Ya, 0.0]) - Xb=(0.5 * Xsign * scale) - B=Vector([Xb, 0.0, 0.0]) - Xc=(-0.5 * Xsign * scale) - C=Vector([Xc, 0.0, 0.0]) - - self.Ya=Ya - self.Xb=Xb - self.Xc=Xc - self.Vertices = [A, B, C,] + if (self.triangleType == 'EQUILATERAL'): + Ya = (math.sqrt(0.75) * Ysign * scale) + A = Vector([0.0, Ya, 0.0]) + Xb = (0.5 * Xsign * scale) + B = Vector([Xb, 0.0, 0.0]) + Xc = (-0.5 * Xsign * scale) + C = Vector([Xc, 0.0, 0.0]) + + self.Ya = Ya + self.Xb = Xb + self.Xc = Xc + self.Vertices = [A, B, C, ] + return True - # Isosceles right angled ( 1, 1, sqrt(2) ) - if ( self.triangleType == 'ISOSCELESRIGHTANGLE' ): - Ya=(1 * Ysign * scale) - A=Vector([0.0, Ya, 0.0]) - Xb=0.0 - B=Vector([Xb, 0.0, 0.0]) - Xc=(1 * Xsign * scale) - C=Vector([Xc, 0.0, 0.0]) - - self.Ya=Ya - self.Xb=Xb - self.Xc=Xc - self.Vertices = [A, B, C,] + # Isosceles right angled (1, 1, sqrt(2)) + if (self.triangleType == 'ISOSCELESRIGHTANGLE'): + Ya = (1 * Ysign * scale) + A = Vector([0.0, Ya, 0.0]) + Xb = 0.0 + B = Vector([Xb, 0.0, 0.0]) + Xc = (1 * Xsign * scale) + C = Vector([Xc, 0.0, 0.0]) + + self.Ya = Ya + self.Xb = Xb + self.Xc = Xc + self.Vertices = [A, B, C, ] return True - # Scalene right angled ( 3, 4, 5 ) - if ( self.triangleType == 'SCALENERIGHTANGLE' ): - Ya=(1 * Ysign * scale) - A=Vector([0.0, Ya, 0.0]) - Xb=0 - B=Vector([Xb, 0.0, 0.0]) - Xc=(0.75 * Xsign * scale) - C=Vector([Xc, 0.0, 0.0]) - - self.Ya=Ya - self.Xb=Xb - self.Xc=Xc - self.Vertices = [A, B, C,] + # Scalene right angled (3, 4, 5) + if (self.triangleType == 'SCALENERIGHTANGLE'): + Ya = (1 * Ysign * scale) + A = Vector([0.0, Ya, 0.0]) + Xb = 0 + B = Vector([Xb, 0.0, 0.0]) + Xc = (0.75 * Xsign * scale) + C = Vector([Xc, 0.0, 0.0]) + + self.Ya = Ya + self.Xb = Xb + self.Xc = Xc + self.Vertices = [A, B, C, ] return True + return False def addFaces(self, fType=None): - Ya=self.Ya - Xb=self.Xb - Xc=self.Xc + Ya = self.Ya + Xb = self.Xb + Xc = self.Xc if (self.triangleFace == 'DEFAULT'): - self.Faces=[[0,1,2]] + self.Faces = [[0, 1, 2]] return True if (self.triangleFace == 'TRIANGLES'): - A=Vector([0.0, Ya, 0.0]) - B=Vector([Xb, 0.0, 0.0]) - C=Vector([Xc, 0.0, 0.0]) - D=Vector([((A.x + B.x + C.x) /3), ((A.y + B.y + C.y) /3), ((A.z + B.z + C.z) /3)]) + A = Vector([0.0, Ya, 0.0]) + B = Vector([Xb, 0.0, 0.0]) + C = Vector([Xc, 0.0, 0.0]) + D = Vector([((A.x + B.x + C.x) / 3), ((A.y + B.y + C.y) / 3), ((A.z + B.z + C.z) / 3)]) - self.Vertices = [A, B, C, D,] - self.Faces=[[0,1,3], [1,2,3], [2,0,3]] + self.Vertices = [A, B, C, D, ] + self.Faces = [[0, 1, 3], [1, 2, 3], [2, 0, 3]] return True if (self.triangleFace == 'QUADS'): - A=Vector([0.0, Ya, 0.0]) - B=Vector([Xb, 0.0, 0.0]) - C=Vector([Xc, 0.0, 0.0]) - D=Vector([((A.x + B.x + C.x) /3), ((A.y + B.y + C.y) /3), ((A.z + B.z + C.z) /3)]) + A = Vector([0.0, Ya, 0.0]) + B = Vector([Xb, 0.0, 0.0]) + C = Vector([Xc, 0.0, 0.0]) + D = Vector([((A.x + B.x + C.x) / 3), ((A.y + B.y + C.y) / 3), ((A.z + B.z + C.z) / 3)]) AB = A.lerp(B, 0.5) AC = A.lerp(C, 0.5) BC = B.lerp(C, 0.5) - self.Vertices = [A, AB, B, BC, C, AC, D,] - self.Faces=[[0,1,6,5], [1,2,3,6], [3,4,5,6]] + self.Vertices = [A, AB, B, BC, C, AC, D, ] + self.Faces = [[0, 1, 6, 5], [1, 2, 3, 6], [3, 4, 5, 6]] return True if (self.triangleFace == 'SAFEQUADS'): - A=Vector([0.0, Ya, 0.0]) - B=Vector([Xb, 0.0, 0.0]) - C=Vector([Xc, 0.0, 0.0]) - D=Vector([((A.x + B.x + C.x) /3), ((A.y + B.y + C.y) /3), ((A.z + B.z + C.z) /3)]) + A = Vector([0.0, Ya, 0.0]) + B = Vector([Xb, 0.0, 0.0]) + C = Vector([Xc, 0.0, 0.0]) + D = Vector([((A.x + B.x + C.x) / 3), ((A.y + B.y + C.y) / 3), ((A.z + B.z + C.z) / 3)]) E = A.lerp(D, 0.5) AB = A.lerp(B, 0.5) AC = A.lerp(C, 0.5) @@ -226,31 +243,33 @@ class MakeTriangle(bpy.types.Operator): BCC = BC.lerp(C, 0.5) CCA = AC.lerp(C, 0.5) - self.Vertices = [A, AAB, BBA, B, BBC, BC, BCC, C, CCA, AAC, D, E,] - self.Faces=[[0,1,11,9], [1,2,10,11], [2,3,4,10], [4,5,6,10], [6,7,8,10], [8,9,11,10]] + self.Vertices = [A, AAB, BBA, B, BBC, BC, BCC, C, CCA, AAC, D, E, ] + self.Faces = [[0, 1, 11, 9], [1, 2, 10, 11], [2, 3, 4, 10], + [4, 5, 6, 10], [6, 7, 8, 10], [8, 9, 11, 10]] return True - return False + return False def action_common(self, context): # definitions: - # a triangle consists of 3 points: A, B, C - # a 'safer' subdividable triangle consists of 4 points: A, B, C, D - # a subdivide friendly triangle consists of 7 points: A, B, C, D, AB, AC, BC - # a truely subdivide friendly triangle consists of (3x4=)12 points: A, B, C, D, E, BC, AAB, AAC, BBA, BBC, BCC, CCA + # a triangle consists of 3 points: A, B, C + # a 'safer' subdividable triangle consists of 4 points: A, B, C, D + # a subdivide friendly triangle consists of 7 points: A, B, C, D, AB, AC, BC + # a truely subdivide friendly triangle consists of (3 x 4 = )12 points: + # A, B, C, D, E, BC, AAB, AAC, BBA, BBC, BCC, CCA - BasicShapeCreated=False - ShapeFacesCreated=False - go=0 + BasicShapeCreated = False + ShapeFacesCreated = False + go = 0 # # call the functions for creating the triangles and test if successfull # - BasicShapeCreated=self.drawBasicTriangleShape() + BasicShapeCreated = self.drawBasicTriangleShape() if (BasicShapeCreated): - ShapeFacesCreated=self.addFaces() - if (ShapeFacesCreated): - go=1 + ShapeFacesCreated = self.addFaces() + if ShapeFacesCreated: + go = 1 if (go == 1): NewMesh = bpy.data.meshes.new("Triangle") @@ -262,38 +281,37 @@ class MakeTriangle(bpy.types.Operator): # before doing the deselect make sure edit mode isn't active exitEditMode() - bpy.ops.object.select_all(action = "DESELECT") + bpy.ops.object.select_all(action="DESELECT") NewObj.select = True context.scene.objects.active = NewObj - if (self.at_3Dcursor == True): + + if self.at_3Dcursor is True: # we'll need to be sure there is actually an object selected - if (NewObj.select == True): + if NewObj.select is True: # we also have to check if we're considered to be in 3D View (view3d) - if (bpy.ops.view3d.snap_selected_to_cursor.poll() == True): + if bpy.ops.view3d.snap_selected_to_cursor.poll() is True: bpy.ops.view3d.snap_selected_to_cursor() else: # as we weren't considered to be in 3D View # the object couldn't be moved to the 3D cursor # so to avoid confusion we change the at_3Dcursor boolean to false self.at_3Dcursor = False + else: - print("Failed to create triangle: ") - print("Triangle type: %s" % self.triangleType) - print("Face type: %s" % self.triangleFace) - print("Ya: %s" % self.Ya) - print("Xb: %s" % self.Xb) - print("Xc: %s" % self.Xc) - print("Vertices: %s" % self.Vertices) - print("Faces: %s" % self.Faces) - - #end action_common - - def execute(self, context) : + self.report({'WARNING'}, + "Triangle could not be completed. (See Console for more Info)") + + print("\n[Add Mesh Extra Objects]\n\nModule: add_mesh_triangle") + print("Triangle type: %s\n" % self.triangleType, + "Face type: %s\n" % self.triangleFace, + "Ya: %s, Xb: %s, Xc: %s\n" % (self.Ya, self.Xb, self.Xc), + "Vertices: %s\n" % self.Vertices, + "Faces: %s\n" % self.Faces) + + def execute(self, context): self.action_common(context) return {"FINISHED"} - #end execute - def invoke(self, context, event) : + def invoke(self, context, event): self.action_common(context) return {"FINISHED"} - #end invoke diff --git a/ant_landscape/__init__.py b/ant_landscape/__init__.py new file mode 100644 index 00000000..02f66ec4 --- /dev/null +++ b/ant_landscape/__init__.py @@ -0,0 +1,757 @@ +# ##### 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 ##### + +# Another Noise Tool - Suite +# Jim Hazevoet 5/2017 + +bl_info = { + "name": "A.N.T.Landscape", + "author": "Jim Hazevoet", + "version": (0, 1, 6), + "blender": (2, 77, 0), + "location": "View3D > Tool Shelf", + "description": "Another Noise Tool: Landscape and Displace", + "warning": "", + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" + "Scripts/Add_Mesh/ANT_Landscape", + "category": "Add Mesh", +} + +if "bpy" in locals(): + import importlib + importlib.reload(add_mesh_ant_landscape) + importlib.reload(ant_landscape_refresh) + importlib.reload(mesh_ant_displace) + importlib.reload(ant_functions) +else: + from ant_landscape import add_mesh_ant_landscape + from ant_landscape import ant_landscape_refresh + from ant_landscape import mesh_ant_displace + from ant_landscape import ant_functions + +import bpy + +from bpy.props import ( + BoolProperty, + FloatProperty, + IntProperty, + StringProperty, + PointerProperty, + EnumProperty, + ) +''' +from .ant_functions import ( + draw_ant_refresh, + draw_ant_main, + draw_ant_noise, + draw_ant_displace, + ) +''' + +# ------------------------------------------------------------ +# Menu and panels + +# Define "Landscape" menu +def menu_func_landscape(self, context): + self.layout.operator('mesh.landscape_add', text="Landscape", icon="RNDCURVE") + + +# Landscape Add Panel +class panel_func_add_landscape(bpy.types.Panel): + bl_space_type = "VIEW_3D" + bl_context = "objectmode" + bl_region_type = "TOOLS" + bl_label = "ANT Landscape" + bl_category = "Create" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + col = self.layout.column() + col.operator('mesh.landscape_add', text="Landscape", icon="RNDCURVE") + + +# Landscape Tools: +class AntLandscapeToolsPanel(bpy.types.Panel): + bl_space_type = "VIEW_3D" + bl_context = "objectmode" + bl_region_type = "TOOLS" + bl_label = "ANT Displace/Slopemap" + bl_category = "Tools" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + ob = context.active_object + if ob and ob.type == 'MESH': + box = layout.box() + col = box.column() + col.label("Mesh:") + col.operator('mesh.ant_displace', text="Displace", icon="RNDCURVE") + col = box.column() + col.operator('mesh.ant_slope_map', icon='GROUP_VERTEX') + else: + box = layout.box() + col = box.column() + col.label("Select a Mesh Object") + + +# Landscape Settings: +class AntLandscapeSettingsPanel(bpy.types.Panel): + bl_space_type = "VIEW_3D" + bl_context = "objectmode" + bl_region_type = "TOOLS" + bl_category = "Create" + bl_options = {'DEFAULT_CLOSED'} + bl_label = "ANT Landscape Settings" + # bl_space_type = 'PROPERTIES' + # bl_region_type = 'WINDOW' + # bl_context = "world" + + def draw(self, context): + 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() + split = box.column().row().split() + split.scale_y = 1.5 + split.operator('mesh.ant_landscape_regenerate', text="", icon="LOOP_FORWARDS") + split.operator('mesh.ant_landscape_refresh', text="", icon="FILE_REFRESH") + + box = layout.box() + box.prop(ant, "show_main_settings", toggle=True) + if ant.show_main_settings: + #row = box.row(align=True) + #split = row.split(align=True) + #split.prop(ant, "at_cursor", toggle=True, icon_only=True, icon='CURSOR') + #split.prop(ant, "smooth_mesh", toggle=True, icon_only=True, icon='SOLID') + #split.prop(ant, "sphere_mesh", toggle=True) + #split.prop(ant, "tri_face", toggle=True, icon_only=True, 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") + + box = layout.box() + box.prop(ant, "show_noise_settings", toggle=True) + if ant.show_noise_settings: + 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") + 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 = layout.box() + box.prop(ant, "show_displace_settings", toggle=True) + if ant.show_displace_settings: + 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() + col.prop(ant, "strata_type") + if ant.strata_type is not "0": + col = box.column() + col.prop(ant, "strata") + + else: + box = layout.box() + col = box.column() + col.label("Select a Landscape Object") + + +# ------------------------------------------------------------ +# Properties group +class AntLandscapePropertiesGroup(bpy.types.PropertyGroup): + + ant_terrain_name = StringProperty( + name="Name", + default="Landscape" + ) + land_material = StringProperty( + name='Material', + default="", + description="Terrain material" + ) + water_material = StringProperty( + name='Material', + default="", + description="Water plane material" + ) + texture_block = StringProperty( + name="Texture", + default="" + ) + at_cursor = BoolProperty( + name="Cursor", + default=True, + description="Place at cursor location", + ) + smooth_mesh = BoolProperty( + name="Smooth", + default=True, + description="Shade smooth" + ) + tri_face = BoolProperty( + name="Triangulate", + default=False, + description="Triangulate faces" + ) + sphere_mesh = BoolProperty( + name="Sphere", + default=False, + description="Generate uv sphere - remove doubles when ready" + ) + subdivision_x = IntProperty( + name="Subdivisions X", + default=128, + min=4, + max=6400, + description="Mesh X subdivisions" + ) + subdivision_y = IntProperty( + default=128, + name="Subdivisions Y", + min=4, + max=6400, + description="Mesh Y subdivisions" + ) + mesh_size = FloatProperty( + default=2.0, + name="Mesh Size", + min=0.01, + max=100000.0, + description="Mesh size" + ) + mesh_size_x = FloatProperty( + default=2.0, + name="Mesh Size X", + min=0.01, + description="Mesh x size" + ) + mesh_size_y = FloatProperty( + name="Mesh Size Y", + default=2.0, + min=0.01, + description="Mesh y size" + ) + + random_seed = IntProperty( + name="Random Seed", + default=0, + min=0, + description="Randomize noise origin" + ) + noise_offset_x = FloatProperty( + name="Offset X", + default=0.0, + description="Noise X Offset" + ) + noise_offset_y = FloatProperty( + name="Offset Y", + default=0.0, + description="Noise Y Offset" + ) + noise_offset_z = FloatProperty( + name="Offset Z", + default=0.0, + description="Noise Z Offset" + ) + noise_size_x = FloatProperty( + default=1.0, + name="Size X", + min=0.01, + max=1000.0, + description="Noise x size" + ) + noise_size_y = FloatProperty( + name="Size Y", + default=1.0, + min=0.01, + max=1000.0, + description="Noise y size" + ) + noise_size_z = FloatProperty( + name="Size Z", + default=1.0, + min=0.01, + max=1000.0, + description="Noise Z size" + ) + noise_size = FloatProperty( + name="Noise Size", + default=1.0, + min=0.01, + max=1000.0, + description="Noise size" + ) + noise_type = EnumProperty( + name="Noise Type", + default='hetero_terrain', + description="Noise type", + items = [ + ('multi_fractal', "Multi Fractal", "Blender: Multi Fractal algorithm", 0), + ('ridged_multi_fractal', "Ridged MFractal", "Blender: Ridged Multi Fractal", 1), + ('hybrid_multi_fractal', "Hybrid MFractal", "Blender: Hybrid Multi Fractal", 2), + ('hetero_terrain', "Hetero Terrain", "Blender: Hetero Terrain", 3), + ('fractal', "fBm Fractal", "Blender: fBm - Fractional Browninian motion", 4), + ('turbulence_vector', "Turbulence", "Blender: Turbulence Vector", 5), + ('variable_lacunarity', "Distorted Noise", "Blender: Distorted Noise", 6), + ('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), + ('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), + ('slick_rock', "Slick Rock", "A.N.T: slick rock", 15), + ('planet_noise', "Planet Noise", "Planet Noise by: Farsthary", 16), + ('blender_texture', "Blender Texture - Texture Nodes", "Blender texture data block", 17)] + ) + basis_type = EnumProperty( + name="Noise Basis", + default="0", + description="Noise basis algorithms", + items = [ + ("0", "Blender", "Blender default noise", 0), + ("1", "Perlin", "Perlin noise", 1), + ("2", "New Perlin", "New Perlin noise", 2), + ("3", "Voronoi F1", "Voronoi F1", 3), + ("4", "Voronoi F2", "Voronoi F2", 4), + ("5", "Voronoi F3", "Voronoi F3", 5), + ("6", "Voronoi F4", "Voronoi F4", 6), + ("7", "Voronoi F2-F1", "Voronoi F2-F1", 7), + ("8", "Voronoi Crackle", "Voronoi Crackle", 8), + ("9", "Cell Noise", "Cell noise", 9)] + ) + vl_basis_type = EnumProperty( + name="vlNoise Basis", + default="0", + description="VLNoise basis algorithms", + items = [ + ("0", "Blender", "Blender default noise", 0), + ("1", "Perlin", "Perlin noise", 1), + ("2", "New Perlin", "New Perlin noise", 2), + ("3", "Voronoi F1", "Voronoi F1", 3), + ("4", "Voronoi F2", "Voronoi F2", 4), + ("5", "Voronoi F3", "Voronoi F3", 5), + ("6", "Voronoi F4", "Voronoi F4", 6), + ("7", "Voronoi F2-F1", "Voronoi F2-F1", 7), + ("8", "Voronoi Crackle", "Voronoi Crackle", 8), + ("9", "Cell Noise", "Cell noise", 9)] + ) + distortion = FloatProperty( + name="Distortion", + default=1.0, + min=0.01, + max=100.0, + description="Distortion amount" + ) + hard_noise = EnumProperty( + name="Soft Hard", + default="0", + description="Soft Noise, Hard noise", + items = [ + ("0", "Soft", "Soft Noise", 0), + ("1", "Hard", "Hard noise", 1)] + ) + noise_depth = IntProperty( + name="Depth", + default=8, + min=0, + max=16, + description="Noise Depth - number of frequencies in the fBm" + ) + amplitude = FloatProperty( + name="Amp", + default=0.5, + min=0.01, + max=1.0, + description="Amplitude" + ) + frequency = FloatProperty( + name="Freq", + default=2.0, + min=0.01, + max=5.0, + description="Frequency" + ) + dimension = FloatProperty( + name="Dimension", + default=1.0, + min=0.01, + max=2.0, + description="H - fractal dimension of the roughest areas" + ) + lacunarity = FloatProperty( + name="Lacunarity", + min=0.01, + max=6.0, + default=2.0, + description="Lacunarity - gap between successive frequencies" + ) + offset = FloatProperty( + name="Offset", + default=1.0, + min=0.01, + max=6.0, + description="Offset - raises the terrain from sea level" + ) + gain = FloatProperty( + name="Gain", + default=1.0, + min=0.01, + max=6.0, + description="Gain - scale factor" + ) + marble_bias = EnumProperty( + name="Bias", + default="0", + description="Marble bias", + items = [ + ("0", "Sin", "Sin", 0), + ("1", "Cos", "Cos", 1), + ("2", "Tri", "Tri", 2), + ("3", "Saw", "Saw", 3)] + ) + marble_sharp = EnumProperty( + name="Sharp", + default="0", + description="Marble sharpness", + items = [ + ("0", "Soft", "Soft", 0), + ("1", "Sharp", "Sharp", 1), + ("2", "Sharper", "Sharper", 2), + ("3", "Soft inv.", "Soft", 3), + ("4", "Sharp inv.", "Sharp", 4), + ("5", "Sharper inv.", "Sharper", 5)] + ) + marble_shape = EnumProperty( + name="Shape", + default="0", + description="Marble shape", + items= [ + ("0", "Default", "Default", 0), + ("1", "Ring", "Ring", 1), + ("2", "Swirl", "Swirl", 2), + ("3", "Bump", "Bump", 3), + ("4", "Wave", "Wave", 4), + ("5", "Z", "Z", 5), + ("6", "Y", "Y", 6), + ("7", "X", "X", 7)] + ) + height = FloatProperty( + name="Height", + default=0.5, + min=-10000.0, + max=10000.0, + description="Noise intensity scale" + ) + height_invert = BoolProperty( + name="Invert", + default=False, + description="Height invert", + ) + height_offset = FloatProperty( + name="Offset", + default=0.0, + min=-10000.0, + max=10000.0, + description="Height offset" + ) + edge_falloff = EnumProperty( + name="Falloff", + default="3", + description="Flatten edges", + items = [ + ("0", "None", "None", 0), + ("1", "Y", "Y Falloff", 1), + ("2", "X", "X Falloff", 2), + ("3", "X Y", "X Y Falloff", 3)] + ) + falloff_x = FloatProperty( + name="Falloff X", + default=4.0, + min=0.1, + max=100.0, + description="Falloff x scale" + ) + falloff_y = FloatProperty( + name="Falloff Y", + default=4.0, + min=0.1, + max=100.0, + description="Falloff y scale" + ) + edge_level = FloatProperty( + name="Edge Level", + default=0.0, + min=-10000.0, + max=10000.0, + description="Edge level, sealevel offset" + ) + maximum = FloatProperty( + name="Maximum", + default=1.0, + min=-10000.0, + max=10000.0, + description="Maximum, flattens terrain at plateau level" + ) + minimum = FloatProperty( + name="Minimum", + default=-1.0, + min=-10000.0, + max=10000.0, + description="Minimum, flattens terrain at seabed level" + ) + use_vgroup = BoolProperty( + name="Vertex Group Weight", + default=False, + description="Use active vertex group weight" + ) + strata = FloatProperty( + name="Amount", + default=5.0, + min=0.01, + max=1000.0, + description="Strata layers / terraces" + ) + strata_type = EnumProperty( + name="Strata", + default="0", + description="Strata types", + items = [ + ("0", "None", "No strata", 0), + ("1", "Smooth", "Smooth transitions", 1), + ("2", "Sharp Sub", "Sharp substract transitions", 2), + ("3", "Sharp Add", "Sharp add transitions", 3), + ("4", "Posterize", "Posterize", 4), + ("5", "Posterize Mix", "Posterize mixed", 5)] + ) + water_plane = BoolProperty( + name="Water Plane", + default=False, + description="Add water plane" + ) + water_level = FloatProperty( + name="Level", + default=0.01, + min=-10000.0, + max=10000.0, + description="Water level" + ) + remove_double = BoolProperty( + name="Remove Doubles", + default=False, + description="Remove doubles" + ) + show_main_settings = BoolProperty( + name="Main Settings", + default=True, + description="Show settings" + ) + show_noise_settings = BoolProperty( + name="Noise Settings", + default=True, + description="Show noise settings" + ) + show_displace_settings = BoolProperty( + name="Displace Settings", + default=True, + description="Show displace settings" + ) + refresh = BoolProperty( + name="Refresh", + default=False, + description="Refresh" + ) + auto_refresh = BoolProperty( + name="Auto", + default=True, + description="Automatic refresh" + ) + + +# ------------------------------------------------------------ +# Register: + +def register(): + bpy.utils.register_module(__name__) + bpy.types.INFO_MT_mesh_add.append(menu_func_landscape) + bpy.types.Object.ant_landscape = PointerProperty(type=AntLandscapePropertiesGroup, name="ANT_Landscape", description="Landscape properties", options={'ANIMATABLE'}) + + +def unregister(): + bpy.utils.unregister_module(__name__) + bpy.types.INFO_MT_mesh_add.remove(menu_func_landscape) + #del bpy.types.Object.AntLandscapePropertiesGroup + +if __name__ == "__main__": + register() diff --git a/ant_landscape/add_mesh_ant_landscape.py b/ant_landscape/add_mesh_ant_landscape.py new file mode 100644 index 00000000..cad52c44 --- /dev/null +++ b/ant_landscape/add_mesh_ant_landscape.py @@ -0,0 +1,668 @@ +# ##### 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 ##### + +# Another Noise Tool - Landscape +# Jim Hazevoet + +# import modules +import bpy +from bpy.props import ( + BoolProperty, + EnumProperty, + FloatProperty, + IntProperty, + StringProperty, + FloatVectorProperty, + ) + +from .ant_functions import ( + grid_gen, + sphere_gen, + create_mesh_object, + store_properties, + draw_ant_refresh, + draw_ant_main, + draw_ant_noise, + draw_ant_displace, + draw_ant_water, + ) + +# ------------------------------------------------------------ +# Add landscape +class AntAddLandscape(bpy.types.Operator): + bl_idname = "mesh.landscape_add" + bl_label = "Another Noise Tool - Landscape" + bl_description = "Add landscape mesh" + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + ant_terrain_name = StringProperty( + name="Name", + default="Landscape" + ) + land_material = StringProperty( + name='Material', + default="", + description="Terrain material" + ) + water_material = StringProperty( + name='Material', + default="", + description="Water plane material" + ) + texture_block = StringProperty( + name="Texture", + default="" + ) + at_cursor = BoolProperty( + name="Cursor", + default=True, + description="Place at cursor location", + ) + smooth_mesh = BoolProperty( + name="Smooth", + default=True, + description="Shade smooth" + ) + tri_face = BoolProperty( + name="Triangulate", + default=False, + description="Triangulate faces" + ) + sphere_mesh = BoolProperty( + name="Sphere", + default=False, + description="Generate uv sphere - remove doubles when ready" + ) + subdivision_x = IntProperty( + name="Subdivisions X", + default=128, + min=4, + max=6400, + description="Mesh X subdivisions" + ) + subdivision_y = IntProperty( + default=128, + name="Subdivisions Y", + min=4, + max=6400, + description="Mesh Y subdivisions" + ) + mesh_size = FloatProperty( + default=2.0, + name="Mesh Size", + min=0.01, + max=100000.0, + description="Mesh size" + ) + mesh_size_x = FloatProperty( + default=2.0, + name="Mesh Size X", + min=0.01, + description="Mesh x size" + ) + mesh_size_y = FloatProperty( + name="Mesh Size Y", + default=2.0, + min=0.01, + description="Mesh y size" + ) + + random_seed = IntProperty( + name="Random Seed", + default=0, + min=0, + description="Randomize noise origin" + ) + noise_offset_x = FloatProperty( + name="Offset X", + default=0.0, + description="Noise X Offset" + ) + noise_offset_y = FloatProperty( + name="Offset Y", + default=0.0, + description="Noise Y Offset" + ) + noise_offset_z = FloatProperty( + name="Offset Z", + default=0.0, + description="Noise Z Offset" + ) + noise_size_x = FloatProperty( + default=1.0, + name="Size X", + min=0.01, + max=1000.0, + description="Noise x size" + ) + noise_size_y = FloatProperty( + name="Size Y", + default=1.0, + min=0.01, + max=1000.0, + description="Noise y size" + ) + noise_size_z = FloatProperty( + name="Size Z", + default=1.0, + min=0.01, + max=1000.0, + description="Noise Z size" + ) + noise_size = FloatProperty( + name="Noise Size", + default=1.0, + min=0.01, + max=1000.0, + description="Noise size" + ) + noise_type = EnumProperty( + name="Noise Type", + default='hetero_terrain', + description="Noise type", + items = [ + ('multi_fractal', "Multi Fractal", "Blender: Multi Fractal algorithm", 0), + ('ridged_multi_fractal', "Ridged MFractal", "Blender: Ridged Multi Fractal", 1), + ('hybrid_multi_fractal', "Hybrid MFractal", "Blender: Hybrid Multi Fractal", 2), + ('hetero_terrain', "Hetero Terrain", "Blender: Hetero Terrain", 3), + ('fractal', "fBm Fractal", "Blender: fBm - Fractional Browninian motion", 4), + ('turbulence_vector', "Turbulence", "Blender: Turbulence Vector", 5), + ('variable_lacunarity', "Distorted Noise", "Blender: Distorted Noise", 6), + ('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), + ('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), + ('slick_rock', "Slick Rock", "A.N.T: slick rock", 15), + ('planet_noise', "Planet Noise", "Planet Noise by: Farsthary", 16), + ('blender_texture', "Blender Texture - Texture Nodes", "Blender texture data block", 17)] + ) + basis_type = EnumProperty( + name="Noise Basis", + default="0", + description="Noise basis algorithms", + items = [ + ("0", "Blender", "Blender default noise", 0), + ("1", "Perlin", "Perlin noise", 1), + ("2", "New Perlin", "New Perlin noise", 2), + ("3", "Voronoi F1", "Voronoi F1", 3), + ("4", "Voronoi F2", "Voronoi F2", 4), + ("5", "Voronoi F3", "Voronoi F3", 5), + ("6", "Voronoi F4", "Voronoi F4", 6), + ("7", "Voronoi F2-F1", "Voronoi F2-F1", 7), + ("8", "Voronoi Crackle", "Voronoi Crackle", 8), + ("9", "Cell Noise", "Cell noise", 9)] + ) + vl_basis_type = EnumProperty( + name="vlNoise Basis", + default="0", + description="VLNoise basis algorithms", + items = [ + ("0", "Blender", "Blender default noise", 0), + ("1", "Perlin", "Perlin noise", 1), + ("2", "New Perlin", "New Perlin noise", 2), + ("3", "Voronoi F1", "Voronoi F1", 3), + ("4", "Voronoi F2", "Voronoi F2", 4), + ("5", "Voronoi F3", "Voronoi F3", 5), + ("6", "Voronoi F4", "Voronoi F4", 6), + ("7", "Voronoi F2-F1", "Voronoi F2-F1", 7), + ("8", "Voronoi Crackle", "Voronoi Crackle", 8), + ("9", "Cell Noise", "Cell noise", 9)] + ) + distortion = FloatProperty( + name="Distortion", + default=1.0, + min=0.01, + max=100.0, + description="Distortion amount" + ) + hard_noise = EnumProperty( + name="Soft Hard", + default="0", + description="Soft Noise, Hard noise", + items = [ + ("0", "Soft", "Soft Noise", 0), + ("1", "Hard", "Hard noise", 1)] + ) + noise_depth = IntProperty( + name="Depth", + default=8, + min=0, + max=16, + description="Noise Depth - number of frequencies in the fBm" + ) + amplitude = FloatProperty( + name="Amp", + default=0.5, + min=0.01, + max=1.0, + description="Amplitude" + ) + frequency = FloatProperty( + name="Freq", + default=2.0, + min=0.01, + max=5.0, + description="Frequency" + ) + dimension = FloatProperty( + name="Dimension", + default=1.0, + min=0.01, + max=2.0, + description="H - fractal dimension of the roughest areas" + ) + lacunarity = FloatProperty( + name="Lacunarity", + min=0.01, + max=6.0, + default=2.0, + description="Lacunarity - gap between successive frequencies" + ) + offset = FloatProperty( + name="Offset", + default=1.0, + min=0.01, + max=6.0, + description="Offset - raises the terrain from sea level" + ) + gain = FloatProperty( + name="Gain", + default=1.0, + min=0.01, + max=6.0, + description="Gain - scale factor" + ) + marble_bias = EnumProperty( + name="Bias", + default="0", + description="Marble bias", + items = [ + ("0", "Sin", "Sin", 0), + ("1", "Cos", "Cos", 1), + ("2", "Tri", "Tri", 2), + ("3", "Saw", "Saw", 3)] + ) + marble_sharp = EnumProperty( + name="Sharp", + default="0", + description="Marble sharpness", + items = [ + ("0", "Soft", "Soft", 0), + ("1", "Sharp", "Sharp", 1), + ("2", "Sharper", "Sharper", 2), + ("3", "Soft inv.", "Soft", 3), + ("4", "Sharp inv.", "Sharp", 4), + ("5", "Sharper inv.", "Sharper", 5)] + ) + marble_shape = EnumProperty( + name="Shape", + default="0", + description="Marble shape", + items= [ + ("0", "Default", "Default", 0), + ("1", "Ring", "Ring", 1), + ("2", "Swirl", "Swirl", 2), + ("3", "Bump", "Bump", 3), + ("4", "Wave", "Wave", 4), + ("5", "Z", "Z", 5), + ("6", "Y", "Y", 6), + ("7", "X", "X", 7)] + ) + height = FloatProperty( + name="Height", + default=0.5, + min=-10000.0, + max=10000.0, + description="Noise intensity scale" + ) + height_invert = BoolProperty( + name="Invert", + default=False, + description="Height invert", + ) + height_offset = FloatProperty( + name="Offset", + default=0.0, + min=-10000.0, + max=10000.0, + description="Height offset" + ) + edge_falloff = EnumProperty( + name="Falloff", + default="3", + description="Flatten edges", + items = [ + ("0", "None", "None", 0), + ("1", "Y", "Y Falloff", 1), + ("2", "X", "X Falloff", 2), + ("3", "X Y", "X Y Falloff", 3)] + ) + falloff_x = FloatProperty( + name="Falloff X", + default=4.0, + min=0.1, + max=100.0, + description="Falloff x scale" + ) + falloff_y = FloatProperty( + name="Falloff Y", + default=4.0, + min=0.1, + max=100.0, + description="Falloff y scale" + ) + edge_level = FloatProperty( + name="Edge Level", + default=0.0, + min=-10000.0, + max=10000.0, + description="Edge level, sealevel offset" + ) + maximum = FloatProperty( + name="Maximum", + default=1.0, + min=-10000.0, + max=10000.0, + description="Maximum, flattens terrain at plateau level" + ) + minimum = FloatProperty( + name="Minimum", + default=-1.0, + min=-10000.0, + max=10000.0, + description="Minimum, flattens terrain at seabed level" + ) + use_vgroup = BoolProperty( + name="Vertex Group Weight", + default=False, + description="Use active vertex group weight" + ) + strata = FloatProperty( + name="Amount", + default=5.0, + min=0.01, + max=1000.0, + description="Strata layers / terraces" + ) + strata_type = EnumProperty( + name="Strata", + default="0", + description="Strata types", + items = [ + ("0", "None", "No strata", 0), + ("1", "Smooth", "Smooth transitions", 1), + ("2", "Sharp Sub", "Sharp substract transitions", 2), + ("3", "Sharp Add", "Sharp add transitions", 3), + ("4", "Posterize", "Posterize", 4), + ("5", "Posterize Mix", "Posterize mixed", 5)] + ) + water_plane = BoolProperty( + name="Water Plane", + default=False, + description="Add water plane" + ) + water_level = FloatProperty( + name="Level", + default=0.01, + min=-10000.0, + max=10000.0, + description="Water level" + ) + remove_double = BoolProperty( + name="Remove Doubles", + default=False, + description="Remove doubles" + ) + show_main_settings = BoolProperty( + name="Main Settings", + default=True, + description="Show settings" + ) + show_noise_settings = BoolProperty( + name="Noise Settings", + default=True, + description="Show noise settings" + ) + show_displace_settings = BoolProperty( + name="Displace Settings", + default=True, + description="Show displace settings" + ) + refresh = BoolProperty( + name="Refresh", + default=False, + description="Refresh" + ) + auto_refresh = BoolProperty( + name="Auto", + default=True, + description="Automatic refresh" + ) + + + def draw(self, context): + draw_ant_refresh(self, context) + draw_ant_main(self, context, generate=True) + draw_ant_noise(self, context) + draw_ant_displace(self, context, generate=True) + draw_ant_water(self, context) + + + def invoke(self, context, event): + self.refresh = True + return self.execute(context) + + + def execute(self, context): + if not self.refresh: + return {'PASS_THROUGH'} + + # turn off undo + undo = bpy.context.user_preferences.edit.use_global_undo + bpy.context.user_preferences.edit.use_global_undo = False + + # deselect all objects when in object mode + if bpy.ops.object.select_all.poll(): + bpy.ops.object.select_all(action='DESELECT') + + # Properties + ant_props = [ + self.ant_terrain_name, + self.at_cursor, + self.smooth_mesh, + self.tri_face, + self.sphere_mesh, + self.land_material, + self.water_material, + self.texture_block, + self.subdivision_x, + self.subdivision_y, + self.mesh_size_x, + self.mesh_size_y, + self.mesh_size, + self.random_seed, + self.noise_offset_x, + self.noise_offset_y, + self.noise_offset_z, + self.noise_size_x, + self.noise_size_y, + self.noise_size_z, + self.noise_size, + self.noise_type, + self.basis_type, + self.vl_basis_type, + self.distortion, + self.hard_noise, + self.noise_depth, + self.amplitude, + self.frequency, + self.dimension, + self.lacunarity, + self.offset, + self.gain, + self.marble_bias, + self.marble_sharp, + self.marble_shape, + self.height, + self.height_invert, + self.height_offset, + self.maximum, + self.minimum, + self.edge_falloff, + self.edge_level, + self.falloff_x, + self.falloff_y, + self.strata_type, + self.strata, + self.water_plane, + self.water_level, + self.use_vgroup, + self.remove_double + ] + + scene = context.scene + + # Main function, create landscape mesh object + if self.ant_terrain_name != "": + new_name = self.ant_terrain_name + else: + new_name = "Landscape" + + if self.sphere_mesh: + # sphere + verts, faces = sphere_gen( + self.subdivision_y, + self.subdivision_x, + self.tri_face, + self.mesh_size, + ant_props, + False, + 0.0 + ) + new_ob = create_mesh_object(context, verts, [], faces, new_name) + if self.remove_double: + new_ob.select = True + bpy.ops.object.mode_set(mode = 'EDIT') + bpy.ops.mesh.remove_doubles(threshold=0.0001, use_unselected=False) + bpy.ops.object.mode_set(mode = 'OBJECT') + else: + # grid + verts, faces = grid_gen( + self.subdivision_x, + self.subdivision_y, + self.tri_face, + self.mesh_size_x, + self.mesh_size_y, + ant_props, + False, + 0.0 + ) + new_ob = create_mesh_object(context, verts, [], faces, new_name) + + new_ob.select = True + + if self.smooth_mesh: + bpy.ops.object.shade_smooth() + + if not self.at_cursor: + new_ob.object.location = (0.0, 0.0, 0.0) + + # Landscape Material + if self.land_material != "" and self.land_material in bpy.data.materials: + mat = bpy.data.materials[self.land_material] + bpy.context.object.data.materials.append(mat) + + # Water plane + if self.water_plane: + if self.sphere_mesh: + # sphere + verts, faces = sphere_gen( + self.subdivision_y, + self.subdivision_x, + self.tri_face, + self.mesh_size, + ant_props, + self.water_plane, + self.water_level + ) + wobj = create_mesh_object(context, verts, [], faces, new_name+"_plane") + if self.remove_double: + wobj.select = True + bpy.ops.object.mode_set(mode = 'EDIT') + bpy.ops.mesh.remove_doubles(threshold=0.0001, use_unselected=False) + bpy.ops.object.mode_set(mode = 'OBJECT') + else: + # grid + verts, faces = grid_gen( + 2, + 2, + self.tri_face, + self.mesh_size_x, + self.mesh_size_y, + ant_props, + self.water_plane, + self.water_level + ) + wobj = create_mesh_object(context, verts, [], faces, new_name+"_plane") + + wobj.select = True + + if self.smooth_mesh: + bpy.ops.object.shade_smooth() + + if not self.at_cursor: + wobj.object.location = (0.0, 0.0, 0.0) + + # Water Material + if self.water_material != "" and self.water_material in bpy.data.materials: + mat = bpy.data.materials[self.water_material] + bpy.context.object.data.materials.append(mat) + + # select landscape and make active + new_ob.select = True + scene.objects.active = new_ob.object + # + new_ob = store_properties(self, new_ob.object) + + if self.auto_refresh is False: + self.refresh = False + + # restore pre operator undo state + context.user_preferences.edit.use_global_undo = undo + + return {'FINISHED'} + +''' +# ------------------------------------------------------------ +# Register: + +def register(): + bpy.utils.register_module(__name__) + + +def unregister(): + bpy.utils.unregister_module(__name__) + + +if __name__ == "__main__": + register() +'''
\ No newline at end of file diff --git a/ant_landscape/ant_functions.py b/ant_landscape/ant_functions.py new file mode 100644 index 00000000..74412d17 --- /dev/null +++ b/ant_landscape/ant_functions.py @@ -0,0 +1,930 @@ +# ##### 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 ##### + +# Another Noise Tool - Functions +# Jim Hazevoet + +# import modules +import bpy +from bpy.props import ( + BoolProperty, + FloatProperty, + StringProperty, + EnumProperty, + IntProperty, + PointerProperty + ) +from mathutils.noise import ( + seed_set, + turbulence, + turbulence_vector, + fractal, + hybrid_multi_fractal, + multi_fractal, + ridged_multi_fractal, + hetero_terrain, + random_unit_vector, + variable_lacunarity, + ) +from math import ( + floor, sqrt, + sin, cos, pi, + ) + +# ------------------------------------------------------------ +# Create a new mesh (object) from verts/edges/faces. +# verts/edges/faces ... List of vertices/edges/faces for the +# new mesh (as used in from_pydata). +# name ... Name of the new mesh (& object) + +from bpy_extras import object_utils + +def create_mesh_object(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, [], faces) + + # Update mesh geometry after adding stuff. + mesh.update() + + #new_ob = bpy.data.objects.new(name, mesh) + #context.scene.objects.link(new_ob) + return object_utils.object_data_add(context, mesh, operator=None) + #return new_ob + + +# Generate XY Grid +def grid_gen(sub_d_x, sub_d_y, tri, meshsize_x, meshsize_y, props, water_plane, water_level): + verts = [] + faces = [] + for i in range (0, sub_d_x): + x = meshsize_x * (i / (sub_d_x - 1) - 1 / 2) + for j in range(0, sub_d_y): + y = meshsize_y * (j / (sub_d_y - 1) - 1 / 2) + if water_plane: + z = water_level + else: + z = noise_gen((x, y, 0), props) + + verts.append((x,y,z)) + + count = 0 + for i in range (0, sub_d_y * (sub_d_x - 1)): + if count < sub_d_y - 1 : + A = i + 1 + B = i + C = (i + sub_d_y) + D = (i + sub_d_y) + 1 + if tri: + faces.append((A, B, D)) + faces.append((B, C, D)) + else: + faces.append((A, B, C, D)) + count = count + 1 + else: + count = 0 + + return verts, faces + + +# Generate UV Sphere +def sphere_gen(sub_d_x, sub_d_y, tri, meshsize, props, water_plane, water_level): + verts = [] + faces = [] + sub_d_x += 1 + sub_d_y += 1 + for i in range(0, sub_d_x): + for j in range(0, sub_d_y): + u = sin(j * pi * 2 / (sub_d_y - 1)) * cos(-pi / 2 + i * pi / (sub_d_x - 1)) * meshsize / 2 + v = cos(j * pi * 2 / (sub_d_y - 1)) * cos(-pi / 2 + i * pi / (sub_d_x - 1)) * meshsize / 2 + w = sin(-pi / 2 + i * pi / (sub_d_x - 1)) * meshsize / 2 + if water_plane: + h = water_level + else: + h = noise_gen((u, v, w), props) / meshsize + verts.append(((u + u * h), (v + v * h), (w + w * h))) + + count = 0 + for i in range (0, sub_d_y * (sub_d_x - 1)): + if count < sub_d_y - 1 : + A = i + 1 + B = i + C = (i + sub_d_y) + D = (i + sub_d_y) + 1 + if tri: + faces.append((A, B, D)) + faces.append((B, C, D)) + else: + faces.append((A, B, C, D)) + count = count + 1 + else: + count = 0 + + return verts, faces + + +# Z normal value to vertex group (Slope map) +class AntVgSlopeMap(bpy.types.Operator): + bl_idname = "mesh.ant_slope_map" + bl_label = "Weight from Slope" + bl_description = "A.N.T. Slope Map - z normal value to vertex group weight" + bl_options = {'REGISTER', 'UNDO'} + + z_method = EnumProperty( + name="Method:", + default='SLOPE_Z', + items=[ + ('SLOPE_Z', "Slope Z", "Slope for planar mesh"), + ('SLOPE_XYZ', "Slope XYZ", "Slope for spherical mesh") + ]) + group_name = StringProperty( + name="Vertex Group Name:", + default="Slope", + description="Name" + ) + select_flat = BoolProperty( + name="Vert Select:", + default=True, + description="Select vertices on flat surface" + ) + select_range = FloatProperty( + name="Vert Select Range:", + default=0.0, + min=0.0, + max=1.0, + description="Increase to select more vertices" + ) + + @classmethod + def poll(cls, context): + ob = context.object + return (ob and ob.type == 'MESH') + + + def invoke(self, context, event): + wm = context.window_manager + return wm.invoke_props_dialog(self) + + + def execute(self, context): + message = "Popup Values: %d, %f, %s, %s" % \ + (self.select_flat, self.select_range, self.group_name, self.z_method) + self.report({'INFO'}, message) + + ob = bpy.context.active_object + dim = ob.dimensions + + if self.select_flat: + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.mesh.select_all(action='DESELECT') + bpy.context.tool_settings.mesh_select_mode = [True, False, False] + bpy.ops.object.mode_set(mode='OBJECT') + + bpy.ops.object.vertex_group_add() + vg_normal = ob.vertex_groups.active + + for v in ob.data.vertices: + if self.z_method == 'SLOPE_XYZ': + zval = (v.co.normalized() * v.normal.normalized()) * 2 - 1 + else: + zval = v.normal[2] + + vg_normal.add([v.index], zval, 'REPLACE') + + if self.select_flat: + if zval >= (1.0 - self.select_range): + v.select = True + + vg_normal.name = self.group_name + + return {'FINISHED'} + + +# ------------------------------------------------------------ +# A.N.T. Noise: + +# Functions for marble_noise: +def sin_bias(a): + return 0.5 + 0.5 * sin(a) + + +def cos_bias(a): + return 0.5 + 0.5 * cos(a) + + +def tri_bias(a): + b = 2 * pi + a = 1 - 2 * abs(floor((a * (1 / b)) + 0.5) - (a * (1 / b))) + return a + + +def saw_bias(a): + b = 2 * pi + n = int(a / b) + a -= n * b + if a < 0: + a += b + return a / b + + +def soft(a): + return a + + +def sharp(a): + return a**0.5 + + +def sharper(a): + return sharp(sharp(a)) + + +def shapes(x, y, z, shape=0): + p = pi + if shape is 1: + # ring + x = x * p + y = y * p + s = cos(x**2 + y**2) / (x**2 + y**2 + 0.5) + elif shape is 2: + # swirl + x = x * p + y = y * p + s = ((x * sin(x * x + y * y) + y * cos(x * x + y * y)) / (x**2 + y**2 + 0.5)) + elif shape is 3: + # bumps + x = x * p + y = y * p + z = z * p + s = 1 - ((cos(x * p) + cos(y * p) + cos(z * p)) - 0.5) + elif shape is 4: + # wave + x = x * p * 2 + y = y * p * 2 + s = sin(x + sin(y)) + elif shape is 5: + # x grad. + s = (z * p) + elif shape is 6: + # y grad. + s = (y * p) + elif shape is 7: + # x grad. + s = (x * p) + else: + # marble default + s = ((x + y + z) * 5) + return s + + +# marble_noise +def marble_noise(x, y, z, origin, size, shape, bias, sharpnes, turb, depth, hard, basis, amp, freq): + + s = shapes(x, y, z, shape) + x += origin[0] + y += origin[1] + z += origin[2] + value = s + turb * turbulence_vector((x, y, z), depth, hard, basis)[1] + + if bias is 1: + value = cos_bias(value) + elif bias is 2: + value = tri_bias(value) + elif bias is 3: + value = saw_bias(value) + else: + value = sin_bias(value) + + if sharpnes is 1: + value = 1.0 - sharp(value) + elif sharpnes is 2: + value = 1.0 - sharper(value) + elif sharpnes is 3: + value = soft(value) + elif sharpnes is 4: + value = sharp(value) + elif sharpnes is 5: + value = sharper(value) + else: + value = 1.0 - soft(value) + + return value + + +# vl_noise_turbulence: +def vlnTurbMode(coords, distort, basis, vlbasis, hardnoise): + # hard noise + if hardnoise: + return (abs(-variable_lacunarity(coords, distort, basis, vlbasis))) + # soft noise + else: + return variable_lacunarity(coords, distort, basis, vlbasis) + + +def vl_noise_turbulence(coords, distort, depth, basis, vlbasis, hardnoise, amp, freq): + x, y, z = coords + value = vlnTurbMode(coords, distort, basis, vlbasis, hardnoise) + i=0 + for i in range(depth): + i+=1 + value += vlnTurbMode((x * (freq * i), y * (freq * i), z * (freq * i)), distort, basis, vlbasis, hardnoise) * (amp * 0.5 / i) + return value + + +## duo_multiFractal: +def double_multiFractal(coords, H, lacunarity, octaves, offset, gain, basis, vlbasis): + x, y, z = coords + n1 = multi_fractal((x * 1.5 + 1, y * 1.5 + 1, z * 1.5 + 1), 1.0, 1.0, 1.0, basis) * (offset * 0.5) + n2 = multi_fractal((x - 1, y - 1, z - 1), H, lacunarity, octaves, vlbasis) * (gain * 0.5) + return (n1 * n1 + n2 * n2) * 0.5 + + +## distorted_heteroTerrain: +def distorted_heteroTerrain(coords, H, lacunarity, octaves, offset, distort, basis, vlbasis): + x, y, z = coords + h1 = (hetero_terrain((x, y, z), 1.0, 2.0, 1.0, 1.0, basis) * 0.5) + d = h1 * distort + h2 = (hetero_terrain((x + d, y + d, z + d), H, lacunarity, octaves, offset, vlbasis) * 0.25) + return (h1 * h1 + h2 * h2) * 0.5 + + +## SlickRock: +def slick_rock(coords, H, lacunarity, octaves, offset, gain, distort, basis, vlbasis): + x, y, z = coords + n = multi_fractal((x,y,z), 1.0, 2.0, 2.0, basis) * distort * 0.25 + r = ridged_multi_fractal((x + n, y + n, z + n), H, lacunarity, octaves, offset + 0.1, gain * 2, vlbasis) + return (n + (n * r)) * 0.5 + + +## vlhTerrain +def vl_hTerrain(coords, H, lacunarity, octaves, offset, basis, vlbasis, distort): + x, y, z = coords + ht = hetero_terrain((x, y, z), H, lacunarity, octaves, offset, basis ) * 0.25 + vl = ht * variable_lacunarity((x, y, z), distort, basis, vlbasis) * 0.5 + 0.5 + return vl * ht + + +# another turbulence +def ant_turbulence(coords, depth, hardnoise, nbasis, amp, freq, distortion): + x, y, z = coords + tv = turbulence_vector((x + 1, y + 2, z + 3), depth, hardnoise, nbasis, amp, freq) + d = (distortion * tv[0]) * 0.25 + return (d + ((tv[0] - tv[1]) * (tv[2])**2)) + + +# shattered_hterrain: +def shattered_hterrain(coords, H, lacunarity, octaves, offset, distort, basis): + x, y, z = coords + d = (turbulence_vector(coords, 6, 0, 0)[0] * 0.5 + 0.5) * distort * 0.5 + t1 = (turbulence_vector((x + d, y + d, z + d), 0, 0, 7)[0] + 0.5) + t2 = (hetero_terrain((x * 2, y * 2, z * 2), H, lacunarity, octaves, offset, basis) * 0.5) + return ((t1 * t2) + t2 * 0.5) * 0.5 + + +# strata_hterrain +def strata_hterrain(coords, H, lacunarity, octaves, offset, distort, basis): + x, y, z = coords + value = hetero_terrain((x, y, z), H, lacunarity, octaves, offset, basis) * 0.5 + steps = (sin(value * (distort * 5) * pi) * (0.1 / (distort * 5) * pi)) + return (value * (1.0 - 0.5) + steps * 0.5) + + +# Planet Noise by: Farsthary +# https://farsthary.com/2010/11/24/new-planet-procedural-texture/ +def planet_noise(coords, oct=6, hard=0, noisebasis=1, nabla=0.001): + x, y, z = coords + d = 0.001 + offset = nabla * 1000 + x = turbulence((x, y, z), oct, hard, noisebasis) + y = turbulence((x + offset, y, z), oct, hard, noisebasis) + z = turbulence((x, y + offset, z), oct, hard, noisebasis) + xdy = x - turbulence((x, y + d, z), oct, hard, noisebasis) + xdz = x - turbulence((x, y, z + d), oct, hard, noisebasis) + ydx = y - turbulence((x + d, y, z), oct, hard, noisebasis) + ydz = y - turbulence((x, y, z + d), oct, hard, noisebasis) + zdx = z - turbulence((x + d, y, z), oct, hard, noisebasis) + zdy = z - turbulence((x, y + d, z), oct, hard, noisebasis) + return (zdy - ydz), (zdx - xdz), (ydx - xdy) + + +# ------------------------------------------------------------ +# landscape_gen +def noise_gen(coords, props): + + terrain_name = props[0] + cursor = props[1] + smooth = props[2] + triface = props[3] + sphere = props[4] + land_mat = props[5] + water_mat = props[6] + texture_name = props[7] + subd_x = props[8] + subd_y = props[9] + meshsize_x = props[10] + meshsize_y = props[11] + meshsize = props[12] + rseed = props[13] + x_offset = props[14] + y_offset = props[15] + z_offset = props[16] + size_x = props[17] + size_y = props[18] + size_z = props[19] + nsize = props[20] + ntype = props[21] + nbasis = int(props[22]) + vlbasis = int(props[23]) + distortion = props[24] + hardnoise = int(props[25]) + depth = props[26] + amp = props[27] + freq = props[28] + dimension = props[29] + lacunarity = props[30] + offset = props[31] + gain = props[32] + marblebias = int(props[33]) + marblesharpnes = int(props[34]) + marbleshape = int(props[35]) + height = props[36] + height_invert = props[37] + height_offset = props[38] + maximum = props[39] + minimum = props[40] + falloff = int(props[41]) + edge_level = props[42] + falloffsize_x = props[43] + falloffsize_y = props[44] + stratatype = props[45] + strata = props[46] + addwater = props[47] + waterlevel = props[48] + + x, y, z = coords + + # Origin + if rseed is 0: + origin = x_offset, y_offset, z_offset + origin_x = x_offset + origin_y = y_offset + origin_z = z_offset + o_range = 1.0 + else: + # Randomise origin + o_range = 10000.0 + seed_set(rseed) + origin = random_unit_vector() + ox = (origin[0] * o_range) + oy = (origin[1] * o_range) + oz = (origin[2] * o_range) + origin_x = (ox - (ox / 2)) + x_offset + origin_y = (oy - (oy / 2)) + y_offset + origin_z = (oz - (oz / 2)) + z_offset + + ncoords = (x / (nsize * size_x) + origin_x, y / (nsize * size_y) + origin_y, z / (nsize * size_z) + origin_z) + + # Noise basis type's + if nbasis == 9: + nbasis = 14 # Cellnoise + if vlbasis == 9: + vlbasis = 14 + + # Noise type's + if ntype in [0, 'multi_fractal']: + value = multi_fractal(ncoords, dimension, lacunarity, depth, nbasis) * 0.5 + + elif ntype in [1, 'ridged_multi_fractal']: + value = ridged_multi_fractal(ncoords, dimension, lacunarity, depth, offset, gain, nbasis) * 0.5 + + elif ntype in [2, 'hybrid_multi_fractal']: + value = hybrid_multi_fractal(ncoords, dimension, lacunarity, depth, offset, gain, nbasis) * 0.5 + + elif ntype in [3, 'hetero_terrain']: + value = hetero_terrain(ncoords, dimension, lacunarity, depth, offset, nbasis) * 0.25 + + elif ntype in [4, 'fractal']: + value = fractal(ncoords, dimension, lacunarity, depth, nbasis) + + elif ntype in [5, 'turbulence_vector']: + value = turbulence_vector(ncoords, depth, hardnoise, nbasis, amp, freq)[0] + + elif ntype in [6, 'variable_lacunarity']: + value = variable_lacunarity(ncoords, distortion, nbasis, vlbasis) + + elif ntype in [7, 'marble_noise']: + value = marble_noise( + (ncoords[0] - origin_x + x_offset), + (ncoords[1] - origin_y + y_offset), + (ncoords[2] - origin_z + z_offset), + (origin[0] + x_offset, origin[1] + y_offset, origin[2] + z_offset), nsize, + marbleshape, marblebias, marblesharpnes, + distortion, depth, hardnoise, nbasis, amp, freq + ) + elif ntype in [8, 'shattered_hterrain']: + value = shattered_hterrain(ncoords, dimension, lacunarity, depth, offset, distortion, nbasis) + + elif ntype in [9, 'strata_hterrain']: + value = strata_hterrain(ncoords, dimension, lacunarity, depth, offset, distortion, nbasis) + + elif ntype in [10, 'ant_turbulence']: + value = ant_turbulence(ncoords, depth, hardnoise, nbasis, amp, freq, distortion) + + elif ntype in [11, 'vl_noise_turbulence']: + value = vl_noise_turbulence(ncoords, distortion, depth, nbasis, vlbasis, hardnoise, amp, freq) + + elif ntype in [12, 'vl_hTerrain']: + value = vl_hTerrain(ncoords, dimension, lacunarity, depth, offset, nbasis, vlbasis, distortion) + + elif ntype in [13, 'distorted_heteroTerrain']: + value = distorted_heteroTerrain(ncoords, dimension, lacunarity, depth, offset, distortion, nbasis, vlbasis) + + elif ntype in [14, 'double_multiFractal']: + value = double_multiFractal(ncoords, dimension, lacunarity, depth, offset, gain, nbasis, vlbasis) + + elif ntype in [15, 'slick_rock']: + value = slick_rock(ncoords,dimension, lacunarity, depth, offset, gain, distortion, nbasis, vlbasis) + + elif ntype in [16, 'planet_noise']: + value = planet_noise(ncoords, depth, hardnoise, nbasis)[2] * 0.5 + 0.5 + + elif ntype in [17, 'blender_texture']: + if texture_name != "" and texture_name in bpy.data.textures: + value = bpy.data.textures[texture_name].evaluate(ncoords)[3] + else: + value = 0.0 + else: + value = 0.5 + + # Adjust height + if height_invert: + value = (1.0 - value) * height + height_offset + else: + value = value * height + height_offset + + # Edge falloff: + if not sphere: + if falloff: + ratio_x, ratio_y = abs(x) * 2 / meshsize_x, abs(y) * 2 / meshsize_y + fallofftypes = [0, + sqrt(ratio_y**falloffsize_y), + sqrt(ratio_x**falloffsize_x), + sqrt(ratio_x**falloffsize_x + ratio_y**falloffsize_y) + ] + dist = fallofftypes[falloff] + value -= edge_level + if(dist < 1.0): + dist = (dist * dist * (3 - 2 * dist)) + value = (value - value * dist) + edge_level + else: + value = edge_level + + # Strata / terrace / layers + if stratatype not in [0, "0"]: + if stratatype in [1, "1"]: + strata = strata / height + strata *= 2 + steps = (sin(value * strata * pi) * (0.1 / strata * pi)) + value = (value * 0.5 + steps * 0.5) * 2.0 + + elif stratatype in [2, "2"]: + strata = strata / height + steps = -abs(sin(value * strata * pi) * (0.1 / strata * pi)) + value = (value * 0.5 + steps * 0.5) * 2.0 + + elif stratatype in [3, "3"]: + strata = strata / height + steps = abs(sin(value * strata * pi) * (0.1 / strata * pi)) + value = (value * 0.5 + steps * 0.5) * 2.0 + + elif stratatype in [4, "4"]: + strata = strata / height + value = int( value * strata ) * 1.0 / strata + + elif stratatype in [5, "5"]: + strata = strata / height + steps = (int( value * strata ) * 1.0 / strata) + value = (value * (1.0 - 0.5) + steps * 0.5) + + # Clamp height min max + if (value < minimum): + value = minimum + if (value > maximum): + value = maximum + + return value + + +# ------------------------------------------------------------ +# draw properties + +def draw_ant_refresh(self, context): + layout = self.layout + if self.auto_refresh is False: + self.refresh = False + elif self.auto_refresh is True: + self.refresh = True + row = layout.box().row() + split = row.split() + split.scale_y = 1.5 + split.prop(self, "auto_refresh", toggle=True, icon_only=True, icon='AUTO') + split.prop(self, "refresh", toggle=True, icon_only=True, icon='FILE_REFRESH') + + +def draw_ant_main(self, context, generate=True): + layout = self.layout + box = layout.box() + box.prop(self, "show_main_settings", toggle=True) + if self.show_main_settings: + if generate: + row = box.row(align=True) + split = row.split(align=True) + split.prop(self, "at_cursor", toggle=True, icon_only=True, icon='CURSOR') + split.prop(self, "smooth_mesh", toggle=True, icon_only=True, icon='SOLID') + split.prop(self, "tri_face", toggle=True, icon_only=True, icon='MESH_DATA') + + if not self.sphere_mesh: + row = box.row(align=True) + row.prop(self, "sphere_mesh", toggle=True) + else: + row = box.row(align=True) + split = row.split(0.5, align=True) + split.prop(self, "sphere_mesh", toggle=True) + split.prop(self, "remove_double", toggle=True) + + box.prop(self, "ant_terrain_name") + box.prop_search(self, "land_material", bpy.data, "materials") + + col = box.column(align=True) + col.prop(self, "subdivision_x") + col.prop(self, "subdivision_y") + col = box.column(align=True) + if self.sphere_mesh: + col.prop(self, "mesh_size") + else: + col.prop(self, "mesh_size_x") + col.prop(self, "mesh_size_y") + + +def draw_ant_noise(self, context): + layout = self.layout + box = layout.box() + box.prop(self, "show_noise_settings", toggle=True) + if self.show_noise_settings: + box.prop(self, "noise_type") + if self.noise_type == "blender_texture": + box.prop_search(self, "texture_block", bpy.data, "textures") + else: + box.prop(self, "basis_type") + + col = box.column(align=True) + col.prop(self, "random_seed") + col = box.column(align=True) + col.prop(self, "noise_offset_x") + col.prop(self, "noise_offset_y") + col.prop(self, "noise_offset_z") + col.prop(self, "noise_size_x") + col.prop(self, "noise_size_y") + col.prop(self, "noise_size_z") + col = box.column(align=True) + col.prop(self, "noise_size") + + col = box.column(align=True) + if self.noise_type == "multi_fractal": + col.prop(self, "noise_depth") + col.prop(self, "dimension") + col.prop(self, "lacunarity") + elif self.noise_type == "ridged_multi_fractal": + col.prop(self, "noise_depth") + col.prop(self, "dimension") + col.prop(self, "lacunarity") + col.prop(self, "offset") + col.prop(self, "gain") + elif self.noise_type == "hybrid_multi_fractal": + col.prop(self, "noise_depth") + col.prop(self, "dimension") + col.prop(self, "lacunarity") + col.prop(self, "offset") + col.prop(self, "gain") + elif self.noise_type == "hetero_terrain": + col.prop(self, "noise_depth") + col.prop(self, "dimension") + col.prop(self, "lacunarity") + col.prop(self, "offset") + elif self.noise_type == "fractal": + col.prop(self, "noise_depth") + col.prop(self, "dimension") + col.prop(self, "lacunarity") + elif self.noise_type == "turbulence_vector": + col.prop(self, "noise_depth") + col.prop(self, "amplitude") + col.prop(self, "frequency") + col.separator() + row = col.row(align=True) + row.prop(self, "hard_noise", expand=True) + elif self.noise_type == "variable_lacunarity": + box.prop(self, "vl_basis_type") + box.prop(self, "distortion") + elif self.noise_type == "marble_noise": + box.prop(self, "marble_shape") + box.prop(self, "marble_bias") + box.prop(self, "marble_sharp") + col = box.column(align=True) + col.prop(self, "distortion") + col.prop(self, "noise_depth") + col.separator() + row = col.row(align=True) + row.prop(self, "hard_noise", expand=True) + elif self.noise_type == "shattered_hterrain": + col.prop(self, "noise_depth") + col.prop(self, "dimension") + col.prop(self, "lacunarity") + col.prop(self, "offset") + col.prop(self, "distortion") + elif self.noise_type == "strata_hterrain": + col.prop(self, "noise_depth") + col.prop(self, "dimension") + col.prop(self, "lacunarity") + col.prop(self, "offset") + col.prop(self, "distortion", text="Strata") + elif self.noise_type == "ant_turbulence": + col.prop(self, "noise_depth") + col.prop(self, "amplitude") + col.prop(self, "frequency") + col.prop(self, "distortion") + col.separator() + row = col.row(align=True) + row.prop(self, "hard_noise", expand=True) + elif self.noise_type == "vl_noise_turbulence": + col.prop(self, "noise_depth") + col.prop(self, "amplitude") + col.prop(self, "frequency") + col.prop(self, "distortion") + col.separator() + col.prop(self, "vl_basis_type") + col.separator() + row = col.row(align=True) + row.prop(self, "hard_noise", expand=True) + elif self.noise_type == "vl_hTerrain": + col.prop(self, "noise_depth") + col.prop(self, "dimension") + col.prop(self, "lacunarity") + col.prop(self, "offset") + col.prop(self, "distortion") + col.separator() + col.prop(self, "vl_basis_type") + elif self.noise_type == "distorted_heteroTerrain": + col.prop(self, "noise_depth") + col.prop(self, "dimension") + col.prop(self, "lacunarity") + col.prop(self, "offset") + col.prop(self, "distortion") + col.separator() + col.prop(self, "vl_basis_type") + elif self.noise_type == "double_multiFractal": + col.prop(self, "noise_depth") + col.prop(self, "dimension") + col.prop(self, "lacunarity") + col.prop(self, "offset") + col.prop(self, "gain") + col.separator() + col.prop(self, "vl_basis_type") + elif self.noise_type == "slick_rock": + col.prop(self, "noise_depth") + col.prop(self, "dimension") + col.prop(self, "lacunarity") + col.prop(self, "gain") + col.prop(self, "offset") + col.prop(self, "distortion") + col.separator() + col.prop(self, "vl_basis_type") + elif self.noise_type == "planet_noise": + col.prop(self, "noise_depth") + col.separator() + row = col.row(align=True) + row.prop(self, "hard_noise", expand=True) + + +def draw_ant_displace(self, context, generate=True): + layout = self.layout + box = layout.box() + box.prop(self, "show_displace_settings", toggle=True) + if self.show_displace_settings: + col = box.column(align=True) + row = col.row(align=True).split(0.92, align=True) + row.prop(self, "height") + row.prop(self, "height_invert", toggle=True, text="", icon='ARROW_LEFTRIGHT') + col.prop(self, "height_offset") + col.prop(self, "maximum") + col.prop(self, "minimum") + if generate: + if not self.sphere_mesh: + col = box.column() + col.prop(self, "edge_falloff") + if self.edge_falloff is not "0": + col = box.column(align=True) + col.prop(self, "edge_level") + if self.edge_falloff in ["2", "3"]: + col.prop(self, "falloff_x") + if self.edge_falloff in ["1", "3"]: + col.prop(self, "falloff_y") + else: + col = box.column(align=False) + col.prop(self, "use_vgroup", toggle=True) + + col = box.column() + col.prop(self, "strata_type") + if self.strata_type is not "0": + col = box.column() + col.prop(self, "strata") + + +def draw_ant_water(self, context): + layout = self.layout + box = layout.box() + col = box.column() + col.prop(self, "water_plane", toggle=True) + if self.water_plane: + col = box.column(align=True) + col.prop_search(self, "water_material", bpy.data, "materials") + col = box.column() + col.prop(self, "water_level") + + +# Store propereties +def store_properties(operator, ob): + ob.ant_landscape.ant_terrain_name = operator.ant_terrain_name + ob.ant_landscape.at_cursor = operator.at_cursor + ob.ant_landscape.smooth_mesh = operator.smooth_mesh + ob.ant_landscape.tri_face = operator.tri_face + ob.ant_landscape.sphere_mesh = operator.sphere_mesh + ob.ant_landscape.land_material = operator.land_material + ob.ant_landscape.water_material = operator.water_material + ob.ant_landscape.texture_block = operator.texture_block + ob.ant_landscape.subdivision_x = operator.subdivision_x + ob.ant_landscape.subdivision_y = operator.subdivision_y + ob.ant_landscape.mesh_size_x = operator.mesh_size_x + ob.ant_landscape.mesh_size_y = operator.mesh_size_y + ob.ant_landscape.mesh_size = operator.mesh_size + ob.ant_landscape.random_seed = operator.random_seed + ob.ant_landscape.noise_offset_x = operator.noise_offset_x + ob.ant_landscape.noise_offset_y = operator.noise_offset_y + ob.ant_landscape.noise_offset_z = operator.noise_offset_z + ob.ant_landscape.noise_size_x = operator.noise_size_x + ob.ant_landscape.noise_size_y = operator.noise_size_y + ob.ant_landscape.noise_size_z = operator.noise_size_z + ob.ant_landscape.noise_size = operator.noise_size + ob.ant_landscape.noise_type = operator.noise_type + ob.ant_landscape.basis_type = operator.basis_type + ob.ant_landscape.vl_basis_type = operator.vl_basis_type + ob.ant_landscape.distortion = operator.distortion + ob.ant_landscape.hard_noise = operator.hard_noise + ob.ant_landscape.noise_depth = operator.noise_depth + ob.ant_landscape.amplitude = operator.amplitude + ob.ant_landscape.frequency = operator.frequency + ob.ant_landscape.dimension = operator.dimension + ob.ant_landscape.lacunarity = operator.lacunarity + ob.ant_landscape.offset = operator.offset + ob.ant_landscape.gain = operator.gain + ob.ant_landscape.marble_bias = operator.marble_bias + ob.ant_landscape.marble_sharp = operator.marble_sharp + ob.ant_landscape.marble_shape = operator.marble_shape + ob.ant_landscape.height = operator.height + ob.ant_landscape.height_invert = operator.height_invert + ob.ant_landscape.height_offset = operator.height_offset + ob.ant_landscape.maximum = operator.maximum + ob.ant_landscape.minimum = operator.minimum + ob.ant_landscape.edge_falloff = operator.edge_falloff + ob.ant_landscape.edge_level = operator.edge_level + ob.ant_landscape.falloff_x = operator.falloff_x + ob.ant_landscape.falloff_y = operator.falloff_y + ob.ant_landscape.strata_type = operator.strata_type + ob.ant_landscape.strata = operator.strata + ob.ant_landscape.water_plane = operator.water_plane + ob.ant_landscape.water_level = operator.water_level + ob.ant_landscape.use_vgroup = operator.use_vgroup + ob.ant_landscape.show_main_settings = operator.show_main_settings + ob.ant_landscape.show_noise_settings = operator.show_noise_settings + ob.ant_landscape.show_displace_settings = operator.show_displace_settings + #print("A.N.T. Landscape Object Properties:") + #for k in ob.ant_landscape.keys(): + # print(k, "-", ob.ant_landscape[k]) + return ob + diff --git a/ant_landscape/ant_landscape_refresh.py b/ant_landscape/ant_landscape_refresh.py new file mode 100644 index 00000000..ae3710de --- /dev/null +++ b/ant_landscape/ant_landscape_refresh.py @@ -0,0 +1,243 @@ +# ##### 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 ##### + +# Another Noise Tool - Landscape Redraw - Regenerate +# Jim Hazevoet + + +# ------------------------------------------------------------ +# import modules +import bpy + +from .ant_functions import ( + noise_gen, + grid_gen, + sphere_gen, + create_mesh_object, + store_properties, + ) + +# ------------------------------------------------------------ +# Do refresh - redraw +class AntLandscapeRefresh(bpy.types.Operator): + bl_idname = "mesh.ant_landscape_refresh" + bl_label = "Refresh" + bl_description = "Refresh landscape with current settings" + bl_options = {'REGISTER', 'UNDO'} + + + @classmethod + def poll(cls, context): + ob = bpy.context.active_object + return (ob.ant_landscape and not ob.ant_landscape['sphere_mesh']) + + + def execute(self, context): + # turn off undo + undo = bpy.context.user_preferences.edit.use_global_undo + bpy.context.user_preferences.edit.use_global_undo = False + + # ant object items + obj = bpy.context.active_object + + bpy.ops.object.mode_set(mode = 'EDIT') + bpy.ops.object.mode_set(mode = 'OBJECT') + + + if obj and obj.ant_landscape.keys(): + obi = obj.ant_landscape.items() + #print("Refresh A.N.T. Landscape Grid") + #for k in obi.keys(): + # print(k, "-", obi[k]) + prop = [] + for i in range(len(obi)): + prop.append(obi[i][1]) + + # redraw verts + mesh = obj.data + for v in mesh.vertices: + v.co[2] = 0 + v.co[2] = noise_gen(v.co, prop) + mesh.update() + else: + pass + + # restore pre operator undo state + context.user_preferences.edit.use_global_undo = undo + + return {'FINISHED'} + + +# ------------------------------------------------------------ +# Do regenerate +class AntLandscapeRegenerate(bpy.types.Operator): + bl_idname = "mesh.ant_landscape_regenerate" + bl_label = "Regenerate" + bl_description = "Regenerate landscape with current settings" + bl_options = {'REGISTER', 'UNDO'} + + + @classmethod + def poll(cls, context): + return bpy.context.active_object.ant_landscape + + + def execute(self, context): + + # turn off undo + undo = bpy.context.user_preferences.edit.use_global_undo + bpy.context.user_preferences.edit.use_global_undo = False + + scene = bpy.context.scene + # ant object items + obj = bpy.context.active_object + + if obj and obj.ant_landscape.keys(): + ob = obj.ant_landscape + obi = ob.items() + #print("Regenerate A.N.T. Landscape Grid") + #for k in obi.keys(): + # print(k, "-", obi[k]) + ant_props = [] + for i in range(len(obi)): + ant_props.append(obi[i][1]) + + new_name = ob.ant_terrain_name + + # Main function, create landscape mesh object + if ob["sphere_mesh"]: + # sphere + verts, faces = sphere_gen( + ob["subdivision_y"], + ob["subdivision_x"], + ob["tri_face"], + ob["mesh_size"], + ant_props, + False, + 0.0 + ) + new_ob = create_mesh_object(context, verts, [], faces, new_name).object + else: + # grid + verts, faces = grid_gen( + ob["subdivision_x"], + ob["subdivision_y"], + ob["tri_face"], + ob["mesh_size_x"], + ob["mesh_size_y"], + ant_props, + False, + 0.0 + ) + new_ob = create_mesh_object(context, verts, [], faces, new_name).object + + new_ob.select = True + + if ob["smooth_mesh"]: + bpy.ops.object.shade_smooth() + + # Landscape Material + if ob["land_material"] != "" and ob["land_material"] in bpy.data.materials: + mat = bpy.data.materials[ob["land_material"]] + bpy.context.object.data.materials.append(mat) + + # Water plane + if ob["water_plane"]: + if ob["sphere_mesh"]: + # sphere + verts, faces = sphere_gen( + ob["subdivision_y"], + ob["subdivision_x"], + ob["tri_face"], + ob["mesh_size"], + ant_props, + ob["water_plane"], + ob["water_level"] + ) + wobj = create_mesh_object(context, verts, [], faces, new_name+"_plane").object + else: + # grid + verts, faces = grid_gen( + 2, + 2, + ob["tri_face"], + ob["mesh_size_x"], + ob["mesh_size_y"], + ant_props, + ob["water_plane"], + ob["water_level"] + ) + wobj = create_mesh_object(context, verts, [], faces, new_name+"_plane").object + + wobj.select = True + + if ob["smooth_mesh"]: + bpy.ops.object.shade_smooth() + + # Water Material + if ob["water_material"] != "" and ob["water_material"] in bpy.data.materials: + mat = bpy.data.materials[ob["water_material"]] + bpy.context.object.data.materials.append(mat) + + # Loc Rot Scale + if ob["water_plane"]: + wobj.location = obj.location + wobj.rotation_euler = obj.rotation_euler + wobj.scale = obj.scale + wobj.select = False + + + new_ob.location = obj.location + new_ob.rotation_euler = obj.rotation_euler + new_ob.scale = obj.scale + + # Store props + new_ob = store_properties(ob, new_ob) + + # Delete old object + new_ob.select = False + + obj.select = True + scene.objects.active = obj + bpy.ops.object.delete(use_global=False) + #scene.update() + + # Select landscape and make active + new_ob.select = True + scene.objects.active = new_ob + + # restore pre operator undo state + context.user_preferences.edit.use_global_undo = undo + + return {'FINISHED'} + +''' +# ------------------------------------------------------------ +# Register: + +def register(): + bpy.utils.register_module(__name__) + + +def unregister(): + bpy.utils.unregister_module(__name__) + + +if __name__ == "__main__": + register() +'''
\ No newline at end of file diff --git a/ant_landscape/mesh_ant_displace.py b/ant_landscape/mesh_ant_displace.py new file mode 100644 index 00000000..7a1c17ea --- /dev/null +++ b/ant_landscape/mesh_ant_displace.py @@ -0,0 +1,562 @@ +# ##### 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 ##### + +# Another Noise Tool - Mesh Displace +# Jim Hazevoet + +# ------------------------------------------------------------ +# import modules +import bpy +from bpy.props import ( + BoolProperty, + EnumProperty, + FloatProperty, + IntProperty, + StringProperty, + FloatVectorProperty, + ) + +from .ant_functions import ( + noise_gen, + draw_ant_refresh, + draw_ant_noise, + draw_ant_displace, + ) + +# ------------------------------------------------------------ +# Do vert displacement +class AntMeshDisplace(bpy.types.Operator): + bl_idname = "mesh.ant_displace" + bl_label = "Another Noise Tool - Displace" + bl_description = "Displace mesh vertices" + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + ant_terrain_name = StringProperty( + name="Name", + default="Landscape" + ) + land_material = StringProperty( + name='Material', + default="", + description="Terrain material" + ) + water_material = StringProperty( + name='Material', + default="", + description="Water plane material" + ) + texture_block = StringProperty( + name="Texture", + default="" + ) + at_cursor = BoolProperty( + name="Cursor", + default=True, + description="Place at cursor location", + ) + smooth_mesh = BoolProperty( + name="Smooth", + default=True, + description="Shade smooth" + ) + tri_face = BoolProperty( + name="Triangulate", + default=False, + description="Triangulate faces" + ) + sphere_mesh = BoolProperty( + name="Sphere", + default=False, + description="Generate uv sphere - remove doubles when ready" + ) + subdivision_x = IntProperty( + name="Subdivisions X", + default=128, + min=4, + max=6400, + description="Mesh X subdivisions" + ) + subdivision_y = IntProperty( + default=128, + name="Subdivisions Y", + min=4, + max=6400, + description="Mesh Y subdivisions" + ) + mesh_size = FloatProperty( + default=2.0, + name="Mesh Size", + min=0.01, + max=100000.0, + description="Mesh size" + ) + mesh_size_x = FloatProperty( + default=2.0, + name="Mesh Size X", + min=0.01, + description="Mesh x size" + ) + mesh_size_y = FloatProperty( + name="Mesh Size Y", + default=2.0, + min=0.01, + description="Mesh y size" + ) + + random_seed = IntProperty( + name="Random Seed", + default=0, + min=0, + description="Randomize noise origin" + ) + noise_offset_x = FloatProperty( + name="Offset X", + default=0.0, + description="Noise X Offset" + ) + noise_offset_y = FloatProperty( + name="Offset Y", + default=0.0, + description="Noise Y Offset" + ) + noise_offset_z = FloatProperty( + name="Offset Z", + default=0.0, + description="Noise Z Offset" + ) + noise_size_x = FloatProperty( + default=1.0, + name="Size X", + min=0.01, + max=1000.0, + description="Noise x size" + ) + noise_size_y = FloatProperty( + name="Size Y", + default=1.0, + min=0.01, + max=1000.0, + description="Noise y size" + ) + noise_size_z = FloatProperty( + name="Size Z", + default=1.0, + min=0.01, + max=1000.0, + description="Noise Z size" + ) + noise_size = FloatProperty( + name="Noise Size", + default=1.0, + min=0.01, + max=1000.0, + description="Noise size" + ) + noise_type = EnumProperty( + name="Noise Type", + default='hetero_terrain', + description="Noise type", + items = [ + ('multi_fractal', "Multi Fractal", "Blender: Multi Fractal algorithm", 0), + ('ridged_multi_fractal', "Ridged MFractal", "Blender: Ridged Multi Fractal", 1), + ('hybrid_multi_fractal', "Hybrid MFractal", "Blender: Hybrid Multi Fractal", 2), + ('hetero_terrain', "Hetero Terrain", "Blender: Hetero Terrain", 3), + ('fractal', "fBm Fractal", "Blender: fBm - Fractional Browninian motion", 4), + ('turbulence_vector', "Turbulence", "Blender: Turbulence Vector", 5), + ('variable_lacunarity', "Distorted Noise", "Blender: Distorted Noise", 6), + ('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), + ('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), + ('slick_rock', "Slick Rock", "A.N.T: slick rock", 15), + ('planet_noise', "Planet Noise", "Planet Noise by: Farsthary", 16), + ('blender_texture', "Blender Texture - Texture Nodes", "Blender texture data block", 17)] + ) + basis_type = EnumProperty( + name="Noise Basis", + default="0", + description="Noise basis algorithms", + items = [ + ("0", "Blender", "Blender default noise", 0), + ("1", "Perlin", "Perlin noise", 1), + ("2", "New Perlin", "New Perlin noise", 2), + ("3", "Voronoi F1", "Voronoi F1", 3), + ("4", "Voronoi F2", "Voronoi F2", 4), + ("5", "Voronoi F3", "Voronoi F3", 5), + ("6", "Voronoi F4", "Voronoi F4", 6), + ("7", "Voronoi F2-F1", "Voronoi F2-F1", 7), + ("8", "Voronoi Crackle", "Voronoi Crackle", 8), + ("9", "Cell Noise", "Cell noise", 9)] + ) + vl_basis_type = EnumProperty( + name="vlNoise Basis", + default="0", + description="VLNoise basis algorithms", + items = [ + ("0", "Blender", "Blender default noise", 0), + ("1", "Perlin", "Perlin noise", 1), + ("2", "New Perlin", "New Perlin noise", 2), + ("3", "Voronoi F1", "Voronoi F1", 3), + ("4", "Voronoi F2", "Voronoi F2", 4), + ("5", "Voronoi F3", "Voronoi F3", 5), + ("6", "Voronoi F4", "Voronoi F4", 6), + ("7", "Voronoi F2-F1", "Voronoi F2-F1", 7), + ("8", "Voronoi Crackle", "Voronoi Crackle", 8), + ("9", "Cell Noise", "Cell noise", 9)] + ) + distortion = FloatProperty( + name="Distortion", + default=1.0, + min=0.01, + max=100.0, + description="Distortion amount" + ) + hard_noise = EnumProperty( + name="Soft Hard", + default="0", + description="Soft Noise, Hard noise", + items = [ + ("0", "Soft", "Soft Noise", 0), + ("1", "Hard", "Hard noise", 1)] + ) + noise_depth = IntProperty( + name="Depth", + default=8, + min=0, + max=16, + description="Noise Depth - number of frequencies in the fBm" + ) + amplitude = FloatProperty( + name="Amp", + default=0.5, + min=0.01, + max=1.0, + description="Amplitude" + ) + frequency = FloatProperty( + name="Freq", + default=2.0, + min=0.01, + max=5.0, + description="Frequency" + ) + dimension = FloatProperty( + name="Dimension", + default=1.0, + min=0.01, + max=2.0, + description="H - fractal dimension of the roughest areas" + ) + lacunarity = FloatProperty( + name="Lacunarity", + min=0.01, + max=6.0, + default=2.0, + description="Lacunarity - gap between successive frequencies" + ) + offset = FloatProperty( + name="Offset", + default=1.0, + min=0.01, + max=6.0, + description="Offset - raises the terrain from sea level" + ) + gain = FloatProperty( + name="Gain", + default=1.0, + min=0.01, + max=6.0, + description="Gain - scale factor" + ) + marble_bias = EnumProperty( + name="Bias", + default="0", + description="Marble bias", + items = [ + ("0", "Sin", "Sin", 0), + ("1", "Cos", "Cos", 1), + ("2", "Tri", "Tri", 2), + ("3", "Saw", "Saw", 3)] + ) + marble_sharp = EnumProperty( + name="Sharp", + default="0", + description="Marble sharpness", + items = [ + ("0", "Soft", "Soft", 0), + ("1", "Sharp", "Sharp", 1), + ("2", "Sharper", "Sharper", 2), + ("3", "Soft inv.", "Soft", 3), + ("4", "Sharp inv.", "Sharp", 4), + ("5", "Sharper inv.", "Sharper", 5)] + ) + marble_shape = EnumProperty( + name="Shape", + default="0", + description="Marble shape", + items= [ + ("0", "Default", "Default", 0), + ("1", "Ring", "Ring", 1), + ("2", "Swirl", "Swirl", 2), + ("3", "Bump", "Bump", 3), + ("4", "Wave", "Wave", 4), + ("5", "Z", "Z", 5), + ("6", "Y", "Y", 6), + ("7", "X", "X", 7)] + ) + height = FloatProperty( + name="Height", + default=0.5, + min=-10000.0, + max=10000.0, + description="Noise intensity scale" + ) + height_invert = BoolProperty( + name="Invert", + default=False, + description="Height invert", + ) + height_offset = FloatProperty( + name="Offset", + default=0.0, + min=-10000.0, + max=10000.0, + description="Height offset" + ) + edge_falloff = EnumProperty( + name="Falloff", + default="0", + description="Flatten edges", + items = [ + ("0", "None", "None", 0), + ("1", "Y", "Y Falloff", 1), + ("2", "X", "X Falloff", 2), + ("3", "X Y", "X Y Falloff", 3)] + ) + falloff_x = FloatProperty( + name="Falloff X", + default=4.0, + min=0.1, + max=100.0, + description="Falloff x scale" + ) + falloff_y = FloatProperty( + name="Falloff Y", + default=4.0, + min=0.1, + max=100.0, + description="Falloff y scale" + ) + edge_level = FloatProperty( + name="Edge Level", + default=0.0, + min=-10000.0, + max=10000.0, + description="Edge level, sealevel offset" + ) + maximum = FloatProperty( + name="Maximum", + default=1.0, + min=-10000.0, + max=10000.0, + description="Maximum, flattens terrain at plateau level" + ) + minimum = FloatProperty( + name="Minimum", + default=-1.0, + min=-10000.0, + max=10000.0, + description="Minimum, flattens terrain at seabed level" + ) + use_vgroup = BoolProperty( + name="Vertex Group Weight", + default=False, + description="Use active vertex group weight" + ) + strata = FloatProperty( + name="Amount", + default=5.0, + min=0.01, + max=1000.0, + description="Strata layers / terraces" + ) + strata_type = EnumProperty( + name="Strata", + default="0", + description="Strata types", + items = [ + ("0", "None", "No strata", 0), + ("1", "Smooth", "Smooth transitions", 1), + ("2", "Sharp Sub", "Sharp substract transitions", 2), + ("3", "Sharp Add", "Sharp add transitions", 3), + ("4", "Posterize", "Posterize", 4), + ("5", "Posterize Mix", "Posterize mixed", 5)] + ) + water_plane = BoolProperty( + name="Water Plane", + default=False, + description="Add water plane" + ) + water_level = FloatProperty( + name="Level", + default=0.01, + min=-10000.0, + max=10000.0, + description="Water level" + ) + remove_double = BoolProperty( + name="Remove Doubles", + default=False, + description="Remove doubles" + ) + show_main_settings = BoolProperty( + name="Main Settings", + default=True, + description="Show settings" + ) + show_noise_settings = BoolProperty( + name="Noise Settings", + default=True, + description="Show noise settings" + ) + show_displace_settings = BoolProperty( + name="Displace Settings", + default=True, + description="Show terrain settings" + ) + refresh = BoolProperty( + name="Refresh", + default=False, + description="Refresh" + ) + auto_refresh = BoolProperty( + name="Auto", + default=False, + description="Automatic refresh" + ) + + + def draw(self, context): + draw_ant_refresh(self, context) + draw_ant_noise(self, context) + draw_ant_displace(self, context, generate=False) + + + @classmethod + def poll(cls, context): + ob = context.object + return (ob and ob.type == 'MESH') + + + def invoke(self, context, event): + self.refresh = True + return self.execute(context) + + + def execute(self, context): + if not self.refresh: + return {'PASS_THROUGH'} + + # turn off undo + undo = bpy.context.user_preferences.edit.use_global_undo + bpy.context.user_preferences.edit.use_global_undo = False + + ob = context.object + + # Properties: + props = [ + self.ant_terrain_name, + self.at_cursor, + self.smooth_mesh, + self.tri_face, + self.sphere_mesh, + self.land_material, + self.water_material, + self.texture_block, + self.subdivision_x, + self.subdivision_y, + self.mesh_size_x, + self.mesh_size_y, + self.mesh_size, + self.random_seed, + self.noise_offset_x, + self.noise_offset_y, + self.noise_offset_z, + self.noise_size_x, + self.noise_size_y, + self.noise_size_z, + self.noise_size, + self.noise_type, + self.basis_type, + self.vl_basis_type, + self.distortion, + self.hard_noise, + self.noise_depth, + self.amplitude, + self.frequency, + self.dimension, + self.lacunarity, + self.offset, + self.gain, + self.marble_bias, + self.marble_sharp, + self.marble_shape, + self.height, + self.height_invert, + self.height_offset, + self.maximum, + self.minimum, + self.edge_falloff, + self.edge_level, + self.falloff_x, + self.falloff_y, + self.strata_type, + self.strata, + self.water_plane, + self.water_level, + self.use_vgroup + ] + + # do displace + mesh = ob.data + + if self.use_vgroup is True: + vertex_group = ob.vertex_groups.active + if vertex_group: + for v in mesh.vertices: + v.co += vertex_group.weight(v.index) * v.normal * noise_gen(v.co, props) + + else: + for v in mesh.vertices: + v.co += v.normal * noise_gen(v.co, props) + mesh.update() + + if bpy.ops.object.shade_smooth == True: + bpy.ops.object.shade_smooth() + + if self.auto_refresh is False: + self.refresh = False + + # restore pre operator undo state + context.user_preferences.edit.use_global_undo = undo + + return {'FINISHED'} diff --git a/blender_id/CHANGELOG.md b/blender_id/CHANGELOG.md new file mode 100644 index 00000000..201ee1d0 --- /dev/null +++ b/blender_id/CHANGELOG.md @@ -0,0 +1,16 @@ +# Blender ID Add-on Changelog + + +## Version 1.3 (released 2017-06-14) + +- Show a message after logging out. +- Store token expiry date in profile JSON. +- Show "validate" button when the token expiration is unknown. +- Urge the user to log out & back in again to refresh the auth token if it expires within 2 weeks. +- Added a method `validate_token()` to the public Blender ID Add-on API. + + +## Older versions + +The history of older versions can be found in the +[Blender ID Add-on Git repository](https://developer.blender.org/diffusion/BIA/). diff --git a/blender_id/__init__.py b/blender_id/__init__.py index ae24af86..a7094c7f 100644 --- a/blender_id/__init__.py +++ b/blender_id/__init__.py @@ -21,7 +21,7 @@ bl_info = { 'name': 'Blender ID authentication', 'author': 'Francesco Siddi, Inês Almeida and Sybren A. Stüvel', - 'version': (1, 2, 0), + 'version': (1, 3, 0), 'blender': (2, 77, 0), 'location': 'Add-on preferences', 'description': @@ -32,6 +32,9 @@ bl_info = { 'support': 'OFFICIAL', } +import datetime +import typing + import bpy from bpy.types import AddonPreferences, Operator, PropertyGroup from bpy.props import PointerProperty, StringProperty @@ -123,6 +126,53 @@ def get_subclient_user_id(subclient_id: str) -> str: return BlenderIdProfile.subclients[subclient_id]['subclient_user_id'] +def validate_token() -> typing.Optional[str]: + """Validates the current user's token with Blender ID. + + Also refreshes the stored token expiry time. + + :returns: None if everything was ok, otherwise returns an error message. + """ + + expires, err = communication.blender_id_server_validate(token=BlenderIdProfile.token) + if err is not None: + return err + + BlenderIdProfile.expires = expires + BlenderIdProfile.save_json() + + return None + + +def token_expires() -> typing.Optional[datetime.datetime]: + """Returns the token expiry timestamp. + + Returns None if the token expiry is unknown. This can happen when + the last login/validation was performed using a version of this + add-on that was older than 1.3. + """ + + exp = BlenderIdProfile.expires + if not exp: + return None + + # Try parsing as different formats. A new Blender ID is coming, + # which may change the format in which timestamps are sent. + formats = [ + '%Y-%m-%dT%H:%M:%S.%fZ', # ISO 8601 with Z-suffix, used by new Blender ID + '%a, %d %b %Y %H:%M:%S GMT', # RFC 1123, used by current Blender ID + ] + for fmt in formats: + try: + return datetime.datetime.strptime(exp, fmt) + except ValueError: + # Just use the next format string and try again. + pass + + # Unable to parse, may as well not be there then. + return None + + class BlenderIdPreferences(AddonPreferences): bl_idname = __name__ @@ -165,11 +215,41 @@ class BlenderIdPreferences(AddonPreferences): active_profile = get_active_profile() if active_profile: - text = 'You are logged in as {0}'.format(active_profile.username) - layout.label(text=text, icon='WORLD_DATA') + expiry = token_expires() + now = datetime.datetime.utcnow() + show_validate_button = bpy.app.debug + + if expiry is None: + layout.label(text='We do not know when your token expires, please validate it.') + show_validate_button = True + elif now >= expiry: + layout.label(text='Your login has expired! Log out and log in again to refresh it.', + icon='ERROR') + else: + time_left = expiry - now + if time_left.days > 14: + exp_str = 'on {:%Y-%m-%d}'.format(expiry) + elif time_left.days > 1: + exp_str = 'in %i days.' % time_left.days + elif time_left.seconds >= 7200: + exp_str = 'in %i hours.' % round(time_left.seconds / 3600) + elif time_left.seconds >= 120: + exp_str = 'in %i minutes.' % round(time_left.seconds / 60) + else: + exp_str = 'within seconds' + + if time_left.days < 14: + layout.label('You are logged in as %s.' % active_profile.username, + icon='WORLD_DATA') + layout.label(text='Your token will expire %s. Please log out and log in again ' + 'to refresh it.' % exp_str, icon='PREVIEW_RANGE') + else: + layout.label('You are logged in as %s. Your authentication token expires %s.' + % (active_profile.username, exp_str), icon='WORLD_DATA') + row = layout.row() row.operator('blender_id.logout') - if bpy.app.debug: + if show_validate_button: row.operator('blender_id.validate') else: layout.prop(self, 'blender_id_username') @@ -196,12 +276,12 @@ class BlenderIdLogin(BlenderIdMixin, Operator): addon_prefs = self.addon_prefs(context) - resp = communication.blender_id_server_authenticate( + auth_result = communication.blender_id_server_authenticate( username=addon_prefs.blender_id_username, password=addon_prefs.blender_id_password ) - if resp['status'] == 'success': + if auth_result.success: # Prevent saving the password in user preferences. Overwrite the password with a # random string, as just setting to '' might only replace the first byte with 0. pwlen = len(addon_prefs.blender_id_password) @@ -211,14 +291,13 @@ class BlenderIdLogin(BlenderIdMixin, Operator): addon_prefs.blender_id_password = '' profiles.save_as_active_profile( - resp['user_id'], - resp['token'], + auth_result, addon_prefs.blender_id_username, {} ) addon_prefs.ok_message = 'Logged in' else: - addon_prefs.error_message = resp['error_message'] + addon_prefs.error_message = auth_result.error_message if BlenderIdProfile.user_id: profiles.logout(BlenderIdProfile.user_id) @@ -234,11 +313,11 @@ class BlenderIdValidate(BlenderIdMixin, Operator): def execute(self, context): addon_prefs = self.addon_prefs(context) - resp = communication.blender_id_server_validate(token=BlenderIdProfile.token) - if resp is None: + err = validate_token() + if err is None: addon_prefs.ok_message = 'Authentication token is valid.' else: - addon_prefs.error_message = '%s; you probably want to log out and log in again.' % resp + addon_prefs.error_message = '%s; you probably want to log out and log in again.' % err BlenderIdProfile.read_json() @@ -250,12 +329,15 @@ class BlenderIdLogout(BlenderIdMixin, Operator): bl_label = 'Logout' def execute(self, context): + addon_prefs = self.addon_prefs(context) + communication.blender_id_server_logout(BlenderIdProfile.user_id, BlenderIdProfile.token) profiles.logout(BlenderIdProfile.user_id) BlenderIdProfile.read_json() + addon_prefs.ok_message = 'You have been logged out.' return {'FINISHED'} diff --git a/blender_id/communication.py b/blender_id/communication.py index ee71c553..90ccf9a1 100644 --- a/blender_id/communication.py +++ b/blender_id/communication.py @@ -19,12 +19,24 @@ # <pep8 compliant> import functools +import typing class BlenderIdCommError(RuntimeError): """Raised when there was an error communicating with Blender ID""" +class AuthResult: + def __init__(self, *, success: bool, + user_id: str=None, token: str=None, expires: str=None, + error_message: typing.Any=None): # when success=False + self.success = success + self.user_id = user_id + self.token = token + self.error_message = str(error_message) + self.expires = expires + + @functools.lru_cache(maxsize=None) def host_label(): import socket @@ -46,7 +58,7 @@ def blender_id_endpoint(endpoint_path=None): return urllib.parse.urljoin(base_url, endpoint_path) -def blender_id_server_authenticate(username, password): +def blender_id_server_authenticate(username, password) -> AuthResult: """Authenticate the user with the server with a single transaction containing username and password (must happen via HTTPS). @@ -73,45 +85,33 @@ def blender_id_server_authenticate(username, password): requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: print('Exception POSTing to {}: {}'.format(url, e)) - return dict( - status='fail', - user_id=None, - token=None, - error_message=str(e) - ) - - user_id = None - token = None - error_message = None + return AuthResult(status, error_message=e) if r.status_code == 200: resp = r.json() status = resp['status'] if status == 'success': - user_id = str(resp['data']['user_id']) - # We just use the access token for now. - token = resp['data']['oauth_token']['access_token'] - elif status == 'fail': - error_message = 'Username and/or password is incorrect' - else: - status = 'fail' - error_message = format('There was a problem communicating with' - ' the server. Error code is: %s' % r.status_code) + return AuthResult(success=True, + user_id=str(resp['data']['user_id']), + token=resp['data']['oauth_token']['access_token'], + expires=resp['data']['oauth_token']['expires'], + ) + if status == 'fail': + return AuthResult(success=False, error_message='Username and/or password is incorrect') - return dict( - status=status, - user_id=user_id, - token=token, - error_message=error_message - ) + return AuthResult(success=False, + error_message='There was a problem communicating with' + ' the server. Error code is: %s' % r.status_code) -def blender_id_server_validate(token): +def blender_id_server_validate(token) -> typing.Tuple[typing.Optional[str], typing.Optional[str]]: """Validate the auth token with the server. @param token: the authentication token @type token: str - @returns: None if the token is valid, or an error message when it's invalid. + @returns: tuple (expiry, error). + The expiry is the expiry date of the token if it is valid, else None. + The error is None if the token is valid, or an error message when it's invalid. """ import requests @@ -121,12 +121,13 @@ def blender_id_server_validate(token): r = requests.post(blender_id_endpoint('u/validate_token'), data={'token': token}, verify=True) except requests.exceptions.RequestException as e: - return str(e) + return (str(e), None) - if r.status_code == 200: - return None + if r.status_code != 200: + return (None, 'Authentication token invalid') - return 'Authentication token invalid' + response = r.json() + return (response['token_expires'], None) def blender_id_server_logout(user_id, token): diff --git a/blender_id/profiles.py b/blender_id/profiles.py index 7dd6e121..2e872a50 100644 --- a/blender_id/profiles.py +++ b/blender_id/profiles.py @@ -21,6 +21,8 @@ import os import bpy +from . import communication + # Set/created upon register. profiles_path = '' profiles_file = '' @@ -44,23 +46,32 @@ class BlenderIdProfile(metaclass=_BIPMeta): user_id = '' username = '' token = '' + expires = '' subclients = {} @classmethod + def reset(cls): + cls.user_id = '' + cls.username = '' + cls.token = '' + cls.expires = '' + cls.subclients = {} + + @classmethod def read_json(cls): """Updates the active profile information from the JSON file.""" + cls.reset() + active_profile = get_active_profile() - if active_profile: - cls.user_id = active_profile['user_id'] - cls.username = active_profile['username'] - cls.token = active_profile['token'] - cls.subclients = active_profile.get('subclients', {}) - else: - cls.user_id = '' - cls.username = '' - cls.token = '' - cls.subclients = {} # mapping from subclient-ID to user info dict. + if not active_profile: + return + + for key, value in active_profile.items(): + if hasattr(cls, key): + setattr(cls, key, value) + else: + print('Skipping key %r from profile JSON' % key) @classmethod def save_json(cls, make_active_profile=False): @@ -70,6 +81,7 @@ class BlenderIdProfile(metaclass=_BIPMeta): jsonfile['profiles'][cls.user_id] = { 'username': cls.username, 'token': cls.token, + 'expires': cls.expires, 'subclients': cls.subclients, } @@ -184,11 +196,13 @@ def save_profiles_data(all_profiles: dict): json.dump(all_profiles, outfile, sort_keys=True) -def save_as_active_profile(user_id, token, username, subclients): +def save_as_active_profile(auth_result: communication.AuthResult, username, subclients): """Saves the given info as the active profile.""" - BlenderIdProfile.user_id = user_id - BlenderIdProfile.token = token + BlenderIdProfile.user_id = auth_result.user_id + BlenderIdProfile.token = auth_result.token + BlenderIdProfile.expires = auth_result.expires + BlenderIdProfile.username = username BlenderIdProfile.subclients = subclients diff --git a/camera_dolly_crane_rigs.py b/camera_dolly_crane_rigs.py index 363cb588..8175ac3f 100644 --- a/camera_dolly_crane_rigs.py +++ b/camera_dolly_crane_rigs.py @@ -1,21 +1,44 @@ +# ##### 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 ##### + + bl_info = { "name": "Add Camera Rigs", "author": "Wayne Dixon, Kris Wittig", - "version": (1, 1), + "version": (1, 1, 1), "blender": (2, 77, 0), "location": "View3D > Add > Camera > Dolly or Crane Rig", "description": "Adds a Camera Rig with UI", "warning": "Enable Auto Run Python Scripts in User Preferences > File", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Rigging/Add_Camera_Rigs", - "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/", + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/" + "Py/Scripts/Rigging/Add_Camera_Rigs", "category": "Camera", } import bpy -from bpy.types import Operator +from bpy.types import ( + Operator, + Panel, + ) from rna_prop_ui import rna_idprop_ui_prop_get from math import radians + # ========================================================================= # Define the functions to build the Widgets # ========================================================================= @@ -32,18 +55,19 @@ def create_widget(self, name): obj = bpy.data.objects.new(obj_name, mesh) scene.objects.link(obj) - #this will put the Widget objects out of the way on layer 19 + # this will put the Widget objects out of the way on layer 19 WDGT_layers = (False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False) obj.layers = WDGT_layers return obj + def create_root_widget(self, name): # Creates a compass-shaped widget. obj = create_widget(self, name) - if obj != None: + if obj is not None: verts = [(0.2102552056312561, -0.0012103617191314697, 0.21025514602661133), (0.11378927528858185, -0.001210339367389679, 0.274711549282074), (-3.070153553608179e-08, -0.0012103626504540443, 0.29734566807746887), @@ -99,11 +123,12 @@ def create_root_widget(self, name): mesh.from_pydata(verts, edges, []) mesh.update() + def create_camera_widget(self, name): - # Creates a camera ctrl widget. + # Creates a camera ctrl widget obj = create_widget(self, name) - if obj != None: + if obj is not None: verts = [(0.13756819069385529, 1.0706068032106941e-08, -0.13756819069385529), (0.1797415018081665, 5.353034016053471e-09, -0.07445136457681656), (0.19455081224441528, -6.381313819948996e-16, 8.504085435845354e-09), @@ -160,27 +185,28 @@ def create_camera_widget(self, name): (0.04472222924232483, -7.0564780685344886e-09, 0.10796899348497391), (0.08263590186834335, -7.0564780685344886e-09, 0.08263590186834335), (0.10796899348497391, -3.5282390342672443e-09, 0.04472223296761513), - (0.11686481535434723, -4.2059886864033273e-16, 5.108323541946902e-09), - (0.10796899348497391, 3.5282390342672443e-09, -0.04472222924232483), - (0.08263590186834335, 7.0564780685344886e-09, -0.08263590186834335), + (0.11686481535434723, -4.2059886864033273e-16, 5.108323541946902e-09), + (0.10796899348497391, 3.5282390342672443e-09, -0.04472222924232483), + (0.08263590186834335, 7.0564780685344886e-09, -0.08263590186834335), (3.725290298461914e-08, -2.1412136064213882e-08, 0.24882805347442627)] edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (7, 8), (0, 8), (10, 11), (9, 12), (11, 12), (10, 13), (9, 14), (13, 15), (14, 15), (16, 22), - (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (7, 17), (6, 16), (23, 24), + (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (7, 17), (6, 16), (23, 24), (23, 25), (24, 29), (25, 28), (26, 29), (27, 28), (31, 32), (30, 33), (32, 33), - (31, 34), (30, 35), (34, 36), (35, 36), (37, 38), (37, 39), (38, 43), (39, 42), + (31, 34), (30, 35), (34, 36), (35, 36), (37, 38), (37, 39), (38, 43), (39, 42), (40, 41), (40, 43), (41, 42), (50, 53), (49, 52), (44, 45), (45, 46), (46, 47), - (47, 48), (48, 49), (44, 50), (51, 59), (51, 52), (53, 54), (54, 55), (55, 56), + (47, 48), (48, 49), (44, 50), (51, 59), (51, 52), (53, 54), (54, 55), (55, 56), (56, 57), (57, 58), (58, 59), (26, 60), (27, 60), (23, 60)] mesh = obj.data mesh.from_pydata(verts, edges, []) mesh.update() + def create_aim_widget(self, name): """ Creates a camera aim widget.""" obj = create_widget(self, name) - if obj != None: + if obj is not None: verts = [(0.15504144132137299, 1.4901161193847656e-08, 0.15504144132137299), (0.20257140696048737, 7.450580596923828e-09, 0.0839078277349472), (0.21926172077655792, -8.881784197001252e-16, -9.584233851001045e-09), @@ -215,7 +241,7 @@ def create_aim_widget(self, name): (-0.052745334804058075, -2.9802322387695312e-08, -0.3996969759464264), (-0.05274537205696106, -2.9802322387695312e-08, -0.49317920207977295), (0.05274519696831703, -2.9802322387695312e-08, -0.49317920207977295), - (-0.09776955097913742, -2.9802322387695312e-08, -0.3996969163417816), + (-0.09776955097913742, -2.9802322387695312e-08, -0.3996969163417816), (0.09776940196752548, -2.9802322387695312e-08, -0.39969703555107117), (-7.148475589247028e-08, -2.9802322387695312e-08, -0.2804329991340637), (-0.2804330289363861, 3.552713678800501e-15, 4.234420103443881e-08), @@ -258,6 +284,7 @@ def create_aim_widget(self, name): mesh.from_pydata(verts, edges, []) mesh.update() + # ========================================================================= # Define the fuction to make the camera active # ========================================================================= @@ -273,10 +300,11 @@ def sceneCamera(): else: return None -class MakeCameraActive(bpy.types.Operator): - '''Makes the camera parented to this rig the active scene camera''' + +class MakeCameraActive(Operator): bl_idname = "scene.make_camera_active" bl_label = "Make Camera Active" + bl_description = "Makes the camera parented to this rig the active scene camera" @classmethod def poll(cls, context): @@ -284,14 +312,16 @@ class MakeCameraActive(bpy.types.Operator): def execute(self, context): sceneCamera() + return {'FINISHED'} + # ========================================================================= # Define function to add marker to timeline and bind camera # ========================================================================= def markerBind(): ob = bpy.context.active_object # rig object - active_cam = ob.children[0] # camera object + active_cam = ob.children[0] # camera object # switch area to timeline to add marker bpy.context.area.type = 'TIMELINE' @@ -307,10 +337,12 @@ def markerBind(): # switch back to 3d view bpy.context.area.type = 'VIEW_3D' -class AddMarkerBind(bpy.types.Operator): - """Add marker to current frame then bind rig camera to it (for camera switching)""" + +class AddMarkerBind(Operator): bl_idname = "add.marker_bind" bl_label = "Add marker and Bind Camera" + bl_description = ("Add marker to current frame then bind " + "rig camera to it (for camera switching)") @classmethod def poll(cls, context): @@ -318,8 +350,10 @@ class AddMarkerBind(bpy.types.Operator): def execute(self, context): markerBind() + return {'FINISHED'} + # ========================================================================= # Define the function to add an Empty as DOF object # ========================================================================= @@ -355,10 +389,11 @@ def add_DOF_Empty(): bpy.ops.object.mode_set(mode=smode, toggle=False) -class AddDofEmpty(bpy.types.Operator): - """Create empty and add as DOF Object""" + +class AddDofEmpty(Operator): bl_idname = "add.dof_empty" bl_label = "Add DOF Empty" + bl_description = "Create empty and add as DOF Object" @classmethod def poll(cls, context): @@ -366,8 +401,10 @@ class AddDofEmpty(bpy.types.Operator): def execute(self, context): add_DOF_Empty() + return {'FINISHED'} + # ========================================================================= # Define the function to build the Dolly Rig # ========================================================================= @@ -427,17 +464,17 @@ def build_dolly_rig(context): # jump into pose mode and add the custom bone shapes bpy.ops.object.mode_set(mode='POSE') - bpy.context.object.pose.bones["Root"].custom_shape = bpy.data.objects[ - "WDGT_Camera_Root"] # add the widget as custom shape + bpy.context.object.pose.bones["Root"].custom_shape = \ + bpy.data.objects["WDGT_Camera_Root"] # add the widget as custom shape # set the wireframe checkbox to true bpy.context.object.data.bones["Root"].show_wire = True - bpy.context.object.pose.bones[ - "AIM"].custom_shape = bpy.data.objects["WDGT_AIM"] + bpy.context.object.pose.bones["AIM"].custom_shape = \ + bpy.data.objects["WDGT_AIM"] bpy.context.object.data.bones["AIM"].show_wire = True - bpy.context.object.pose.bones["AIM"].custom_shape_transform = bpy.data.objects[ - rig.name].pose.bones["AIM_child"] # sets the "At" field to the child - bpy.context.object.pose.bones[ - "CTRL"].custom_shape = bpy.data.objects["WDGT_CTRL"] + bpy.context.object.pose.bones["AIM"].custom_shape_transform = \ + bpy.data.objects[rig.name].pose.bones["AIM_child"] # sets the "At" field to the child + bpy.context.object.pose.bones["CTRL"].custom_shape = \ + bpy.data.objects["WDGT_CTRL"] bpy.context.object.data.bones["CTRL"].show_wire = True # jump into object mode @@ -497,7 +534,7 @@ def build_dolly_rig(context): cam_data_name = bpy.context.object.data.name bpy.data.cameras[cam_data_name].draw_size = 1.0 - cam.rotation_euler[0] = 1.5708 # rotate the camera 90 degrees in x + cam.rotation_euler[0] = 1.5708 # rotate the camera 90 degrees in x cam.location = (0.0, -2.0, 0.0) # move the camera to the correct postion cam.parent = rig cam.parent_type = "BONE" @@ -527,6 +564,7 @@ def build_dolly_rig(context): return rig + # ========================================================================= # Define the function to build the Crane Rig # ========================================================================= @@ -681,11 +719,12 @@ def build_crane_rig(context): cam_data_name = bpy.context.object.data.name bpy.data.cameras[cam_data_name].draw_size = 1.0 - cam.rotation_euler[0] = 1.5708 # rotate the camera 90 degrees in x + cam.rotation_euler[0] = 1.5708 # rotate the camera 90 degrees in x cam.location = (0.0, -2.0, 0.0) # move the camera to the correct postion cam.parent = rig cam.parent_type = "BONE" cam.parent_bone = "CTRL" + # Add blank drivers to lock the camera loc, rot scale cam.driver_add('location', 0) cam.driver_add('location', 1) @@ -710,10 +749,11 @@ def build_crane_rig(context): return rig + # ========================================================================= # This is the UI for the Dolly Camera Rig # ========================================================================= -class DollyCameraUI(bpy.types.Panel): +class DollyCameraUI(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_label = "Dolly Camera UI" @@ -729,7 +769,6 @@ class DollyCameraUI(bpy.types.Panel): def draw(self, context): layout = self.layout ob = bpy.context.active_object - arm = context.active_object.data pose_bones = context.active_object.pose.bones # find the children on the rig (the camera name) active_cam = ob.children[0].name @@ -737,7 +776,7 @@ class DollyCameraUI(bpy.types.Panel): cam = bpy.data.cameras[bpy.data.objects[active_cam].data.name] box = layout.box() col = box.column() - row = col.row() + col.separator() # Display Camera Properties col.label(text="Clipping:") @@ -745,6 +784,7 @@ class DollyCameraUI(bpy.types.Panel): col.prop(cam, "clip_end", text="End") col.prop(cam, "type") col.prop(cam, "dof_object") + if cam.dof_object is None: col.operator("add.dof_empty", text="Add DOF Empty") col.prop(cam, "dof_distance") @@ -752,12 +792,15 @@ class DollyCameraUI(bpy.types.Panel): col.prop_menu_enum(cam, "show_guide", text="Compostion Guides") col.prop(bpy.data.objects[active_cam], "hide_select", text="Make Camera Unselectable") + col.operator("add.marker_bind", text="Add Marker and Bind") + if bpy.context.scene.camera.name != active_cam: - col.operator( - "scene.make_camera_active", text="Make Active Camera", icon='CAMERA_DATA') - col.prop( - context.active_object, 'show_x_ray', toggle=False, text='X Ray') + col.operator("scene.make_camera_active", + text="Make Active Camera", icon='CAMERA_DATA') + + col.prop(context.active_object, + 'show_x_ray', toggle=False, text='X Ray') col.prop(cam, "show_limits") col.prop(cam, "show_safe_areas") col.prop(cam, "show_passepartout") @@ -771,10 +814,11 @@ class DollyCameraUI(bpy.types.Panel): col.label(text="Tracking:") col.prop(pose_bones["CTRL"], '["Lock"]', text="Aim Lock", slider=True) + # ========================================================================= # This is the UI for the Crane Rig Camera # ========================================================================= -class CraneCameraUI(bpy.types.Panel): +class CraneCameraUI(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_label = "Crane Camera UI" @@ -790,7 +834,6 @@ class CraneCameraUI(bpy.types.Panel): def draw(self, context): layout = self.layout ob = bpy.context.active_object - arm = context.active_object.data pose_bones = context.active_object.pose.bones # find the children on the rig (camera) active_cam = ob.children[0].name @@ -798,7 +841,7 @@ class CraneCameraUI(bpy.types.Panel): box = layout.box() col = box.column() - row = col.row() + col.separator() # Display Camera Properties col.label(text="Clipping:") @@ -806,6 +849,7 @@ class CraneCameraUI(bpy.types.Panel): col.prop(cam, "clip_end", text="End") col.prop(cam, "type") col.prop(cam, "dof_object") + if cam.dof_object is None: col.operator("add.dof_empty", text="Add DOF object") col.prop(cam, "dof_distance") @@ -814,6 +858,7 @@ class CraneCameraUI(bpy.types.Panel): col.prop(bpy.data.objects[active_cam], "hide_select", text="Make Camera Unselectable") col.operator("add.marker_bind", text="Add Marker and Bind") + if bpy.context.scene.camera.name != active_cam: col.operator( "scene.make_camera_active", text="Make Active Camera", icon='CAMERA_DATA') @@ -833,25 +878,28 @@ class CraneCameraUI(bpy.types.Panel): col.prop(pose_bones["CTRL"], '["Lock"]', text="Aim Lock", slider=True) # make this camera active if more than one camera exists - '''if cam != bpy.context.scene.camera: - col.op(, text="Make Active Camera", toggle=True)''' + """ + if cam != bpy.context.scene.camera: + col.op(, text="Make Active Camera", toggle=True) + """ box = layout.box() col = box.column() - row = col.row() + col.separator() # Crane arm stuff col.label(text="Crane Arm:") col.prop(pose_bones["Height"], 'scale', index=1, text="Arm Height") col.prop(pose_bones["Crane_Arm"], 'scale', index=1, text="Arm Length") + # ========================================================================= # This is the operator that will call all the functions and build the dolly rig # ========================================================================= -class BuildDollyRig(bpy.types.Operator): - """Build a Camera Dolly Rig""" +class BuildDollyRig(Operator): bl_idname = "object.build_dolly_rig" bl_label = "Build Dolly Camera Rig" + bl_description = "Build a Camera Dolly Rig" bl_options = {'REGISTER', 'UNDO'} def execute(self, context): @@ -863,15 +911,17 @@ class BuildDollyRig(bpy.types.Operator): # call the function to build the rig build_dolly_rig(context) + return {'FINISHED'} + # ========================================================================= # This is the operator that will call all the functions and build the crane rig # ========================================================================= -class BuildCraneRig(bpy.types.Operator): - """Build a Camera Crane Rig""" +class BuildCraneRig(Operator): bl_idname = "object.build_crane_rig" bl_label = "Build Crane Camera Rig" + bl_description = "Build a Camera Crane Rig" bl_options = {'REGISTER', 'UNDO'} def execute(self, context): @@ -883,26 +933,28 @@ class BuildCraneRig(bpy.types.Operator): # call the function to build the rig build_crane_rig(context) + return {'FINISHED'} + # ========================================================================= # Registration: # ========================================================================= -# dolly button in Armature menu -def add_dolly_button(self, context): - if context.mode == 'OBJECT': - self.layout.operator( - BuildDollyRig.bl_idname, - text="Dolly Camera Rig", - icon='CAMERA_DATA') -# crane button in Armature menu -def add_crane_button(self, context): +# dolly and crane entries in the Add Object > Camera Menu +def add_dolly_crane_buttons(self, context): if context.mode == 'OBJECT': self.layout.operator( - BuildCraneRig.bl_idname, - text="Crane Camera Rig", - icon='CAMERA_DATA') + BuildDollyRig.bl_idname, + text="Dolly Camera Rig", + icon='CAMERA_DATA' + ) + self.layout.operator( + BuildCraneRig.bl_idname, + text="Crane Camera Rig", + icon='CAMERA_DATA' + ) + def register(): bpy.utils.register_class(BuildDollyRig) @@ -912,8 +964,8 @@ def register(): bpy.utils.register_class(MakeCameraActive) bpy.utils.register_class(AddMarkerBind) bpy.utils.register_class(AddDofEmpty) - bpy.types.INFO_MT_camera_add.append(add_dolly_button) - bpy.types.INFO_MT_camera_add.append(add_crane_button) + bpy.types.INFO_MT_camera_add.append(add_dolly_crane_buttons) + def unregister(): bpy.utils.unregister_class(BuildDollyRig) @@ -923,8 +975,8 @@ def unregister(): bpy.utils.unregister_class(MakeCameraActive) bpy.utils.unregister_class(AddMarkerBind) bpy.utils.unregister_class(AddDofEmpty) - bpy.types.INFO_MT_camera_add.remove(add_dolly_button) - bpy.types.INFO_MT_camera_add.remove(add_crane_button) + bpy.types.INFO_MT_camera_add.remove(add_dolly_crane_buttons) + if __name__ == "__main__": register() diff --git a/camera_turnaround.py b/camera_turnaround.py index a2dafe9f..5b655681 100644 --- a/camera_turnaround.py +++ b/camera_turnaround.py @@ -22,7 +22,7 @@ bl_info = { "author": "Antonio Vazquez (antonioya)", "version": (0, 2, 4), "blender": (2, 68, 0), - "location": "View3D > Toolshelf > Turnaround camera", + "location": "View3D > Toolshelf > Animation > Turnaround camera", "description": "Add a camera rotation around selected object.", "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Animation/TurnaroundCamera", "category": "Camera"} diff --git a/development_edit_operator.py b/development_edit_operator.py new file mode 100644 index 00000000..3124146b --- /dev/null +++ b/development_edit_operator.py @@ -0,0 +1,162 @@ +# ##### 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 ##### + + +bl_info = { + "name": "Edit Operator Source", + "author": "scorpion81", + "version": (1, 2, 2), + "blender": (2, 78, 0), + "location": "Text Editor > Edit > Edit Operator", + "description": "Opens source file of chosen operator, if it is an add-on one", + "warning": "", + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/" + "Py/Scripts/Development/Edit_Operator_Source", + "category": "Development"} + +import bpy +import sys +import inspect +from bpy.types import ( + Operator, + Panel, + ) +from bpy.props import EnumProperty + + +def getclazz(opname): + opid = opname.split(".") + opmod = getattr(bpy.ops, opid[0]) + op = getattr(opmod, opid[1]) + id = op.get_rna().bl_rna.identifier + clazz = getattr(bpy.types, id) + return clazz + + +def getmodule(opname): + addon = True + clazz = getclazz(opname) + modn = clazz.__module__ + + try: + line = inspect.getsourcelines(clazz)[1] + except IOError: + line = -1 + except TypeError: + line = -1 + + if modn == 'bpy.types': + mod = 'C operator' + addon = False + elif modn != '__main__': + mod = sys.modules[modn].__file__ + else: + addon = False + mod = modn + + return mod, line, addon + + +def get_ops(): + allops = [] + opsdir = dir(bpy.ops) + for opmodname in opsdir: + opmod = getattr(bpy.ops, opmodname) + opmoddir = dir(opmod) + for o in opmoddir: + name = opmodname + "." + o + clazz = getclazz(name) + if (clazz.__module__ != 'bpy.types'): + allops.append(name) + del opmoddir + + # add own operator name too, since its not loaded yet when this is called + allops.append("text.edit_operator") + l = sorted(allops) + del allops + del opsdir + + return [(y, y, "", x) for x, y in enumerate(l)] + + +class EditOperator(Operator): + bl_idname = "text.edit_operator" + bl_label = "Edit Operator" + bl_description = "Opens the source file of operators chosen from Menu" + bl_property = "op" + + items = get_ops() + + op = EnumProperty( + name="Op", + description="", + items=items + ) + + def invoke(self, context, event): + context.window_manager.invoke_search_popup(self) + return {'PASS_THROUGH'} + + def execute(self, context): + found = False + path, line, addon = getmodule(self.op) + if addon: + for t in bpy.data.texts: + if t.filepath == path: + ctx = context.copy() + ctx['edit_text'] = t + bpy.ops.text.jump(ctx, line=line) + found = True + break + + if (found is False): + self.report({'INFO'}, + "Opened file: " + path) + bpy.ops.text.open(filepath=path) + bpy.ops.text.jump(line=line) + + return {'FINISHED'} + else: + self.report({'WARNING'}, + "Found no source file for " + self.op) + + return {'CANCELLED'} + + +class EditOperatorPanel(Panel): + bl_space_type = 'TEXT_EDITOR' + bl_region_type = 'UI' + bl_label = "Edit Operator" + + def draw(self, context): + layout = self.layout + layout.operator("text.edit_operator") + + +def register(): + bpy.utils.register_class(EditOperator) + bpy.utils.register_class(EditOperatorPanel) + + +def unregister(): + bpy.utils.unregister_class(EditOperatorPanel) + bpy.utils.unregister_class(EditOperator) + + +if __name__ == "__main__": + register() diff --git a/io_blend_utils/README.md b/io_blend_utils/README.md index 436ec684..bfff16b9 100644 --- a/io_blend_utils/README.md +++ b/io_blend_utils/README.md @@ -10,17 +10,23 @@ Bundling BAM with Blender ------------------------- Blender is bundled with a version of [BAM](https://pypi.python.org/pypi/blender-bam/). -To update this version, first build a new `wheel <http://pythonwheels.com/>`_ file in +To update this version, first build a new [wheel](http://pythonwheels.com/) file in BAM itself: python3 setup.py bdist_wheel -Then copy this wheel to Blender: +Since we do not want to have binaries in the addons repository, unpack this wheel to Blender +by running: - cp dist/blender_bam-xxx.whl /path/to/blender/release/scripts/addons/io_blend_utils/ + python3 install_whl.py /path/to/blender-asset-manager/dist/blender_bam-xxx.whl -Remove old wheels that are still in `/path/to/blender/release/scripts/addons/io_blend_utils/` -before committing. +This script also updates `__init__.py` to update the version number of the extracted +wheel, and removes any pre-existing older versions of the BAM wheels. + +The version number and `.whl` extension are maintained in the directory name on purpose. +This way it is clear that it is not a directory to import directly into Blender itself. +Furthermore, I (Sybren) hope that it helps to get changes made in the addons repository +back into the BAM repository. Running bam-pack from the wheel @@ -29,4 +35,3 @@ Running bam-pack from the wheel This is the way that Blender runs bam-pack: PYTHONPATH=./path/to/blender_bam-xxx.whl python3 -m bam.pack - diff --git a/io_blend_utils/__init__.py b/io_blend_utils/__init__.py index a00366ac..d44d4754 100644 --- a/io_blend_utils/__init__.py +++ b/io_blend_utils/__init__.py @@ -29,7 +29,7 @@ bl_info = { "category": "Import-Export", } -BAM_WHEEL_FILE = 'blender_bam-1.1.7-py3-none-any.whl' +BAM_WHEEL_PATH = 'blender_bam-unpacked.whl' import logging @@ -117,11 +117,11 @@ def pythonpath() -> str: log = logging.getLogger('%s.pythonpath' % __name__) # Find the wheel to run. - wheelpath = pathlib.Path(__file__).with_name(BAM_WHEEL_FILE) + wheelpath = pathlib.Path(__file__).with_name(BAM_WHEEL_PATH) if not wheelpath.exists(): - raise EnvironmentError('Wheel file %s does not exist!' % wheelpath) + raise EnvironmentError('Wheel %s does not exist!' % wheelpath) - log.info('Using wheel file %s to run BAM-Pack', wheelpath) + log.info('Using wheel %s to run BAM-Pack', wheelpath) # Update the PYTHONPATH to include that wheel. existing_pypath = os.environ.get('PYTHONPATH', '') diff --git a/io_blend_utils/blender_bam-1.1.7-py3-none-any.whl b/io_blend_utils/blender_bam-1.1.7-py3-none-any.whl Binary files differdeleted file mode 100644 index 72fad694..00000000 --- a/io_blend_utils/blender_bam-1.1.7-py3-none-any.whl +++ /dev/null diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/__init__.py b/io_blend_utils/blender_bam-unpacked.whl/bam/__init__.py new file mode 100644 index 00000000..26c0a813 --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/__init__.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- + +__version__ = '1.1.8' + +if __name__ == '__main__': + from .cli import main + + main() diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/__main__.py b/io_blend_utils/blender_bam-unpacked.whl/bam/__main__.py new file mode 100644 index 00000000..c5f166b0 --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/__main__.py @@ -0,0 +1,8 @@ +"""Main module for running python -m bam. + +Doesn't do much, except for printing general usage information. +""" + +print("The 'bam' module cannot be run directly. The following subcommand is available:") +print() +print("python -m bam.pack") diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/blend/__init__.py b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/__init__.py diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile.py b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile.py new file mode 100644 index 00000000..e471beae --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile.py @@ -0,0 +1,956 @@ +# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# +# (c) 2009, At Mind B.V. - Jeroen Bakker +# (c) 2014, Blender Foundation - Campbell Barton + +import gzip +import logging +import os +import struct +import tempfile + +log = logging.getLogger("blendfile") + +FILE_BUFFER_SIZE = 1024 * 1024 + + +class BlendFileError(Exception): + """Raised when there was an error reading/parsing a blend file.""" + + +# ----------------------------------------------------------------------------- +# module global routines +# +# read routines +# open a filename +# determine if the file is compressed +# and returns a handle +def open_blend(filename, access="rb"): + """Opens a blend file for reading or writing pending on the access + supports 2 kind of blend files. Uncompressed and compressed. + Known issue: does not support packaged blend files + """ + handle = open(filename, access) + magic_test = b"BLENDER" + magic = handle.read(len(magic_test)) + if magic == magic_test: + log.debug("normal blendfile detected") + handle.seek(0, os.SEEK_SET) + bfile = BlendFile(handle) + bfile.is_compressed = False + bfile.filepath_orig = filename + return bfile + elif magic[:2] == b'\x1f\x8b': + log.debug("gzip blendfile detected") + handle.close() + log.debug("decompressing started") + fs = gzip.open(filename, "rb") + data = fs.read(FILE_BUFFER_SIZE) + magic = data[:len(magic_test)] + if magic == magic_test: + handle = tempfile.TemporaryFile() + while data: + handle.write(data) + data = fs.read(FILE_BUFFER_SIZE) + log.debug("decompressing finished") + fs.close() + log.debug("resetting decompressed file") + handle.seek(os.SEEK_SET, 0) + bfile = BlendFile(handle) + bfile.is_compressed = True + bfile.filepath_orig = filename + return bfile + else: + raise BlendFileError("filetype inside gzip not a blend") + else: + raise BlendFileError("filetype not a blend or a gzip blend") + + +def pad_up_4(offset): + return (offset + 3) & ~3 + + +# ----------------------------------------------------------------------------- +# module classes + + +class BlendFile: + """ + Blend file. + """ + __slots__ = ( + # file (result of open()) + "handle", + # str (original name of the file path) + "filepath_orig", + # BlendFileHeader + "header", + # struct.Struct + "block_header_struct", + # BlendFileBlock + "blocks", + # [DNAStruct, ...] + "structs", + # dict {b'StructName': sdna_index} + # (where the index is an index into 'structs') + "sdna_index_from_id", + # dict {addr_old: block} + "block_from_offset", + # int + "code_index", + # bool (did we make a change) + "is_modified", + # bool (is file gzipped) + "is_compressed", + ) + + def __init__(self, handle): + log.debug("initializing reading blend-file") + self.handle = handle + self.header = BlendFileHeader(handle) + self.block_header_struct = self.header.create_block_header_struct() + self.blocks = [] + self.code_index = {} + self.structs = [] + self.sdna_index_from_id = {} + + block = BlendFileBlock(handle, self) + while block.code != b'ENDB': + if block.code == b'DNA1': + (self.structs, + self.sdna_index_from_id, + ) = BlendFile.decode_structs(self.header, block, handle) + else: + handle.seek(block.size, os.SEEK_CUR) + + self.blocks.append(block) + self.code_index.setdefault(block.code, []).append(block) + + block = BlendFileBlock(handle, self) + self.is_modified = False + self.blocks.append(block) + + if not self.structs: + raise BlendFileError("No DNA1 block in file, this is not a valid .blend file!") + + # cache (could lazy init, incase we never use?) + self.block_from_offset = {block.addr_old: block for block in self.blocks if block.code != b'ENDB'} + + def __repr__(self): + return '<%s %r>' % (self.__class__.__qualname__, self.handle) + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + self.close() + + def find_blocks_from_code(self, code): + assert(type(code) == bytes) + if code not in self.code_index: + return [] + return self.code_index[code] + + def find_block_from_offset(self, offset): + # same as looking looping over all blocks, + # then checking ``block.addr_old == offset`` + assert(type(offset) is int) + return self.block_from_offset.get(offset) + + def close(self): + """ + Close the blend file + writes the blend file to disk if changes has happened + """ + handle = self.handle + + if self.is_modified: + if self.is_compressed: + log.debug("close compressed blend file") + handle.seek(os.SEEK_SET, 0) + log.debug("compressing started") + fs = gzip.open(self.filepath_orig, "wb") + data = handle.read(FILE_BUFFER_SIZE) + while data: + fs.write(data) + data = handle.read(FILE_BUFFER_SIZE) + fs.close() + log.debug("compressing finished") + + handle.close() + + def ensure_subtype_smaller(self, sdna_index_curr, sdna_index_next): + # never refine to a smaller type + if (self.structs[sdna_index_curr].size > + self.structs[sdna_index_next].size): + + raise RuntimeError("cant refine to smaller type (%s -> %s)" % + (self.structs[sdna_index_curr].dna_type_id.decode('ascii'), + self.structs[sdna_index_next].dna_type_id.decode('ascii'))) + + @staticmethod + def decode_structs(header, block, handle): + """ + DNACatalog is a catalog of all information in the DNA1 file-block + """ + log.debug("building DNA catalog") + shortstruct = DNA_IO.USHORT[header.endian_index] + shortstruct2 = struct.Struct(header.endian_str + b'HH') + intstruct = DNA_IO.UINT[header.endian_index] + + data = handle.read(block.size) + types = [] + names = [] + + structs = [] + sdna_index_from_id = {} + + offset = 8 + names_len = intstruct.unpack_from(data, offset)[0] + offset += 4 + + log.debug("building #%d names" % names_len) + for i in range(names_len): + tName = DNA_IO.read_data0_offset(data, offset) + offset = offset + len(tName) + 1 + names.append(DNAName(tName)) + del names_len + + offset = pad_up_4(offset) + offset += 4 + types_len = intstruct.unpack_from(data, offset)[0] + offset += 4 + log.debug("building #%d types" % types_len) + for i in range(types_len): + dna_type_id = DNA_IO.read_data0_offset(data, offset) + # None will be replaced by the DNAStruct, below + types.append(DNAStruct(dna_type_id)) + offset += len(dna_type_id) + 1 + + offset = pad_up_4(offset) + offset += 4 + log.debug("building #%d type-lengths" % types_len) + for i in range(types_len): + tLen = shortstruct.unpack_from(data, offset)[0] + offset = offset + 2 + types[i].size = tLen + del types_len + + offset = pad_up_4(offset) + offset += 4 + + structs_len = intstruct.unpack_from(data, offset)[0] + offset += 4 + log.debug("building #%d structures" % structs_len) + for sdna_index in range(structs_len): + d = shortstruct2.unpack_from(data, offset) + struct_type_index = d[0] + offset += 4 + dna_struct = types[struct_type_index] + sdna_index_from_id[dna_struct.dna_type_id] = sdna_index + structs.append(dna_struct) + + fields_len = d[1] + dna_offset = 0 + + for field_index in range(fields_len): + d2 = shortstruct2.unpack_from(data, offset) + field_type_index = d2[0] + field_name_index = d2[1] + offset += 4 + dna_type = types[field_type_index] + dna_name = names[field_name_index] + if dna_name.is_pointer or dna_name.is_method_pointer: + dna_size = header.pointer_size * dna_name.array_size + else: + dna_size = dna_type.size * dna_name.array_size + + field = DNAField(dna_type, dna_name, dna_size, dna_offset) + dna_struct.fields.append(field) + dna_struct.field_from_name[dna_name.name_only] = field + dna_offset += dna_size + + return structs, sdna_index_from_id + + +class BlendFileBlock: + """ + Instance of a struct. + """ + __slots__ = ( + # BlendFile + "file", + "code", + "size", + "addr_old", + "sdna_index", + "count", + "file_offset", + "user_data", + ) + + def __str__(self): + return ("<%s.%s (%s), size=%d at %s>" % + # fields=[%s] + (self.__class__.__name__, + self.dna_type_name, + self.code.decode(), + self.size, + # b", ".join(f.dna_name.name_only for f in self.dna_type.fields).decode('ascii'), + hex(self.addr_old), + )) + + def __init__(self, handle, bfile): + OLDBLOCK = struct.Struct(b'4sI') + + self.file = bfile + self.user_data = None + + data = handle.read(bfile.block_header_struct.size) + + if len(data) != bfile.block_header_struct.size: + print("WARNING! Blend file seems to be badly truncated!") + self.code = b'ENDB' + self.size = 0 + self.addr_old = 0 + self.sdna_index = 0 + self.count = 0 + self.file_offset = 0 + return + # header size can be 8, 20, or 24 bytes long + # 8: old blend files ENDB block (exception) + # 20: normal headers 32 bit platform + # 24: normal headers 64 bit platform + if len(data) > 15: + blockheader = bfile.block_header_struct.unpack(data) + self.code = blockheader[0].partition(b'\0')[0] + if self.code != b'ENDB': + self.size = blockheader[1] + self.addr_old = blockheader[2] + self.sdna_index = blockheader[3] + self.count = blockheader[4] + self.file_offset = handle.tell() + else: + self.size = 0 + self.addr_old = 0 + self.sdna_index = 0 + self.count = 0 + self.file_offset = 0 + else: + blockheader = OLDBLOCK.unpack(data) + self.code = blockheader[0].partition(b'\0')[0] + self.code = DNA_IO.read_data0(blockheader[0]) + self.size = 0 + self.addr_old = 0 + self.sdna_index = 0 + self.count = 0 + self.file_offset = 0 + + @property + def dna_type(self): + return self.file.structs[self.sdna_index] + + @property + def dna_type_name(self): + return self.dna_type.dna_type_id.decode('ascii') + + def refine_type_from_index(self, sdna_index_next): + assert(type(sdna_index_next) is int) + sdna_index_curr = self.sdna_index + self.file.ensure_subtype_smaller(sdna_index_curr, sdna_index_next) + self.sdna_index = sdna_index_next + + def refine_type(self, dna_type_id): + assert(type(dna_type_id) is bytes) + self.refine_type_from_index(self.file.sdna_index_from_id[dna_type_id]) + + def get_file_offset(self, path, + default=..., + sdna_index_refine=None, + base_index=0, + ): + """ + Return (offset, length) + """ + assert(type(path) is bytes) + + ofs = self.file_offset + if base_index != 0: + assert(base_index < self.count) + ofs += (self.size // self.count) * base_index + self.file.handle.seek(ofs, os.SEEK_SET) + + if sdna_index_refine is None: + sdna_index_refine = self.sdna_index + else: + self.file.ensure_subtype_smaller(self.sdna_index, sdna_index_refine) + + dna_struct = self.file.structs[sdna_index_refine] + field = dna_struct.field_from_path( + self.file.header, self.file.handle, path) + + return (self.file.handle.tell(), field.dna_name.array_size) + + def get(self, path, + default=..., + sdna_index_refine=None, + use_nil=True, use_str=True, + base_index=0, + ): + + ofs = self.file_offset + if base_index != 0: + assert(base_index < self.count) + ofs += (self.size // self.count) * base_index + self.file.handle.seek(ofs, os.SEEK_SET) + + if sdna_index_refine is None: + sdna_index_refine = self.sdna_index + else: + self.file.ensure_subtype_smaller(self.sdna_index, sdna_index_refine) + + dna_struct = self.file.structs[sdna_index_refine] + return dna_struct.field_get( + self.file.header, self.file.handle, path, + default=default, + use_nil=use_nil, use_str=use_str, + ) + + def get_recursive_iter(self, path, path_root=b"", + default=..., + sdna_index_refine=None, + use_nil=True, use_str=True, + base_index=0, + ): + if path_root: + path_full = ( + (path_root if type(path_root) is tuple else (path_root, )) + + (path if type(path) is tuple else (path, ))) + else: + path_full = path + + try: + yield (path_full, self.get(path_full, default, sdna_index_refine, use_nil, use_str, base_index)) + except NotImplementedError as ex: + msg, dna_name, dna_type = ex.args + struct_index = self.file.sdna_index_from_id.get(dna_type.dna_type_id, None) + if struct_index is None: + yield (path_full, "<%s>" % dna_type.dna_type_id.decode('ascii')) + else: + struct = self.file.structs[struct_index] + for f in struct.fields: + yield from self.get_recursive_iter( + f.dna_name.name_only, path_full, default, None, use_nil, use_str, 0) + + def items_recursive_iter(self): + for k in self.keys(): + yield from self.get_recursive_iter(k, use_str=False) + + def get_data_hash(self): + """ + Generates a 'hash' that can be used instead of addr_old as block id, and that should be 'stable' across .blend + file load & save (i.e. it does not changes due to pointer addresses variations). + """ + # TODO This implementation is most likely far from optimal... and CRC32 is not renown as the best hashing + # algo either. But for now does the job! + import zlib + def _is_pointer(self, k): + return self.file.structs[self.sdna_index].field_from_path( + self.file.header, self.file.handle, k).dna_name.is_pointer + + hsh = 1 + for k, v in self.items_recursive_iter(): + if not _is_pointer(self, k): + hsh = zlib.adler32(str(v).encode(), hsh) + return hsh + + def set(self, path, value, + sdna_index_refine=None, + ): + + if sdna_index_refine is None: + sdna_index_refine = self.sdna_index + else: + self.file.ensure_subtype_smaller(self.sdna_index, sdna_index_refine) + + dna_struct = self.file.structs[sdna_index_refine] + self.file.handle.seek(self.file_offset, os.SEEK_SET) + self.file.is_modified = True + return dna_struct.field_set( + self.file.header, self.file.handle, path, value) + + # --------------- + # Utility get/set + # + # avoid inline pointer casting + def get_pointer( + self, path, + default=..., + sdna_index_refine=None, + base_index=0, + ): + if sdna_index_refine is None: + sdna_index_refine = self.sdna_index + result = self.get(path, default, sdna_index_refine=sdna_index_refine, base_index=base_index) + + # default + if type(result) is not int: + return result + + assert(self.file.structs[sdna_index_refine].field_from_path( + self.file.header, self.file.handle, path).dna_name.is_pointer) + if result != 0: + # possible (but unlikely) + # that this fails and returns None + # maybe we want to raise some exception in this case + return self.file.find_block_from_offset(result) + else: + return None + + # ---------------------- + # Python convenience API + + # dict like access + def __getitem__(self, item): + return self.get(item, use_str=False) + + def __setitem__(self, item, value): + self.set(item, value) + + def keys(self): + return (f.dna_name.name_only for f in self.dna_type.fields) + + def values(self): + for k in self.keys(): + try: + yield self[k] + except NotImplementedError as ex: + msg, dna_name, dna_type = ex.args + yield "<%s>" % dna_type.dna_type_id.decode('ascii') + + def items(self): + for k in self.keys(): + try: + yield (k, self[k]) + except NotImplementedError as ex: + msg, dna_name, dna_type = ex.args + yield (k, "<%s>" % dna_type.dna_type_id.decode('ascii')) + + +# ----------------------------------------------------------------------------- +# Read Magic +# +# magic = str +# pointer_size = int +# is_little_endian = bool +# version = int + + +class BlendFileHeader: + """ + BlendFileHeader allocates the first 12 bytes of a blend file + it contains information about the hardware architecture + """ + __slots__ = ( + # str + "magic", + # int 4/8 + "pointer_size", + # bool + "is_little_endian", + # int + "version", + # str, used to pass to 'struct' + "endian_str", + # int, used to index common types + "endian_index", + ) + + def __init__(self, handle): + FILEHEADER = struct.Struct(b'7s1s1s3s') + + log.debug("reading blend-file-header") + values = FILEHEADER.unpack(handle.read(FILEHEADER.size)) + self.magic = values[0] + pointer_size_id = values[1] + if pointer_size_id == b'-': + self.pointer_size = 8 + elif pointer_size_id == b'_': + self.pointer_size = 4 + else: + assert(0) + endian_id = values[2] + if endian_id == b'v': + self.is_little_endian = True + self.endian_str = b'<' + self.endian_index = 0 + elif endian_id == b'V': + self.is_little_endian = False + self.endian_index = 1 + self.endian_str = b'>' + else: + assert(0) + + version_id = values[3] + self.version = int(version_id) + + def create_block_header_struct(self): + return struct.Struct(b''.join(( + self.endian_str, + b'4sI', + b'I' if self.pointer_size == 4 else b'Q', + b'II', + ))) + + +class DNAName: + """ + DNAName is a C-type name stored in the DNA + """ + __slots__ = ( + "name_full", + "name_only", + "is_pointer", + "is_method_pointer", + "array_size", + ) + + def __init__(self, name_full): + self.name_full = name_full + self.name_only = self.calc_name_only() + self.is_pointer = self.calc_is_pointer() + self.is_method_pointer = self.calc_is_method_pointer() + self.array_size = self.calc_array_size() + + def __repr__(self): + return '%s(%r)' % (type(self).__qualname__, self.name_full) + + def as_reference(self, parent): + if parent is None: + result = b'' + else: + result = parent + b'.' + + result = result + self.name_only + return result + + def calc_name_only(self): + result = self.name_full.strip(b'*()') + index = result.find(b'[') + if index != -1: + result = result[:index] + return result + + def calc_is_pointer(self): + return (b'*' in self.name_full) + + def calc_is_method_pointer(self): + return (b'(*' in self.name_full) + + def calc_array_size(self): + result = 1 + temp = self.name_full + index = temp.find(b'[') + + while index != -1: + index_2 = temp.find(b']') + result *= int(temp[index + 1:index_2]) + temp = temp[index_2 + 1:] + index = temp.find(b'[') + + return result + + +class DNAField: + """ + DNAField is a coupled DNAStruct and DNAName + and cache offset for reuse + """ + __slots__ = ( + # DNAName + "dna_name", + # tuple of 3 items + # [bytes (struct name), int (struct size), DNAStruct] + "dna_type", + # size on-disk + "dna_size", + # cached info (avoid looping over fields each time) + "dna_offset", + ) + + def __init__(self, dna_type, dna_name, dna_size, dna_offset): + self.dna_type = dna_type + self.dna_name = dna_name + self.dna_size = dna_size + self.dna_offset = dna_offset + + +class DNAStruct: + """ + DNAStruct is a C-type structure stored in the DNA + """ + __slots__ = ( + "dna_type_id", + "size", + "fields", + "field_from_name", + "user_data", + ) + + def __init__(self, dna_type_id): + self.dna_type_id = dna_type_id + self.fields = [] + self.field_from_name = {} + self.user_data = None + + def __repr__(self): + return '%s(%r)' % (type(self).__qualname__, self.dna_type_id) + + def field_from_path(self, header, handle, path): + """ + Support lookups as bytes or a tuple of bytes and optional index. + + C style 'id.name' --> (b'id', b'name') + C style 'array[4]' --> ('array', 4) + """ + if type(path) is tuple: + name = path[0] + if len(path) >= 2 and type(path[1]) is not bytes: + name_tail = path[2:] + index = path[1] + assert(type(index) is int) + else: + name_tail = path[1:] + index = 0 + else: + name = path + name_tail = None + index = 0 + + assert(type(name) is bytes) + + field = self.field_from_name.get(name) + + if field is not None: + handle.seek(field.dna_offset, os.SEEK_CUR) + if index != 0: + if field.dna_name.is_pointer: + index_offset = header.pointer_size * index + else: + index_offset = field.dna_type.size * index + assert(index_offset < field.dna_size) + handle.seek(index_offset, os.SEEK_CUR) + if not name_tail: # None or () + return field + else: + return field.dna_type.field_from_path(header, handle, name_tail) + + def field_get(self, header, handle, path, + default=..., + use_nil=True, use_str=True, + ): + field = self.field_from_path(header, handle, path) + if field is None: + if default is not ...: + return default + else: + raise KeyError("%r not found in %r (%r)" % + (path, [f.dna_name.name_only for f in self.fields], self.dna_type_id)) + + dna_type = field.dna_type + dna_name = field.dna_name + dna_size = field.dna_size + + if dna_name.is_pointer: + return DNA_IO.read_pointer(handle, header) + elif dna_type.dna_type_id == b'int': + if dna_name.array_size > 1: + return [DNA_IO.read_int(handle, header) for i in range(dna_name.array_size)] + return DNA_IO.read_int(handle, header) + elif dna_type.dna_type_id == b'short': + if dna_name.array_size > 1: + return [DNA_IO.read_short(handle, header) for i in range(dna_name.array_size)] + return DNA_IO.read_short(handle, header) + elif dna_type.dna_type_id == b'uint64_t': + if dna_name.array_size > 1: + return [DNA_IO.read_ulong(handle, header) for i in range(dna_name.array_size)] + return DNA_IO.read_ulong(handle, header) + elif dna_type.dna_type_id == b'float': + if dna_name.array_size > 1: + return [DNA_IO.read_float(handle, header) for i in range(dna_name.array_size)] + return DNA_IO.read_float(handle, header) + elif dna_type.dna_type_id == b'char': + if dna_size == 1: + # Single char, assume it's bitflag or int value, and not a string/bytes data... + return DNA_IO.read_char(handle, header) + if use_str: + if use_nil: + return DNA_IO.read_string0(handle, dna_name.array_size) + else: + return DNA_IO.read_string(handle, dna_name.array_size) + else: + if use_nil: + return DNA_IO.read_bytes0(handle, dna_name.array_size) + else: + return DNA_IO.read_bytes(handle, dna_name.array_size) + else: + raise NotImplementedError("%r exists but isn't pointer, can't resolve field %r" % + (path, dna_name.name_only), dna_name, dna_type) + + def field_set(self, header, handle, path, value): + assert(type(path) == bytes) + + field = self.field_from_path(header, handle, path) + if field is None: + raise KeyError("%r not found in %r" % + (path, [f.dna_name.name_only for f in self.fields])) + + dna_type = field.dna_type + dna_name = field.dna_name + + if dna_type.dna_type_id == b'char': + if type(value) is str: + return DNA_IO.write_string(handle, value, dna_name.array_size) + else: + return DNA_IO.write_bytes(handle, value, dna_name.array_size) + else: + raise NotImplementedError("Setting %r is not yet supported for %r" % + (dna_type, dna_name), dna_name, dna_type) + + +class DNA_IO: + """ + Module like class, for read-write utility functions. + + Only stores static methods & constants. + """ + + __slots__ = () + + def __new__(cls, *args, **kwargs): + raise RuntimeError("%s should not be instantiated" % cls) + + @staticmethod + def write_string(handle, astring, fieldlen): + assert(isinstance(astring, str)) + if len(astring) >= fieldlen: + stringw = astring[0:fieldlen] + else: + stringw = astring + '\0' + handle.write(stringw.encode('utf-8')) + + @staticmethod + def write_bytes(handle, astring, fieldlen): + assert(isinstance(astring, (bytes, bytearray))) + if len(astring) >= fieldlen: + stringw = astring[0:fieldlen] + else: + stringw = astring + b'\0' + + handle.write(stringw) + + @staticmethod + def read_bytes(handle, length): + data = handle.read(length) + return data + + @staticmethod + def read_bytes0(handle, length): + data = handle.read(length) + return DNA_IO.read_data0(data) + + @staticmethod + def read_string(handle, length): + return DNA_IO.read_bytes(handle, length).decode('utf-8') + + @staticmethod + def read_string0(handle, length): + return DNA_IO.read_bytes0(handle, length).decode('utf-8') + + @staticmethod + def read_data0_offset(data, offset): + add = data.find(b'\0', offset) - offset + return data[offset:offset + add] + + @staticmethod + def read_data0(data): + add = data.find(b'\0') + return data[:add] + + UCHAR = struct.Struct(b'<b'), struct.Struct(b'>b') + + @staticmethod + def read_char(handle, fileheader): + st = DNA_IO.UCHAR[fileheader.endian_index] + return st.unpack(handle.read(st.size))[0] + + USHORT = struct.Struct(b'<H'), struct.Struct(b'>H') + + @staticmethod + def read_ushort(handle, fileheader): + st = DNA_IO.USHORT[fileheader.endian_index] + return st.unpack(handle.read(st.size))[0] + + SSHORT = struct.Struct(b'<h'), struct.Struct(b'>h') + + @staticmethod + def read_short(handle, fileheader): + st = DNA_IO.SSHORT[fileheader.endian_index] + return st.unpack(handle.read(st.size))[0] + + UINT = struct.Struct(b'<I'), struct.Struct(b'>I') + + @staticmethod + def read_uint(handle, fileheader): + st = DNA_IO.UINT[fileheader.endian_index] + return st.unpack(handle.read(st.size))[0] + + SINT = struct.Struct(b'<i'), struct.Struct(b'>i') + + @staticmethod + def read_int(handle, fileheader): + st = DNA_IO.SINT[fileheader.endian_index] + return st.unpack(handle.read(st.size))[0] + + FLOAT = struct.Struct(b'<f'), struct.Struct(b'>f') + + @staticmethod + def read_float(handle, fileheader): + st = DNA_IO.FLOAT[fileheader.endian_index] + return st.unpack(handle.read(st.size))[0] + + ULONG = struct.Struct(b'<Q'), struct.Struct(b'>Q') + + @staticmethod + def read_ulong(handle, fileheader): + st = DNA_IO.ULONG[fileheader.endian_index] + return st.unpack(handle.read(st.size))[0] + + @staticmethod + def read_pointer(handle, header): + """ + reads an pointer from a file handle + the pointer size is given by the header (BlendFileHeader) + """ + if header.pointer_size == 4: + st = DNA_IO.UINT[header.endian_index] + return st.unpack(handle.read(st.size))[0] + if header.pointer_size == 8: + st = DNA_IO.ULONG[header.endian_index] + return st.unpack(handle.read(st.size))[0] diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_copy.py b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_copy.py new file mode 100644 index 00000000..595f2b0f --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_copy.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 + +# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** + +""" +A simply utility to copy blend files and their deps to a new location. + +Similar to packing, but don't attempt any path remapping. +""" + +from bam.blend import blendfile_path_walker + +TIMEIT = False + +# ------------------ +# Ensure module path +import os +import sys +path = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "modules")) +if path not in sys.path: + sys.path.append(path) +del os, sys, path +# -------- + + +def copy_paths( + paths, + output, + base, + + # load every libs dep, not just used deps. + all_deps=False, + # yield reports + report=None, + + # Filename filter, allow to exclude files from the pack, + # function takes a string returns True if the files should be included. + filename_filter=None, + ): + + import os + import shutil + + from bam.utils.system import colorize, is_subdir + + path_copy_files = set(paths) + + # Avoid walking over same libs many times + lib_visit = {} + + yield report("Reading %d blend file(s)\n" % len(paths)) + for blendfile_src in paths: + yield report(" %s: %r\n" % (colorize("blend", color='blue'), blendfile_src)) + for fp, (rootdir, fp_blend_basename) in blendfile_path_walker.FilePath.visit_from_blend( + blendfile_src, + readonly=True, + recursive=True, + recursive_all=all_deps, + lib_visit=lib_visit, + ): + + f_abs = os.path.normpath(fp.filepath_absolute) + path_copy_files.add(f_abs) + + # Source -> Dest Map + path_src_dst_map = {} + + for path_src in sorted(path_copy_files): + + if filename_filter and not filename_filter(path_src): + yield report(" %s: %r\n" % (colorize("exclude", color='yellow'), path_src)) + continue + + if not os.path.exists(path_src): + yield report(" %s: %r\n" % (colorize("missing path", color='red'), path_src)) + continue + + if not is_subdir(path_src, base): + yield report(" %s: %r\n" % (colorize("external path ignored", color='red'), path_src)) + continue + + path_rel = os.path.relpath(path_src, base) + path_dst = os.path.join(output, path_rel) + + path_src_dst_map[path_src] = path_dst + + # Create directories + path_dst_dir = {os.path.dirname(path_dst) for path_dst in path_src_dst_map.values()} + yield report("Creating %d directories in %r\n" % (len(path_dst_dir), output)) + for path_dir in sorted(path_dst_dir): + os.makedirs(path_dir, exist_ok=True) + del path_dst_dir + + # Copy files + yield report("Copying %d files to %r\n" % (len(path_src_dst_map), output)) + for path_src, path_dst in sorted(path_src_dst_map.items()): + yield report(" %s: %r -> %r\n" % (colorize("copying", color='blue'), path_src, path_dst)) + shutil.copy(path_src, path_dst) diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_pack.py b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_pack.py new file mode 100644 index 00000000..0c44d6dc --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_pack.py @@ -0,0 +1,676 @@ +#!/usr/bin/env python3 + +# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** + +import os +import sys +import shutil +from bam.blend import blendfile_path_walker + +TIMEIT = False + +# ------------------ +# Ensure module path +path = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "modules")) +if path not in sys.path: + sys.path.append(path) +del path +# -------- + + +# ---------------------- +# debug low level output +# +# ... when internals _really_ fail & we want to know why +def _dbg(text): + from bam.utils.system import colorize + if type(text) is bytes: + text = text.decode('utf-8') + sys.__stdout__.write(colorize(text, color='red') + "\n") + sys.__stdout__.flush() + + +def _relpath_remap( + path_src, + base_dir_src, + fp_basedir, + blendfile_src_dir_fakeroot=None, + ): + + if not os.path.isabs(path_src): + # Absolute win32 paths on a unix system + # cause bad issues! + if len(path_src) >= 2: + if path_src[0] != b'/'[0] and path_src[1] == b':'[0]: + pass + else: + raise Exception("Internal error 'path_src' -> %r must be absolute" % path_src) + + path_src = os.path.normpath(path_src) + if os.name != "nt": + path_dst = os.path.relpath(path_src, base_dir_src) + else: + # exception for windows, we need to support mapping between drives + try: + path_dst = os.path.relpath(path_src, base_dir_src) + except ValueError: + # include the absolute path when the file is on a different drive. + path_dst = os.path.relpath( + os.path.join(base_dir_src, b'__' + path_src.replace(b':', b'\\')), + base_dir_src, + ) + + if blendfile_src_dir_fakeroot is None: + # /foo/../bar.png --> /foo/__/bar.png + path_dst = path_dst.replace(b'..', b'__') + path_dst = os.path.normpath(path_dst) + else: + if b'..' in path_dst: + # remap, relative to project root + + # paths + path_dst = os.path.join(blendfile_src_dir_fakeroot, path_dst) + path_dst = os.path.normpath(path_dst) + # if there are paths outside the root still... + # This means they are outside the project directory, We dont support this, + # so name accordingly + if b'..' in path_dst: + # SHOULD NEVER HAPPEN + path_dst = path_dst.replace(b'..', b'__nonproject__') + path_dst = b'_' + path_dst + + # _dbg(b"FINAL A: " + path_dst) + path_dst_final = os.path.join(os.path.relpath(base_dir_src, fp_basedir), path_dst) + path_dst_final = os.path.normpath(path_dst_final) + # _dbg(b"FINAL B: " + path_dst_final) + + return path_dst, path_dst_final + + +def pack( + # store the blendfile relative to this directory, can be: + # os.path.dirname(blendfile_src) + # but in some cases we wan't to use a path higher up. + # base_dir_src, + blendfile_src, blendfile_dst, + + # the path to the top directory of the project's repository. + # the packed archive will reproduce the exact same hierarchy below that base path + # if set to None, it defaults to the given blendfile_src's directory. + # especially useful when used together with the warn_remap_externals option. + repository_base_path=None, + + # type of archive to produce (either ZIP or plain usual directory). + mode='ZIP', + + # optionally pass in the temp dir + base_dir_dst_temp=None, + paths_remap_relbase=None, + deps_remap=None, paths_remap=None, paths_uuid=None, + # load every libs dep, not just used deps. + all_deps=False, + compress_level=-1, + # yield reports + report=None, + + # The project path, eg: + # /home/me/myproject/mysession/path/to/blend/file.blend + # the path would be: b'path/to/blend' + # + # This is needed so we can choose to store paths + # relative to project or relative to the current file. + # + # When None, map _all_ paths are relative to the current blend. + # converting: '../../bar' --> '__/__/bar' + # so all paths are nested and not moved outside the session path. + blendfile_src_dir_fakeroot=None, + + # Read variations from json files. + use_variations=False, + + # do _everything_ except to write the paths. + # useful if we want to calculate deps to remap but postpone applying them. + readonly=False, + # Warn when we found a dependency external to given repository_base_path. + warn_remap_externals=False, + # dict of binary_edits: + # {file: [(ofs, bytes), ...], ...} + # ... where the file is the relative 'packed' location. + binary_edits=None, + + # Filename filter, allow to exclude files from the pack, + # function takes a string returns True if the files should be included. + filename_filter=None, + ): + """ + :param deps_remap: Store path deps_remap info as follows. + {"file.blend": {"path_new": "path_old", ...}, ...} + + :type deps_remap: dict or None + """ + + # Internal details: + # - we copy to a temp path before operating on the blend file + # so we can modify in-place. + # - temp files are only created once, (if we never touched them before), + # this way, for linked libraries - a single blend file may be used + # multiple times, each access will apply new edits on top of the old ones. + # - we track which libs we have touched (using 'lib_visit' arg), + # this means that the same libs wont be touched many times to modify the same data + # also prevents cyclic loops from crashing. + + if sys.stdout.isatty(): + from bam.utils.system import colorize + else: + from bam.utils.system import colorize_dummy as colorize + + assert isinstance(blendfile_src, bytes) + assert isinstance(blendfile_dst, bytes) + + # in case this is directly from the command line or user-input + blendfile_src = os.path.normpath(os.path.abspath(blendfile_src)) + blendfile_dst = os.path.normpath(os.path.abspath(blendfile_dst)) + assert blendfile_src != blendfile_dst + + # first check args are OK + # fakeroot _cant_ start with a separator, since we prepend chars to it. + if blendfile_src_dir_fakeroot is not None: + assert isinstance(blendfile_src_dir_fakeroot, bytes) + assert not blendfile_src_dir_fakeroot.startswith(os.sep.encode('ascii')) + + path_temp_files = set() + path_copy_files = set() + + # path_temp_files --> original-location + path_temp_files_orig = {} + + TEMP_SUFFIX = b'@' + + if report is None: + def report(msg): + return msg + + yield report("%s: %r...\n" % (colorize("\nscanning deps", color='bright_green'), blendfile_src)) + + if TIMEIT: + import time + t = time.time() + + base_dir_src = os.path.dirname(blendfile_src) if repository_base_path is None \ + else os.path.normpath(os.path.abspath(repository_base_path)) + base_dir_dst = os.path.dirname(blendfile_dst) + # _dbg(blendfile_src) + # _dbg(blendfile_dst) + + if base_dir_dst_temp is None: + # Always try to pack using a unique folder name. + import uuid + + suf = 'temp' if mode == 'ZIP' else 'pack' + + while True: + unique = uuid.uuid4().hex + name = '__blendfile_%s_%s__' % (unique, suf) + base_dir_dst_temp = os.path.join(base_dir_dst, name.encode('ascii')) + + if not os.path.exists(base_dir_dst_temp): + break + + def temp_remap_cb(filepath, rootdir): + """ + Create temp files in the destination path. + """ + filepath = blendfile_path_walker.utils.compatpath(filepath) + + if use_variations: + if blendfile_levels_dict_curr: + filepath = blendfile_levels_dict_curr.get(filepath, filepath) + + # ... + + # first remap this blend file to the location it will end up (so we can get images relative to _that_) + # TODO(cam) cache the results + fp_basedir_conv = _relpath_remap(os.path.join(rootdir, b'dummy'), base_dir_src, base_dir_src, blendfile_src_dir_fakeroot)[0] + fp_basedir_conv = os.path.join(base_dir_src, os.path.dirname(fp_basedir_conv)) + + # then get the file relative to the new location + filepath_tmp = _relpath_remap(filepath, base_dir_src, fp_basedir_conv, blendfile_src_dir_fakeroot)[0] + filepath_tmp = os.path.normpath(os.path.join(base_dir_dst_temp, filepath_tmp)) + TEMP_SUFFIX + + # only overwrite once (so we can write into a path already containing files) + if filepath_tmp not in path_temp_files: + if mode != 'NONE': + import shutil + os.makedirs(os.path.dirname(filepath_tmp), exist_ok=True) + shutil.copy(filepath, filepath_tmp) + path_temp_files.add(filepath_tmp) + path_temp_files_orig[filepath_tmp] = filepath + if mode != 'NONE': + return filepath_tmp + else: + return filepath + + # ----------------- + # Variation Support + # + # Use a json file to allow recursive-remapping of variations. + # + # file_a.blend + # file_a.json '{"variations": ["tree.blue.blend", ...]}' + # file_a.blend -> file_b.blend + # file_b.blend --> tree.blend + # + # the variation of `file_a.blend` causes `file_b.blend` + # to link in `tree.blue.blend` + + if use_variations: + blendfile_levels = [] + blendfile_levels_dict = [] + blendfile_levels_dict_curr = {} + + def blendfile_levels_rebuild(): + # after changing blend file configurations, + # re-create current variation lookup table + blendfile_levels_dict_curr.clear() + for d in blendfile_levels_dict: + if d is not None: + blendfile_levels_dict_curr.update(d) + + # use variations! + def blendfile_level_cb_enter(filepath): + import json + + filepath_json = os.path.splitext(filepath)[0] + b".json" + if os.path.exists(filepath_json): + with open(filepath_json, encoding='utf-8') as f_handle: + variations = [f.encode("utf-8") for f in json.load(f_handle).get("variations")] + # convert to absolute paths + basepath = os.path.dirname(filepath) + variations = { + # Reverse lookup, from non-variation to variation we specify in this file. + # {"/abs/path/foo.png": "/abs/path/foo.variation.png", ...} + # .. where the input _is_ the variation, + # we just make it absolute and use the non-variation as + # the key to the variation value. + b".".join(f.rsplit(b".", 2)[0::2]): f for f_ in variations + for f in (os.path.normpath(os.path.join(basepath, f_)),) + } + else: + variations = None + + blendfile_levels.append(filepath) + blendfile_levels_dict.append(variations) + + if variations: + blendfile_levels_rebuild() + + def blendfile_level_cb_exit(filepath): + blendfile_levels.pop() + blendfile_levels_dict.pop() + + if blendfile_levels_dict_curr: + blendfile_levels_rebuild() + else: + blendfile_level_cb_enter = blendfile_level_cb_exit = None + blendfile_levels_dict_curr = None + + lib_visit = {} + fp_blend_basename_last = b'' + + for fp, (rootdir, fp_blend_basename) in blendfile_path_walker.FilePath.visit_from_blend( + blendfile_src, + readonly=readonly, + temp_remap_cb=temp_remap_cb, + recursive=True, + recursive_all=all_deps, + lib_visit=lib_visit, + blendfile_level_cb=( + blendfile_level_cb_enter, + blendfile_level_cb_exit, + ) + ): + + # we could pass this in! + fp_blend = os.path.join(fp.basedir, fp_blend_basename) + + if fp_blend_basename_last != fp_blend_basename: + yield report(" %s: %r\n" % (colorize("blend", color='blue'), fp_blend)) + fp_blend_basename_last = fp_blend_basename + + if binary_edits is not None: + # TODO, temp_remap_cb makes paths, this isn't ideal, + # in this case we only want to remap! + if mode == 'NONE': + tmp = temp_remap_cb(fp_blend, base_dir_src) + tmp = os.path.relpath(tmp, base_dir_src) + else: + tmp = temp_remap_cb(fp_blend, base_dir_src) + tmp = os.path.relpath(tmp[:-len(TEMP_SUFFIX)], base_dir_dst_temp) + binary_edits_curr = binary_edits.setdefault(tmp, []) + del tmp + + # assume the path might be relative + path_src_orig = fp.filepath + path_rel = blendfile_path_walker.utils.compatpath(path_src_orig) + path_src = blendfile_path_walker.utils.abspath(path_rel, fp.basedir) + path_src = os.path.normpath(path_src) + + if warn_remap_externals and b".." in os.path.relpath(path_src, base_dir_src): + yield report(" %s: %r\n" % (colorize("non-local", color='bright_yellow'), path_src)) + + if filename_filter and not filename_filter(path_src): + yield report(" %s: %r\n" % (colorize("exclude", color='yellow'), path_src)) + continue + + # apply variation (if available) + if use_variations: + if blendfile_levels_dict_curr: + path_src_variation = blendfile_levels_dict_curr.get(path_src) + if path_src_variation is not None: + path_src = path_src_variation + path_rel = os.path.join(os.path.dirname(path_rel), os.path.basename(path_src)) + del path_src_variation + + # destination path realtive to the root + # assert(b'..' not in path_src) + assert(b'..' not in base_dir_src) + + # first remap this blend file to the location it will end up (so we can get images relative to _that_) + # TODO(cam) cache the results + fp_basedir_conv = _relpath_remap(fp_blend, base_dir_src, base_dir_src, blendfile_src_dir_fakeroot)[0] + fp_basedir_conv = os.path.join(base_dir_src, os.path.dirname(fp_basedir_conv)) + + # then get the file relative to the new location + path_dst, path_dst_final = _relpath_remap(path_src, base_dir_src, fp_basedir_conv, blendfile_src_dir_fakeroot) + + path_dst = os.path.join(base_dir_dst, path_dst) + + path_dst_final = b'//' + path_dst_final + + # Assign direct or add to edit-list (to apply later) + if not readonly: + fp.filepath = path_dst_final + if binary_edits is not None: + fp.filepath_assign_edits(path_dst_final, binary_edits_curr) + + # add to copy-list + # never copy libs (handled separately) + if not isinstance(fp, blendfile_path_walker.FPElem_block_path) or fp.userdata[0].code != b'LI': + path_copy_files.add((path_src, path_dst)) + + for file_list in ( + blendfile_path_walker.utils.find_sequence_paths(path_src) if fp.is_sequence else (), + fp.files_siblings(), + ): + + _src_dir = os.path.dirname(path_src) + _dst_dir = os.path.dirname(path_dst) + path_copy_files.update( + {(os.path.join(_src_dir, f), os.path.join(_dst_dir, f)) + for f in file_list + }) + del _src_dir, _dst_dir + + if deps_remap is not None: + # this needs to become JSON later... ugh, need to use strings + deps_remap.setdefault( + fp_blend_basename.decode('utf-8'), + {})[path_dst_final.decode('utf-8')] = path_src_orig.decode('utf-8') + + del lib_visit, fp_blend_basename_last + + if TIMEIT: + print(" Time: %.4f\n" % (time.time() - t)) + + yield report(("%s: %d files\n") % + (colorize("\narchiving", color='bright_green'), len(path_copy_files) + 1)) + + # handle deps_remap and file renaming + if deps_remap is not None: + blendfile_src_basename = os.path.basename(blendfile_src).decode('utf-8') + blendfile_dst_basename = os.path.basename(blendfile_dst).decode('utf-8') + + if blendfile_src_basename != blendfile_dst_basename: + if mode == 'FILE': + deps_remap[blendfile_dst_basename] = deps_remap[blendfile_src_basename] + del deps_remap[blendfile_src_basename] + del blendfile_src_basename, blendfile_dst_basename + + # store path mapping {dst: src} + if paths_remap is not None: + + if paths_remap_relbase is not None: + def relbase(fn): + return os.path.relpath(fn, paths_remap_relbase) + else: + def relbase(fn): + return fn + + for src, dst in path_copy_files: + # TODO. relative to project-basepath + paths_remap[os.path.relpath(dst, base_dir_dst).decode('utf-8')] = relbase(src).decode('utf-8') + # main file XXX, should have better way! + paths_remap[os.path.basename(blendfile_src).decode('utf-8')] = relbase(blendfile_src).decode('utf-8') + + # blend libs + for dst in path_temp_files: + src = path_temp_files_orig[dst] + k = os.path.relpath(dst[:-len(TEMP_SUFFIX)], base_dir_dst_temp).decode('utf-8') + paths_remap[k] = relbase(src).decode('utf-8') + del k + + del relbase + + if paths_uuid is not None: + from bam.utils.system import uuid_from_file + + for src, dst in path_copy_files: + # reports are handled again, later on. + if os.path.exists(src): + paths_uuid[os.path.relpath(dst, base_dir_dst).decode('utf-8')] = uuid_from_file(src) + # XXX, better way to store temp target + blendfile_dst_tmp = temp_remap_cb(blendfile_src, base_dir_src) + paths_uuid[os.path.basename(blendfile_src).decode('utf-8')] = uuid_from_file(blendfile_dst_tmp) + + # blend libs + for dst in path_temp_files: + k = os.path.relpath(dst[:-len(TEMP_SUFFIX)], base_dir_dst_temp).decode('utf-8') + if k not in paths_uuid: + if mode == 'NONE': + dst = path_temp_files_orig[dst] + paths_uuid[k] = uuid_from_file(dst) + del k + + del blendfile_dst_tmp + del uuid_from_file + + # -------------------- + # Handle File Copy/Zip + + if mode == 'FILE': + blendfile_dst_tmp = temp_remap_cb(blendfile_src, base_dir_src) + + shutil.move(blendfile_dst_tmp, blendfile_dst) + path_temp_files.remove(blendfile_dst_tmp) + + # strip TEMP_SUFFIX and move to the destination directory. + for fn in path_temp_files: + dst_rel, _ = _relpath_remap(fn[:-len(TEMP_SUFFIX)], base_dir_dst_temp, base_dir_dst, None) + dst = os.path.join(base_dir_dst, dst_rel) + yield report(" %s: %r -> %r\n" % (colorize("moving", color='blue'), fn, dst)) + os.makedirs(os.path.dirname(dst), exist_ok=True) + shutil.move(fn, dst) + + for src, dst in path_copy_files: + assert(b'.blend' not in dst) + assert src != dst + + # in rare cases a filepath could point to a directory + if (not os.path.exists(src)) or os.path.isdir(src): + yield report(" %s: %r\n" % (colorize("source missing", color='red'), src)) + else: + yield report(" %s: %r -> %r\n" % (colorize("copying", color='blue'), src, dst)) + os.makedirs(os.path.dirname(dst), exist_ok=True) + shutil.copy(src, dst) + + shutil.rmtree(base_dir_dst_temp) + + yield report(" %s: %r\n" % (colorize("written", color='green'), blendfile_dst)) + + elif mode == 'ZIP': + import zipfile + + # not awesome! + import zlib + assert(compress_level in range(-1, 10)) + _compress_level_orig = zlib.Z_DEFAULT_COMPRESSION + zlib.Z_DEFAULT_COMPRESSION = compress_level + _compress_mode = zipfile.ZIP_STORED if (compress_level == 0) else zipfile.ZIP_DEFLATED + if _compress_mode == zipfile.ZIP_STORED: + def is_compressed_filetype(fn): + return False + else: + from bam.utils.system import is_compressed_filetype + + with zipfile.ZipFile(blendfile_dst.decode('utf-8'), 'w', _compress_mode) as zip_handle: + for fn in path_temp_files: + yield report(" %s: %r -> <archive>\n" % (colorize("copying", color='blue'), fn)) + zip_handle.write( + fn.decode('utf-8'), + arcname=os.path.relpath(fn[:-1], base_dir_dst_temp).decode('utf-8'), + ) + os.remove(fn) + + shutil.rmtree(base_dir_dst_temp) + + for src, dst in path_copy_files: + assert(not dst.endswith(b'.blend')) + + # in rare cases a filepath could point to a directory + if (not os.path.exists(src)) or os.path.isdir(src): + yield report(" %s: %r\n" % (colorize("source missing", color='red'), src)) + else: + yield report(" %s: %r -> <archive>\n" % (colorize("copying", color='blue'), src)) + zip_handle.write( + src.decode('utf-8'), + arcname=os.path.relpath(dst, base_dir_dst).decode('utf-8'), + compress_type=zipfile.ZIP_STORED if is_compressed_filetype(dst) else _compress_mode, + ) + + zlib.Z_DEFAULT_COMPRESSION = _compress_level_orig + del _compress_level_orig, _compress_mode + + yield report(" %s: %r\n" % (colorize("written", color='green'), blendfile_dst)) + elif mode == 'NONE': + pass + else: + raise Exception("%s not a known mode" % mode) + + +def create_argparse(): + import argparse + + parser = argparse.ArgumentParser( + description="Run this script to extract blend-files(s) and their dependencies " + "to a destination path.") + + # for main_render() only, but validate args. + parser.add_argument( + "-i", "--input", dest="path_src", metavar='FILE', required=True, + help="Input path(s) or a wildcard to glob many files", + ) + parser.add_argument( + "-e", "--exclude", dest="exclude", metavar='PATTERN', required=False, + help='Exclusion pattern, such as "*.abc;*.mov;*.mkv"') + parser.add_argument( + "-o", "--output", dest="path_dst", metavar='DIR', required=True, + help="Output file (must be a .blend for --mode=FILE or a .zip when --mode=ZIP), " + "or a directory when multiple inputs are passed", + ) + parser.add_argument( + "-m", "--mode", dest="mode", metavar='MODE', required=False, + choices=('FILE', 'ZIP'), default='ZIP', + help="FILE copies the blend file(s) + dependencies to a directory, ZIP to an archive.", + ) + parser.add_argument( + "-q", "--quiet", dest="use_quiet", action='store_true', required=False, + help="Suppress status output", + ) + parser.add_argument( + "-t", "--temp", dest="temp_path", metavar='DIR', required=False, + help="Temporary directory to use. When not supplied, a unique directory is used.", + ) + + return parser + + +def exclusion_filter(exclude: str): + """Converts a filter string "*.abc;*.def" to a function that can be passed to pack(). + + If 'exclude' is None or an empty string, returns None (which means "no filtering"). + """ + + if not exclude: + return None + + import re + import fnmatch + + # convert string into regex callback that operates on bytes + # "*.txt;*.png;*.rst" --> rb".*\.txt$|.*\.png$|.*\.rst$" + pattern = b'|'.join(fnmatch.translate(f).encode('utf-8') + for f in exclude.split(';') + if f) + compiled_pattern = re.compile(pattern, re.IGNORECASE) + + def filename_filter(fname: bytes): + return not compiled_pattern.match(fname) + + return filename_filter + + +def encode_none_safe(value: str): + if value is None: + return None + return value.encode('utf8') + +def main(): + parser = create_argparse() + args = parser.parse_args() + + if args.use_quiet: + def report(msg): + pass + else: + def report(msg): + sys.stdout.write(msg) + sys.stdout.flush() + + for msg in pack( + args.path_src.encode('utf8'), + args.path_dst.encode('utf8'), + mode=args.mode, + base_dir_dst_temp=encode_none_safe(args.temp_path), + filename_filter=exclusion_filter(args.exclude), + ): + report(msg) + + +if __name__ == "__main__": + main() diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_pack_restore.py b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_pack_restore.py new file mode 100644 index 00000000..653d362f --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_pack_restore.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 + +# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** + +""" +This script takes Blend-File and remaps their paths to the original locations. + +(needed for uploading to the server) +""" + +VERBOSE = 1 + +from bam.blend import blendfile_path_walker + + +def blendfile_remap( + blendfile_src, blendpath_dst, + deps_remap=None, deps_remap_cb=None, + deps_remap_cb_userdata=None, + ): + import os + + def temp_remap_cb(filepath, level): + """ + Simply point to the output dir. + """ + basename = os.path.basename(blendfile_src) + filepath_tmp = os.path.join(blendpath_dst, basename) + + # ideally we could avoid copying _ALL_ blends + # TODO(cam) + import shutil + shutil.copy(filepath, filepath_tmp) + + return filepath_tmp + + for fp, (rootdir, fp_blend_basename) in blendfile_path_walker.FilePath.visit_from_blend( + blendfile_src, + readonly=False, + temp_remap_cb=temp_remap_cb, + recursive=False, + ): + + # path_dst_final - current path in blend. + # path_src_orig - original path from JSON. + + path_dst_final_b = fp.filepath + + # support 2 modes, callback or dictionary + if deps_remap_cb is not None: + path_src_orig = deps_remap_cb(path_dst_final_b, deps_remap_cb_userdata) + if path_src_orig is not None: + fp.filepath = path_src_orig + if VERBOSE: + print(" Remapping:", path_dst_final_b, "->", path_src_orig) + else: + path_dst_final = path_dst_final_b.decode('utf-8') + path_src_orig = deps_remap.get(path_dst_final) + if path_src_orig is not None: + fp.filepath = path_src_orig.encode('utf-8') + if VERBOSE: + print(" Remapping:", path_dst_final, "->", path_src_orig) + + +def pack_restore(blendfile_dir_src, blendfile_dir_dst, pathmap): + import os + + for dirpath, dirnames, filenames in os.walk(blendfile_dir_src): + if dirpath.startswith(b"."): + continue + + for filename in filenames: + if os.path.splitext(filename)[1].lower() == b".blend": + remap = pathmap.get(filename.decode('utf-8')) + if remap is not None: + filepath = os.path.join(dirpath, filename) + + # main function call + blendfile_remap(filepath, blendfile_dir_dst, remap) + + +def create_argparse(): + import os + import argparse + + usage_text = ( + "Run this script to remap blend-file(s) paths using a JSON file created by 'packer.py':" + + os.path.basename(__file__) + + "--input=DIR --remap=JSON [options]") + + parser = argparse.ArgumentParser(description=usage_text) + + # for main_render() only, but validate args. + parser.add_argument( + "-i", "--input", dest="path_src", metavar='DIR', required=True, + help="Input path(s) or a wildcard to glob many files") + parser.add_argument( + "-o", "--output", dest="path_dst", metavar='DIR', required=True, + help="Output directory ") + parser.add_argument( + "-r", "--deps_remap", dest="deps_remap", metavar='JSON', required=True, + help="JSON file containing the path remapping info") + + return parser + + +def main(): + import sys + import json + + parser = create_argparse() + args = parser.parse_args(sys.argv[1:]) + + encoding = sys.getfilesystemencoding() + + with open(args.deps_remap, 'r', encoding='utf-8') as f: + pathmap = json.load(f) + + pack_restore( + args.path_src.encode(encoding), + args.path_dst.encode(encoding), + pathmap, + ) + + +if __name__ == "__main__": + main() diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_path_remap.py b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_path_remap.py new file mode 100644 index 00000000..3b792c3a --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_path_remap.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python3 + +# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** + +""" +Module for remapping paths from one directory to another. +""" + +import os + + +# ---------------------------------------------------------------------------- +# private utility functions + +def _is_blend(f): + return f.lower().endswith(b'.blend') + + +def _warn__ascii(msg): + print(" warning: %s" % msg) + + +def _info__ascii(msg): + print(msg) + + +def _warn__json(msg): + import json + print(json.dumps(("warning", msg)), end=",\n") + +def _info__json(msg): + import json + print(json.dumps(("info", msg)), end=",\n") + + +def _uuid_from_file(fn, block_size=1 << 20): + with open(fn, 'rb') as f: + # first get the size + f.seek(0, os.SEEK_END) + size = f.tell() + f.seek(0, os.SEEK_SET) + # done! + + import hashlib + sha1 = hashlib.new('sha512') + while True: + data = f.read(block_size) + if not data: + break + sha1.update(data) + return (hex(size)[2:] + sha1.hexdigest()).encode() + + +def _iter_files(paths, check_ext=None): + # note, sorting isn't needed + # just gives predictable output + for p in paths: + p = os.path.abspath(p) + for dirpath, dirnames, filenames in sorted(os.walk(p)): + # skip '.svn' + if dirpath.startswith(b'.') and dirpath != b'.': + continue + + for filename in sorted(filenames): + if check_ext is None or check_ext(filename): + filepath = os.path.join(dirpath, filename) + yield filepath + + +# ---------------------------------------------------------------------------- +# Public Functions + +def start( + paths, + is_quiet=False, + dry_run=False, + use_json=False, + ): + + if use_json: + warn = _warn__json + info = _info__json + else: + warn = _warn__ascii + info = _info__ascii + + if use_json: + print("[") + + # {(sha1, length): "filepath"} + remap_uuid = {} + + # relative paths which don't exist, + # don't complain when they're missing on remap. + # {f_src: [relative path deps, ...]} + remap_lost = {} + + # all files we need to map + # absolute paths + files_to_map = set() + + # TODO, validate paths aren't nested! ["/foo", "/foo/bar"] + # it will cause problems touching files twice! + + # ------------------------------------------------------------------------ + # First walk over all blends + from bam.blend import blendfile_path_walker + + for blendfile_src in _iter_files(paths, check_ext=_is_blend): + if not is_quiet: + info("blend read: %r" % blendfile_src) + + remap_lost[blendfile_src] = remap_lost_blendfile_src = set() + + for fp, (rootdir, fp_blend_basename) in blendfile_path_walker.FilePath.visit_from_blend( + blendfile_src, + readonly=True, + recursive=False, + ): + # TODO. warn when referencing files outside 'paths' + + # so we can update the reference + f_abs = fp.filepath_absolute + f_abs = os.path.normpath(f_abs) + if os.path.exists(f_abs): + files_to_map.add(f_abs) + else: + if not is_quiet: + warn("file %r not found!" % f_abs) + + # don't complain about this file being missing on remap + remap_lost_blendfile_src.add(fp.filepath) + + # so we can know where its moved to + files_to_map.add(blendfile_src) + del blendfile_path_walker + + # ------------------------------------------------------------------------ + # Store UUID + # + # note, sorting is only to give predictable warnings/behavior + for f in sorted(files_to_map): + f_uuid = _uuid_from_file(f) + + f_match = remap_uuid.get(f_uuid) + if f_match is not None: + if not is_quiet: + warn("duplicate file found! (%r, %r)" % (f_match, f)) + + remap_uuid[f_uuid] = f + + # now find all deps + remap_data_args = ( + remap_uuid, + remap_lost, + ) + + if use_json: + if not remap_uuid: + print("\"nothing to remap!\"") + else: + print("\"complete\"") + print("]") + else: + if not remap_uuid: + print("Nothing to remap!") + + return remap_data_args + + +def finish( + paths, remap_data_args, + is_quiet=False, + force_relative=False, + dry_run=False, + use_json=False, + ): + + if use_json: + warn = _warn__json + info = _info__json + else: + warn = _warn__ascii + info = _info__ascii + + if use_json: + print("[") + + (remap_uuid, + remap_lost, + ) = remap_data_args + + remap_src_to_dst = {} + remap_dst_to_src = {} + + for f_dst in _iter_files(paths): + f_uuid = _uuid_from_file(f_dst) + f_src = remap_uuid.get(f_uuid) + if f_src is not None: + remap_src_to_dst[f_src] = f_dst + remap_dst_to_src[f_dst] = f_src + + # now the fun begins, remap _all_ paths + from bam.blend import blendfile_path_walker + + for blendfile_dst in _iter_files(paths, check_ext=_is_blend): + blendfile_src = remap_dst_to_src.get(blendfile_dst) + if blendfile_src is None: + if not is_quiet: + warn("new blendfile added since beginning 'remap': %r" % blendfile_dst) + continue + + # not essential, just so we can give more meaningful errors + remap_lost_blendfile_src = remap_lost[blendfile_src] + + if not is_quiet: + info("blend write: %r -> %r" % (blendfile_src, blendfile_dst)) + + blendfile_src_basedir = os.path.dirname(blendfile_src) + blendfile_dst_basedir = os.path.dirname(blendfile_dst) + for fp, (rootdir, fp_blend_basename) in blendfile_path_walker.FilePath.visit_from_blend( + blendfile_dst, + readonly=False, + recursive=False, + ): + # TODO. warn when referencing files outside 'paths' + + # so we can update the reference + f_src_orig = fp.filepath + + if f_src_orig in remap_lost_blendfile_src: + # this file never existed, so we can't remap it + continue + + is_relative = f_src_orig.startswith(b'//') + if is_relative: + f_src_abs = fp.filepath_absolute_resolve(basedir=blendfile_src_basedir) + else: + f_src_abs = f_src_orig + + f_src_abs = os.path.normpath(f_src_abs) + f_dst_abs = remap_src_to_dst.get(f_src_abs) + + if f_dst_abs is None: + if not is_quiet: + warn("file %r not found in map!" % f_src_abs) + continue + + # now remap! + if is_relative or force_relative: + f_dst_final = b'//' + os.path.relpath(f_dst_abs, blendfile_dst_basedir) + else: + f_dst_final = f_dst_abs + + if f_dst_final != f_src_orig: + if not dry_run: + fp.filepath = f_dst_final + if not is_quiet: + info("remap %r -> %r" % (f_src_abs, f_dst_abs)) + + del blendfile_path_walker + + if use_json: + print("\"complete\"\n]") diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_path_walker.py b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_path_walker.py new file mode 100644 index 00000000..df07235e --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_path_walker.py @@ -0,0 +1,953 @@ +#!/usr/bin/env python3 + +# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** + +import os +import logging + +from . import blendfile + +# gives problems with scripts that use stdout, for testing 'bam deps' for eg. +DEBUG = False +VERBOSE = DEBUG or False # os.environ.get('BAM_VERBOSE', False) +TIMEIT = False + +USE_ALEMBIC_BRANCH = True + + +class C_defs: + __slots__ = () + + def __new__(cls, *args, **kwargs): + raise RuntimeError("%s should not be instantiated" % cls) + + # DNA_sequence_types.h (Sequence.type) + SEQ_TYPE_IMAGE = 0 + SEQ_TYPE_META = 1 + SEQ_TYPE_SCENE = 2 + SEQ_TYPE_MOVIE = 3 + SEQ_TYPE_SOUND_RAM = 4 + SEQ_TYPE_SOUND_HD = 5 + SEQ_TYPE_MOVIECLIP = 6 + SEQ_TYPE_MASK = 7 + SEQ_TYPE_EFFECT = 8 + + IMA_SRC_FILE = 1 + IMA_SRC_SEQUENCE = 2 + IMA_SRC_MOVIE = 3 + + # DNA_modifier_types.h + eModifierType_MeshCache = 46 + + # DNA_particle_types.h + PART_DRAW_OB = 7 + PART_DRAW_GR = 8 + + # DNA_object_types.h + # Object.transflag + OB_DUPLIGROUP = 1 << 8 + + if USE_ALEMBIC_BRANCH: + CACHE_LIBRARY_SOURCE_CACHE = 1 + +log_deps = logging.getLogger("path_walker") +log_deps.setLevel({ + (True, True): logging.DEBUG, + (False, True): logging.INFO, + (False, False): logging.WARNING +}[DEBUG, VERBOSE]) + +if VERBOSE: + def set_as_str(s): + if s is None: + return "None" + return ", ".join(sorted(str(i) for i in s)) + + +class FPElem: + """ + Tiny filepath class to hide blendfile. + """ + + __slots__ = ( + "basedir", + + # library link level + "level", + + # True when this is apart of a sequence (image or movieclip) + "is_sequence", + + "userdata", + ) + + def __init__(self, basedir, level, + # subclasses get/set functions should use + userdata): + self.basedir = basedir + self.level = level + self.is_sequence = False + + # subclass must call + self.userdata = userdata + + def files_siblings(self): + return () + + # -------- + # filepath + + def filepath_absolute_resolve(self, basedir=None): + """ + Resolve the filepath, with the option to override the basedir. + """ + filepath = self.filepath + if filepath.startswith(b'//'): + if basedir is None: + basedir = self.basedir + return os.path.normpath(os.path.join( + basedir, + utils.compatpath(filepath[2:]), + )) + else: + return utils.compatpath(filepath) + + def filepath_assign_edits(self, filepath, binary_edits): + self._set_cb_edits(filepath, binary_edits) + + @staticmethod + def _filepath_assign_edits(block, path, filepath, binary_edits): + """ + Record the write to a separate entry (binary file-like object), + this lets us replay the edits later. + (so we can replay them onto the clients local cache without a file transfer). + """ + import struct + assert(type(filepath) is bytes) + assert(type(path) is bytes) + ofs, size = block.get_file_offset(path) + # ensure we dont write past the field size & allow for \0 + filepath = filepath[:size - 1] + binary_edits.append((ofs, filepath + b'\0')) + + @property + def filepath(self): + return self._get_cb() + + @filepath.setter + def filepath(self, filepath): + self._set_cb(filepath) + + @property + def filepath_absolute(self): + return self.filepath_absolute_resolve() + + +class FPElem_block_path(FPElem): + """ + Simple block-path: + userdata = (block, path) + """ + __slots__ = () + + def _get_cb(self): + block, path = self.userdata + return block[path] + + def _set_cb(self, filepath): + block, path = self.userdata + block[path] = filepath + + def _set_cb_edits(self, filepath, binary_edits): + block, path = self.userdata + self._filepath_assign_edits(block, path, filepath, binary_edits) + + +class FPElem_sequence_single(FPElem): + """ + Movie sequence + userdata = (block, path, sub_block, sub_path) + """ + __slots__ = () + + def _get_cb(self): + block, path, sub_block, sub_path = self.userdata + return block[path] + sub_block[sub_path] + + def _set_cb(self, filepath): + block, path, sub_block, sub_path = self.userdata + head, sep, tail = utils.splitpath(filepath) + + block[path] = head + sep + sub_block[sub_path] = tail + + def _set_cb_edits(self, filepath, binary_edits): + block, path, sub_block, sub_path = self.userdata + head, sep, tail = utils.splitpath(filepath) + + self._filepath_assign_edits(block, path, head + sep, binary_edits) + self._filepath_assign_edits(sub_block, sub_path, tail, binary_edits) + + +class FPElem_sequence_image_seq(FPElem_sequence_single): + """ + Image sequence + userdata = (block, path, sub_block, sub_path) + """ + __slots__ = () + + def files_siblings(self): + block, path, sub_block, sub_path = self.userdata + + array = block.get_pointer(b'stripdata') + files = [array.get(b'name', use_str=False, base_index=i) for i in range(array.count)] + return files + + +class FilePath: + __slots__ = () + + def __new__(cls, *args, **kwargs): + raise RuntimeError("%s should not be instantiated" % cls) + + # ------------------------------------------------------------------------ + # Main function to visit paths + @staticmethod + def visit_from_blend( + filepath, + + # never modify the blend + readonly=True, + # callback that creates a temp file and returns its path. + temp_remap_cb=None, + + # recursive options + recursive=False, + # recurse all indirectly linked data + # (not just from the initially referenced blend file) + recursive_all=False, + # list of ID block names we want to load, or None to load all + block_codes=None, + # root when we're loading libs indirectly + rootdir=None, + level=0, + # dict of id's used so we don't follow these links again + # prevents cyclic references too! + # {lib_path: set([block id's ...])} + lib_visit=None, + + # optional blendfile callbacks + # These callbacks run on enter-exit blend files + # so you can keep track of what file and level you're at. + blendfile_level_cb=(None, None), + ): + # print(level, block_codes) + import os + + filepath = os.path.abspath(filepath) + + indent_str = " " * level + # print(indent_str + "Opening:", filepath) + # print(indent_str + "... blocks:", block_codes) + + log = log_deps.getChild('visit_from_blend') + log.info("~") + log.info("%sOpening: %s", indent_str, filepath) + if VERBOSE: + log.info("%s blocks: %s", indent_str, set_as_str(block_codes)) + + blendfile_level_cb_enter, blendfile_level_cb_exit = blendfile_level_cb + + if blendfile_level_cb_enter is not None: + blendfile_level_cb_enter(filepath) + + basedir = os.path.dirname(filepath) + if rootdir is None: + rootdir = basedir + + if lib_visit is None: + lib_visit = {} + + + + if recursive and (level > 0) and (block_codes is not None) and (recursive_all is False): + # prevent from expanding the + # same datablock more then once + # note: we could *almost* id_name, however this isn't unique for libraries. + expand_addr_visit = set() + # {lib_id: {block_ids... }} + expand_codes_idlib = {} + + # libraries used by this blend + block_codes_idlib = set() + + # XXX, checking 'block_codes' isn't 100% reliable, + # but at least don't touch the same blocks twice. + # whereas block_codes is intended to only operate on blocks we requested. + lib_block_codes_existing = lib_visit.setdefault(filepath, set()) + + # only for this block + def _expand_codes_add_test(block, code): + # return True, if the ID should be searched further + # + # we could investigate a better way... + # Not to be accessing ID blocks at this point. but its harmless + if code == b'ID': + assert(code == block.code) + if recursive: + expand_codes_idlib.setdefault(block[b'lib'], set()).add(block[b'name']) + return False + else: + id_name = block[b'id', b'name'] + + # if we touched this already, don't touch again + # (else we may modify the same path multiple times) + # + # FIXME, works in some cases but not others + # keep, without this we get errors + # Gooseberry r668 + # bam pack scenes/01_island/01_meet_franck/01_01_01_A/01_01_01_A.comp.blend + # gives strange errors + ''' + if id_name not in block_codes: + return False + ''' + + # instead just don't operate on blocks multiple times + # ... rather than attempt to check on what we need or not. + len_prev = len(lib_block_codes_existing) + lib_block_codes_existing.add(id_name) + if len_prev == len(lib_block_codes_existing): + return False + + len_prev = len(expand_addr_visit) + expand_addr_visit.add(block.addr_old) + return (len_prev != len(expand_addr_visit)) + + def block_expand(block, code): + assert(block.code == code) + if _expand_codes_add_test(block, code): + yield block + + assert(block.code == code) + fn = ExpandID.expand_funcs.get(code) + if fn is not None: + for sub_block in fn(block): + if sub_block is not None: + yield from block_expand(sub_block, sub_block.code) + else: + if code == b'ID': + yield block + else: + expand_addr_visit = None + + # set below + expand_codes_idlib = None + + # never set + block_codes_idlib = None + + def block_expand(block, code): + assert(block.code == code) + yield block + + # ------ + # Define + # + # - iter_blocks_id(code) + # - iter_blocks_idlib() + if block_codes is None: + def iter_blocks_id(code): + return blend.find_blocks_from_code(code) + + def iter_blocks_idlib(): + return blend.find_blocks_from_code(b'LI') + else: + def iter_blocks_id(code): + for block in blend.find_blocks_from_code(code): + if block[b'id', b'name'] in block_codes: + yield from block_expand(block, code) + + if block_codes_idlib is not None: + def iter_blocks_idlib(): + for block in blend.find_blocks_from_code(b'LI'): + # TODO, this should work but in fact mades some libs not link correctly. + if block[b'name'] in block_codes_idlib: + yield from block_expand(block, b'LI') + else: + def iter_blocks_idlib(): + return blend.find_blocks_from_code(b'LI') + + if temp_remap_cb is not None: + filepath_tmp = temp_remap_cb(filepath, rootdir) + else: + filepath_tmp = filepath + + # store info to pass along with each iteration + extra_info = rootdir, os.path.basename(filepath) + + with blendfile.open_blend(filepath_tmp, "rb" if readonly else "r+b") as blend: + + for code in blend.code_index.keys(): + # handle library blocks as special case + if ((len(code) != 2) or + (code in { + # libraries handled below + b'LI', + b'ID', + # unneeded + b'WM', + b'SN', # bScreen + })): + + continue + + # if VERBOSE: + # print(" Scanning", code) + + for block in iter_blocks_id(code): + yield from FilePath.from_block(block, basedir, extra_info, level) + + # print("A:", expand_addr_visit) + # print("B:", block_codes) + if VERBOSE: + log.info("%s expand_addr_visit=%s", indent_str, set_as_str(expand_addr_visit)) + + if recursive: + + if expand_codes_idlib is None: + expand_codes_idlib = {} + for block in blend.find_blocks_from_code(b'ID'): + expand_codes_idlib.setdefault(block[b'lib'], set()).add(block[b'name']) + + # look into libraries + lib_all = [] + + for lib_id, lib_block_codes in sorted(expand_codes_idlib.items()): + lib = blend.find_block_from_offset(lib_id) + lib_path = lib[b'name'] + + # get all data needed to read the blend files here (it will be freed!) + # lib is an address at the moment, we only use as a way to group + + lib_all.append((lib_path, lib_block_codes)) + # import IPython; IPython.embed() + + # ensure we expand indirect linked libs + if block_codes_idlib is not None: + block_codes_idlib.add(lib_path) + + # do this after, incase we mangle names above + for block in iter_blocks_idlib(): + yield from FilePath.from_block(block, basedir, extra_info, level) + del blend + + + # ---------------- + # Handle Recursive + if recursive: + # now we've closed the file, loop on other files + + # note, sorting - isn't needed, it just gives predictable load-order. + for lib_path, lib_block_codes in lib_all: + lib_path_abs = os.path.normpath(utils.compatpath(utils.abspath(lib_path, basedir))) + + # if we visited this before, + # check we don't follow the same links more than once + lib_block_codes_existing = lib_visit.setdefault(lib_path_abs, set()) + lib_block_codes -= lib_block_codes_existing + + # don't touch them again + # XXX, this is now maintained in "_expand_generic_material" + # lib_block_codes_existing.update(lib_block_codes) + + # print("looking for", lib_block_codes) + + if not lib_block_codes: + if VERBOSE: + print((indent_str + " "), "Library Skipped (visited): ", filepath, " -> ", lib_path_abs, sep="") + continue + + if not os.path.exists(lib_path_abs): + if VERBOSE: + print((indent_str + " "), "Library Missing: ", filepath, " -> ", lib_path_abs, sep="") + continue + + # import IPython; IPython.embed() + if VERBOSE: + print((indent_str + " "), "Library: ", filepath, " -> ", lib_path_abs, sep="") + # print((indent_str + " "), lib_block_codes) + yield from FilePath.visit_from_blend( + lib_path_abs, + readonly=readonly, + temp_remap_cb=temp_remap_cb, + recursive=True, + block_codes=lib_block_codes, + rootdir=rootdir, + level=level + 1, + lib_visit=lib_visit, + blendfile_level_cb=blendfile_level_cb, + ) + + if blendfile_level_cb_exit is not None: + blendfile_level_cb_exit(filepath) + + # ------------------------------------------------------------------------ + # Direct filepaths from Blocks + # + # (no expanding or following references) + + @staticmethod + def from_block(block: blendfile.BlendFileBlock, basedir, extra_info, level): + assert(block.code != b'DATA') + fn = FilePath._from_block_dict.get(block.code) + if fn is None: + return + + yield from fn(block, basedir, extra_info, level) + + @staticmethod + def _from_block_OB(block, basedir, extra_info, level): + # 'ob->modifiers[...].filepath' + for block_mod in bf_utils.iter_ListBase( + block.get_pointer((b'modifiers', b'first')), + next_item=(b'modifier', b'next')): + item_md_type = block_mod[b'modifier', b'type'] + if item_md_type == C_defs.eModifierType_MeshCache: + yield FPElem_block_path(basedir, level, (block_mod, b'filepath')), extra_info + + @staticmethod + def _from_block_MC(block, basedir, extra_info, level): + # TODO, image sequence + fp = FPElem_block_path(basedir, level, (block, b'name')) + fp.is_sequence = True + yield fp, extra_info + + @staticmethod + def _from_block_IM(block, basedir, extra_info, level): + # old files miss this + image_source = block.get(b'source', C_defs.IMA_SRC_FILE) + if image_source not in {C_defs.IMA_SRC_FILE, C_defs.IMA_SRC_SEQUENCE, C_defs.IMA_SRC_MOVIE}: + return + if block[b'packedfile']: + return + + fp = FPElem_block_path(basedir, level, (block, b'name')) + if image_source == C_defs.IMA_SRC_SEQUENCE: + fp.is_sequence = True + yield fp, extra_info + + @staticmethod + def _from_block_VF(block, basedir, extra_info, level): + if block[b'packedfile']: + return + if block[b'name'] != b'<builtin>': # builtin font + yield FPElem_block_path(basedir, level, (block, b'name')), extra_info + + @staticmethod + def _from_block_SO(block, basedir, extra_info, level): + if block[b'packedfile']: + return + yield FPElem_block_path(basedir, level, (block, b'name')), extra_info + + @staticmethod + def _from_block_ME(block, basedir, extra_info, level): + block_external = block.get_pointer((b'ldata', b'external'), None) + if block_external is None: + block_external = block.get_pointer((b'fdata', b'external'), None) + + if block_external is not None: + yield FPElem_block_path(basedir, level, (block_external, b'filename')), extra_info + + if USE_ALEMBIC_BRANCH: + @staticmethod + def _from_block_CL(block, basedir, extra_info, level): + if block[b'source_mode'] == C_defs.CACHE_LIBRARY_SOURCE_CACHE: + yield FPElem_block_path(basedir, level, (block, b'input_filepath')), extra_info + + @staticmethod + def _from_block_CF(block, basedir, extra_info, level): + yield FPElem_block_path(basedir, level, (block, b'filepath')), extra_info + + + @staticmethod + def _from_block_SC(block, basedir, extra_info, level): + block_ed = block.get_pointer(b'ed') + if block_ed is not None: + sdna_index_Sequence = block.file.sdna_index_from_id[b'Sequence'] + + def seqbase(someseq): + for item in someseq: + item_type = item.get(b'type', sdna_index_refine=sdna_index_Sequence) + + if item_type >= C_defs.SEQ_TYPE_EFFECT: + pass + elif item_type == C_defs.SEQ_TYPE_META: + yield from seqbase(bf_utils.iter_ListBase( + item.get_pointer((b'seqbase', b'first'), sdna_index_refine=sdna_index_Sequence))) + else: + item_strip = item.get_pointer(b'strip', sdna_index_refine=sdna_index_Sequence) + if item_strip is None: # unlikely! + continue + item_stripdata = item_strip.get_pointer(b'stripdata') + + if item_type == C_defs.SEQ_TYPE_IMAGE: + yield FPElem_sequence_image_seq( + basedir, level, (item_strip, b'dir', item_stripdata, b'name')), extra_info + elif item_type in {C_defs.SEQ_TYPE_MOVIE, C_defs.SEQ_TYPE_SOUND_RAM, C_defs.SEQ_TYPE_SOUND_HD}: + yield FPElem_sequence_single( + basedir, level, (item_strip, b'dir', item_stripdata, b'name')), extra_info + + yield from seqbase(bf_utils.iter_ListBase(block_ed.get_pointer((b'seqbase', b'first')))) + + @staticmethod + def _from_block_LI(block, basedir, extra_info, level): + if block.get(b'packedfile', None): + return + + yield FPElem_block_path(basedir, level, (block, b'name')), extra_info + + # _from_block_IM --> {b'IM': _from_block_IM, ...} + _from_block_dict = { + k.rpartition("_")[2].encode('ascii'): s_fn.__func__ for k, s_fn in locals().items() + if isinstance(s_fn, staticmethod) + if k.startswith("_from_block_") + } + + +class bf_utils: + @staticmethod + def iter_ListBase(block, next_item=b'next'): + while block: + yield block + block = block.file.find_block_from_offset(block[next_item]) + + def iter_array(block, length=-1): + assert(block.code == b'DATA') + from . import blendfile + import os + handle = block.file.handle + header = block.file.header + + for i in range(length): + block.file.handle.seek(block.file_offset + (header.pointer_size * i), os.SEEK_SET) + offset = blendfile.DNA_IO.read_pointer(handle, header) + sub_block = block.file.find_block_from_offset(offset) + yield sub_block + + +# ----------------------------------------------------------------------------- +# ID Expand + +class ExpandID: + # fake module + # + # TODO: + # + # Array lookups here are _WAY_ too complicated, + # we need some nicer way to represent pointer indirection (easy like in C!) + # but for now, use what we have. + # + __slots__ = () + + def __new__(cls, *args, **kwargs): + raise RuntimeError("%s should not be instantiated" % cls) + + @staticmethod + def _expand_generic_material(block): + array_len = block.get(b'totcol') + if array_len != 0: + array = block.get_pointer(b'mat') + for sub_block in bf_utils.iter_array(array, array_len): + yield sub_block + + @staticmethod + def _expand_generic_mtex(block): + field = block.dna_type.field_from_name[b'mtex'] + array_len = field.dna_size // block.file.header.pointer_size + + for i in range(array_len): + item = block.get_pointer((b'mtex', i)) + if item: + yield item.get_pointer(b'tex') + yield item.get_pointer(b'object') + + @staticmethod + def _expand_generic_nodetree(block): + assert(block.dna_type.dna_type_id == b'bNodeTree') + + sdna_index_bNode = block.file.sdna_index_from_id[b'bNode'] + for item in bf_utils.iter_ListBase(block.get_pointer((b'nodes', b'first'))): + item_type = item.get(b'type', sdna_index_refine=sdna_index_bNode) + + if item_type != 221: # CMP_NODE_R_LAYERS + yield item.get_pointer(b'id', sdna_index_refine=sdna_index_bNode) + + def _expand_generic_nodetree_id(block): + block_ntree = block.get_pointer(b'nodetree', None) + if block_ntree is not None: + yield from ExpandID._expand_generic_nodetree(block_ntree) + + @staticmethod + def _expand_generic_animdata(block): + block_adt = block.get_pointer(b'adt') + if block_adt: + yield block_adt.get_pointer(b'action') + # TODO, NLA + + @staticmethod + def expand_OB(block): # 'Object' + yield from ExpandID._expand_generic_animdata(block) + yield from ExpandID._expand_generic_material(block) + + has_dup_group = False + yield block.get_pointer(b'data') + if block[b'transflag'] & C_defs.OB_DUPLIGROUP: + dup_group = block.get_pointer(b'dup_group') + if dup_group is not None: + has_dup_group = True + yield dup_group + del dup_group + + yield block.get_pointer(b'proxy') + yield block.get_pointer(b'proxy_group') + + if USE_ALEMBIC_BRANCH: + if has_dup_group: + sdna_index_CacheLibrary = block.file.sdna_index_from_id.get(b'CacheLibrary') + if sdna_index_CacheLibrary is not None: + yield block.get_pointer(b'cache_library') + + # 'ob->pose->chanbase[...].custom' + block_pose = block.get_pointer(b'pose') + if block_pose is not None: + assert(block_pose.dna_type.dna_type_id == b'bPose') + sdna_index_bPoseChannel = block_pose.file.sdna_index_from_id[b'bPoseChannel'] + for item in bf_utils.iter_ListBase(block_pose.get_pointer((b'chanbase', b'first'))): + item_custom = item.get_pointer(b'custom', sdna_index_refine=sdna_index_bPoseChannel) + if item_custom is not None: + yield item_custom + # Expand the objects 'ParticleSettings' via: + # 'ob->particlesystem[...].part' + sdna_index_ParticleSystem = block.file.sdna_index_from_id.get(b'ParticleSystem') + if sdna_index_ParticleSystem is not None: + for item in bf_utils.iter_ListBase( + block.get_pointer((b'particlesystem', b'first'))): + item_part = item.get_pointer(b'part', sdna_index_refine=sdna_index_ParticleSystem) + if item_part is not None: + yield item_part + + @staticmethod + def expand_ME(block): # 'Mesh' + yield from ExpandID._expand_generic_animdata(block) + yield from ExpandID._expand_generic_material(block) + yield block.get_pointer(b'texcomesh') + # TODO, TexFace? - it will be slow, we could simply ignore :S + + @staticmethod + def expand_CU(block): # 'Curve' + yield from ExpandID._expand_generic_animdata(block) + yield from ExpandID._expand_generic_material(block) + + sub_block = block.get_pointer(b'vfont') + if sub_block is not None: + yield sub_block + yield block.get_pointer(b'vfontb') + yield block.get_pointer(b'vfonti') + yield block.get_pointer(b'vfontbi') + + yield block.get_pointer(b'bevobj') + yield block.get_pointer(b'taperobj') + yield block.get_pointer(b'textoncurve') + + @staticmethod + def expand_MB(block): # 'MBall' + yield from ExpandID._expand_generic_animdata(block) + yield from ExpandID._expand_generic_material(block) + + @staticmethod + def expand_AR(block): # 'bArmature' + yield from ExpandID._expand_generic_animdata(block) + + @staticmethod + def expand_LA(block): # 'Lamp' + yield from ExpandID._expand_generic_animdata(block) + yield from ExpandID._expand_generic_nodetree_id(block) + yield from ExpandID._expand_generic_mtex(block) + + @staticmethod + def expand_MA(block): # 'Material' + yield from ExpandID._expand_generic_animdata(block) + yield from ExpandID._expand_generic_nodetree_id(block) + yield from ExpandID._expand_generic_mtex(block) + + yield block.get_pointer(b'group') + + @staticmethod + def expand_TE(block): # 'Tex' + yield from ExpandID._expand_generic_animdata(block) + yield from ExpandID._expand_generic_nodetree_id(block) + yield block.get_pointer(b'ima') + + @staticmethod + def expand_WO(block): # 'World' + yield from ExpandID._expand_generic_animdata(block) + yield from ExpandID._expand_generic_nodetree_id(block) + yield from ExpandID._expand_generic_mtex(block) + + @staticmethod + def expand_NT(block): # 'bNodeTree' + yield from ExpandID._expand_generic_animdata(block) + yield from ExpandID._expand_generic_nodetree(block) + + @staticmethod + def expand_PA(block): # 'ParticleSettings' + yield from ExpandID._expand_generic_animdata(block) + block_ren_as = block[b'ren_as'] + if block_ren_as == C_defs.PART_DRAW_GR: + yield block.get_pointer(b'dup_group') + elif block_ren_as == C_defs.PART_DRAW_OB: + yield block.get_pointer(b'dup_ob') + yield from ExpandID._expand_generic_mtex(block) + + @staticmethod + def expand_SC(block): # 'Scene' + yield from ExpandID._expand_generic_animdata(block) + yield from ExpandID._expand_generic_nodetree_id(block) + yield block.get_pointer(b'camera') + yield block.get_pointer(b'world') + yield block.get_pointer(b'set', None) + yield block.get_pointer(b'clip', None) + + sdna_index_Base = block.file.sdna_index_from_id[b'Base'] + for item in bf_utils.iter_ListBase(block.get_pointer((b'base', b'first'))): + yield item.get_pointer(b'object', sdna_index_refine=sdna_index_Base) + + block_ed = block.get_pointer(b'ed') + if block_ed is not None: + sdna_index_Sequence = block.file.sdna_index_from_id[b'Sequence'] + + def seqbase(someseq): + for item in someseq: + item_type = item.get(b'type', sdna_index_refine=sdna_index_Sequence) + + if item_type >= C_defs.SEQ_TYPE_EFFECT: + pass + elif item_type == C_defs.SEQ_TYPE_META: + yield from seqbase(bf_utils.iter_ListBase( + item.get_pointer((b'seqbase' b'first'), sdna_index_refine=sdna_index_Sequence))) + else: + if item_type == C_defs.SEQ_TYPE_SCENE: + yield item.get_pointer(b'scene') + elif item_type == C_defs.SEQ_TYPE_MOVIECLIP: + yield item.get_pointer(b'clip') + elif item_type == C_defs.SEQ_TYPE_MASK: + yield item.get_pointer(b'mask') + elif item_type == C_defs.SEQ_TYPE_SOUND_RAM: + yield item.get_pointer(b'sound') + + yield from seqbase(bf_utils.iter_ListBase( + block_ed.get_pointer((b'seqbase', b'first')))) + + @staticmethod + def expand_GR(block): # 'Group' + sdna_index_GroupObject = block.file.sdna_index_from_id[b'GroupObject'] + for item in bf_utils.iter_ListBase(block.get_pointer((b'gobject', b'first'))): + yield item.get_pointer(b'ob', sdna_index_refine=sdna_index_GroupObject) + + # expand_GR --> {b'GR': expand_GR, ...} + expand_funcs = { + k.rpartition("_")[2].encode('ascii'): s_fn.__func__ for k, s_fn in locals().items() + if isinstance(s_fn, staticmethod) + if k.startswith("expand_") + } + + +# ----------------------------------------------------------------------------- +# Packing Utility + + +class utils: + # fake module + __slots__ = () + + def __new__(cls, *args, **kwargs): + raise RuntimeError("%s should not be instantiated" % cls) + + @staticmethod + def abspath(path, start, library=None): + import os + if path.startswith(b'//'): + # if library: + # start = os.path.dirname(abspath(library.filepath)) + return os.path.join(start, path[2:]) + return path + + if __import__("os").sep == '/': + @staticmethod + def compatpath(path): + return path.replace(b'\\', b'/') + else: + @staticmethod + def compatpath(path): + # keep '//' + return path[:2] + path[2:].replace(b'/', b'\\') + + @staticmethod + def splitpath(path): + """ + Splits the path using either slashes + """ + split1 = path.rpartition(b'/') + split2 = path.rpartition(b'\\') + if len(split1[0]) > len(split2[0]): + return split1 + else: + return split2 + + def find_sequence_paths(filepath, use_fullpath=True): + # supports str, byte paths + basedir, filename = os.path.split(filepath) + if not os.path.exists(basedir): + return [] + + filename_noext, ext = os.path.splitext(filename) + + from string import digits + if isinstance(filepath, bytes): + digits = digits.encode() + filename_nodigits = filename_noext.rstrip(digits) + + if len(filename_nodigits) == len(filename_noext): + # input isn't from a sequence + return [] + + files = os.listdir(basedir) + files[:] = [ + f for f in files + if f.startswith(filename_nodigits) and + f.endswith(ext) and + f[len(filename_nodigits):-len(ext) if ext else -1].isdigit() + ] + if use_fullpath: + files[:] = [ + os.path.join(basedir, f) for f in files + ] + + return files diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/cli.py b/io_blend_utils/blender_bam-unpacked.whl/bam/cli.py new file mode 100644 index 00000000..ef7dfe47 --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/cli.py @@ -0,0 +1,2018 @@ +#!/usr/bin/env python3 + +# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** + +""" +This is the entry point for command line access. +""" + +import os +import sys +import json + +# ------------------ +# Ensure module path +path = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "modules")) +if path not in sys.path: + sys.path.append(path) +del path +# -------- + +import logging +log = logging.getLogger("bam_cli") + + +def fatal(msg): + if __name__ == "__main__": + sys.stderr.write("fatal: ") + sys.stderr.write(msg) + sys.stderr.write("\n") + sys.exit(1) + else: + raise RuntimeError(msg) + + +class bam_config: + # fake module + __slots__ = () + + def __new__(cls, *args, **kwargs): + raise RuntimeError("%s should not be instantiated" % cls) + + CONFIG_DIR = ".bam" + # can infact be any file in the session + SESSION_FILE = ".bam_paths_remap.json" + + @staticmethod + def find_basedir(cwd=None, path_suffix=None, abort=False, test_subpath=CONFIG_DIR, descr="<unknown>"): + """ + Return the config path (or None when not found) + Actually should raise an error? + """ + + if cwd is None: + cwd = os.getcwd() + + parent = (os.path.normpath( + os.path.abspath( + cwd))) + + parent_prev = None + + while parent != parent_prev: + test_dir = os.path.join(parent, test_subpath) + if os.path.exists(test_dir): + if path_suffix is not None: + test_dir = os.path.join(test_dir, path_suffix) + return test_dir + + parent_prev = parent + parent = os.path.dirname(parent) + + if abort is True: + fatal("Not a %s (or any of the parent directories): %s" % (descr, test_subpath)) + + return None + + @staticmethod + def find_rootdir(cwd=None, path_suffix=None, abort=False, test_subpath=CONFIG_DIR, descr="<unknown>"): + """ + find_basedir(), without '.bam' suffix + """ + path = bam_config.find_basedir( + cwd=cwd, + path_suffix=path_suffix, + abort=abort, + test_subpath=test_subpath, + ) + + return path[:-(len(test_subpath) + 1)] + + def find_sessiondir(cwd=None, abort=False): + """ + from: my_project/my_session/some/subdir + to: my_project/my_session + where: my_project/.bam/ (is the basedir) + """ + session_rootdir = bam_config.find_basedir( + cwd=cwd, + test_subpath=bam_config.SESSION_FILE, + abort=abort, + descr="bam session" + ) + + if session_rootdir is not None: + return session_rootdir[:-len(bam_config.SESSION_FILE)] + else: + if abort: + if not os.path.isdir(session_rootdir): + fatal("Expected a directory (%r)" % session_rootdir) + return None + + @staticmethod + def load(id_="config", cwd=None, abort=False): + filepath = bam_config.find_basedir( + cwd=cwd, + path_suffix=id_, + descr="bam repository", + ) + if abort is True: + if filepath is None: + fatal("Not a bam repository (or any of the parent directories): .bam") + + with open(filepath, 'r') as f: + return json.load(f) + + @staticmethod + def write(id_="config", data=None, cwd=None): + filepath = bam_config.find_basedir( + cwd=cwd, + path_suffix=id_, + descr="bam repository", + ) + + from bam.utils.system import write_json_to_file + write_json_to_file(filepath, data) + + @staticmethod + def write_bamignore(cwd=None): + path = bam_config.find_rootdir(cwd=cwd) + if path: + filepath = os.path.join(path, ".bamignore") + with open(filepath, 'w') as f: + f.write(r".*\.blend\d+$") + + @staticmethod + def create_bamignore_filter(id_=".bamignore", cwd=None): + path = bam_config.find_rootdir() + bamignore = os.path.join(path, id_) + if os.path.isfile(bamignore): + with open(bamignore, 'r', encoding='utf-8') as f: + compiled_patterns = [] + + import re + for i, l in enumerate(f): + l = l.rstrip() + if l: + try: + p = re.compile(l) + except re.error as e: + fatal("%s:%d file contains an invalid regular expression, %s" % + (bamignore, i + 1, str(e))) + compiled_patterns.append(p) + + if compiled_patterns: + def filter_ignore(f): + for pattern in filter_ignore.compiled_patterns: + if re.match(pattern, f): + return False + return True + filter_ignore.compiled_patterns = compiled_patterns + + return filter_ignore + + return None + + +class bam_session: + # fake module + __slots__ = () + + def __new__(cls, *args, **kwargs): + raise RuntimeError("%s should not be instantiated" % cls) + + def session_path_to_cache( + path, + cachedir=None, + session_rootdir=None, + paths_remap_relbase=None, + abort=True): + """ + Given an absolute path, give us the cache-path on disk. + """ + + if session_rootdir is None: + session_rootdir = bam_config.find_sessiondir(path, abort=abort) + + if paths_remap_relbase is None: + with open(os.path.join(session_rootdir, ".bam_paths_remap.json")) as fp: + paths_remap = json.load(fp) + paths_remap_relbase = paths_remap.get(".", "") + del fp, paths_remap + + cachedir = os.path.join(bam_config.find_rootdir(cwd=session_rootdir, abort=True), ".cache") + path_rel = os.path.relpath(path, session_rootdir) + if path_rel[0] == "_": + path_cache = os.path.join(cachedir, path_rel[1:]) + else: + path_cache = os.path.join(cachedir, paths_remap_relbase, path_rel) + path_cache = os.path.normpath(path_cache) + return path_cache + + @staticmethod + def request_url(req_path): + cfg = bam_config.load() + result = "%s/%s" % (cfg['url'], req_path) + return result + + @staticmethod + def status(session_rootdir, + paths_uuid_update=None): + + paths_add = {} + paths_remove = {} + paths_modified = {} + + from bam.utils.system import uuid_from_file + + session_rootdir = os.path.abspath(session_rootdir) + + # don't commit metadata + paths_used = { + os.path.join(session_rootdir, ".bam_paths_uuid.json"), + os.path.join(session_rootdir, ".bam_paths_remap.json"), + os.path.join(session_rootdir, ".bam_deps_remap.json"), + os.path.join(session_rootdir, ".bam_paths_edit.data"), + os.path.join(session_rootdir, ".bam_tmp.zip"), + } + + paths_uuid = bam_session.load_paths_uuid(session_rootdir) + + for f_rel, sha1 in paths_uuid.items(): + f_abs = os.path.join(session_rootdir, f_rel) + if os.path.exists(f_abs): + sha1_modified = uuid_from_file(f_abs) + if sha1_modified != sha1: + paths_modified[f_rel] = f_abs + if paths_uuid_update is not None: + paths_uuid_update[f_rel] = sha1_modified + paths_used.add(f_abs) + else: + paths_remove[f_rel] = f_abs + + # ---- + # find new files + def iter_files(path, filename_check=None): + for dirpath, dirnames, filenames in os.walk(path): + + # skip '.svn' + if dirpath.startswith(".") and dirpath != ".": + continue + + for filename in filenames: + filepath = os.path.join(dirpath, filename) + if filename_check is None or filename_check(filepath): + yield filepath + + bamignore_filter = bam_config.create_bamignore_filter() + + for f_abs in iter_files(session_rootdir, bamignore_filter): + if f_abs not in paths_used: + # we should be clever - add the file to a useful location based on some rules + # (category, filetype & tags?) + + f_rel = os.path.relpath(f_abs, session_rootdir) + + paths_add[f_rel] = f_abs + + if paths_uuid_update is not None: + paths_uuid_update[f_rel] = uuid_from_file(f_abs) + + return paths_add, paths_remove, paths_modified + + @staticmethod + def load_paths_uuid(session_rootdir): + with open(os.path.join(session_rootdir, ".bam_paths_uuid.json")) as f: + return json.load(f) + + @staticmethod + def is_dirty(session_rootdir): + paths_add, paths_remove, paths_modified = bam_session.status(session_rootdir) + return any((paths_add, paths_modified, paths_remove)) + + @staticmethod + def binary_edits_apply_single( + blendfile_abs, # str + blendfile, # bytes + binary_edits, + session_rootdir, + paths_uuid_update=None, + ): + + sys.stdout.write(" operating on: %r\n" % blendfile_abs) + sys.stdout.flush() + # we don't want to read, just edit whats there. + with open(blendfile_abs, 'rb+') as fh_blend: + for ofs, data in binary_edits: + # sys.stdout.write("\n%r\n" % data) + sys.stdout.flush() + # ensure we're writing to the correct location. + # fh_blend.seek(ofs) + # sys.stdout.write(repr(b'existing data: ' + fh_blend.read(len(data) + 1))) + fh_blend.seek(ofs) + fh_blend.write(data) + sys.stdout.write("\n") + sys.stdout.flush() + + if paths_uuid_update is not None: + # update hash! + # we could do later, but the file is fresh in cache, so do now + from bam.utils.system import uuid_from_file + f_rel = os.path.relpath(blendfile_abs, session_rootdir) + paths_uuid_update[f_rel] = uuid_from_file(blendfile_abs) + del uuid_from_file + + @staticmethod + def binary_edits_apply_all( + session_rootdir, + # collection of local paths or None (to apply all binary edits) + paths=None, + update_uuid=False, + ): + + # sanity check + if paths is not None: + for path in paths: + assert(type(path) is bytes) + assert(not os.path.isabs(path)) + assert(os.path.exists(os.path.join(session_rootdir, path.decode('utf-8')))) + + with open(os.path.join(session_rootdir, ".bam_paths_remap.json")) as fp: + paths_remap = json.load(fp) + paths_remap_relbase = paths_remap.get(".", "") + paths_remap_reverse = {v: k for k, v in paths_remap.items()} + del paths_remap + + with open(os.path.join(session_rootdir, ".bam_paths_edit.data"), 'rb') as fh: + import pickle + binary_edits_all = pickle.load(fh) + paths_uuid_update = {} if update_uuid else None + for blendfile, binary_edits in binary_edits_all.items(): + if binary_edits: + if paths is not None and blendfile not in paths: + continue + + # get the absolute path as it is in the main repo + # then remap back to our local checkout + blendfile_abs_remote = os.path.normpath(os.path.join(paths_remap_relbase, blendfile.decode('utf-8'))) + blendfile_abs = os.path.join(session_rootdir, paths_remap_reverse[blendfile_abs_remote]) + + bam_session.binary_edits_apply_single( + blendfile_abs, + blendfile, + binary_edits, + session_rootdir, + paths_uuid_update, + ) + del pickle + del binary_edits_all + + if update_uuid and paths_uuid_update: + # freshen the UUID's based on the replayed binary_edits + from bam.utils.system import write_json_to_file + paths_uuid = bam_session.load_paths_uuid(session_rootdir) + paths_uuid.update(paths_uuid_update) + write_json_to_file(os.path.join(session_rootdir, ".bam_paths_uuid.json"), paths_uuid) + del write_json_to_file + del paths_uuid + + @staticmethod + def binary_edits_update_single( + blendfile_abs, + binary_edits, + # callback, takes a filepath + remap_filepath_cb, + ): + """ + After committing a blend file, we need to re-create the binary edits. + """ + from bam.blend import blendfile_path_walker + for fp, (rootdir, fp_blend_basename) in blendfile_path_walker.FilePath.visit_from_blend( + blendfile_abs, + readonly=True, + recursive=False, + ): + f_rel_orig = fp.filepath + f_rel = remap_filepath_cb(f_rel_orig) + fp.filepath_assign_edits(f_rel, binary_edits) + + +class bam_commands: + """ + Sub-commands from the command-line map directly to these methods. + """ + # fake module + __slots__ = () + + def __new__(cls, *args, **kwargs): + raise RuntimeError("%s should not be instantiated" % cls) + + @staticmethod + def init(url, directory_name=None): + import urllib.parse + + if "@" in url: + # first & last :) + username, url = url.rpartition('@')[0::2] + else: + import getpass + username = getpass.getuser() + print("Using username:", username) + del getpass + + parsed_url = urllib.parse.urlsplit(url) + + proj_dirname = os.path.basename(parsed_url.path) + if directory_name: + proj_dirname = directory_name + proj_dirname_abs = os.path.join(os.getcwd(), proj_dirname) + + if os.path.exists(proj_dirname_abs): + fatal("Cannot create project %r already exists" % proj_dirname_abs) + + # Create the project directory inside the current directory + os.mkdir(proj_dirname_abs) + # Create the .bam directory + bam_basedir = os.path.join(proj_dirname_abs, bam_config.CONFIG_DIR) + os.mkdir(bam_basedir) + + # Add a config file with project url, username and password + bam_config.write( + data={ + "url": url, + "user": username, + "password": "", + "config_version": 1 + }, + cwd=proj_dirname_abs) + + # Create the default .bamignore + # TODO (fsiddi) get this data from the project config on the server + bam_config.write_bamignore(cwd=proj_dirname_abs) + + print("Project %r initialized" % proj_dirname) + + @staticmethod + def create(session_name): + rootdir = bam_config.find_rootdir(abort=True) + + session_rootdir = os.path.join(rootdir, session_name) + + if os.path.exists(session_rootdir): + fatal("session path exists %r" % session_rootdir) + if rootdir != bam_config.find_rootdir(cwd=session_rootdir): + fatal("session is located outside %r" % rootdir) + + def write_empty(f, data): + with open(os.path.join(session_rootdir, f), 'wb') as f: + f.write(data) + + os.makedirs(session_rootdir) + + write_empty(".bam_paths_uuid.json", b'{}') + write_empty(".bam_paths_remap.json", b'{}') + write_empty(".bam_deps_remap.json", b'{}') + + print("Session %r created" % session_name) + + @staticmethod + def checkout( + path, + output_dir=None, + session_rootdir_partial=None, + all_deps=False, + ): + + # --------- + # constants + CHUNK_SIZE = 1024 + + cfg = bam_config.load(abort=True) + + if output_dir is None: + # fallback to the basename + session_rootdir = os.path.splitext(os.path.basename(path))[0] + else: + output_dir = os.path.realpath(output_dir) + if os.sep in output_dir.rstrip(os.sep): + # are we a subdirectory? + # (we know this exists, since we have config already) + project_rootdir = bam_config.find_rootdir(abort=True) + if ".." in os.path.relpath(output_dir, project_rootdir).split(os.sep): + fatal("Output %r is outside the project path %r" % (output_dir, project_rootdir)) + del project_rootdir + session_rootdir = output_dir + del output_dir + + if bam_config.find_sessiondir(cwd=session_rootdir): + fatal("Can't checkout in existing session. Use update.") + + payload = { + "filepath": path, + "command": "checkout", + "arguments": json.dumps({ + "all_deps": all_deps, + }), + } + + # -------------------------------------------------------------------- + # First request we simply get a list of files to download + # + import requests + r = requests.get( + bam_session.request_url("file"), + params=payload, + auth=(cfg['user'], cfg['password']), + stream=True, + ) + + if r.status_code not in {200, }: + # TODO(cam), make into reusable function? + print("Error %d:\n%s" % (r.status_code, next(r.iter_content(chunk_size=1024)).decode('utf-8'))) + return + + # TODO(cam) how to tell if we get back a message payload? or real data??? + dst_dir_data = payload['filepath'].split('/')[-1] + + if 1: + dst_dir_data += ".zip" + + with open(dst_dir_data, 'wb') as f: + import struct + ID_MESSAGE = 1 + ID_PAYLOAD = 2 + head = r.raw.read(4) + if head != b'BAM\0': + fatal("bad header from server") + + while True: + msg_type, msg_size = struct.unpack("<II", r.raw.read(8)) + if msg_type == ID_MESSAGE: + sys.stdout.write(r.raw.read(msg_size).decode('utf-8')) + sys.stdout.flush() + elif msg_type == ID_PAYLOAD: + # payload + break + + tot_size = 0 + for chunk in r.iter_content(chunk_size=CHUNK_SIZE): + if chunk: # filter out keep-alive new chunks + tot_size += len(chunk) + f.write(chunk) + f.flush() + + sys.stdout.write("\rdownload: [%03d%%]" % ((100 * tot_size) // msg_size)) + sys.stdout.flush() + del struct + + # --------------- + # extract the zip + import zipfile + with open(dst_dir_data, 'rb') as zip_file: + zip_handle = zipfile.ZipFile(zip_file) + zip_handle.extractall(session_rootdir) + del zipfile, zip_file + + os.remove(dst_dir_data) + sys.stdout.write("\nwritten: %r\n" % session_rootdir) + + # ---- + # Update cache + cachedir = os.path.join(bam_config.find_rootdir(cwd=session_rootdir, abort=True), ".cache") + # os.makedirs(cachedir, exist_ok=True) + + # -------------------------------------------------------------------- + # Second request we simply download the files.. + # + # which we don't have in cache, + # note that its possible we have all in cache and don't need to make a second request. + files = [] + with open(os.path.join(session_rootdir, ".bam_paths_remap.json")) as fp: + from bam.utils.system import uuid_from_file + paths_remap = json.load(fp) + + paths_uuid = bam_session.load_paths_uuid(session_rootdir) + + for f_src, f_dst in paths_remap.items(): + if f_src == ".": + continue + + uuid = paths_uuid.get(f_src) + if uuid is not None: + f_dst_abs = os.path.join(cachedir, f_dst) + if os.path.exists(f_dst_abs): + # check if we need to download this file? + uuid_exists = uuid_from_file(f_dst_abs) + assert(type(uuid) is type(uuid_exists)) + if uuid == uuid_exists: + continue + + files.append(f_dst) + + del uuid_from_file + + if files: + payload = { + "command": "checkout_download", + "arguments": json.dumps({ + "files": files, + }), + } + import requests + r = requests.get( + bam_session.request_url("file"), + params=payload, + auth=(cfg['user'], cfg['password']), + stream=True, + ) + + if r.status_code not in {200, }: + # TODO(cam), make into reusable function? + print("Error %d:\n%s" % (r.status_code, next(r.iter_content(chunk_size=1024)).decode('utf-8'))) + return + + # TODO(cam) how to tell if we get back a message payload? or real data??? + # needed so we don't read past buffer bounds + def iter_content_size(r, size, chunk_size=CHUNK_SIZE): + while size >= chunk_size: + size -= chunk_size + yield r.raw.read(chunk_size) + if size: + yield r.raw.read(size) + + + import struct + ID_MESSAGE = 1 + ID_PAYLOAD = 2 + ID_PAYLOAD_APPEND = 3 + ID_PAYLOAD_EMPTY = 4 + ID_DONE = 5 + head = r.raw.read(4) + if head != b'BAM\0': + fatal("bad header from server") + + file_index = 0 + is_header_read = True + while True: + if is_header_read: + msg_type, msg_size = struct.unpack("<II", r.raw.read(8)) + else: + is_header_read = True + + if msg_type == ID_MESSAGE: + sys.stdout.write(r.raw.read(msg_size).decode('utf-8')) + sys.stdout.flush() + elif msg_type == ID_PAYLOAD_EMPTY: + file_index += 1 + elif msg_type == ID_PAYLOAD: + f_rel = files[file_index] + f_abs = os.path.join(cachedir, files[file_index]) + file_index += 1 + + # server also prints... we could do this a bit different... + sys.stdout.write("file: %r" % f_rel) + sys.stdout.flush() + + os.makedirs(os.path.dirname(f_abs), exist_ok=True) + + with open(f_abs, "wb") as f: + while True: + tot_size = 0 + # No need to worry about filling memory, + # total chunk size is capped by the server + chunks = [] + # for chunk in r.iter_content(chunk_size=CHUNK_SIZE): + for chunk in iter_content_size(r, msg_size, chunk_size=CHUNK_SIZE): + if chunk: # filter out keep-alive new chunks + tot_size += len(chunk) + # f.write(chunk) + # f.flush() + chunks.append(chunk) + + sys.stdout.write("\rdownload: [%03d%%]" % ((100 * tot_size) // msg_size)) + sys.stdout.flush() + assert(tot_size == msg_size) + + # decompress all chunks + import lzma + f.write(lzma.decompress(b''.join(chunks))) + f.flush() + del chunks + + # take care! - re-reading the next header to see if + # we're appending to this file or not + msg_type, msg_size = struct.unpack("<II", r.raw.read(8)) + if msg_type == ID_PAYLOAD_APPEND: + continue + # otherwise continue the outer loop, without re-reading the header + + # don't re-read the header next iteration + is_header_read = False + break + + elif msg_type == ID_DONE: + break + elif msg_type == ID_PAYLOAD_APPEND: + # Should only handle in a read-loop above + raise Exception("Invalid state for message-type %d" % msg_type) + else: + raise Exception("Unknown message-type %d" % msg_type) + del struct + + + del files + + # ------------ + # Update Cache + # + # TODO, remove stale cache + # we need this to map to project level paths + # + # Copy cache into our session before applying binary edits. + with open(os.path.join(session_rootdir, ".bam_paths_remap.json")) as fp: + paths_remap = json.load(fp) + for f_dst, f_src in paths_remap.items(): + if f_dst == ".": + continue + + f_src_abs = os.path.join(cachedir, f_src) + + # this should 'almost' always be true + if os.path.exists(f_src_abs): + + f_dst_abs = os.path.join(session_rootdir, f_dst) + os.makedirs(os.path.dirname(f_dst_abs), exist_ok=True) + + import shutil + # print("from ", f_dst_abs, os.path.exists(f_dst_abs)) + # print("to ", f_src_abs, os.path.exists(f_src_abs)) + # print("CREATING: ", f_src_abs) + shutil.copyfile(f_src_abs, f_dst_abs) + del shutil + # import time + # time.sleep(10000) + + del paths_remap, cachedir + # ...done updating cache + # ---------------------- + + # ------------------- + # replay binary edits + # + # We've downloaded the files pristine from their repo. + # This means we can use local cache and avoid re-downloading. + # + # But for files to work locally we have to apply binary edits given to us by the server. + + sys.stdout.write("replaying edits...\n") + bam_session.binary_edits_apply_all(session_rootdir, paths=None, update_uuid=True) + + # ...done with binary edits + # ------------------------- + + @staticmethod + def update(paths): + # Load project configuration + # cfg = bam_config.load(abort=True) + + # TODO(cam) multiple paths + session_rootdir = bam_config.find_sessiondir(paths[0], abort=True) + # so as to avoid off-by-one errors string mangling + session_rootdir = session_rootdir.rstrip(os.sep) + + paths_uuid = bam_session.load_paths_uuid(session_rootdir) + + if not paths_uuid: + print("Nothing to update!") + return + + if bam_session.is_dirty(session_rootdir): + fatal("Local changes detected, commit before checking out!") + + # ------------------------------------------------------------------------------- + # TODO(cam) don't guess this important info + files = [f for f in os.listdir(session_rootdir) if not f.startswith(".")] + files_blend = [f for f in files if f.endswith(".blend")] + if files_blend: + f = files_blend[0] + else: + f = files[0] + with open(os.path.join(session_rootdir, ".bam_paths_remap.json")) as fp: + paths_remap = json.load(fp) + paths_remap_relbase = paths_remap.get(".", "") + path = os.path.join(paths_remap_relbase, f) + # ------------------------------------------------------------------------------- + + # merge sessions + session_tmp = session_rootdir + ".tmp" + bam_commands.checkout( + path, + output_dir=session_tmp, + session_rootdir_partial=session_rootdir, + ) + + for dirpath, dirnames, filenames in os.walk(session_tmp): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + f_src = filepath + f_dst = session_rootdir + filepath[len(session_tmp):] + os.rename(f_src, f_dst) + import shutil + shutil.rmtree(session_tmp) + + @staticmethod + def revert(paths): + # Copy files back from the cache + # a relatively lightweight operation + + def _get_from_path(session_rootdir, cachedir, paths_remap, path_abs): + print("====================") + print(path_abs) + path_abs = os.path.normpath(path_abs) + print(paths_remap) + for f_src, f_dst in paths_remap.items(): + if f_src == ".": + continue + print("-----------------") + f_src_abs = os.path.join(session_rootdir, f_src) + #if os.path.samefile(f_src_abs, path_abs): + print(f_src_abs) + print(f_src) + print(f_dst) + if f_src_abs == path_abs: + f_dst_abs = os.path.join(cachedir, f_dst) + return f_src, f_src_abs, f_dst_abs + return None, None, None + + # 2 passes, once to check, another to execute + for pass_ in range(2): + for path in paths: + path = os.path.normpath(os.path.abspath(path)) + if os.path.isdir(path): + fatal("Reverting a directory not yet supported (%r)" % path) + + # possible we try revert different session's files + session_rootdir = bam_config.find_sessiondir(path, abort=True) + cachedir = os.path.join(bam_config.find_rootdir(cwd=session_rootdir, abort=True), ".cache") + if not os.path.exists(cachedir): + fatal("Local cache missing (%r)" % + cachedir) + + path_rel = os.path.relpath(path, session_rootdir) + + with open(os.path.join(session_rootdir, ".bam_paths_uuid.json")) as fp: + paths_uuid = json.load(fp) + if paths_uuid.get(path_rel) is None: + fatal("Given path isn't in the session, skipping (%s)" % + path_abs) + + # first pass is sanity check only + if pass_ == 0: + continue + + with open(os.path.join(session_rootdir, ".bam_paths_remap.json")) as fp: + paths_remap = json.load(fp) + paths_remap_relbase = paths_remap.get(".", "") + del fp, paths_remap + + path_cache = bam_session.session_path_to_cache( + path, + cachedir=cachedir, + session_rootdir=session_rootdir, + paths_remap_relbase=paths_remap_relbase, + ) + + if not os.path.exists(path_cache): + fatal("Given path missing cache disk (%s)" % + path_cache) + + if pass_ == 1: + # for real + print(" Reverting %r" % path) + os.makedirs(os.path.dirname(path), exist_ok=True) + import shutil + shutil.copyfile(path_cache, path) + + bam_session.binary_edits_apply_all( + session_rootdir, + paths={path_rel.encode('utf-8')}, + update_uuid=False, + ) + + @staticmethod + def commit(paths, message): + from bam.utils.system import write_json_to_file, write_json_to_zip + import requests + + # Load project configuration + cfg = bam_config.load(abort=True) + + session_rootdir = bam_config.find_sessiondir(paths[0], abort=True) + + cachedir = os.path.join(bam_config.find_rootdir(cwd=session_rootdir, abort=True), ".cache") + basedir = bam_config.find_basedir( + cwd=session_rootdir, + descr="bam repository", + ) + basedir_temp = os.path.join(basedir, "tmp") + + if os.path.isdir(basedir_temp): + fatal("Path found, " + "another commit in progress, or remove with path! (%r)" % + basedir_temp) + + if not os.path.exists(os.path.join(session_rootdir, ".bam_paths_uuid.json")): + fatal("Path not a project session, (%r)" % + session_rootdir) + + + # make a zipfile from session + paths_uuid = bam_session.load_paths_uuid(session_rootdir) + + # No longer used + """ + with open(os.path.join(session_rootdir, ".bam_deps_remap.json")) as f: + deps_remap = json.load(f) + """ + + paths_uuid_update = {} + + paths_add, paths_remove, paths_modified = bam_session.status(session_rootdir, paths_uuid_update) + + if not any((paths_add, paths_modified, paths_remove)): + print("Nothing to commit!") + return + + # we need to update paths_remap as we go + with open(os.path.join(session_rootdir, ".bam_paths_remap.json")) as f: + paths_remap = json.load(f) + paths_remap_relbase = paths_remap.get(".", "") + paths_remap_relbase_bytes = paths_remap_relbase.encode("utf-8") + + def remap_filepath_bytes(f_rel): + assert(type(f_rel) is bytes) + f_rel_in_proj = paths_remap.get(f_rel.decode("utf-8")) + if f_rel_in_proj is None: + if paths_remap_relbase_bytes: + if f_rel.startswith(b'_'): + f_rel_in_proj = f_rel[1:] + else: + f_rel_in_proj = os.path.join(paths_remap_relbase_bytes, f_rel) + else: + if f_rel.startswith(b'_'): + # we're already project relative + f_rel_in_proj = f_rel[1:] + else: + f_rel_in_proj = f_rel + else: + f_rel_in_proj = f_rel_in_proj.encode("utf-8") + return f_rel_in_proj + + def remap_filepath(f_rel): + assert(type(f_rel) is str) + f_rel_in_proj = paths_remap.get(f_rel) + if f_rel_in_proj is None: + if paths_remap_relbase: + if f_rel.startswith("_"): + f_rel_in_proj = f_rel[1:] + else: + f_rel_in_proj = os.path.join(paths_remap_relbase, f_rel) + else: + if f_rel.startswith("_"): + # we're already project relative + f_rel_in_proj = f_rel[1:] + else: + f_rel_in_proj = f_rel + + return f_rel_in_proj + + def remap_cb(f, data): + # check for the absolute path hint + if f.startswith(b'//_'): + proj_base_b = data + return b'//' + os.path.relpath(f[3:], proj_base_b) + return None + + def remap_file(f_rel, f_abs): + f_abs_remap = os.path.join(basedir_temp, f_rel) + dir_remap = os.path.dirname(f_abs_remap) + os.makedirs(dir_remap, exist_ok=True) + + # final location in the project + f_rel_in_proj = remap_filepath(f_rel) + proj_base_b = os.path.dirname(f_rel_in_proj).encode("utf-8") + + from bam.blend import blendfile_pack_restore + blendfile_pack_restore.blendfile_remap( + f_abs.encode('utf-8'), + dir_remap.encode('utf-8'), + deps_remap_cb=remap_cb, + deps_remap_cb_userdata=proj_base_b, + ) + return f_abs_remap + + for f_rel, f_abs in list(paths_modified.items()): + if f_abs.endswith(".blend"): + f_abs_remap = remap_file(f_rel, f_abs) + if os.path.exists(f_abs_remap): + paths_modified[f_rel] = f_abs_remap + + for f_rel, f_abs in list(paths_add.items()): + if f_abs.endswith(".blend"): + f_abs_remap = remap_file(f_rel, f_abs) + if os.path.exists(f_abs_remap): + paths_add[f_rel] = f_abs_remap + + """ + deps = deps_remap.get(f_rel) + if deps: + # ---- + # remap! + f_abs_remap = os.path.join(basedir_temp, f_rel) + dir_remap = os.path.dirname(f_abs_remap) + os.makedirs(dir_remap, exist_ok=True) + import blendfile_pack_restore + blendfile_pack_restore.blendfile_remap( + f_abs.encode('utf-8'), + dir_remap.encode('utf-8'), + deps, + ) + if os.path.exists(f_abs_remap): + f_abs = f_abs_remap + paths_modified[f_rel] = f_abs + """ + + # ------------------------- + print("Now make a zipfile") + import zipfile + temp_zip = os.path.join(session_rootdir, ".bam_tmp.zip") + with zipfile.ZipFile(temp_zip, 'w', zipfile.ZIP_DEFLATED) as zip_handle: + for paths_dict, op in ((paths_modified, 'M'), (paths_add, 'A')): + for (f_rel, f_abs) in paths_dict.items(): + print(" packing (%s): %r" % (op, f_abs)) + zip_handle.write(f_abs, arcname=f_rel) + + # make a paths remap that only includes modified files + # TODO(cam), from 'packer.py' + + paths_remap_subset = { + f_rel: f_rel_in_proj + for f_rel, f_rel_in_proj in paths_remap.items() if f_rel in paths_modified} + paths_remap_subset.update({ + f_rel: remap_filepath(f_rel) + for f_rel in paths_add}) + + # paths_remap_subset.update(paths_remap_subset_add) + write_json_to_zip(zip_handle, ".bam_paths_remap.json", paths_remap_subset) + + # build a list of path manipulation operations + paths_ops = {} + # paths_remove ... + for f_rel, f_abs in paths_remove.items(): + # TODO + f_abs_remote = paths_remap[f_rel] + paths_ops[f_abs_remote] = 'D' + + write_json_to_zip(zip_handle, ".bam_paths_ops.json", paths_ops) + log.debug(paths_ops) + + + # -------------- + # Commit Request + payload = { + "command": "commit", + "arguments": json.dumps({ + 'message': message, + }), + } + files = { + "file": open(temp_zip, 'rb'), + } + + with files["file"]: + r = requests.put( + bam_session.request_url("file"), + params=payload, + auth=(cfg["user"], cfg["password"]), + files=files) + + os.remove(temp_zip) + + try: + r_json = r.json() + print(r_json.get("message", "<empty>")) + except Exception: + print(r.text) + + # TODO, handle error cases + ok = True + if ok: + + # ---------- + # paths_uuid + paths_uuid.update(paths_uuid_update) + write_json_to_file(os.path.join(session_rootdir, ".bam_paths_uuid.json"), paths_uuid_update) + + # ----------- + # paths_remap + paths_remap.update(paths_remap_subset) + for k in paths_remove: + del paths_remap[k] + write_json_to_file(os.path.join(session_rootdir, ".bam_paths_remap.json"), paths_remap) + del write_json_to_file + + # ------------------ + # Update Local Cache + # + # We now have 'pristine' files in basedir_temp, the commit went fine. + # So move these into local cache AND we have to remake the binary_edit data. + # since files were modified, if we don't do this - we wont be able to revert or avoid + # re-downloading the files later. + binary_edits_all_update = {} + binary_edits_all_remove = set() + for paths_dict, op in ((paths_modified, 'M'), (paths_add, 'A')): + for f_rel, f_abs in paths_dict.items(): + print(" caching (%s): %r" % (op, f_abs)) + f_dst_abs = os.path.join(cachedir, f_rel) + os.makedirs(os.path.dirname(f_dst_abs), exist_ok=True) + if f_abs.startswith(basedir_temp): + os.rename(f_abs, f_dst_abs) + else: + import shutil + shutil.copyfile(f_abs, f_dst_abs) + del shutil + binary_edits = binary_edits_all_update[f_rel.encode('utf-8')] = [] + + # update binary_edits + if f_rel.endswith(".blend"): + bam_session.binary_edits_update_single( + f_dst_abs, + binary_edits, + remap_filepath_cb=remap_filepath_bytes, + ) + for f_rel, f_abs in paths_remove.items(): + binary_edits_all_remove.add(f_rel) + + paths_edit_abs = os.path.join(session_rootdir, ".bam_paths_edit.data") + if binary_edits_all_update or binary_edits_all_remove: + if os.path.exists(paths_edit_abs): + with open(paths_edit_abs, 'rb') as fh: + import pickle + binary_edits_all = pickle.load(fh) + del pickle + else: + binary_edits_all = {} + + if binary_edits_all_remove and binary_edits_all: + for f_rel in binary_edits_all_remove: + if f_rel in binary_edits_all: + try: + del binary_edits_all[f_rel] + except KeyError: + pass + if binary_edits_all_update: + binary_edits_all.update(binary_edits_all_update) + + import pickle + with open(paths_edit_abs, 'wb') as fh: + print() + pickle.dump(binary_edits_all, fh, pickle.HIGHEST_PROTOCOL) + del binary_edits_all + del paths_edit_abs + del pickle + + # ------------------------------ + # Cleanup temp dir to finish off + if os.path.exists(basedir_temp): + import shutil + shutil.rmtree(basedir_temp) + del shutil + + @staticmethod + def status(paths, use_json=False): + # TODO(cam) multiple paths + path = paths[0] + del paths + + session_rootdir = bam_config.find_sessiondir(path, abort=True) + paths_add, paths_remove, paths_modified = bam_session.status(session_rootdir) + + if not use_json: + for f in sorted(paths_add): + print(" A: %s" % f) + for f in sorted(paths_modified): + print(" M: %s" % f) + for f in sorted(paths_remove): + print(" D: %s" % f) + else: + ret = [] + for f in sorted(paths_add): + ret.append(("A", f)) + for f in sorted(paths_modified): + ret.append(("M", f)) + for f in sorted(paths_remove): + ret.append(("D", f)) + + print(json.dumps(ret)) + + @staticmethod + def list_dir(paths, use_full=False, use_json=False): + import requests + + # Load project configuration + cfg = bam_config.load(abort=True) + + # TODO(cam) multiple paths + path = paths[0] + del paths + + payload = { + "path": path, + } + r = requests.get( + bam_session.request_url("file_list"), + params=payload, + auth=(cfg['user'], cfg['password']), + stream=True, + ) + + r_json = r.json() + items = r_json.get("items_list") + if items is None: + fatal(r_json.get("message", "<empty>")) + + items.sort() + + if use_json: + ret = [] + for (name_short, name_full, file_type) in items: + ret.append((name_short, file_type)) + + print(json.dumps(ret)) + else: + def strip_dot_slash(f): + return f[2:] if f.startswith("./") else f + + for (name_short, name_full, file_type) in items: + if file_type == "dir": + print(" %s/" % (strip_dot_slash(name_full) if use_full else name_short)) + for (name_short, name_full, file_type) in items: + if file_type != "dir": + print(" %s" % (strip_dot_slash(name_full) if use_full else name_short)) + + @staticmethod + def deps(paths, recursive=False, use_json=False): + + def deps_path_walker(): + from bam.blend import blendfile_path_walker + for blendfile_src in paths: + blendfile_src = blendfile_src.encode('utf-8') + yield from blendfile_path_walker.FilePath.visit_from_blend( + blendfile_src, + readonly=True, + recursive=recursive, + ) + + def status_walker(): + for fp, (rootdir, fp_blend_basename) in deps_path_walker(): + f_rel = fp.filepath + f_abs = fp.filepath_absolute + + yield ( + # blendfile-src + os.path.join(fp.basedir, fp_blend_basename).decode('utf-8'), + # fillepath-dst + f_rel.decode('utf-8'), + f_abs.decode('utf-8'), + # filepath-status + "OK" if os.path.exists(f_abs) else "MISSING FILE", + ) + + if use_json: + is_first = True + # print in parts, so we don't block the output + print("[") + for f_src, f_dst, f_dst_abs, f_status in status_walker(): + if is_first: + is_first = False + else: + print(",") + + print(json.dumps((f_src, f_dst, f_dst_abs, f_status)), end="") + print("]") + else: + for f_src, f_dst, f_dst_abs, f_status in status_walker(): + print(" %r -> (%r = %r) %s" % (f_src, f_dst, f_dst_abs, f_status)) + + @staticmethod + def pack( + paths, + output, + mode, + repository_base_path=None, + all_deps=False, + use_quiet=False, + warn_remap_externals=False, + compress_level=-1, + filename_filter=None, + ): + # Local packing (don't use any project/session stuff) + from .blend import blendfile_pack + + # TODO(cam) multiple paths + path = paths[0] + del paths + + if output is None: + fatal("Output path must be given when packing with: --mode=FILE") + + if os.path.isdir(output): + if mode == "ZIP": + output = os.path.join(output, os.path.splitext(path)[0] + ".zip") + else: # FILE + output = os.path.join(output, os.path.basename(path)) + + if use_quiet: + report = lambda msg: None + else: + report = lambda msg: print(msg, end="") + + if repository_base_path is not None: + repository_base_path = repository_base_path.encode('utf-8') + + # replace var with a pattern matching callback + filename_filter_cb = blendfile_pack.exclusion_filter(filename_filter) + + for msg in blendfile_pack.pack( + path.encode('utf-8'), + output.encode('utf-8'), + mode=mode, + all_deps=all_deps, + repository_base_path=repository_base_path, + compress_level=compress_level, + report=report, + warn_remap_externals=warn_remap_externals, + use_variations=True, + filename_filter=filename_filter_cb, + ): + pass + + @staticmethod + def copy( + paths, + output, + base, + all_deps=False, + use_quiet=False, + filename_filter=None, + ): + # Local packing (don't use any project/session stuff) + from .blend import blendfile_copy + from bam.utils.system import is_subdir + + paths = [os.path.abspath(path) for path in paths] + base = os.path.abspath(base) + output = os.path.abspath(output) + + # check all blends are in the base path + for path in paths: + if not is_subdir(path, base): + fatal("Input blend file %r is not a sub directory of %r" % (path, base)) + + if use_quiet: + report = lambda msg: None + else: + report = lambda msg: print(msg, end="") + + # replace var with a pattern matching callback + if filename_filter: + # convert string into regex callback + # "*.txt;*.png;*.rst" --> r".*\.txt$|.*\.png$|.*\.rst$" + import re + import fnmatch + + compiled_pattern = re.compile( + b'|'.join(fnmatch.translate(f).encode('utf-8') + for f in filename_filter.split(";") if f), + re.IGNORECASE, + ) + + def filename_filter(f): + return (not filename_filter.compiled_pattern.match(f)) + filename_filter.compiled_pattern = compiled_pattern + + del compiled_pattern + del re, fnmatch + + for msg in blendfile_copy.copy_paths( + [path.encode('utf-8') for path in paths], + output.encode('utf-8'), + base.encode('utf-8'), + all_deps=all_deps, + report=report, + filename_filter=filename_filter, + ): + pass + + @staticmethod + def remap_start( + paths, + use_json=False, + ): + filepath_remap = "bam_remap.data" + + for p in paths: + if not os.path.exists(p): + fatal("Path %r not found!" % p) + paths = [p.encode('utf-8') for p in paths] + + if os.path.exists(filepath_remap): + fatal("Remap in progress, run with 'finish' or remove %r" % filepath_remap) + + from bam.blend import blendfile_path_remap + remap_data = blendfile_path_remap.start( + paths, + use_json=use_json, + ) + + with open(filepath_remap, 'wb') as fh: + import pickle + pickle.dump(remap_data, fh, pickle.HIGHEST_PROTOCOL) + del pickle + + @staticmethod + def remap_finish( + paths, + force_relative=False, + dry_run=False, + use_json=False, + ): + filepath_remap = "bam_remap.data" + + for p in paths: + if not os.path.exists(p): + fatal("Path %r not found!" % p) + # bytes needed for blendfile_path_remap API + paths = [p.encode('utf-8') for p in paths] + + if not os.path.exists(filepath_remap): + fatal("Remap not started, run with 'start', (%r not found)" % filepath_remap) + + with open(filepath_remap, 'rb') as fh: + import pickle + remap_data = pickle.load(fh) + del pickle + + from bam.blend import blendfile_path_remap + blendfile_path_remap.finish( + paths, remap_data, + force_relative=force_relative, + dry_run=dry_run, + use_json=use_json, + ) + + if not dry_run: + os.remove(filepath_remap) + + @staticmethod + def remap_reset( + use_json=False, + ): + filepath_remap = "bam_remap.data" + if os.path.exists(filepath_remap): + os.remove(filepath_remap) + else: + fatal("remapping not started, nothing to do!") + + +# ----------------------------------------------------------------------------- +# Argument Parser + +def init_argparse_common( + subparse, + use_json=False, + use_all_deps=False, + use_quiet=False, + use_compress_level=False, + use_exclude=False, + ): + import argparse + + if use_json: + subparse.add_argument( + "-j", "--json", dest="json", action='store_true', + help="Generate JSON output", + ) + if use_all_deps: + subparse.add_argument( + "-a", "--all-deps", dest="all_deps", action='store_true', + help="Follow all dependencies (unused indirect dependencies too)", + ) + if use_quiet: + subparse.add_argument( + "-q", "--quiet", dest="use_quiet", action='store_true', + help="Suppress status output", + ) + if use_compress_level: + class ChoiceToZlibLevel(argparse.Action): + def __call__(self, parser, namespace, value, option_string=None): + setattr(namespace, self.dest, {"default": -1, "fast": 1, "best": 9, "store": 0}[value[0]]) + + subparse.add_argument( + "-c", "--compress", dest="compress_level", nargs=1, default=-1, metavar='LEVEL', + action=ChoiceToZlibLevel, + choices=('default', 'fast', 'best', 'store'), + help="Compression level for resulting archive", + ) + if use_exclude: + subparse.add_argument( + "-e", "--exclude", dest="exclude", metavar='PATTERN(S)', required=False, + default="", + help=""" + Optionally exclude files from the pack. + + Using Unix shell-style wildcards *(case insensitive)*. + ``--exclude="*.png"`` + + Multiple patterns can be passed using the ``;`` separator. + ``--exclude="*.txt;*.avi;*.wav"`` + """ + ) + + +def create_argparse_init(subparsers): + subparse = subparsers.add_parser("init", + help="Initialize a new project directory") + subparse.add_argument( + dest="url", + help="Project repository url", + ) + subparse.add_argument( + dest="directory_name", nargs="?", + help="Directory name", + ) + subparse.set_defaults( + func=lambda args: + bam_commands.init(args.url, args.directory_name), + ) + + +def create_argparse_create(subparsers): + subparse = subparsers.add_parser( + "create", aliases=("cr",), + help="Create a new empty session directory", + ) + subparse.add_argument( + dest="session_name", nargs=1, + help="Name of session directory", + ) + subparse.set_defaults( + func=lambda args: + bam_commands.create(args.session_name[0]), + ) + + +def create_argparse_checkout(subparsers): + subparse = subparsers.add_parser( + "checkout", aliases=("co",), + help="Checkout a remote path in an existing project", + ) + subparse.add_argument( + dest="path", type=str, metavar='REMOTE_PATH', + help="Path to checkout on the server", + ) + subparse.add_argument( + "-o", "--output", dest="output", type=str, metavar='DIRNAME', + help="Local name to checkout the session into (optional, falls back to path name)", + ) + + init_argparse_common(subparse, use_all_deps=True) + + subparse.set_defaults( + func=lambda args: + bam_commands.checkout(args.path, args.output, args.all_deps), + ) + + +def create_argparse_update(subparsers): + subparse = subparsers.add_parser( + "update", aliases=("up",), + help="Update a local session with changes from the remote project", + ) + subparse.add_argument( + dest="paths", nargs="*", + help="Path(s) to operate on", + ) + subparse.set_defaults( + func=lambda args: + bam_commands.update(args.paths or ["."]), + ) + + +def create_argparse_revert(subparsers): + subparse = subparsers.add_parser( + "revert", aliases=("rv",), + help="Reset local changes back to the state at time of checkout", + ) + subparse.add_argument( + dest="paths", nargs="+", + help="Path(s) to operate on", + ) + subparse.set_defaults( + func=lambda args: + bam_commands.revert(args.paths or ["."]), + ) + + +def create_argparse_commit(subparsers): + subparse = subparsers.add_parser( + "commit", aliases=("ci",), + help="Commit changes from a session to the remote project", + ) + subparse.add_argument( + "-m", "--message", dest="message", metavar='MESSAGE', + required=True, + help="Commit message", + ) + subparse.add_argument( + dest="paths", nargs="*", + help="paths to commit", + ) + subparse.set_defaults( + func=lambda args: + bam_commands.commit(args.paths or ["."], args.message), + ) + + +def create_argparse_status(subparsers): + subparse = subparsers.add_parser( + "status", aliases=("st",), + help="Show any edits made in the local session", + ) + subparse.add_argument( + dest="paths", nargs="*", + help="Path(s) to operate on", + ) + + init_argparse_common(subparse, use_json=True) + + subparse.set_defaults( + func=lambda args: + bam_commands.status(args.paths or ["."], use_json=args.json), + ) + + +def create_argparse_list(subparsers): + subparse = subparsers.add_parser( + "list", aliases=("ls",), + help="List the contents of a remote directory", + ) + subparse.add_argument( + dest="paths", nargs="*", + help="Path(s) to operate on", + ) + subparse.add_argument( + "-f", "--full", dest="full", action='store_true', + help="Show the full paths", + ) + + init_argparse_common(subparse, use_json=True) + + subparse.set_defaults( + func=lambda args: + bam_commands.list_dir( + args.paths or ["."], + use_full=args.full, + use_json=args.json, + ), + ) + + +def create_argparse_deps(subparsers): + subparse = subparsers.add_parser( + "deps", aliases=("dp",), + help="List dependencies for file(s)", + ) + subparse.add_argument( + dest="paths", nargs="+", + help="Path(s) to operate on", + ) + subparse.add_argument( + "-r", "--recursive", dest="recursive", action='store_true', + help="Scan dependencies recursively", + ) + + init_argparse_common(subparse, use_json=True) + + subparse.set_defaults( + func=lambda args: + bam_commands.deps( + args.paths, args.recursive, + use_json=args.json), + ) + + +def create_argparse_pack(subparsers): + import argparse + subparse = subparsers.add_parser( + "pack", aliases=("pk",), + help="Pack a blend file and its dependencies into an archive", + description= + """ + You can simply pack a blend file like this to create a zip-file of the same name. + + .. code-block:: sh + + bam pack /path/to/scene.blend + + You may also want to give an explicit output directory. + + This command is used for packing a ``.blend`` file into a ``.zip`` file for redistribution. + + .. code-block:: sh + + # pack a blend with maximum compression for online downloads + bam pack /path/to/scene.blend --output my_scene.zip --compress=best + + You may also pack a .blend while keeping your whole repository hierarchy by passing + the path to the top directory of the repository, and ask to be warned about dependencies paths + outside of that base path: + + .. code-block:: sh + + bam pack --repo="/path/to/repo" --warn-external /path/to/repo/path/to/scene.blend + + """, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + subparse.add_argument( + dest="paths", nargs="+", + help="Path(s) to operate on", + ) + subparse.add_argument( + "-o", "--output", dest="output", metavar='FILE', required=False, + help="Output file or a directory when multiple inputs are passed", + ) + subparse.add_argument( + "-m", "--mode", dest="mode", metavar='MODE', required=False, + default='ZIP', + choices=('ZIP', 'FILE'), + help="Output file or a directory when multiple inputs are passed", + ) + subparse.add_argument( + "--repo", dest="repository_base_path", metavar='DIR', required=False, + help="Base directory from which you want to keep existing hierarchy (usually to repository directory)," + "will default to packed blend file's directory if not specified", + ) + subparse.add_argument( + "--warn-external", dest="warn_remap_externals", action='store_true', + help="Warn for every dependency outside of given repository base path", + ) + + init_argparse_common(subparse, use_all_deps=True, use_quiet=True, use_compress_level=True, use_exclude=True) + + subparse.set_defaults( + func=lambda args: + bam_commands.pack( + args.paths, + args.output or + ((os.path.splitext(args.paths[0])[0] + ".zip") + if args.mode == 'ZIP' else None), + args.mode, + repository_base_path=args.repository_base_path or None, + all_deps=args.all_deps, + use_quiet=args.use_quiet, + warn_remap_externals=args.warn_remap_externals, + compress_level=args.compress_level, + filename_filter=args.exclude, + ), + ) + + +def create_argparse_copy(subparsers): + import argparse + subparse = subparsers.add_parser( + "copy", aliases=("cp",), + help="Copy blend file(s) and their dependencies to a new location (maintaining the directory structure).", + description= + """ + The line below will copy ``scene.blend`` to ``/destination/to/scene.blend``. + + .. code-block:: sh + + bam copy /path/to/scene.blend --base=/path --output=/destination + + .. code-block:: sh + + # you can also copy multiple files + bam copy /path/to/scene.blend /path/other/file.blend --base=/path --output /other/destination + """, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + subparse.add_argument( + dest="paths", nargs="+", + help="Path(s) to blend files to operate on", + ) + subparse.add_argument( + "-o", "--output", dest="output", metavar='DIR', required=True, + help="Output directory where where files will be copied to", + ) + subparse.add_argument( + "-b", "--base", dest="base", metavar='DIR', required=True, + help="Base directory for input paths (files outside this path will be omitted)", + ) + + init_argparse_common(subparse, use_all_deps=True, use_quiet=True, use_exclude=True) + + subparse.set_defaults( + func=lambda args: + bam_commands.copy( + args.paths, + args.output, + args.base, + all_deps=args.all_deps, + use_quiet=args.use_quiet, + filename_filter=args.exclude, + ), + ) + + +def create_argparse_remap(subparsers): + import argparse + + subparse = subparsers.add_parser( + "remap", + help="Remap blend file paths", + description= + """ + This command is a 3 step process: + + - first run ``bam remap start .`` which stores the current state of your project (recursively). + - then re-arrange the files on the filesystem (rename, relocate). + - finally run ``bam remap finish`` to apply the changes, updating the ``.blend`` files internal paths. + + + .. code-block:: sh + + cd /my/project + + bam remap start . + mv photos textures + mv house_v14_library.blend house_libraray.blend + bam remap finish + + .. note:: + + Remapping creates a file called ``bam_remap.data`` in the current directory. + You can relocate the entire project to a new location but on executing ``finish``, + this file must be accessible from the current directory. + + .. note:: + + This command depends on files unique contents, + take care not to modify the files once remap is started. + """, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + + subparse_remap_commands = subparse.add_subparsers( + title="Remap commands", + description='valid subcommands', + help='additional help', + ) + sub_subparse = subparse_remap_commands.add_parser( + "start", + help="Start remapping the blend files", + ) + + sub_subparse.add_argument( + dest="paths", nargs="*", + help="Path(s) to operate on", + ) + init_argparse_common(sub_subparse, use_json=True) + + sub_subparse.set_defaults( + func=lambda args: + bam_commands.remap_start( + args.paths or ["."], + use_json=args.json, + ), + ) + + sub_subparse = subparse_remap_commands.add_parser( + "finish", + help="Finish remapping the blend files", + ) + sub_subparse.add_argument( + dest="paths", nargs="*", + help="Path(s) to operate on", + ) + sub_subparse.add_argument( + "-r", "--force-relative", dest="force_relative", action='store_true', + help="Make all remapped paths relative (even if they were originally absolute)", + ) + sub_subparse.add_argument( + "-d", "--dry-run", dest="dry_run", action='store_true', + help="Just print output as if the paths are being run", + ) + init_argparse_common(sub_subparse, use_json=True) + + sub_subparse.set_defaults( + func=lambda args: + bam_commands.remap_finish( + args.paths or ["."], + force_relative=args.force_relative, + dry_run=args.dry_run, + use_json=args.json, + ), + ) + + sub_subparse = subparse_remap_commands.add_parser( + "reset", + help="Cancel path remapping", + ) + init_argparse_common(sub_subparse, use_json=True) + + sub_subparse.set_defaults( + func=lambda args: + bam_commands.remap_reset( + use_json=args.json, + ), + ) + + +def create_argparse(): + import argparse + + usage_text = ( + "BAM!\n" + + __doc__ + ) + + parser = argparse.ArgumentParser( + prog="bam", + description=usage_text, + ) + + subparsers = parser.add_subparsers( + title='subcommands', + description='valid subcommands', + help='additional help', + ) + + create_argparse_init(subparsers) + create_argparse_create(subparsers) + create_argparse_checkout(subparsers) + create_argparse_commit(subparsers) + create_argparse_update(subparsers) + create_argparse_revert(subparsers) + create_argparse_status(subparsers) + create_argparse_list(subparsers) + + # non-bam project commands + create_argparse_deps(subparsers) + create_argparse_pack(subparsers) + create_argparse_copy(subparsers) + create_argparse_remap(subparsers) + + return parser + + +def main(argv=None): + if argv is None: + argv = sys.argv[1:] + + logging.basicConfig( + level=logging.INFO, + format='%(asctime)-15s %(levelname)8s %(name)s %(message)s', + ) + + parser = create_argparse() + args = parser.parse_args(argv) + + # call subparser callback + if not hasattr(args, "func"): + parser.print_help() + return + + args.func(args) + + +if __name__ == "__main__": + raise Exception("This module can't be executed directly, Call '../bam_cli.py'") diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/pack.py b/io_blend_utils/blender_bam-unpacked.whl/bam/pack.py new file mode 100644 index 00000000..8df5b9d4 --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/pack.py @@ -0,0 +1,10 @@ +"""CLI interface to BAM-pack. + +Run this using: + +python -m bam.pack +""" + +if __name__ == '__main__': + from bam.blend import blendfile_pack + blendfile_pack.main() diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/utils/__init__.py b/io_blend_utils/blender_bam-unpacked.whl/bam/utils/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/utils/__init__.py diff --git a/io_blend_utils/blender_bam-unpacked.whl/bam/utils/system.py b/io_blend_utils/blender_bam-unpacked.whl/bam/utils/system.py new file mode 100644 index 00000000..313173ee --- /dev/null +++ b/io_blend_utils/blender_bam-unpacked.whl/bam/utils/system.py @@ -0,0 +1,143 @@ +# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** + +def colorize_dummy(msg, color=None): + return msg + +_USE_COLOR = True +if _USE_COLOR: + color_codes = { + 'black': '\033[0;30m', + 'bright_gray': '\033[0;37m', + 'blue': '\033[0;34m', + 'white': '\033[1;37m', + 'green': '\033[0;32m', + 'bright_blue': '\033[1;34m', + 'cyan': '\033[0;36m', + 'bright_green': '\033[1;32m', + 'red': '\033[0;31m', + 'bright_cyan': '\033[1;36m', + 'purple': '\033[0;35m', + 'bright_red': '\033[1;31m', + 'yellow': '\033[0;33m', + 'bright_purple':'\033[1;35m', + 'dark_gray': '\033[1;30m', + 'bright_yellow':'\033[1;33m', + 'normal': '\033[0m', + } + + def colorize(msg, color=None): + return (color_codes[color] + msg + color_codes['normal']) +else: + colorize = colorize_dummy + + +def uuid_from_file(fn, block_size=1 << 20): + """ + Returns an arbitrary sized unique ASCII string based on the file contents. + (exact hashing method may change). + """ + with open(fn, 'rb') as f: + # first get the size + import os + f.seek(0, os.SEEK_END) + size = f.tell() + f.seek(0, os.SEEK_SET) + del os + # done! + + import hashlib + sha1 = hashlib.new('sha512') + while True: + data = f.read(block_size) + if not data: + break + sha1.update(data) + # skip the '0x' + return hex(size)[2:] + sha1.hexdigest() + + +def write_json_to_zip(zip_handle, path, data=None): + import json + zip_handle.writestr( + path, + json.dumps( + data, + check_circular=False, + # optional (pretty) + sort_keys=True, indent=4, separators=(',', ': '), + ).encode('utf-8')) + + +def write_json_to_file(path, data): + import json + with open(path, 'w') as file_handle: + json.dump( + data, file_handle, ensure_ascii=False, + check_circular=False, + # optional (pretty) + sort_keys=True, indent=4, separators=(',', ': '), + ) + + +def is_compressed_filetype(filepath): + """ + Use to check if we should compress files in a zip. + """ + # for now, only include files which Blender is likely to reference + import os + assert(isinstance(filepath, bytes)) + return os.path.splitext(filepath)[1].lower() in { + # images + b'.exr', + b'.jpg', b'.jpeg', + b'.png', + + # audio + b'.aif', b'.aiff', + b'.mp3', + b'.ogg', b'.ogv', + b'.wav', + + # video + b'.avi', + b'.mkv', + b'.mov', + b'.mpg', b'.mpeg', + + # archives + # '.bz2', '.tbz', + # '.gz', '.tgz', + # '.zip', + } + + +def is_subdir(path, directory): + """ + Returns true if *path* in a subdirectory of *directory*. + """ + import os + from os.path import normpath, normcase, sep + path = normpath(normcase(path)) + directory = normpath(normcase(directory)) + if len(path) > len(directory): + sep = sep.encode('ascii') if isinstance(directory, bytes) else sep + if path.startswith(directory.rstrip(sep) + sep): + return True + return False + diff --git a/io_blend_utils/install_whl.py b/io_blend_utils/install_whl.py new file mode 100755 index 00000000..e1af5a48 --- /dev/null +++ b/io_blend_utils/install_whl.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3.5 + +"""This Python script installs a new version of BAM here.""" + +import pathlib + +my_dir = pathlib.Path(__file__).absolute().parent + + +def main(): + import argparse + + parser = argparse.ArgumentParser(description="This script installs a new version of BAM here.") + parser.add_argument('wheelfile', type=pathlib.Path, + help='Location of the wheel file to install.') + + args = parser.parse_args() + install(args.wheelfile.expanduser()) + + +def install(wheelfile: pathlib.Path): + import json + import os + import re + + assert_is_zipfile(wheelfile) + wipe_preexisting() + + print('Installing %s' % wheelfile) + target = my_dir / 'blender_bam-unpacked.whl' + print('Creating target directory %s' % target) + target.mkdir(parents=True) + + extract(wheelfile, target) + copy_files(target) + + version = find_version(target) + print('This is BAM version %s' % (version, )) + update_init_file(version) + + print('Done installing %s' % wheelfile.name) + + +def assert_is_zipfile(wheelfile: pathlib.Path): + import zipfile + + # In Python 3.6 conversion to str is not necessary any more: + if not zipfile.is_zipfile(str(wheelfile)): + log.error('%s is not a valid ZIP file!' % wheelfile) + raise SystemExit() + + +def wipe_preexisting(): + import shutil + + for existing in sorted(my_dir.glob('blender_bam-*.whl')): + if existing.is_dir(): + print('Wiping pre-existing directory %s' % existing) + # In Python 3.6 conversion to str is not necessary any more: + shutil.rmtree(str(existing)) + else: + print('Wiping pre-existing file %s' % existing) + existing.unlink() + + +def extract(wheelfile: pathlib.Path, target: pathlib.Path): + import os + import zipfile + + # In Python 3.6 conversion to str is not necessary any more: + os.chdir(str(target)) + + print('Extracting wheel') + # In Python 3.6 conversion to str is not necessary any more: + with zipfile.ZipFile(str(wheelfile)) as whlzip: + whlzip.extractall() + + os.chdir(str(my_dir)) + + +def copy_files(target: pathlib.Path): + import shutil + + print('Copying some files from wheel to other locations') + # In Python 3.6 conversion to str is not necessary any more: + shutil.copy(str(target / 'bam' / 'blend' / 'blendfile_path_walker.py'), './blend') + shutil.copy(str(target / 'bam' / 'blend' / 'blendfile.py'), './blend') + shutil.copy(str(target / 'bam' / 'utils' / 'system.py'), './utils') + + +def find_version(target: pathlib.Path): + import json + import shutil + + print('Obtaining version number from wheel.') + + distinfo = next(target.glob('*.dist-info')) + with (distinfo / 'metadata.json').open() as infofile: + metadata = json.load(infofile) + + print('Wiping dist-info directory.') + shutil.rmtree(str(distinfo)) + + # "1.2.3" -> (1, 2, 3) + str_ver = metadata['version'] + return tuple(int(x) for x in str_ver.split('.')) + + +def update_init_file(version: tuple): + import os + import re + + print('Updating __init__.py to have the correct version.') + version_line_re = re.compile(r'^\s+[\'"]version[\'"]: (\([0-9,]+\)),') + + with open('__init__.py', 'r') as infile, \ + open('__init__.py~whl~installer~', 'w') as outfile: + + for line in infile: + if version_line_re.match(line): + outfile.write(" 'version': %s,%s" % (version, os.linesep)) + else: + outfile.write(line) + + os.unlink('__init__.py') + os.rename('__init__.py~whl~installer~', '__init__.py') + +if __name__ == '__main__': + main() diff --git a/io_convert_image_to_mesh_img/__init__.py b/io_convert_image_to_mesh_img/__init__.py index 35b60997..4594b751 100644 --- a/io_convert_image_to_mesh_img/__init__.py +++ b/io_convert_image_to_mesh_img/__init__.py @@ -1,130 +1,62 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### +# This file is a part of the HiRISE DTM Importer for Blender # -# 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. +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. # -# 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. +# 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. # -# 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. +# 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. # -# ##### END GPL LICENSE BLOCK ##### +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. + +"""A HiRISE DTM Importer for Blender""" + +import bpy + +from .ui import importer +from .ui import terrainpanel bl_info = { - "name": "HiRISE DTM from PDS IMG", - "author": "Tim Spriggs (tims@uahirise.org)", - "version": (0, 1, 4), - "blender": (2, 63, 0), - "location": "File > Import > HiRISE DTM from PDS IMG (.IMG)", - "description": "Import a HiRISE DTM formatted as a PDS IMG file", + "name": "HiRISE DTM Importer", + "author": "Nicholas Wolf (nicwolf@pirl.lpl.arizona.edu)", + "version": (0, 2, 1), + "blender": (2, 78, 0), + "location": "File > Import > HiRISE DTM (.img)", + "description": "Import a HiRISE DTM as a mesh.", "warning": "May consume a lot of memory", "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" "Scripts/Import-Export/HiRISE_DTM_from_PDS_IMG", "category": "Import-Export", } - -# Revision History: -# 0.1.1 - make default import 12x12 bin (fast) to not consume too much memory -# by default (TJS - 2010-12-07) -# 0.1.2 - included into svn under the tree: -# trunk/py/scripts/addons/io_convert_image_to_mesh_img -# may be moved out to contrib once the blender downloader works well -# (TJS - 2010-12-14) -# 0.1.3 - upstream blender updates -# performance enhancements by Chris Van Horne -# (TJS - 2012-03-14) -# 0.1.4 - use bmesh from_pydata in blender 2.6.3 -# fixed/optimized bin2 method -# (TJS - 2012-04-30) - - if "bpy" in locals(): - import importlib - importlib.reload(import_img) -else: - from . import import_img - - -import bpy -from bpy.props import * -from bpy_extras.io_utils import ImportHelper - - -class ImportHiRISEIMGDTM(bpy.types.Operator, ImportHelper): - """Import a HiRISE DTM formatted as a PDS IMG file""" - bl_idname = "import_shape.img" - bl_label = "Import HiRISE DTM from PDS IMG" - bl_options = {'UNDO'} + import imp + imp.reload(importer) + imp.reload(terrainpanel) - filename_ext = ".IMG" - filter_glob = StringProperty(default="*.IMG", options={'HIDDEN'}) - - scale = FloatProperty(name="Scale", - description="Scale the IMG by this value", - min=0.0001, - max=10.0, - soft_min=0.001, - soft_max=100.0, - default=0.01) - - bin_mode = EnumProperty(items=( - ('NONE', "None", "Don't bin the image"), - ('BIN2', "2x2", "use 2x2 binning to import the mesh"), - ('BIN6', "6x6", "use 6x6 binning to import the mesh"), - ('BIN6-FAST', "6x6 Fast", "use one sample per 6x6 region"), - ('BIN12', "12x12", "use 12x12 binning to import the mesh"), - ('BIN12-FAST', "12x12 Fast", "use one sample per 12x12 region"), - ), - name="Binning", - description="Import Binning", - default='BIN12-FAST' - ) - - ## TODO: add support for cropping on import when the checkbox is checked - # do_crop = BoolProperty(name="Crop Image", description="Crop the image during import", ... ) - ## we only want these visible when the above is "true" - # crop_x = IntProperty(name="X", description="Offset from left side of image") - # crop_y = IntProperty(name="Y", description="Offset from top of image") - # crop_w = IntProperty(name="Width", description="width of cropped operation") - # crop_h = IntProperty(name="Height", description="height of cropped region") - ## This is also a bit ugly and maybe an anti-pattern. The problem is that - ## importing a HiRISE DTM at full resolution will likely kill any mortal user with - ## less than 16 GB RAM and getting at specific features in a DTM at full res - ## may prove beneficial. Someday most mortals will have 16GB RAM. - ## -TJS 2010-11-23 - - def execute(self, context): - filepath = self.filepath - filepath = bpy.path.ensure_ext(filepath, self.filename_ext) - - return import_img.load(self, context, - filepath=self.filepath, - scale=self.scale, - bin_mode=self.bin_mode, - cropVars=False, - ) - -## How to register the script inside of Blender def menu_import(self, context): - self.layout.operator(ImportHiRISEIMGDTM.bl_idname, text="HiRISE DTM from PDS IMG (*.IMG)") + i = importer.ImportHiRISETerrain + self.layout.operator(i.bl_idname, text=i.bl_label) + def register(): bpy.utils.register_module(__name__) - bpy.types.INFO_MT_file_import.append(menu_import) + def unregister(): bpy.utils.unregister_module(__name__) - bpy.types.INFO_MT_file_import.remove(menu_import) -if __name__ == "__main__": + +if __name__ == '__main__': register() diff --git a/io_convert_image_to_mesh_img/import_img.py b/io_convert_image_to_mesh_img/import_img.py deleted file mode 100644 index 7c9e76d1..00000000 --- a/io_convert_image_to_mesh_img/import_img.py +++ /dev/null @@ -1,713 +0,0 @@ -# ##### 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 ##### - -""" -This script can import a HiRISE DTM .IMG file. -""" - -import bpy -from bpy.props import * - -from struct import pack, unpack -import os -import queue, threading - -class image_properties: - """ keeps track of image attributes throughout the hirise_dtm_importer class """ - def __init__(self, name, dimensions, pixel_scale): - self.name( name ) - self.dims( dimensions ) - self.processed_dims( dimensions ) - self.pixel_scale( pixel_scale ) - - def dims(self, dims=None): - if dims is not None: - self.__dims = dims - return self.__dims - - def processed_dims(self, processed_dims=None): - if processed_dims is not None: - self.__processed_dims = processed_dims - return self.__processed_dims - - def name(self, name=None): - if name is not None: - self.__name = name - return self.__name - - def pixel_scale(self, pixel_scale=None): - if pixel_scale is not None: - self.__pixel_scale = pixel_scale - return self.__pixel_scale - -class hirise_dtm_importer(object): - """ methods to understand/import a HiRISE DTM formatted as a PDS .IMG """ - - def __init__(self, context, filepath): - self.__context = context - self.__filepath = filepath - self.__ignore_value = 0x00000000 - self.__bin_mode = 'BIN6' - self.scale( 1.0 ) - self.__cropXY = False - - def bin_mode(self, bin_mode=None): - if bin_mode is not None: - self.__bin_mode = bin_mode - return self.__bin_mode - - def scale(self, scale=None): - if scale is not None: - self.__scale = scale - return self.__scale - - def crop(self, widthX, widthY, offX, offY): - self.__cropXY = [ widthX, widthY, offX, offY ] - return self.__cropXY - - ############################################################################ - ## PDS Label Operations - ############################################################################ - - def parsePDSLabel(self, labelIter, currentObjectName=None, level = ""): - # Let's parse this thing... semi-recursively - ## I started writing this caring about everything in the PDS standard but ... - ## it's a mess and I only need a few things -- thar be hacks below - ## Mostly I just don't care about continued data from previous lines - label_structure = [] - - # When are we done with this level? - endStr = "END" - if not currentObjectName is None: - endStr = "END_OBJECT = %s" % currentObjectName - line = "" - - while not line.rstrip() == endStr: - line = next(labelIter) - - # Get rid of comments - comment = line.find("/*") - if comment > -1: - line = line[:comment] - - # Take notice of objects - if line[:8] == "OBJECT =": - objName = line[8:].rstrip() - label_structure.append( - ( - objName.lstrip().rstrip(), - self.parsePDSLabel(labelIter, objName.lstrip().rstrip(), level + " ") - ) - ) - elif line.find("END_OBJECT =") > -1: - pass - elif len(line.rstrip().lstrip()) > 0: - key_val = line.split(" = ", 2) - if len(key_val) == 2: - label_structure.append( (key_val[0].rstrip().lstrip(), key_val[1].rstrip().lstrip()) ) - - return label_structure - - # There has got to be a better way in python? - def iterArr(self, label): - for line in label: - yield line - - def getPDSLabel(self, img): - # Just takes file and stores it into an array for later use - label = [] - done = False; - # Grab label into array of lines - while not done: - line = str(img.readline(), 'utf-8') - if line.rstrip() == "END": - done = True - label.append(line) - return (label, self.parsePDSLabel(self.iterArr(label))) - - def getLinesAndSamples(self, label): - """ uses the parsed PDS Label to get the LINES and LINE_SAMPLES parameters - from the first object named "IMAGE" -- is hackish - """ - for obj in label: - if obj[0] == "IMAGE": - return self.getLinesAndSamples(obj[1]) - if obj[0] == "LINES": - lines = int(obj[1]) - if obj[0] == "LINE_SAMPLES": - line_samples = int(obj[1]) - - return ( line_samples, lines ) - - def getValidMinMax(self, label): - """ uses the parsed PDS Label to get the VALID_MINIMUM and VALID_MAXIMUM parameters - from the first object named "IMAGE" -- is hackish - """ - for obj in label: - if obj[0] == "IMAGE": - return self.getValidMinMax(obj[1]) - if obj[0] == "VALID_MINIMUM": - vmin = float(obj[1]) - if obj[0] == "VALID_MAXIMUM": - vmax = float(obj[1]) - - return vmin, vmax - - def getMissingConstant(self, label): - """ uses the parsed PDS Label to get the MISSING_CONSTANT parameter - from the first object named "IMAGE" -- is hackish - """ - for obj in label: - if obj[0] == "IMAGE": - return self.getMissingConstant(obj[1]) - if obj[0] == "MISSING_CONSTANT": - bit_string_repr = obj[1] - - # This is always the same for a HiRISE image, so we are just checking it - # to be a little less insane here. If someone wants to support another - # constant then go for it. Just make sure this one continues to work too - pieces = bit_string_repr.split("#") - if pieces[0] == "16" and pieces[1] == "FF7FFFFB": - ignore_value = unpack("f", pack("I", 0xFF7FFFFB))[0] - - return ( ignore_value ) - - ############################################################################ - ## Image operations - ############################################################################ - - def bin2(self, image_iter, bin2_method_type="SLOW"): - """ this is an iterator that: Given an image iterator will yield binned lines """ - - ignore_value = self.__ignore_value - - img_props = next(image_iter) - # dimensions shrink as we remove pixels - processed_dims = img_props.processed_dims() - processed_dims = ( processed_dims[0]//2, processed_dims[1]//2 ) - img_props.processed_dims( processed_dims ) - # each pixel is larger as binning gets larger - pixel_scale = img_props.pixel_scale() - pixel_scale = ( pixel_scale[0]*2, pixel_scale[1]*2 ) - img_props.pixel_scale( pixel_scale ) - yield img_props - - # Take two lists [a1, a2, a3], [b1, b2, b3] and combine them into one - # list of [a1 + b1, a2+b2, ... ] as long as both values are not ignorable - combine_fun = lambda a, b: a != ignore_value and b != ignore_value and (a + b)/2 or ignore_value - - line_count = 0 - ret_list = [] - for line in image_iter: - if line_count == 1: - line_count = 0 - tmp_list = list(map(combine_fun, line, last_line)) - while len(tmp_list) > 1: - ret_list.append( combine_fun( tmp_list[0], tmp_list[1] ) ) - del tmp_list[0:2] - yield ret_list - ret_list = [] - else: - last_line = line - line_count += 1 - - def bin6(self, image_iter, bin6_method_type="SLOW"): - """ this is an iterator that: Given an image iterator will yield binned lines """ - - img_props = next(image_iter) - # dimensions shrink as we remove pixels - processed_dims = img_props.processed_dims() - processed_dims = ( processed_dims[0]//6, processed_dims[1]//6 ) - img_props.processed_dims( processed_dims ) - # each pixel is larger as binning gets larger - pixel_scale = img_props.pixel_scale() - pixel_scale = ( pixel_scale[0]*6, pixel_scale[1]*6 ) - img_props.pixel_scale( pixel_scale ) - yield img_props - - if bin6_method_type == "FAST": - bin6_method = self.bin6_real_fast - else: - bin6_method = self.bin6_real - - raw_data = [] - line_count = 0 - for line in image_iter: - raw_data.append( line ) - line_count += 1 - if line_count == 6: - yield bin6_method( raw_data ) - line_count = 0 - raw_data = [] - - def bin6_real(self, raw_data): - """ does a 6x6 sample of raw_data and returns a single line of data """ - # TODO: make this more efficient - - binned_data = [] - - # Filter out those unwanted hugely negative values... - IGNORE_VALUE = self.__ignore_value - - base = 0 - for i in range(0, len(raw_data[0])//6): - - ints = (raw_data[0][base:base+6] + - raw_data[1][base:base+6] + - raw_data[2][base:base+6] + - raw_data[3][base:base+6] + - raw_data[4][base:base+6] + - raw_data[5][base:base+6] ) - - ints = [num for num in ints if num != IGNORE_VALUE] - - # If we have all pesky values, return a pesky value - if not ints: - binned_data.append( IGNORE_VALUE ) - else: - binned_data.append( sum(ints, 0.0) / len(ints) ) - - base += 6 - - return binned_data - - def bin6_real_fast(self, raw_data): - """ takes a single value from each 6x6 sample of raw_data and returns a single line of data """ - # TODO: make this more efficient - - binned_data = [] - - base = 0 - for i in range(0, len(raw_data[0])//6): - binned_data.append( raw_data[0][base] ) - base += 6 - - return binned_data - - def bin12(self, image_iter, bin12_method_type="SLOW"): - """ this is an iterator that: Given an image iterator will yield binned lines """ - - img_props = next(image_iter) - # dimensions shrink as we remove pixels - processed_dims = img_props.processed_dims() - processed_dims = ( processed_dims[0]//12, processed_dims[1]//12 ) - img_props.processed_dims( processed_dims ) - # each pixel is larger as binning gets larger - pixel_scale = img_props.pixel_scale() - pixel_scale = ( pixel_scale[0]*12, pixel_scale[1]*12 ) - img_props.pixel_scale( pixel_scale ) - yield img_props - - if bin12_method_type == "FAST": - bin12_method = self.bin12_real_fast - else: - bin12_method = self.bin12_real - - raw_data = [] - line_count = 0 - for line in image_iter: - raw_data.append( line ) - line_count += 1 - if line_count == 12: - yield bin12_method( raw_data ) - line_count = 0 - raw_data = [] - - def bin12_real(self, raw_data): - """ does a 12x12 sample of raw_data and returns a single line of data """ - - binned_data = [] - - # Filter out those unwanted hugely negative values... - filter_fun = lambda a: self.__ignore_value.__ne__(a) - - base = 0 - for i in range(0, len(raw_data[0])//12): - - ints = list(filter( filter_fun, raw_data[0][base:base+12] + - raw_data[1][base:base+12] + - raw_data[2][base:base+12] + - raw_data[3][base:base+12] + - raw_data[4][base:base+12] + - raw_data[5][base:base+12] + - raw_data[6][base:base+12] + - raw_data[7][base:base+12] + - raw_data[8][base:base+12] + - raw_data[9][base:base+12] + - raw_data[10][base:base+12] + - raw_data[11][base:base+12] )) - len_ints = len( ints ) - - # If we have all pesky values, return a pesky value - if len_ints == 0: - binned_data.append( self.__ignore_value ) - else: - binned_data.append( sum(ints) / len(ints) ) - - base += 12 - return binned_data - - def bin12_real_fast(self, raw_data): - """ takes a single value from each 12x12 sample of raw_data and returns a single line of data """ - return raw_data[0][11::12] - - def cropXY(self, image_iter, XSize=None, YSize=None, XOffset=0, YOffset=0): - """ return a cropped portion of the image """ - - img_props = next(image_iter) - # dimensions shrink as we remove pixels - processed_dims = img_props.processed_dims() - - if XSize is None: - XSize = processed_dims[0] - if YSize is None: - YSize = processed_dims[1] - - if XSize + XOffset > processed_dims[0]: - XSize = processed_dims[0] - XOffset = 0 - if YSize + YOffset > processed_dims[1]: - YSize = processed_dims[1] - YOffset = 0 - - img_props.processed_dims( (XSize, YSize) ) - yield img_props - - currentY = 0 - for line in image_iter: - if currentY >= YOffset and currentY <= YOffset + YSize: - yield line[XOffset:XOffset+XSize] - # Not much point in reading the rest of the data... - if currentY == YOffset + YSize: - return - currentY += 1 - - def getImage(self, img, img_props): - """ Assumes 32-bit pixels -- bins image """ - dims = img_props.dims() - - # setup to unpack more efficiently. - x_len = dims[0] - # little endian (PC_REAL) - unpack_str = "<" - # unpack_str = ">" - unpack_bytes_str = "<" - pack_bytes_str = "=" - # 32 bits/sample * samples/line = y_bytes (per line) - x_bytes = 4*x_len - for x in range(0, x_len): - # 32-bit float is "d" - unpack_str += "f" - unpack_bytes_str += "I" - pack_bytes_str += "I" - - # Each iterator yields this first ... it is for reference of the next iterator: - yield img_props - - for y in range(0, dims[1]): - # pixels is a byte array - pixels = b'' - while len(pixels) < x_bytes: - new_pixels = img.read( x_bytes - len(pixels) ) - pixels += new_pixels - if len(new_pixels) == 0: - x_bytes = -1 - pixels = [] - if len(pixels) == x_bytes: - if 0 == 1: - repacked_pixels = b'' - for integer in unpack(unpack_bytes_str, pixels): - repacked_pixels += pack("=I", integer) - yield unpack( unpack_str, repacked_pixels ) - else: - yield unpack( unpack_str, pixels ) - - def shiftToOrigin(self, image_iter, image_min_max): - """ takes a generator and shifts the points by the valid minimum - also removes points with value self.__ignore_value and replaces them with None - """ - - # use the passed in values ... - valid_min = image_min_max[0] - - # pass on dimensions/pixel_scale since we don't modify them here - yield next(image_iter) - - - # closures rock! - def normalize_fun(point): - if point == self.__ignore_value: - return None - return point - valid_min - - for line in image_iter: - yield list(map(normalize_fun, line)) - - def scaleZ(self, image_iter, scale_factor): - """ scales the mesh values by a factor """ - # pass on dimensions since we don't modify them here - yield next(image_iter) - - scale_factor = self.scale() - - def scale_fun(point): - try: - return point * scale_factor - except: - return None - - for line in image_iter: - yield list(map(scale_fun, line)) - - def genMesh(self, image_iter): - """Returns a mesh object from an image iterator this has the - value-added feature that a value of "None" is ignored - """ - - # Get the output image size given the above transforms - img_props = next(image_iter) - - # Let's interpolate the binned DTM with blender -- yay meshes! - coords = [] - faces = [] - face_count = 0 - coord = -1 - max_x = img_props.processed_dims()[0] - max_y = img_props.processed_dims()[1] - - scale_x = self.scale() * img_props.pixel_scale()[0] - scale_y = self.scale() * img_props.pixel_scale()[1] - - line_count = 0 - # seed the last line (or previous line) with a line - last_line = next(image_iter) - point_offset = 0 - previous_point_offset = 0 - - # Let's add any initial points that are appropriate - x = 0 - point_offset += len( last_line ) - last_line.count(None) - for z in last_line: - if z is not None: - coords.append( (x*scale_x, 0.0, z) ) - coord += 1 - x += 1 - - # We want to ignore points with a value of "None" but we also need to create vertices - # with an index that we can re-create on the next line. The solution is to remember - # two offsets: the point offset and the previous point offset. - # these offsets represent the point index that blender gets -- not the number of - # points we have read from the image - - # if "x" represents points that are "None" valued then conceptually this is how we - # think of point indices: - # - # previous line: offset0 x x +1 +2 +3 - # current line: offset1 x +1 +2 +3 x - - # once we can map points we can worry about making triangular or square faces to fill - # the space between vertices so that blender is more efficient at managing the final - # structure. - - # read each new line and generate coordinates+faces - for dtm_line in image_iter: - - # Keep track of where we are in the image - line_count += 1 - y_val = line_count*-scale_y - - # Just add all points blindly - # TODO: turn this into a map - x = 0 - for z in dtm_line: - if z is not None: - coords.append( (x*scale_x, y_val, z) ) - coord += 1 - x += 1 - - # Calculate faces - for x in range(0, max_x - 1): - vals = [ - last_line[ x + 1 ], - last_line[ x ], - dtm_line[ x ], - dtm_line[ x + 1 ], - ] - - # Two or more values of "None" means we can ignore this block - none_val = vals.count(None) - - # Common case: we can create a square face - if none_val == 0: - faces.append( ( - previous_point_offset, - previous_point_offset+1, - point_offset+1, - point_offset, - ) ) - face_count += 1 - elif none_val == 1: - # special case: we can implement a triangular face - ## NB: blender 2.5 makes a triangular face when the last coord is 0 - # TODO: implement a triangular face - pass - - if vals[1] is not None: - previous_point_offset += 1 - if vals[2] is not None: - point_offset += 1 - - # Squeeze the last point offset increment out of the previous line - if last_line[-1] is not None: - previous_point_offset += 1 - - # Squeeze the last point out of the current line - if dtm_line[-1] is not None: - point_offset += 1 - - # remember what we just saw (and forget anything before that) - last_line = dtm_line - - me = bpy.data.meshes.new(img_props.name()) # create a new mesh - #from_pydata(self, vertices, edges, faces) - #Make a mesh from a list of vertices/edges/faces - #Until we have a nicer way to make geometry, use this. - #:arg vertices: - # float triplets each representing (X, Y, Z) - # eg: [(0.0, 1.0, 0.5), ...]. - #:type vertices: iterable object - #:arg edges: - # int pairs, each pair contains two indices to the - # *vertices* argument. eg: [(1, 2), ...] - #:type edges: iterable object - #:arg faces: - # iterator of faces, each faces contains three or more indices to - # the *vertices* argument. eg: [(5, 6, 8, 9), (1, 2, 3), ...] - #:type faces: iterable object - me.from_pydata(coords, [], faces) - - # me.vertices.add(len(coords)/3) - # me.vertices.foreach_set("co", coords) - # me.faces.add(len(faces)/4) - # me.faces.foreach_set("vertices_raw", faces) - - me.update() - - bin_desc = self.bin_mode() - if bin_desc == 'NONE': - bin_desc = 'No Bin' - - ob=bpy.data.objects.new("DTM - %s" % bin_desc, me) - - return ob - - ################################################################################ - # Yay, done with importer functions ... let's see the abstraction in action! # - ################################################################################ - def execute(self): - - img = open(self.__filepath, 'rb') - - (label, parsedLabel) = self.getPDSLabel(img) - - image_dims = self.getLinesAndSamples(parsedLabel) - img_min_max_vals = self.getValidMinMax(parsedLabel) - self.__ignore_value = self.getMissingConstant(parsedLabel) - - - # MAGIC VALUE? -- need to formalize this to rid ourselves of bad points - img.seek(28) - # Crop off 4 lines - img.seek(4*image_dims[0]) - - # HiRISE images (and most others?) have 1m x 1m pixels - pixel_scale=(1, 1) - - # The image we are importing - image_name = os.path.basename( self.__filepath ) - - # Set the properties of the image in a manageable object - img_props = image_properties( image_name, image_dims, pixel_scale ) - - # Get an iterator to iterate over lines - image_iter = self.getImage(img, img_props) - - ## Wrap the image_iter generator with other generators to modify the dtm on a - ## line-by-line basis. This creates a stream of modifications instead of reading - ## all of the data at once, processing all of the data (potentially several times) - ## and then handing it off to blender - ## TODO: find a way to alter projection based on transformations below - - if self.__cropXY: - image_iter = self.cropXY(image_iter, - XSize=self.__cropXY[0], - YSize=self.__cropXY[1], - XOffset=self.__cropXY[2], - YOffset=self.__cropXY[3] - ) - - # Select an appropriate binning mode - ## TODO: generalize the binning fn's - bin_mode = self.bin_mode() - bin_mode_funcs = { - 'BIN2': self.bin2(image_iter), - 'BIN6': self.bin6(image_iter), - 'BIN6-FAST': self.bin6(image_iter, 'FAST'), - 'BIN12': self.bin12(image_iter), - 'BIN12-FAST': self.bin12(image_iter, 'FAST') - } - if bin_mode in bin_mode_funcs.keys(): - image_iter = bin_mode_funcs[ bin_mode ] - - image_iter = self.shiftToOrigin(image_iter, img_min_max_vals) - - if self.scale != 1.0: - image_iter = self.scaleZ(image_iter, img_min_max_vals) - - # Create a new mesh object and set data from the image iterator - ob_new = self.genMesh(image_iter) - - if img: - img.close() - - # Add mesh object to the current scene - scene = self.__context.scene - scene.objects.link(ob_new) - scene.update() - - # deselect other objects - bpy.ops.object.select_all(action='DESELECT') - - # scene.objects.active = ob_new - # Select the new mesh - ob_new.select = True - - return ('FINISHED',) - -def load(operator, context, filepath, scale, bin_mode, cropVars): - print("Bin Mode: %s" % bin_mode) - print("Scale: %f" % scale) - importer = hirise_dtm_importer(context,filepath) - importer.bin_mode( bin_mode ) - importer.scale( scale ) - if cropVars: - importer.crop( cropVars[0], cropVars[1], cropVars[2], cropVars[3] ) - importer.execute() - - print("Loading %s" % filepath) - return {'FINISHED'} diff --git a/io_convert_image_to_mesh_img/mesh/__init__.py b/io_convert_image_to_mesh_img/mesh/__init__.py new file mode 100644 index 00000000..edbc8c88 --- /dev/null +++ b/io_convert_image_to_mesh_img/mesh/__init__.py @@ -0,0 +1,25 @@ +# This file is a part of the HiRISE DTM Importer for Blender +# +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. +# +# 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/>. + +"""A sub-package for loading DTMs as 3D models""" + +from . import dtm +from . import terrain + +__all__ = ['dtm', 'terrain', ] diff --git a/io_convert_image_to_mesh_img/mesh/dtm.py b/io_convert_image_to_mesh_img/mesh/dtm.py new file mode 100644 index 00000000..a6ab6e30 --- /dev/null +++ b/io_convert_image_to_mesh_img/mesh/dtm.py @@ -0,0 +1,219 @@ +# This file is a part of the HiRISE DTM Importer for Blender +# +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. +# +# 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/>. + +"""Objects for importing HiRISE DTMs.""" + +import numpy as np + +from .. import pvl + + +class DTM: + """ + HiRISE Digital Terrain Model + + This class imports a HiRISE DTM from a Planetary Data Systems (PDS) + compliant .IMG file. + + Parameters + ---------- + path : str + terrain_resolution : float, optional + Controls the resolution the DTM is read at. This should be a float + in the range [0.01, 1.0] (and will be constrained to this range). A + value of 1.0 will result in the DTM being read at full resolution. A + value of 0.01 will result in the DTM being read at 1/100th resolution. + Default is 1.0 (no downsampling). + + Todo + ---- + * Use GDAL for importing the DTM if it is installed for this Python + environment. If/when I have the time to do this, it probably + warrants breaking out separate importer classes. The benefits of + doing this are pretty substantial, though: + + + More reliable (doesn't rely on my PVL parser for finding the + valid values in the DTM, for locating the starting position of + the elevation data in the .IMG file) + + + Other, better, downsampling algorithms are already built in. + + + Would make this much better at general PDS DTM importing, + currently some of the import code is specific to HiRISE DTMs. + + """ + + # Special constants in our data: + # NULL : No data at this point. + # LRS : Low Representation Saturation + # LIS : Low Instrument Saturation + # HRS : High Representation Saturation + # HIS : High Insturment Saturation + SPECIAL_VALUES = { + "NULL": np.fromstring(b'\xFF\x7F\xFF\xFB', dtype='>f4')[0], + "LRS": np.fromstring(b'\xFF\x7F\xFF\xFC', dtype='>f4')[0], + "LIS": np.fromstring(b'\xFF\x7F\xFF\xFD', dtype='>f4')[0], + "HRS": np.fromstring(b'\xFF\x7F\xFF\xFE', dtype='>f4')[0], + "HIS": np.fromstring(b'\xFF\x7F\xFF\xFF', dtype='>f4')[0] + } + + def __init__(self, path, terrain_resolution=1.0): + self.path = path + self.terrain_resolution = terrain_resolution + self.label = self._read_label() + self.data = self._read_data() + + def _read_label(self): + """Returns a dict-like representation of a PVL label""" + return pvl.load(self.path) + + def _read_data(self): + """ + Reads elevation data from a PDS .IMG file. + + Notes + ----- + * Uses nearest-neighbor to downsample data. + + Todo + ---- + * Add other downsampling algorithms. + + """ + h, w = self.image_resolution + max_samples = int(w - w % self.bin_size) + + data = np.zeros(self.shape) + with open(self.path, 'rb') as f: + # Seek to the first byte of data + start_byte = self._get_data_start() + f.seek(start_byte) + # Iterate over each row of the data + for r in range(data.shape[0]): + # Each iteration, seek to the right location before + # reading a row. We determine this location as the + # first byte of data PLUS a offset which we calculate as the + # product of: + # + # 4, the number of bytes in a single record + # r, the current row index + # w, the number of records in a row of the DTM + # bin_size, the number of records in a bin + # + # This is where we account for skipping over rows. + offset = int(4 * r * w * self.bin_size) + f.seek(start_byte + offset) + # Read a row + row = np.fromfile(f, dtype=np.float32, count=max_samples) + # This is where we account for skipping over columns. + data[r] = row[::self.bin_size] + + data = self._process_invalid_data(data) + return data + + def _get_data_start(self): + """Gets the start position of the DTM data block""" + label_length = self.label['RECORD_BYTES'] + num_labels = self.label.get('LABEL_RECORDS', 1) + return int(label_length * num_labels) + + def _process_invalid_data(self, data): + """Sets any 'NULL' elevation values to np.NaN""" + invalid_data_mask = (data <= self.SPECIAL_VALUES['NULL']) + data[invalid_data_mask] = np.NaN + return data + + @property + def map_size(self): + """Geographic size of the bounding box around the DTM""" + scale = self.map_scale * self.unit_scale + w = self.image_resolution[0] * scale + h = self.image_resolution[1] * scale + return (w, h) + + @property + def mesh_scale(self): + """Geographic spacing between mesh vertices""" + return self.bin_size * self.map_scale * self.unit_scale + + @property + def map_info(self): + """Map Projection metadata""" + return self.label['IMAGE_MAP_PROJECTION'] + + @property + def map_scale(self): + """Geographic spacing between DTM posts""" + map_scale = self.map_info.get('MAP_SCALE', None) + return getattr(map_scale, 'value', 1.0) + + @property + def map_units(self): + """Geographic unit for spacing between DTM posts""" + map_scale = self.map_info.get('MAP_SCALE', None) + return getattr(map_scale, 'units', None) + + @property + def unit_scale(self): + """ + The function that creates a Blender mesh from this object will assume + that the height values passed into it are in meters --- this + property is a multiplier to convert DTM-units to meters. + """ + scaling_factors = { + 'KM/PIXEL': 1000, + 'METERS/PIXEL': 1 + } + return scaling_factors.get(self.map_units, 1.0) + + @property + def terrain_resolution(self): + """Vertex spacing, meters""" + return self._terrain_resolution + + @terrain_resolution.setter + def terrain_resolution(self, t): + self._terrain_resolution = np.clip(t, 0.01, 1.0) + + @property + def bin_size(self): + """The width of the (square) downsampling bin""" + return int(np.ceil(1 / self.terrain_resolution)) + + @property + def image_stats(self): + """Image statistics from the original DTM label""" + return self.label['IMAGE'] + + @property + def image_resolution(self): + """(Line, Sample) resolution of the original DTM""" + return (self.image_stats['LINES'], self.image_stats['LINE_SAMPLES']) + + @property + def size(self): + """Number of posts in our reduced DTM""" + return self.shape[0] * self.shape[1] + + @property + def shape(self): + """Shape of our reduced DTM""" + num_rows = self.image_resolution[0] // self.bin_size + num_cols = self.image_resolution[1] // self.bin_size + return (num_rows, num_cols) diff --git a/io_convert_image_to_mesh_img/mesh/terrain.py b/io_convert_image_to_mesh_img/mesh/terrain.py new file mode 100644 index 00000000..db866289 --- /dev/null +++ b/io_convert_image_to_mesh_img/mesh/terrain.py @@ -0,0 +1,245 @@ +# This file is a part of the HiRISE DTM Importer for Blender +# +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. +# +# 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/>. + +"""Objects for creating 3D models in Blender""" + +import bpy +import bmesh + +import numpy as np + +from .triangulate import Triangulate + + +class BTerrain: + """ + Functions for creating Blender meshes from DTM objects + + This class contains functions that convert DTM objects to Blender meshes. + Its main responsiblity is to triangulate a mesh from the elevation data in + the DTM. Additionally, it attaches some metadata to the object and creates + a UV map for it so that companion ortho-images drape properly. + + This class provides two public methods: `new()` and `reload()`. + + `new()` creates a new object[1] and attaches a new mesh to it. + + `reload()` replaces the mesh that is attached to an already existing + object. This allows us to retain the location and orientation of the parent + object's coordinate system but to reload the terrain at a different + resolution. + + Notes + ---------- + [1] If you're unfamiliar with Blender, one thing that will help you in + reading this code is knowing the difference between 'meshes' and + 'objects'. A mesh is just a collection of vertices, edges and + faces. An object may have a mesh as a child data object and + contains additional information, e.g. the location and orientation + of the coordinate system its child-meshes are reckoned in terms of. + + """ + + @staticmethod + def new(dtm, name='Terrain'): + """ + Loads a new terrain + + Parameters + ---------- + dtm : DTM + name : str, optional + The name that will be assigned to the new object, defaults + to 'Terrain' (and, if an object named 'Terrain' already + exists, Blender will automatically extend the name of the + new object to something like 'Terrain.001') + + Returns + ---------- + obj : bpy_types.Object + + """ + bpy.ops.object.add(type="MESH") + obj = bpy.context.object + obj.name = name + + # Fill the object data with a Terrain mesh + obj.data = BTerrain._mesh_from_dtm(dtm) + + # Add some meta-information to the object + metadata = BTerrain._create_metadata(dtm) + BTerrain._setobjattrs(obj, **metadata) + + # Center the mesh to its origin and create a UV map for draping + # ortho images. + BTerrain._center(obj) + + return obj + + @staticmethod + def reload(obj, dtm): + """ + Replaces an exisiting object's terrain mesh + + This replaces an object's mesh with a new mesh, transferring old + materials over to the new mesh. This is useful for reloading DTMs + at different resolutions but maintaining textures/location/rotation. + + Parameters + ----------- + obj : bpy_types.Object + An already existing Blender object + dtm : DTM + + Returns + ---------- + obj : bpy_types.Object + + """ + old_mesh = obj.data + new_mesh = BTerrain._mesh_from_dtm(dtm) + + # Copy any old materials to the new mesh + for mat in old_mesh.materials: + new_mesh.materials.append(mat.copy()) + + # Swap out the old mesh for the new one + obj.data = new_mesh + + # Update out-dated meta-information + metadata = BTerrain._create_metadata(dtm) + BTerrain._setobjattrs(obj, **metadata) + + # Center the mesh to its origin and create a UV map for draping + # ortho images. + BTerrain._center(obj) + + return obj + + @staticmethod + def _mesh_from_dtm(dtm, name='Terrain'): + """ + Creates a Blender *mesh* from a DTM + + Parameters + ---------- + dtm : DTM + name : str, optional + The name that will be assigned to the new mesh, defaults + to 'Terrain' (and, if an object named 'Terrain' already + exists, Blender will automatically extend the name of the + new object to something like 'Terrain.001') + + Returns + ---------- + mesh : bpy_types.Mesh + + Notes + ---------- + * We are switching coordinate systems from the NumPy to Blender. + + Numpy: Blender: + + ----> (0, j) ^ (0, y) + | | + | | + v (i, 0) + ----> (x, 0) + + """ + # Create an empty mesh + mesh = bpy.data.meshes.new(name) + + # Get the xy-coordinates from the DTM, see docstring notes + y, x = np.indices(dtm.data.shape).astype('float64') + x *= dtm.mesh_scale + y *= -1 * dtm.mesh_scale + + # Create an array of 3D vertices + vertices = np.dstack([x, y, dtm.data]).reshape((-1, 3)) + + # Drop vertices with NaN values (used in the DTM to represent + # areas with no data) + vertices = vertices[~np.isnan(vertices).any(axis=1)] + + # Calculate the faces of the mesh + triangulation = Triangulate(dtm.data) + faces = triangulation.face_list() + + # Fill the mesh + mesh.from_pydata(vertices, [], faces) + mesh.update() + + # Create a new UV layer + mesh.uv_textures.new("HiRISE Generated UV Map") + # We'll use a bmesh to populate the UV map with values + bm = bmesh.new() + bm.from_mesh(mesh) + bm.faces.ensure_lookup_table() + uv_layer = bm.loops.layers.uv[0] + + # Iterate over each face in the bmesh + num_faces = len(bm.faces) + w = dtm.data.shape[1] + h = dtm.data.shape[0] + for face_index in range(num_faces): + # Iterate over each loop in the face + for loop in bm.faces[face_index].loops: + # Get this loop's vertex coordinates + vert_coords = loop.vert.co.xy + # And calculate it's uv coordinate. We do this by dividing the + # vertice's x and y coordinates by: + # + # d + 1, dimensions of DTM (in "posts") + # mesh_scale, meters/DTM "post" + # + # This has the effect of mapping the vertex to its + # corresponding "post" index in the DTM, and then mapping + # that value to the range [0, 1). + u = vert_coords.x / ((w + 1) * dtm.mesh_scale) + v = 1 + vert_coords.y / ((h + 1) * dtm.mesh_scale) + loop[uv_layer].uv = (u, v) + + bm.to_mesh(mesh) + + return mesh + + @staticmethod + def _center(obj): + """Move object geometry to object origin""" + bpy.context.scene.objects.active = obj + bpy.ops.object.origin_set(center='BOUNDS') + + @staticmethod + def _setobjattrs(obj, **attrs): + for key, value in attrs.items(): + obj[key] = value + + @staticmethod + def _create_metadata(dtm): + """Returns a dict containing meta-information about a DTM""" + return { + 'PATH': dtm.path, + 'MESH_SCALE': dtm.mesh_scale, + 'DTM_RESOLUTION': dtm.terrain_resolution, + 'BIN_SIZE': dtm.bin_size, + 'MAP_SIZE': dtm.map_size, + 'MAP_SCALE': dtm.map_scale * dtm.unit_scale, + 'UNIT_SCALE': dtm.unit_scale, + 'IS_TERRAIN': True, + 'HAS_UV_MAP': True + } diff --git a/io_convert_image_to_mesh_img/mesh/triangulate.py b/io_convert_image_to_mesh_img/mesh/triangulate.py new file mode 100644 index 00000000..bb0a50ac --- /dev/null +++ b/io_convert_image_to_mesh_img/mesh/triangulate.py @@ -0,0 +1,186 @@ +# This file is a part of the HiRISE DTM Importer for Blender +# +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. +# +# 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/>. + +"""Triangulation algorithms""" + +import numpy as np + + +class Triangulate: + """ + A triangulation algorithm for creating a mesh from a DTM raster. + + I have been re-writing parts of the Blender HiRISE DTM importer in an + effort to cull its dependencies on external packages. Originally, the + add-on relied on SciPy's Delaunay triangulation (really a wrapper for + Qhull's Delaunay triangulation) to triangulate a mesh from a HiRISE DTM. + + This re-write is much better suited to the problem domain. The SciPy + Delaunay triangulation creates a mesh from any arbitrary point cloud and, + while robust, doesn't care about the fact that our HiRISE DTMs are + regularly gridded rasters. This triangulation algorithm is less robust + but much faster. Credit is due to Tim Spriggs for his work on the previous + Blender HiRISE DTM importer --- this triangulation algorithm largely + models the one in his add-on with a few changes (namely interfacing + with NumPy's API). + + Overview + ---------- + Suppose we have a DTM: + + .. code:: + + - - - - - - - - X X - - - - - + - - - - - - X X X X X - - - - + - - - - X X X X X X X X - - - + - - X X X X X X X X X X X - - + X X X X X X X X X X X X X X - + - X X X X X X X X X X X X X X + - - X X X X X X X X X X X - - + - - - X X X X X X X X - - - - + - - - - X X X X X - - - - - - + - - - - - X X - - - - - - - - + + where 'X' represents valid values and '-' represents invalid values. + Valid values should become vertices in the resulting mesh, invalid + values should be ignored. + + Our end goal is to supply Blender with: + + 1. an (n x 3) list of vertices + + 2. an (m x 3) list of faces. + + A vertex is a 3-tuple that we get from the DTM raster array. The + z-coordinate is whatever elevation value is in the DTM and the xy- + coordinates are the image indices multiplied by the resolution of the + DTM (e.g. if the DTM is at 5m/px, the first vertex is at (0m, 0m, + z_00) and the vertex to the right of it is at (5m, 0m, z_01)). + + A face is a 3-tuple (because we're using triangles) where each element + is an index of a vertex in the vertices list. Computing the faces is + tricky because we want to leverage the orthogonal structure of the DTM + raster for computational efficiency but we also need to reference + vertex indices in our faces, which don't observe any regular + structure. + + We take two rows at a time from the DTM raster and track the *raster + row* indices as well as well as the *vertex* indices. Raster row + indices are the distance of a pixel in the raster from the left-most + (valid *or* invalid) pixel of the row. The first vertex is index 0 and + corresponds to the upperleft-most valid pixel in the DTM raster. + Vertex indices increase to the right and then down. + + For example, the first two rows: + + .. code:: + + - - - - - - - - X X - - - - - + - - - - - - X X X X X - - - - + + in vertex indices: + + .. code:: + + - - - - - - - - 0 1 - - - - - + - - - - - - 2 3 4 5 6 - - - - + + and in raster row indices: + + .. code:: + + - - - - - - - - 9 10 - - - - - + - - - - - - 7 8 9 10 11 - - - - + + To simplify, we will only add valid square regions to our mesh. So, + for these first two rows the only region that will be added to our + mesh is the quadrilateral formed by vertices 0, 1, 4 and 5. We + further divide this area into 2 triangles and add the vertices to the + face list in CCW order (i.e. t1: (4, 1, 0), t2: (4, 5, 1)). + + After the triangulation between two rows is completed, the bottom + row is cached as the top row and the next row in the DTM raster is + read as the new bottom row. This process continues until the entire + raster has been triangulated. + + Todo + --------- + * It should be pretty trivial to add support for triangular + regions (i.e. in the example above, also adding the triangles + formed by (3, 4, 0) and (5, 6, 1)). + + """ + def __init__(self, array): + self.array = array + self.faces = self._triangulate() + + def _triangulate(self): + """Triangulate a mesh from a topography array.""" + # Allocate memory for the triangles array + max_tris = (self.array.shape[0] - 1) * (self.array.shape[1] - 1) * 2 + tris = np.zeros((max_tris, 3), dtype=int) + ntri = 0 + + # We initialize a vertex counter at 0 + prev_vtx_start = 0 + # We don't care about the values in the array, just whether or not + # they are valid. + prev = ~np.isnan(self.array[0]) + # We can sum this boolean array to count the number of valid entries + prev_num_valid = prev.sum() + # TODO: Probably a more clear (and faster) function than argmax for + # getting the first Truth-y value in a 1d array. + prev_img_start = np.argmax(prev) + + # Start quadrangulation + for i in range(1, self.array.shape[0]): + # Fetch this row, get our bearings in image *and* vertex space + curr = ~np.isnan(self.array[i]) + curr_vtx_start = prev_vtx_start + prev_num_valid + curr_img_start = np.argmax(curr) + curr_num_valid = curr.sum() + # Find the overlap between this row and the previous one + overlap = np.logical_and(prev, curr) + num_tris = overlap.sum() - 1 + overlap_start = np.argmax(overlap) + # Store triangles + for j in range(num_tris): + curr_pad = overlap_start - curr_img_start + j + prev_pad = overlap_start - prev_img_start + j + tris[ntri + 0] = [ + curr_vtx_start + curr_pad, + prev_vtx_start + prev_pad + 1, + prev_vtx_start + prev_pad + ] + tris[ntri + 1] = [ + curr_vtx_start + curr_pad, + curr_vtx_start + curr_pad + 1, + prev_vtx_start + prev_pad + 1 + ] + ntri += 2 + # Cache current row as previous row + prev = curr + prev_vtx_start = curr_vtx_start + prev_img_start = curr_img_start + prev_num_valid = curr_num_valid + + return tris[:ntri] + + def face_list(self): + return list(self.faces) diff --git a/io_convert_image_to_mesh_img/pvl/__init__.py b/io_convert_image_to_mesh_img/pvl/__init__.py new file mode 100644 index 00000000..4fcf394e --- /dev/null +++ b/io_convert_image_to_mesh_img/pvl/__init__.py @@ -0,0 +1,27 @@ +# This file is a part of the HiRISE DTM Importer for Blender +# +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. +# +# 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/>. + +"""A sub-package for parsing PVL labels""" + +from .parse import LabelParser + + +def load(path): + """Returns a dict-like representation of a PVL label""" + return LabelParser.load(path) diff --git a/io_convert_image_to_mesh_img/pvl/label.py b/io_convert_image_to_mesh_img/pvl/label.py new file mode 100644 index 00000000..68d4f914 --- /dev/null +++ b/io_convert_image_to_mesh_img/pvl/label.py @@ -0,0 +1,24 @@ +# This file is a part of the HiRISE DTM Importer for Blender +# +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. +# +# 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/>. + + +class Label(dict): + """A dict-like representation of a PVL label""" + def __init__(self, *args, **kwargs): + super(Label, self).__init__(*args, **kwargs) diff --git a/io_convert_image_to_mesh_img/pvl/parse.py b/io_convert_image_to_mesh_img/pvl/parse.py new file mode 100644 index 00000000..3a87d2f3 --- /dev/null +++ b/io_convert_image_to_mesh_img/pvl/parse.py @@ -0,0 +1,147 @@ +# This file is a part of the HiRISE DTM Importer for Blender +# +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. +# +# 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/>. + +"""PVL Label Parsing""" + +import collections +import re + +from . import patterns +from .label import Label + +Quantity = collections.namedtuple('Quantity', ['value', 'units']) + + +class PVLParseError(Exception): + """Error parsing PVL file""" + def __init__(self, message): + super(PVLParseError, self).__init__(message) + + +class LabelParser: + """A PVL Parser""" + @staticmethod + def load(path): + """ + Load a dict-like representation of a PVL label header + + Parameters + ---------- + path : str + Path to a file containing a PVL header + + Returns + ---------- + label : pvl.Label + + """ + raw = LabelParser._read(path) + return Label(**LabelParser._parse(raw)) + + @staticmethod + def _read(path): + """ + Get the PVL header from a file as a string + + Parameters + ---------- + path : str + Path to a file containing a PVL header + + Returns + ---------- + raw : str + + Notes + --------- + * This function assumes that the file begins with a PVL header + and it will read lines from the file until it encounters + a PVL end statement. + + To-Do + --------- + * This could be more robust. What happens if there is no label + in the file? + + """ + with open(path, 'rb') as f: + raw = '' + while True: + try: + line = f.readline().decode() + raw += line + if re.match(patterns.END, line): + break + except UnicodeDecodeError: + raise PVLParseError("Error parsing PVL label from " + "file: {}".format(path)) + return raw + + @staticmethod + def _remove_comments(raw): + return re.sub(patterns.COMMENT, '', raw) + + @staticmethod + def _parse(raw): + raw = LabelParser._remove_comments(raw) + label_iter = re.finditer(patterns.STATEMENT, raw) + return LabelParser._parse_iter(label_iter) + + @staticmethod + def _parse_iter(label_iter): + """Recursively parse a PVL label iterator""" + obj = {} + while True: + try: + # Try to fetch the next match from the iter + match = next(label_iter) + val = match.group('val') + key = match.group('key') + # Handle nested object groups + if key == 'OBJECT': + obj.update({ + val: LabelParser._parse_iter(label_iter) + }) + elif key == 'END_OBJECT': + return obj + # Add key/value pair to dict + else: + # Should this value be a numeric type? + try: + val = LabelParser._convert_to_numeric(val) + except ValueError: + pass + # Should this value have units? + if match.group('units'): + val = Quantity(val, match.group('units')) + # Add it to the dict + obj.update({key: val}) + except StopIteration: + break + return obj + + @staticmethod + def _convert_to_numeric(s): + """Convert a string to its appropriate numeric type""" + if re.match(patterns.INTEGER, s): + return int(s) + elif re.match(patterns.FLOATING, s): + return float(s) + else: + raise ValueError diff --git a/io_convert_image_to_mesh_img/pvl/patterns.py b/io_convert_image_to_mesh_img/pvl/patterns.py new file mode 100644 index 00000000..af921803 --- /dev/null +++ b/io_convert_image_to_mesh_img/pvl/patterns.py @@ -0,0 +1,59 @@ +# This file is a part of the HiRISE DTM Importer for Blender +# +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. +# +# 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/>. + +"""PVL Regular Expression Patterns""" + +import re + +# End of PVL File +END = re.compile( + r'\s* \bEND\b \s*', (re.VERBOSE + re.IGNORECASE) +) + +# PVL Comment +COMMENT = re.compile( + r'/\* .*? \*/', (re.DOTALL + re.VERBOSE) +) + +# PVL Statement +STATEMENT = re.compile( + r""" + \s* (?P<key>\w+) # Match a PVL key + \s* = \s* # Who knows how many spaces we encounter + (?P<val> # Match a PVL value + ([+-]?\d+\.?\d*) # We could match a number + | (['"]?((\w+ \s*?)+)['"]?) # Or a string + ) + (\s* <(?P<units>.*?) >)? # The value may have an associated unit + """, re.VERBOSE +) + +# Integer Number +INTEGER = re.compile( + r""" + [+-]?(?<!\.)\b[0-9]+\b(?!\.[0-9]) + """, re.VERBOSE +) + +# Floating Point Number +FLOATING = re.compile( + r""" + [+-]?\b[0-9]*\.?[0-9]+ + """, re.VERBOSE +) diff --git a/io_convert_image_to_mesh_img/ui/__init__.py b/io_convert_image_to_mesh_img/ui/__init__.py new file mode 100644 index 00000000..57bd9fde --- /dev/null +++ b/io_convert_image_to_mesh_img/ui/__init__.py @@ -0,0 +1,25 @@ +# This file is a part of the HiRISE DTM Importer for Blender +# +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. +# +# 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/>. + +"""A sub-package for Blender UI elements""" + +from . import importer +from . import terrainpanel + +__all__ = ['importer', 'terrainpanel', ] diff --git a/io_convert_image_to_mesh_img/ui/importer.py b/io_convert_image_to_mesh_img/ui/importer.py new file mode 100644 index 00000000..981e49c2 --- /dev/null +++ b/io_convert_image_to_mesh_img/ui/importer.py @@ -0,0 +1,177 @@ +# This file is a part of the HiRISE DTM Importer for Blender +# +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. +# +# 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/>. + +"""Blender menu importer for loading a DTM""" + +import bpy +import bpy.props +from bpy_extras.io_utils import ImportHelper + +from ..mesh.terrain import BTerrain +from ..mesh.dtm import DTM + + +class ImportHiRISETerrain(bpy.types.Operator, ImportHelper): + """DTM Import Helper""" + bl_idname = "import.pds_dtm" + bl_label = "Import HiRISE Terrain Model" + bl_options = {'UNDO'} + filename_ext = ".img" + filter_glob = bpy.props.StringProperty( + options={'HIDDEN'}, + default="*.img" + ) + + # Allow the user to specify a resolution factor for loading the + # terrain data at. This is useful because it allows the user to stage + # a scene with a low resolution terrain map, apply textures, modifiers, + # etc. and then increase the resolution to prepare for final rendering. + # + # Displaying this value as a percentage (0, 100] is an intuitive way + # for users to grasp what this value does. The DTM importer, however, + # wants to recieve a value between (0, 1]. This is obviously a + # straightforward conversion: + # + # f(x) = x / 100 + # + # But this conversion should happen here, in the terrain panel, rather + # than in the DTM importing utility itself. We can't pass get/set + # functions to the property itself because they result in a recursion + # error. Instead, we use another, hidden, property to store the scaled + # resolution. + dtm_resolution = bpy.props.FloatProperty( + subtype="PERCENTAGE", + description=( + "Percentage scale for terrain model resolution. 100\% loads the " + "model at full resolution (i.e. one vertex for each post in the " + "original terrain model) and is *MEMORY INTENSIVE*. Downsampling " + "uses Nearest Neighbors. You will be able to increase the " + "resolution of your mesh later, and still maintain all textures, " + "transformations, modifiers, etc., so best practice is to start " + "small. The downsampling algorithm may need to alter the " + "resolution you specify here to ensure it results in a whole " + "number of vertices. If it needs to alter the value you specify, " + "you are guaranteed that it will shrink it (i.e. decrease the " + "DTM resolution." + ), + name="Terrain Model Resolution", + min=1.0, max=100.0, default=10.0 + ) + scaled_dtm_resolution = bpy.props.FloatProperty( + options={'HIDDEN'}, + name="Scaled Terrain Model Resolution", + get=(lambda self: self.dtm_resolution / 100) + ) + + # HiRISE DTMs are huge, but it can be nice to load them in at scale. Here, + # we present the user with the option of setting up the Blender viewport + # to avoid a couple of common pitfalls encountered when working with such + # a large mesh. + # + # 1. The Blender viewport has a default clipping distance of 1km. HiRISE + # DTMs are often many kilometers in each direction. If this setting is + # not changed, an unsuspecting user may only see part (or even nothing + # at all) of the terrain. This option (true, by default) instructs + # Blender to change the clipping distance to something appropriate for + # the DTM, and scales the grid floor to have gridlines 1km apart, + # instead of 1m apart. + should_setup_viewport = bpy.props.BoolProperty( + description=( + "Set up the Blender screen to try and avoid clipping the DTM " + "and to make the grid floor larger. *WARNING* This will change " + "clipping distances and the Blender grid floor, and will fit the " + "DTM in the viewport." + ), + name="Setup Blender Scene", default=True + ) + # 2. Blender's default units are dimensionless. This option instructs + # Blender to change its unit's dimension to meters. + should_setup_units = bpy.props.BoolProperty( + description=( + "Set the Blender scene to use meters as its unit." + ), + name="Set Blender Units to Meters", default=True + ) + + def execute(self, context): + """Runs when the "Import HiRISE Terrain Model" button is pressed""" + filepath = bpy.path.ensure_ext(self.filepath, self.filename_ext) + # Create a BTerrain from the DTM + dtm = DTM(filepath, self.scaled_dtm_resolution) + BTerrain.new(dtm) + + # Set up the Blender UI + if self.should_setup_units: + self._setup_units(context) + if self.should_setup_viewport: + self._setup_viewport(context) + + return {"FINISHED"} + + def _setup_units(self, context): + """Sets up the Blender scene for viewing the DTM""" + scene = bpy.context.scene + + # Set correct units + scene.unit_settings.system = 'METRIC' + scene.unit_settings.scale_length = 1.0 + + return {'FINISHED'} + + def _setup_viewport(self, context): + """Sets up the Blender screen to make viewing the DTM easier""" + screen = bpy.context.screen + + # Fetch the 3D_VIEW Area + for area in screen.areas: + if area.type == 'VIEW_3D': + space = area.spaces[0] + # Adjust 3D View Properties + # TODO: Can these be populated more intelligently? + space.clip_end = 100000 + space.grid_scale = 1000 + space.grid_lines = 50 + + # Fly to a nice view of the DTM + self._view_dtm(context) + + return {'FINISHED'} + + def _view_dtm(self, context): + """Sets up the Blender screen to make viewing the DTM easier""" + screen = bpy.context.screen + + # Fetch the 3D_VIEW Area + for area in screen.areas: + if area.type == 'VIEW_3D': + # Move the camera around in the viewport. This requires + # a context override. + for region in area.regions: + if region.type == 'WINDOW': + override = { + 'area': area, + 'region': region, + 'edit_object': bpy.context.edit_object + } + # Center View on DTM (SHORTCUT: '.') + bpy.ops.view3d.view_selected(override) + # Move to 'TOP' viewport (SHORTCUT: NUMPAD7) + bpy.ops.view3d.viewnumpad(override, type='TOP') + + return {'FINISHED'} diff --git a/io_convert_image_to_mesh_img/ui/terrainpanel.py b/io_convert_image_to_mesh_img/ui/terrainpanel.py new file mode 100644 index 00000000..80dfe8e4 --- /dev/null +++ b/io_convert_image_to_mesh_img/ui/terrainpanel.py @@ -0,0 +1,133 @@ +# This file is a part of the HiRISE DTM Importer for Blender +# +# Copyright (C) 2017 Arizona Board of Regents on behalf of the Planetary Image +# Research Laboratory, Lunar and Planetary Laboratory at the University of +# Arizona. +# +# 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/>. + +"""Blender panel for managing a DTM *after* it's been imported""" + +import bpy + +from ..mesh.terrain import BTerrain +from ..mesh.dtm import DTM + + +class TerrainPanel(bpy.types.Panel): + """Creates a Panel in the Object properites window for terrain objects""" + bl_label = "Terrain Model" + bl_idname = "OBJECT_PT_terrain" + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "object" + + # Allow the user to specify a new resolution factor for reloading the + # terrain data at. This is useful because it allows the user to stage + # a scene with a low resolution terrain map, apply textures, modifiers, + # etc. and then increase the resolution to prepare for final rendering. + # + # Displaying this value as a percentage (0, 100] is an intuitive way + # for users to grasp what this value does. The DTM importer, however, + # wants to recieve a value between (0, 1]. This is obviously a + # straightforward conversion: + # + # f(x) = x / 100 + # + # But this conversion should happen here, in the terrain panel, rather + # than in the DTM importing utility itself. We can't pass get/set + # functions to the property itself because they result in a recursion + # error. Instead, we use another, hidden, property to store the scaled + # resolution. + bpy.types.Object.dtm_resolution = bpy.props.FloatProperty( + subtype="PERCENTAGE", + name="New Resolution", + description=( + "Percentage scale for terrain model resolution. 100\% loads the " + "model at full resolution (i.e. one vertex for each post in the " + "original terrain model) and is *MEMORY INTENSIVE*. Downsampling " + "uses Nearest Neighbors. The downsampling algorithm may need to " + "alter the resolution you specify here to ensure it results in a " + "whole number of vertices. If it needs to alter the value you " + "specify, you are guaranteed that it will shrink it (i.e. " + "decrease the DTM resolution." + ), + min=1.0, max=100.0, default=10.0 + ) + bpy.types.Object.scaled_dtm_resolution = bpy.props.FloatProperty( + options={'HIDDEN'}, + name="Scaled Terrain Model Resolution", + get=(lambda self: self.dtm_resolution / 100.0) + ) + + @classmethod + def poll(cls, context): + return context.object.get("IS_TERRAIN", False) + + def draw(self, context): + obj = context.active_object + layout = self.layout + + # User Controls + layout.prop(obj, 'dtm_resolution') + layout.operator("terrain.reload") + + # Metadata + self.draw_metadata_panel(context) + + def draw_metadata_panel(self, context): + """Display some metadata about the DTM""" + obj = context.active_object + layout = self.layout + + metadata_panel = layout.box() + + dtm_resolution = metadata_panel.row() + dtm_resolution.label('Current Resolution: ') + dtm_resolution.label('{:9,.2%}'.format( + obj['DTM_RESOLUTION'] + )) + + mesh_scale = metadata_panel.row() + mesh_scale.label('Current Scale: ') + mesh_scale.label('{:9,.2f} m/post'.format( + obj['MESH_SCALE'] + )) + + dtm_scale = metadata_panel.row() + dtm_scale.label('Original Scale: ') + dtm_scale.label('{:9,.2f} m/post'.format( + obj['MAP_SCALE'] + )) + + return {'FINISHED'} + + +class ReloadTerrain(bpy.types.Operator): + """Button for reloading the terrain mesh at a new resolution.""" + bl_idname = "terrain.reload" + bl_label = "Reload Terrain" + + def execute(self, context): + # Reload the terrain + obj = context.object + path = obj['PATH'] + + scaled_dtm_resolution = obj.scaled_dtm_resolution + + # Reload BTerrain with new DTM + dtm = DTM(path, scaled_dtm_resolution) + BTerrain.reload(obj, dtm) + + return {"FINISHED"} diff --git a/io_scene_obj/__init__.py b/io_scene_obj/__init__.py index 6d1312ec..7712747c 100644 --- a/io_scene_obj/__init__.py +++ b/io_scene_obj/__init__.py @@ -21,8 +21,8 @@ bl_info = { "name": "Wavefront OBJ format", "author": "Campbell Barton, Bastien Montagne", - "version": (2, 3, 3), - "blender": (2, 77, 0), + "version": (2, 3, 5), + "blender": (2, 78, 0), "location": "File > Import-Export", "description": "Import-Export OBJ, Import OBJ mesh, UV's, materials and textures", "warning": "", diff --git a/io_scene_obj/export_obj.py b/io_scene_obj/export_obj.py index 89613368..e28d607d 100644 --- a/io_scene_obj/export_obj.py +++ b/io_scene_obj/export_obj.py @@ -397,6 +397,9 @@ def write_file(filepath, objects, scene, continue me.transform(EXPORT_GLOBAL_MATRIX * ob_mat) + # If negative scaling, we have to invert the normals... + if ob_mat.determinant() < 0.0: + me.flip_normals() if EXPORT_TRI: # _must_ do this first since it re-allocs arrays diff --git a/io_scene_obj/import_obj.py b/io_scene_obj/import_obj.py index 36b0106d..eb314c01 100644 --- a/io_scene_obj/import_obj.py +++ b/io_scene_obj/import_obj.py @@ -315,16 +315,16 @@ def create_materials(filepath, relpath, if do_highlight: if use_cycles: - context_mat_wrap.hardness_value_set = 1.0 + context_mat_wrap.hardness_value_set(1.0) # FIXME, how else to use this? context_material.specular_intensity = 1.0 else: if use_cycles: - context_mat_wrap.hardness_value_set = 0.0 + context_mat_wrap.hardness_value_set(0.0) if do_reflection: if use_cycles: - context_mat_wrap.reflect_factor_set = 1.0 + context_mat_wrap.reflect_factor_set(1.0) context_material.raytrace_mirror.use = True context_material.raytrace_mirror.reflect_factor = 1.0 diff --git a/lighting_dynamic_sky.py b/lighting_dynamic_sky.py new file mode 100644 index 00000000..85b57ce0 --- /dev/null +++ b/lighting_dynamic_sky.py @@ -0,0 +1,405 @@ +# Dynamic Sky.py (c) 2015 Pratik Solanki (Draguu) + +# ##### 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 ##### + +bl_info = { + "name": "Dynamic Sky", + "author": "Pratik Solanki", + "version": (1, 0, 2), + "blender": (2, 78, 0), + "location": "View3D > Tools", + "description": "Creates Dynamic Sky for Cycles", + "warning": "", + "wiki_url": "http://www.dragoneex.com/downloads/dynamic-skyadd-on", + "category": "Lighting", + } + +import bpy +from bpy.props import StringProperty +from bpy.types import ( + Operator, + Panel, + ) + + +# Handle error notifications +def error_handlers(self, error, reports="ERROR"): + if self and reports: + self.report({'WARNING'}, reports + " (See Console for more info)") + + print("\n[Dynamic Sky]\nError: {}\n".format(error)) + + +def check_world_name(name_id="Dynamic"): + # check if the new name pattern is in world data + name_list = [] + suffix = 1 + try: + name_list = [world.name for world in bpy.data.worlds if name_id in world.name] + new_name = "{}_{}".format(name_id, len(name_list) + suffix) + if new_name in name_list: + # KISS failed - numbering is not sequential + # try harvesting numbers in world names, find the rightmost ones + test_num = [] + from re import findall + for words in name_list: + test_num.append(findall("\d+", words)) + + suffix += max([int(l[-1]) for l in test_num]) + new_name = "{}_{}".format(name_id, suffix) + return new_name + except Exception as e: + error_handlers(False, e) + pass + return name_id + + +class dsky(Operator): + bl_idname = "sky.dyn" + bl_label = "Make a Procedural sky" + bl_description = "Make a Procedural Sky" + + def execute(self, context): + try: + get_name = check_world_name() + context.scene.dynamic_sky_name = get_name + bpy.context.scene.render.engine = 'CYCLES' + + world = bpy.data.worlds.new(get_name) + world.cycles.sample_as_light = True + world.cycles.sample_map_resolution = 2048 + world.use_nodes = True + + nt = world.node_tree + bg = world.node_tree.nodes['Background'] + + bg.inputs[0].default_value[:3] = (0.5, .1, 0.6) + bg.inputs[1].default_value = 1 + ntl = nt.links.new + tcor = nt.nodes.new(type="ShaderNodeTexCoord") + map = nt.nodes.new(type="ShaderNodeMapping") + map.vector_type = 'NORMAL' + + nor = nt.nodes.new(type="ShaderNodeNormal") + + cr1 = nt.nodes.new(type="ShaderNodeValToRGB") + cr1.color_ramp.elements[0].position = 0.969 + cr1.color_ramp.interpolation = 'EASE' + cr2 = nt.nodes.new(type="ShaderNodeValToRGB") + cr2.color_ramp.elements[0].position = 0.991 + cr2.color_ramp.elements[1].position = 1 + cr2.color_ramp.interpolation = 'EASE' + cr3 = nt.nodes.new(type="ShaderNodeValToRGB") + cr3.color_ramp.elements[0].position = 0.779 + cr3.color_ramp.elements[1].position = 1 + cr3.color_ramp.interpolation = 'EASE' + + mat1 = nt.nodes.new(type="ShaderNodeMath") + mat1.operation = 'MULTIPLY' + mat1.inputs[1].default_value = 0.2 + mat2 = nt.nodes.new(type="ShaderNodeMath") + mat2.operation = 'MULTIPLY' + mat2.inputs[1].default_value = 2 + mat3 = nt.nodes.new(type="ShaderNodeMath") + mat3.operation = 'MULTIPLY' + mat3.inputs[1].default_value = 40.9 + mat4 = nt.nodes.new(type="ShaderNodeMath") + mat4.operation = 'SUBTRACT' + mat4.inputs[1].default_value = 1 + ntl(mat2.inputs[0], mat1.outputs[0]) + ntl(mat4.inputs[0], mat3.outputs[0]) + ntl(mat1.inputs[0], cr3.outputs[0]) + ntl(mat3.inputs[0], cr2.outputs[0]) + + soft = nt.nodes.new(type="ShaderNodeMixRGB") + soft_1 = nt.nodes.new(type="ShaderNodeMixRGB") + soft.inputs[0].default_value = 1 + soft_1.inputs[0].default_value = 0.466 + ntl(soft.inputs[1], mat2.outputs[0]) + ntl(soft.inputs[2], mat4.outputs[0]) + ntl(soft_1.inputs[1], mat2.outputs[0]) + ntl(soft_1.inputs[2], cr2.outputs[0]) + + mix1 = nt.nodes.new(type="ShaderNodeMixRGB") + mix1.blend_type = 'MULTIPLY' + mix1.inputs[0].default_value = 1 + mix1_1 = nt.nodes.new(type="ShaderNodeMixRGB") + mix1_1.blend_type = 'MULTIPLY' + mix1_1.inputs[0].default_value = 1 + + mix2 = nt.nodes.new(type="ShaderNodeMixRGB") + mix2_1 = nt.nodes.new(type="ShaderNodeMixRGB") + mix2.inputs[1].default_value = (0, 0, 0, 1) + mix2.inputs[2].default_value = (32, 22, 14, 200) + mix2_1.inputs[1].default_value = (0, 0, 0, 1) + mix2_1.inputs[2].default_value = (1, 0.820, 0.650, 1) + + ntl(mix1.inputs[1], soft.outputs[0]) + ntl(mix1_1.inputs[1], soft_1.outputs[0]) + ntl(mix2.inputs[0], mix1.outputs[0]) + ntl(mix2_1.inputs[0], mix1_1.outputs[0]) + + gam = nt.nodes.new(type="ShaderNodeGamma") + gam.inputs[1].default_value = 2.3 + gam2 = nt.nodes.new(type="ShaderNodeGamma") + gam2.inputs[1].default_value = 1 + gam3 = nt.nodes.new(type="ShaderNodeGamma") + gam3.inputs[1].default_value = 1 + + sunopa = nt.nodes.new(type="ShaderNodeMixRGB") + sunopa.blend_type = 'ADD' + sunopa.inputs[0].default_value = 1 + sunopa_1 = nt.nodes.new(type="ShaderNodeMixRGB") + sunopa_1.blend_type = 'ADD' + sunopa_1.inputs[0].default_value = 1 + + combine = nt.nodes.new(type="ShaderNodeMixRGB") + ntl(combine.inputs[1], sunopa.outputs[0]) + ntl(combine.inputs[2], sunopa_1.outputs[0]) + lp = nt.nodes.new(type="ShaderNodeLightPath") + ntl(combine.inputs[0], lp.outputs[0]) + + ntl(gam2.inputs[0], gam.outputs[0]) + ntl(gam.inputs[0], mix2.outputs[0]) + ntl(bg.inputs[0], combine.outputs[0]) + + map2 = nt.nodes.new(type="ShaderNodeMapping") + map2.scale[2] = 6.00 + map2.scale[0] = 1.5 + map2.scale[1] = 1.5 + + n1 = nt.nodes.new(type="ShaderNodeTexNoise") + n1.inputs[1].default_value = 3.8 + n1.inputs[2].default_value = 2.4 + n1.inputs[3].default_value = 0.5 + + n2 = nt.nodes.new(type="ShaderNodeTexNoise") + n2.inputs[1].default_value = 2.0 + n2.inputs[2].default_value = 10 + n2.inputs[3].default_value = 0.2 + + ntl(n2.inputs[0], map2.outputs[0]) + ntl(n1.inputs[0], map2.outputs[0]) + + sc1 = nt.nodes.new(type="ShaderNodeValToRGB") + sc2 = nt.nodes.new(type="ShaderNodeValToRGB") + sc3 = nt.nodes.new(type="ShaderNodeValToRGB") + sc3_1 = nt.nodes.new(type="ShaderNodeValToRGB") + sc4 = nt.nodes.new(type="ShaderNodeValToRGB") + + sc1.color_ramp.elements[1].position = 0.649 + sc1.color_ramp.elements[0].position = 0.408 + + sc2.color_ramp.elements[1].position = 0.576 + sc2.color_ramp.elements[0].position = 0.408 + + sc3.color_ramp.elements.new(0.5) + sc3.color_ramp.elements[2].position = 0.435 + + sc3.color_ramp.elements[1].position = 0.160 + sc3.color_ramp.elements[0].position = 0.027 + + sc3.color_ramp.elements[1].color = (1, 1, 1, 1) + sc3.color_ramp.elements[0].color = (0.419, 0.419, 0.419, 0.419) + + sc3.color_ramp.elements[0].position = 0.0 + sc4.color_ramp.elements[0].position = 0.0 + sc4.color_ramp.elements[1].position = 0.469 + sc4.color_ramp.elements[1].color = (0, 0, 0, 1) + sc4.color_ramp.elements[0].color = (1, 1, 0.917412, 1) + + sc3_1.color_ramp.elements.new(0.5) + sc3_1.color_ramp.elements[2].position = 0.435 + + sc3_1.color_ramp.elements[1].position = 0.187 + sc3_1.color_ramp.elements[1].color = (1, 1, 1, 1) + sc3_1.color_ramp.elements[0].color = (0, 0, 0, 0) + sc3_1.color_ramp.elements[0].position = 0.0 + + smix1 = nt.nodes.new(type="ShaderNodeMixRGB") + smix2 = nt.nodes.new(type="ShaderNodeMixRGB") + smix2_1 = nt.nodes.new(type="ShaderNodeMixRGB") + smix3 = nt.nodes.new(type="ShaderNodeMixRGB") + smix4 = nt.nodes.new(type="ShaderNodeMixRGB") + smix5 = nt.nodes.new(type="ShaderNodeMixRGB") + + smix1.inputs[1].default_value = (1, 1, 1, 1) + smix1.inputs[2].default_value = (0, 0, 0, 1) + smix2.inputs[0].default_value = 0.267 + smix2.blend_type = 'MULTIPLY' + smix2_1.inputs[0].default_value = 1 + smix2_1.blend_type = 'MULTIPLY' + + smix3.inputs[1].default_value = (0.434, 0.838, 1, 1) + smix3.inputs[2].default_value = (0.962, 0.822, 0.822, 1) + smix4.blend_type = 'MULTIPLY' + smix4.inputs[0].default_value = 1 + smix5.blend_type = 'SCREEN' + smix5.inputs[0].default_value = 1 + + srgb = nt.nodes.new(type="ShaderNodeSeparateRGB") + aniadd = nt.nodes.new(type="ShaderNodeMath") + crgb = nt.nodes.new(type="ShaderNodeCombineRGB") + sunrgb = nt.nodes.new(type="ShaderNodeMixRGB") + sunrgb.blend_type = 'MULTIPLY' + sunrgb.inputs[2].default_value = (32, 30, 30, 200) + sunrgb.inputs[0].default_value = 1 + + ntl(mix2.inputs[2], sunrgb.outputs[0]) + + ntl(smix1.inputs[0], sc2.outputs[0]) + ntl(smix2.inputs[1], smix1.outputs[0]) + ntl(smix2.inputs[2], sc1.outputs[0]) + ntl(smix2_1.inputs[2], sc3_1.outputs[0]) + ntl(smix3.inputs[0], sc4.outputs[0]) + ntl(smix4.inputs[2], smix3.outputs[0]) + ntl(smix4.inputs[1], sc3.outputs[0]) + ntl(smix5.inputs[1], smix4.outputs[0]) + ntl(smix2_1.inputs[1], smix2.outputs[0]) + ntl(smix5.inputs[2], smix2_1.outputs[0]) + ntl(sunopa.inputs[1], gam3.outputs[0]) + ntl(gam3.inputs[0], smix5.outputs[0]) + ntl(mix1.inputs[2], sc3.outputs[0]) + ntl(sunopa.inputs[2], gam2.outputs[0]) + + ntl(sc1.inputs[0], n1.outputs[0]) + ntl(sc2.inputs[0], n2.outputs[0]) + + skynor = nt.nodes.new(type="ShaderNodeNormal") + + ntl(sc3.inputs[0], skynor.outputs[1]) + ntl(sc4.inputs[0], skynor.outputs[1]) + ntl(sc3_1.inputs[0], skynor.outputs[1]) + ntl(map2.inputs[0], crgb.outputs[0]) + ntl(skynor.inputs[0], tcor.outputs[0]) + ntl(mix1_1.inputs[2], sc3.outputs[0]) + ntl(srgb.inputs[0], tcor.outputs[0]) + ntl(crgb.inputs[1], srgb.outputs[1]) + ntl(crgb.inputs[2], srgb.outputs[2]) + ntl(aniadd.inputs[1], srgb.outputs[0]) + ntl(crgb.inputs[0], aniadd.outputs[0]) + + ntl(cr1.inputs[0], nor.outputs[1]) + ntl(cr2.inputs[0], cr1.outputs[0]) + ntl(cr3.inputs[0], nor.outputs[1]) + ntl(nor.inputs[0], map.outputs[0]) + ntl(map.inputs[0], tcor.outputs[0]) + ntl(sunopa_1.inputs[1], smix5.outputs[0]) + ntl(sunopa_1.inputs[2], mix2_1.outputs[0]) + + except Exception as e: + error_handlers(self, e, "Make a Procedural sky has failed") + + return {"CANCELLED"} + + return {'FINISHED'} + + +def draw_world_settings(col, context): + get_world = context.scene.world + stored_name = context.scene.dynamic_sky_name + get_world_keys = bpy.data.worlds.keys() + + if stored_name not in get_world_keys or len(get_world_keys) < 1: + col.label(text="The {} World could not".format(stored_name), + icon="INFO") + col.label(text="be found in the Worlds' Data", icon="BLANK1") + return + + elif not (get_world and get_world.name == stored_name): + col.label(text="Please select the World", icon="INFO") + col.label(text="named {}".format(stored_name), icon="BLANK1") + col.label(text="from the Properties > World", icon="BLANK1") + return + + pick_world = bpy.data.worlds[stored_name] + try: + m = pick_world.node_tree.nodes[28] + m = pick_world.node_tree.nodes['Mix.012'].inputs[1] + n = pick_world.node_tree.nodes['Mix.012'].inputs[2] + o = pick_world.node_tree.nodes['Mix.014'].inputs[0] + d = pick_world.node_tree.nodes['Mix.010'].inputs[0] + so = pick_world.node_tree.nodes['Gamma.001'].inputs[1] + so2 = pick_world.node_tree.nodes['Gamma.002'].inputs[1] + # sc = pick_world.node_tree.nodes['Mix.004'].inputs[2] + no = pick_world.node_tree.nodes['Normal'].outputs[0] + sof = pick_world.node_tree.nodes['Mix'].inputs[0] + bgp = pick_world.node_tree.nodes['Background'].inputs[1] + + suc = pick_world.node_tree.nodes['Mix.015'].inputs[1] + except: + col.label(text="Please Create a new World", icon="INFO") + col.label(text="seems that there was already", icon="BLANK1") + col.label(text="one called {}".format(stored_name), icon="BLANK1") + return + + col.label("World: %s" % stored_name) + col.separator() + + col.label("Scene Control") + col.prop(bgp, "default_value", text="Brightness") + col.prop(so2, "default_value", text="Shadow color saturation") + + col.label("Sky Control") + col.prop(m, "default_value", text="Cloud color") + col.prop(n, "default_value", text="Horizon Color") + col.prop(o, "default_value", text="Cloud opacity") + col.prop(d, "default_value", text="Cloud density") + + col.label("Sun Control") + col.prop(suc, "default_value", text="") + col.prop(so, "default_value", text="Sun value") + col.prop(sof, "default_value", text="Soft hard") + + col.prop(no, "default_value", text="") + + +class Dynapanel(Panel): + bl_label = "Dynamic sky" + bl_idname = "SCENE_PT_layout" + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' + bl_context = "objectmode" + bl_category = "Tools" + + def draw(self, context): + layout = self.layout + layout.operator("sky.dyn", text="Create", icon='MAT_SPHERE_SKY') + + col = layout.column() + draw_world_settings(col, context) + + +def register(): + bpy.utils.register_class(Dynapanel) + bpy.utils.register_class(dsky) + bpy.types.Scene.dynamic_sky_name = StringProperty( + name="", + default="Dynamic" + ) + + +def unregister(): + bpy.utils.unregister_class(Dynapanel) + bpy.utils.unregister_class(dsky) + del bpy.types.Scene.dynamic_sky_name + + +if __name__ == "__main__": + register() diff --git a/measureit/measureit_main.py b/measureit/measureit_main.py index 024fa71c..f5d78ad8 100644 --- a/measureit/measureit_main.py +++ b/measureit/measureit_main.py @@ -677,6 +677,7 @@ class MeasureitConfPanel(Panel): bl_space_type = 'VIEW_3D' bl_region_type = "TOOLS" bl_category = 'Measureit' + bl_options = {'DEFAULT_CLOSED'} # ------------------------------ # Draw UI @@ -711,6 +712,7 @@ class MeasureitRenderPanel(Panel): bl_space_type = 'VIEW_3D' bl_region_type = "TOOLS" bl_category = 'Measureit' + bl_options = {'DEFAULT_CLOSED'} # ------------------------------ # Draw UI diff --git a/mesh_extra_tools/__init__.py b/mesh_extra_tools/__init__.py index eeeb7594..3ea99e58 100644 --- a/mesh_extra_tools/__init__.py +++ b/mesh_extra_tools/__init__.py @@ -25,7 +25,7 @@ bl_info = { "name": "Edit Tools 2", "author": "meta-androcto", - "version": (0, 3, 3), + "version": (0, 3, 4), "blender": (2, 78, 0), "location": "View3D > Toolshelf > Tools and Specials (W-key)", "description": "Extra mesh edit tools - modifying meshes and selection", diff --git a/mesh_extra_tools/mesh_edge_roundifier.py b/mesh_extra_tools/mesh_edge_roundifier.py index e8ef63b3..de3eb2bf 100644 --- a/mesh_extra_tools/mesh_edge_roundifier.py +++ b/mesh_extra_tools/mesh_edge_roundifier.py @@ -20,7 +20,7 @@ bl_info = { "name": "Edge Roundifier", "category": "Mesh", "author": "Piotr Komisarczyk (komi3D), PKHG", - "version": (1, 0, 0), + "version": (1, 0, 1), "blender": (2, 7, 3), "location": "SPACE > Edge Roundifier or CTRL-E > " "Edge Roundifier or Tools > Addons > Edge Roundifier", @@ -224,7 +224,7 @@ class CalculationHelper: return refPoint -# SELECTION METHODS # +# Selection Methods # class SelectionHelper: @@ -414,8 +414,10 @@ class EdgeRoundifier(Operator): description="Entry mode switch between Angle and Radius\n" "If Angle is selected, arc radius is calculated from it" ) - rotateCenterItems = [("Spin", "Spin", ""), ("V1", "V1", ""), - ("Edge", "Edge", ""), ("V2", "V2", "")] + rotateCenterItems = [ + ("Spin", "Spin", ""), ("V1", "V1", ""), + ("Edge", "Edge", ""), ("V2", "V2", "") + ] rotateCenter = EnumProperty( items=rotateCenterItems, name="", @@ -429,10 +431,12 @@ class EdgeRoundifier(Operator): default='FullEdgeArc', description="Arc mode - switch between Full and Half arcs" ) - angleItems = [('Other', "Other", "User defined angle"), ('180', "180", "HemiCircle (2 sides)"), - ('120', "120", "TriangleCircle (3 sides)"), ('90', "90", "QuadCircle (4 sides)"), - ('72', "72", "PentagonCircle (5 sides)"), ('60', "60", "HexagonCircle (6 sides)"), - ('45', "45", "OctagonCircle (8 sides)"), ('30', "30", "DodecagonCircle (12 sides)")] + angleItems = [ + ('Other', "Other", "User defined angle"), ('180', "180", "HemiCircle (2 sides)"), + ('120', "120", "TriangleCircle (3 sides)"), ('90', "90", "QuadCircle (4 sides)"), + ('72', "72", "PentagonCircle (5 sides)"), ('60', "60", "HexagonCircle (6 sides)"), + ('45', "45", "OctagonCircle (8 sides)"), ('30', "30", "DodecagonCircle (12 sides)") + ] angleEnum = EnumProperty( items=angleItems, name="", @@ -447,18 +451,22 @@ class EdgeRoundifier(Operator): default='ORG', description="Reference location used to calculate initial centers of drawn arcs" ) - planeItems = [(XY, "XY", "XY Plane (Z=0)"), - (YZ, "YZ", "YZ Plane (X=0)"), - (XZ, "XZ", "XZ Plane (Y=0)")] + planeItems = [ + (XY, "XY", "XY Plane (Z=0)"), + (YZ, "YZ", "YZ Plane (X=0)"), + (XZ, "XZ", "XZ Plane (Y=0)") + ] planeEnum = EnumProperty( items=planeItems, name="", default='XY', description="Plane used to calculate spin plane of drawn arcs" ) - edgeScaleCenterItems = [('V1', "V1", "v1 - First Edge's Vertex"), - ('CENTER', "Center", "Center of the Edge"), - ('V2', "V2", "v2 - Second Edge's Vertex")] + edgeScaleCenterItems = [ + ('V1', "V1", "v1 - First Edge's Vertex"), + ('CENTER', "Center", "Center of the Edge"), + ('V2', "V2", "v2 - Second Edge's Vertex") + ] edgeScaleCenterEnum = EnumProperty( items=edgeScaleCenterItems, name="Edge scale center", @@ -471,8 +479,9 @@ class EdgeRoundifier(Operator): @classmethod def poll(cls, context): - return ((context.scene.objects.active.type == 'MESH') and - (context.scene.objects.active.mode == 'EDIT')) + obj = context.active_object + return (obj and obj.type == 'MESH' and + obj.mode == 'EDIT') def prepareMesh(self, context): bpy.ops.object.mode_set(mode='OBJECT') diff --git a/mesh_tissue/__init__.py b/mesh_tissue/__init__.py index 1c0945ed..7c1e7fba 100644 --- a/mesh_tissue/__init__.py +++ b/mesh_tissue/__init__.py @@ -17,7 +17,7 @@ # ##### END GPL LICENSE BLOCK ##### # --------------------------------- TISSUE ------------------------------------# -#-------------------------------- version 0.29 --------------------------------# +#-------------------------------- version 0.3 ---------------------------------# # # # Creates duplicates of selected mesh to active morphing the shape according # # to target faces. # @@ -41,6 +41,7 @@ else: from . import tessellate_numpy from . import colors_groups_exchanger from . import dual_mesh + from . import lattice import bpy from mathutils import Vector @@ -50,8 +51,8 @@ from mathutils import Vector bl_info = { "name": "Tissue", "author": "Alessandro Zomparelli (Co-de-iT)", - "version": (0, 2, 9), - "blender": (2, 7, 8), + "version": (0, 3, 1), + "blender": (2, 7, 9), "location": "", "description": "Tools for Computational Design", "warning": "", @@ -71,6 +72,7 @@ def unregister(): tessellate_numpy.unregister() colors_groups_exchanger.unregister() dual_mesh.unregister() + lattice.unregister() if __name__ == "__main__": diff --git a/mesh_tissue/colors_groups_exchanger.py b/mesh_tissue/colors_groups_exchanger.py index c2e45e6f..39b3c115 100644 --- a/mesh_tissue/colors_groups_exchanger.py +++ b/mesh_tissue/colors_groups_exchanger.py @@ -26,7 +26,7 @@ # For use the command "Vertex Clors to Vertex Groups" use the search bar # # (space bar). # # # -# (c) Alessandro Zomparelli # +# (c) Alessandro Zomparelli # # (2017) # # # # http://www.co-de-it.com/ # @@ -35,6 +35,7 @@ import bpy import math +from math import pi bl_info = { "name": "Colors/Groups Exchanger", @@ -51,8 +52,9 @@ bl_info = { class vertex_colors_to_vertex_groups(bpy.types.Operator): bl_idname = "object.vertex_colors_to_vertex_groups" - bl_label = "Weight from Colors" + bl_label = "Vertex Color" bl_options = {'REGISTER', 'UNDO'} + bl_description = ("Convert the active Vertex Color into a Vertex Group.") red = bpy.props.BoolProperty( name="red channel", default=False, description="convert red channel") @@ -135,8 +137,9 @@ class vertex_colors_to_vertex_groups(bpy.types.Operator): class vertex_group_to_vertex_colors(bpy.types.Operator): bl_idname = "object.vertex_group_to_vertex_colors" - bl_label = "Colors from Weight" + bl_label = "Vertex Group" bl_options = {'REGISTER', 'UNDO'} + bl_description = ("Convert the active Vertex Group into a Vertex Color.") channel = bpy.props.EnumProperty( items=[('Blue', 'Blue Channel', 'Convert to Blue Channel'), @@ -212,13 +215,59 @@ class vertex_group_to_vertex_colors(bpy.types.Operator): bpy.context.object.data.vertex_colors[colors_id].active_render = True return {'FINISHED'} +class curvature_to_vertex_groups(bpy.types.Operator): + bl_idname = "object.curvature_to_vertex_groups" + bl_label = "Curvature" + bl_options = {'REGISTER', 'UNDO'} + invert = bpy.props.BoolProperty( + name="invert", default=False, description="invert values") + bl_description = ("Generate a Vertex Group based on the curvature of the" + "mesh. Is based on Dirty Vertex Color.") + + blur_strength = bpy.props.FloatProperty( + name="Blur Strength", default=1, min=0.001, + max=1, description="Blur strength per iteration") + + blur_iterations = bpy.props.IntProperty( + name="Blur Iterations", default=1, min=0, + max=40, description="Number of times to blur the values") + + min_angle = bpy.props.FloatProperty( + name="Min Angle", default=0, min=0, + max=pi/2, subtype='ANGLE', description="Minimum angle") + + max_angle = bpy.props.FloatProperty( + name="Max Angle", default=pi, min=pi/2, + max=pi, subtype='ANGLE', description="Maximum angle") + + invert = bpy.props.BoolProperty( + name="Invert", default=False, + description="Invert the curvature map") + + def execute(self, context): + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.mesh.vertex_color_add() + vertex_colors = bpy.context.active_object.data.vertex_colors + vertex_colors[-1].active = True + vertex_colors[-1].active_render = True + vertex_colors[-1].name = "Curvature" + for c in vertex_colors[-1].data: c.color.r, c.color.g, c.color.b = 1,1,1 + bpy.ops.object.mode_set(mode='VERTEX_PAINT') + bpy.ops.paint.vertex_color_dirt(blur_strength=self.blur_strength, blur_iterations=self.blur_iterations, clean_angle=self.max_angle, dirt_angle=self.min_angle) + bpy.ops.object.vertex_colors_to_vertex_groups(invert=self.invert) + bpy.ops.mesh.vertex_color_remove() + return {'FINISHED'} + + class face_area_to_vertex_groups(bpy.types.Operator): bl_idname = "object.face_area_to_vertex_groups" - bl_label = "Weight from Faces Area" + bl_label = "Area" bl_options = {'REGISTER', 'UNDO'} invert = bpy.props.BoolProperty( name="invert", default=False, description="invert values") + bl_description = ("Generate a Vertex Group based on the area of individual" + "faces.") def execute(self, context): obj = bpy.context.active_object @@ -237,7 +286,6 @@ class face_area_to_vertex_groups(bpy.types.Operator): max_area = False n_values = [0]*len(obj.data.vertices) values = [0]*len(obj.data.vertices) - print(len(values)) for p in obj.data.polygons: for v in p.vertices: n_values[v] += 1 @@ -266,20 +314,31 @@ class face_area_to_vertex_groups(bpy.types.Operator): class colors_groups_exchanger_panel(bpy.types.Panel): - bl_label = "Colors-Weight Exchanger" - bl_category = "Create" + bl_label = "Tissue Tools" + bl_category = "Tools" bl_space_type = "VIEW_3D" bl_region_type = "TOOLS" + bl_options = {'DEFAULT_CLOSED'} #bl_context = "objectmode" def draw(self, context): - layout = self.layout - col = layout.column(align=True) - col.operator("object.vertex_group_to_vertex_colors", icon="GROUP_VCOL") - col.operator( - "object.vertex_colors_to_vertex_groups", icon="GROUP_VERTEX") - col.separator() - col.operator("object.face_area_to_vertex_groups", icon="SNAP_FACE") + try: + if bpy.context.active_object.type == 'MESH': + layout = self.layout + col = layout.column(align=True) + col.label(text="Transform:") + col.operator("object.dual_mesh") + col.separator() + col.label(text="Weight from:") + col.operator( + "object.vertex_colors_to_vertex_groups", icon="GROUP_VCOL") + col.operator("object.face_area_to_vertex_groups", icon="SNAP_FACE") + col.operator("object.curvature_to_vertex_groups", icon="SMOOTHCURVE") + col.separator() + col.label(text="Vertex Color from:") + col.operator("object.vertex_group_to_vertex_colors", icon="GROUP_VERTEX") + except: + pass def register(): diff --git a/mesh_tissue/dual_mesh.py b/mesh_tissue/dual_mesh.py index a4610254..29926250 100644 --- a/mesh_tissue/dual_mesh.py +++ b/mesh_tissue/dual_mesh.py @@ -15,13 +15,14 @@ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # ##### END GPL LICENSE BLOCK ##### + #---------------------------------- DUAL MESH ---------------------------------# #--------------------------------- version 0.3 --------------------------------# # # # Convert a generic mesh to its dual. With open meshes it can get some wired # # effect on the borders. # # # -# (c) Alessandro Zomparelli # +# (c) Alessandro Zomparelli # # (2017) # # # # http://www.co-de-it.com/ # @@ -47,6 +48,7 @@ class dual_mesh(bpy.types.Operator): bl_idname = "object.dual_mesh" bl_label = "Dual Mesh" bl_options = {'REGISTER', 'UNDO'} + bl_description = ("Convert a generic mesh into a polygonal mesh.") quad_method = bpy.props.EnumProperty( items=[('BEAUTY', 'Beauty', @@ -73,14 +75,31 @@ class dual_mesh(bpy.types.Operator): name="Preserve Borders", default=True, description="Preserve original borders") + apply_modifiers = bpy.props.BoolProperty( + name="Apply Modifiers", default=True, + description="Apply object's modifiers") + def execute(self, context): + mode = context.mode + if mode == 'EDIT_MESH': mode = 'EDIT' act = bpy.context.active_object - sel = bpy.context.selected_objects + if mode != 'OBJECT': + sel = [act] + bpy.ops.object.mode_set(mode='OBJECT') + else: sel = bpy.context.selected_objects doneMeshes = [] + ''' + if self.new_object: + bpy.ops.object.duplicate_move() + for i in range(len(sel)): + bpy.context.selected_objects[i].name = sel[i].name + "_dual" + if sel[i] == act: + bpy.context.scene.objects.active = bpy.context.selected_objects[i] + sel = bpy.context.selected_objects + ''' for ob0 in sel: if ob0.type != 'MESH': continue if ob0.data.name in doneMeshes: continue - ##ob = bpy.data.objects.new("dual_mesh_wip", ob0.data.copy()) ob = ob0 mesh_name = ob0.data.name @@ -94,31 +113,33 @@ class dual_mesh(bpy.types.Operator): count+=1 clones.append(o) if count == n_users: break + if self.apply_modifiers: bpy.ops.object.convert(target='MESH') ob.data = ob.data.copy() bpy.ops.object.select_all(action='DESELECT') ob.select = True bpy.context.scene.objects.active = ob0 bpy.ops.object.mode_set(mode = 'EDIT') - if self.preserve_borders: - bpy.ops.mesh.select_mode( - use_extend=False, use_expand=False, type='EDGE') - bpy.ops.mesh.select_non_manifold( - extend=False, use_wire=False, use_boundary=True, - use_multi_face=False, use_non_contiguous=False, - use_verts=False) - bpy.ops.mesh.extrude_region_move( - MESH_OT_extrude_region={"mirror":False}, - TRANSFORM_OT_translate={"value":(0, 0, 0), - "constraint_axis":(False, False, False), - "constraint_orientation":'GLOBAL', "mirror":False, - "proportional":'DISABLED', - "proportional_edit_falloff":'SMOOTH', "proportional_size":1, - "snap":False, "snap_target":'CLOSEST', - "snap_point":(0, 0, 0), "snap_align":False, - "snap_normal":(0, 0, 0), "gpencil_strokes":False, - "texture_space":False, "remove_on_cancel":False, - "release_confirm":False}) + # prevent borders erosion + bpy.ops.mesh.select_mode( + use_extend=False, use_expand=False, type='EDGE') + bpy.ops.mesh.select_non_manifold( + extend=False, use_wire=False, use_boundary=True, + use_multi_face=False, use_non_contiguous=False, + use_verts=False) + bpy.ops.mesh.extrude_region_move( + MESH_OT_extrude_region={"mirror":False}, + TRANSFORM_OT_translate={"value":(0, 0, 0), + "constraint_axis":(False, False, False), + "constraint_orientation":'GLOBAL', "mirror":False, + "proportional":'DISABLED', + "proportional_edit_falloff":'SMOOTH', "proportional_size":1, + "snap":False, "snap_target":'CLOSEST', + "snap_point":(0, 0, 0), "snap_align":False, + "snap_normal":(0, 0, 0), "gpencil_strokes":False, + "texture_space":False, "remove_on_cancel":False, + "release_confirm":False}) + bpy.ops.mesh.select_mode( use_extend=False, use_expand=False, type='VERT', @@ -130,6 +151,9 @@ class dual_mesh(bpy.types.Operator): bpy.ops.object.mode_set(mode = 'OBJECT') bpy.ops.object.modifier_add(type='SUBSURF') ob.modifiers[-1].name = "dual_mesh_subsurf" + while True: + bpy.ops.object.modifier_move_up(modifier="dual_mesh_subsurf") + if ob.modifiers[0].name == "dual_mesh_subsurf": break bpy.ops.object.modifier_apply( apply_as='DATA', modifier='dual_mesh_subsurf') @@ -197,6 +221,14 @@ class dual_mesh(bpy.types.Operator): bpy.ops.mesh.dissolve_verts() bpy.ops.mesh.select_all(action = 'DESELECT') + # remove border faces + if not self.preserve_borders: + bpy.ops.mesh.select_non_manifold( + extend=False, use_wire=False, use_boundary=True, + use_multi_face=False, use_non_contiguous=False, use_verts=False) + bpy.ops.mesh.select_more() + bpy.ops.mesh.delete(type='FACE') + # clean wires bpy.ops.mesh.select_non_manifold( extend=False, use_wire=True, use_boundary=False, @@ -209,12 +241,13 @@ class dual_mesh(bpy.types.Operator): for o in clones: o.data = ob.data for o in sel: o.select = True bpy.context.scene.objects.active = act + bpy.ops.object.mode_set(mode=mode) return {'FINISHED'} - +''' class dual_mesh_panel(bpy.types.Panel): bl_label = "Dual Mesh" - bl_category = "Create" + bl_category = "Tools" bl_space_type = "VIEW_3D" bl_region_type = "TOOLS" bl_context = (("objectmode")) @@ -227,16 +260,17 @@ class dual_mesh_panel(bpy.types.Panel): col.operator("object.dual_mesh") except: pass +''' def register(): bpy.utils.register_class(dual_mesh) - bpy.utils.register_class(dual_mesh_panel) + #bpy.utils.register_class(dual_mesh_panel) def unregister(): bpy.utils.unregister_class(dual_mesh) - bpy.utils.unregister_class(dual_mesh_panel) + #bpy.utils.unregister_class(dual_mesh_panel) if __name__ == "__main__": diff --git a/mesh_tissue/lattice.py b/mesh_tissue/lattice.py new file mode 100644 index 00000000..0c9e51ea --- /dev/null +++ b/mesh_tissue/lattice.py @@ -0,0 +1,432 @@ +# ##### 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 ##### +#---------------------------- LATTICE ALONG SURFACE ---------------------------# +#--------------------------------- version 0.3 --------------------------------# +# # +# Automatically generate and assign a lattice that follows the active surface. # +# # +# (c) Alessandro Zomparelli # +# (2017) # +# # +# http://www.co-de-it.com/ # +# # +################################################################################ + +import bpy, bmesh +from mathutils import Vector, Matrix + +bl_info = { + "name": "Lattice", + "author": "Alessandro Zomparelli (Co-de-iT)", + "version": (0, 3), + "blender": (2, 7, 8), + "location": "", + "description": "Generate a Lattice based on a grid mesh", + "warning": "", + "wiki_url": "", + "tracker_url": "", + "category": "Mesh"} + + +def not_in(element, grid): + output = True + for loop in grid: + if element in loop: + output = False + break + return output + +def grid_from_mesh(mesh, swap_uv): + bm = bmesh.new() + bm.from_mesh(mesh) + verts_grid = [] + edges_grid = [] + faces_grid = [] + + running_grid = True + while running_grid: + verts_loop = [] + edges_loop = [] + faces_loop = [] + + # storing first point + verts_candidates = [] + if len(faces_grid) == 0: verts_candidates = bm.verts # for first loop check all vertices + else: verts_candidates = [v for v in bm.faces[faces_grid[-1][0]].verts if not_in(v.index, verts_grid)] # for other loops start form the vertices of the first face the last loop, skipping already used vertices + + # check for last loop + is_last = False + for vert in verts_candidates: + if len(vert.link_faces) == 1: # check if corner vertex + vert.select = True + verts_loop.append(vert.index) + is_last = True + break + if not is_last: + for vert in verts_candidates: + new_link_faces = [f for f in vert.link_faces if not_in(f.index, faces_grid)] + if len(new_link_faces) < 2: # check if corner vertex + vert.select = True + verts_loop.append(vert.index) + break + + running_loop = len(verts_loop) > 0 + + while running_loop: + bm.verts.ensure_lookup_table() + id = verts_loop[-1] + link_edges = bm.verts[id].link_edges + # storing second point + if len(verts_loop) == 1: # only one vertex stored in the loop + if len(faces_grid) == 0: ### first loop ### + edge = link_edges[swap_uv] # chose direction + for vert in edge.verts: + if vert.index != id: + vert.select = True + verts_loop.append(vert.index) # new vertex + edges_loop.append(edge.index) # chosen edge + faces_loop.append(edge.link_faces[0].index) # only one face + #edge.link_faces[0].select = True + else: ### other loops ### + for edge in bm.faces[faces_grid[-1][0]].edges: # start from the edges of the first face of the last loop + if bm.verts[verts_loop[0]] in edge.verts and bm.verts[verts_grid[-1][0]] not in edge.verts: # chose an edge starting from the first vertex that is not returning back + for vert in edge.verts: + if vert.index != id: + vert.select = True + verts_loop.append(vert.index) + edges_loop.append(edge.index) + for face in edge.link_faces: + if not_in(face.index,faces_grid): + faces_loop.append(face.index) + # continuing the loop + else: + for edge in link_edges: + for vert in edge.verts: + store_data = False + if not_in(vert.index, verts_grid) and vert.index not in verts_loop: + if len(faces_loop) > 0: + bm.faces.ensure_lookup_table() + if vert not in bm.faces[faces_loop[-1]].verts: store_data = True + else: + store_data = True + if store_data: + vert.select = True + verts_loop.append(vert.index) + edges_loop.append(edge.index) + for face in edge.link_faces: + if not_in(face.index, faces_grid): + faces_loop.append(face.index) + break + # ending condition + if verts_loop[-1] == id or verts_loop[-1] == verts_loop[0]: running_loop = False + + verts_grid.append(verts_loop) + edges_grid.append(edges_loop) + faces_grid.append(faces_loop) + if len(faces_loop) == 0: running_grid = False + return verts_grid, edges_grid, faces_grid + +class lattice_along_surface(bpy.types.Operator): + bl_idname = "object.lattice_along_surface" + bl_label = "Lattice along Surface" + bl_description = ("Automatically add a Lattice modifier to the selected " + "object, adapting it to the active one.\nThe active " + "object must be a rectangular grid compatible with the " + "Lattice's topology.") + bl_options = {'REGISTER', 'UNDO'} + + set_parent = bpy.props.BoolProperty( + name="Set Parent", default=True, + description="Automatically set the Lattice as parent") + + flipNormals = bpy.props.BoolProperty( + name="Flip Normals", default=False, + description="Flip normals direction") + + swapUV = bpy.props.BoolProperty( + name="Swap UV", default=False, + description="Flip grid's U and V") + + flipU = bpy.props.BoolProperty( + name="Flip U", default=False, + description="Flip grid's U") + + flipV = bpy.props.BoolProperty( + name="Flip V", default=False, + description="Flip grid's V") + + flipW = bpy.props.BoolProperty( + name="Flip W", default=False, + description="Flip grid's W") + + use_groups = bpy.props.BoolProperty( + name="Vertex Group", default=False, + description="Use active Vertex Group for lattice's thickness") + + high_quality_lattice = bpy.props.BoolProperty( + name="High quality", default=True, + description="Increase the the subdivisions in normal direction for a " + "more correct result") + + hide_lattice = bpy.props.BoolProperty( + name="Hide Lattice", default=True, + description="Automatically hide the Lattice object") + + scale_x = bpy.props.FloatProperty( + name="Scale X", default=1, min=0.001, + max=1, description="Object scale") + + scale_y = bpy.props.FloatProperty( + name="Scale Y", default=1, min=0.001, + max=1, description="Object scale") + + scale_z = bpy.props.FloatProperty( + name="Scale Z", default=1, min=0.001, + max=1, description="Object scale") + + thickness = bpy.props.FloatProperty( + name="Thickness", default=1, soft_min=0, + soft_max=5, description="Lattice thickness") + + displace = bpy.props.FloatProperty( + name="Displace", default=0, soft_min=-1, + soft_max=1, description="Lattice displace") + + def draw(self, context): + layout = self.layout + col = layout.column(align=True) + col.label(text="Thickness:") + col.prop( + self, "thickness", text="Thickness", icon='NONE', expand=False, + slider=True, toggle=False, icon_only=False, event=False, + full_event=False, emboss=True, index=-1) + col.prop( + self, "displace", text="Offset", icon='NONE', expand=False, + slider=True, toggle=False, icon_only=False, event=False, + full_event=False, emboss=True, index=-1) + row = col.row() + row.prop(self, "use_groups") + col.separator() + col.label(text="Scale:") + col.prop( + self, "scale_x", text="U", icon='NONE', expand=False, + slider=True, toggle=False, icon_only=False, event=False, + full_event=False, emboss=True, index=-1) + col.prop( + self, "scale_y", text="V", icon='NONE', expand=False, + slider=True, toggle=False, icon_only=False, event=False, + full_event=False, emboss=True, index=-1) + ''' + col.prop( + self, "scale_z", text="W", icon='NONE', expand=False, + slider=True, toggle=False, icon_only=False, event=False, + full_event=False, emboss=True, index=-1) + ''' + col.separator() + col.label(text="Flip:") + row = col.row() + row.prop(self, "flipU", text="U") + row.prop(self, "flipV", text="V") + row.prop(self, "flipW", text="W") + col.prop(self, "swapUV") + col.prop(self, "flipNormals") + col.separator() + col.label(text="Lattice Options:") + col.prop(self, "high_quality_lattice") + col.prop(self, "hide_lattice") + col.prop(self, "set_parent") + + def execute(self, context): + if len(bpy.context.selected_objects) != 2: + self.report({'ERROR'}, "Please, select two objects") + return {'CANCELLED'} + grid_obj = bpy.context.active_object + if grid_obj.type not in ('MESH', 'CURVE', 'SURFACE'): + self.report({'ERROR'}, "The surface object is not valid. Only Mesh," + "Curve and Surface objects are allowed.") + return {'CANCELLED'} + obj = None + for o in bpy.context.selected_objects: + if o.name != grid_obj.name and o.type in ('MESH', 'CURVE', \ + 'SURFACE', 'FONT'): + obj = o + o.select = False + break + try: + obj_dim = obj.dimensions + obj_me = obj.to_mesh(bpy.context.scene, apply_modifiers=True, + settings = 'PREVIEW') + except: + self.report({'ERROR'}, "The object to deform is not valid. Only " + "Mesh, Curve, Surface and Font objects are allowed.") + return {'CANCELLED'} + + bpy.ops.object.duplicate_move() + grid_obj = bpy.context.active_object + bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) + grid_mesh = grid_obj.to_mesh(bpy.context.scene, apply_modifiers=True, + settings = 'PREVIEW') + if len(grid_mesh.polygons) > 64*64: + bpy.ops.object.delete(use_global=False) + bpy.context.scene.objects.active = obj + obj.select = True + self.report({'ERROR'}, "Maximum resolution allowed for Lattice is 64") + return {'CANCELLED'} + # CREATING LATTICE + min = Vector((0,0,0)) + max = Vector((0,0,0)) + first = True + for v in obj_me.vertices: + vert = obj.matrix_world * v.co + if vert[0] < min[0] or first: + min[0] = vert[0] + if vert[1] < min[1] or first: + min[1] = vert[1] + if vert[2] < min[2] or first: + min[2] = vert[2] + if vert[0] > max[0] or first: + max[0] = vert[0] + if vert[1] > max[1] or first: + max[1] = vert[1] + if vert[2] > max[2] or first: + max[2] = vert[2] + first = False + bb = max-min + lattice_loc = (max+min)/2 + bpy.ops.object.add(type='LATTICE', view_align=False, + enter_editmode=False) + lattice = bpy.context.active_object + lattice.location = lattice_loc + lattice.scale = Vector((bb.x/self.scale_x, bb.y/self.scale_y, + bb.z/self.scale_z)) + if bb.x == 0: lattice.scale.x = 1 + if bb.y == 0: lattice.scale.y = 1 + if bb.z == 0: lattice.scale.z = 1 + bpy.context.scene.objects.active = obj + bpy.ops.object.modifier_add(type='LATTICE') + obj.modifiers[-1].object = lattice + + # set as parent + if self.set_parent: + obj.select = True + lattice.select = True + bpy.context.scene.objects.active = lattice + bpy.ops.object.parent_set(type='LATTICE') + + # reading grid structure + verts_grid, edges_grid, faces_grid = grid_from_mesh(grid_mesh, + swap_uv=self.swapUV) + nu = len(verts_grid) + nv = len(verts_grid[0]) + nw = 2 + scale_normal = self.thickness + + try: + lattice.data.points_u = nu + lattice.data.points_v = nv + lattice.data.points_w = nw + for i in range(nu): + for j in range(nv): + for w in range(nw): + if self.use_groups: + try: + displace = grid_obj.vertex_groups.active.weight(verts_grid[i][j])*scale_normal*bb.z + except: + displace = scale_normal*bb.z + else: displace = scale_normal*bb.z + target_point = (grid_mesh.vertices[verts_grid[i][j]].co + grid_mesh.vertices[verts_grid[i][j]].normal*(w + self.displace/2 - 0.5)*displace) - lattice.location + if self.flipW: w = 1-w + if self.flipU: i = nu-i-1 + if self.flipV: j = nv-j-1 + lattice.data.points[i + j*nu + w*nu*nv].co_deform.x = target_point.x / bpy.data.objects[lattice.name].scale.x + lattice.data.points[i + j*nu + w*nu*nv].co_deform.y = target_point.y / bpy.data.objects[lattice.name].scale.y + lattice.data.points[i + j*nu + w*nu*nv].co_deform.z = target_point.z / bpy.data.objects[lattice.name].scale.z + except: + bpy.ops.object.mode_set(mode='OBJECT') + grid_obj.select = True + lattice.select = True + obj.select = False + bpy.ops.object.delete(use_global=False) + bpy.context.scene.objects.active = obj + obj.select = True + bpy.ops.object.modifier_remove(modifier=obj.modifiers[-1].name) + if nu > 64 or nv > 64: + self.report({'ERROR'}, "Maximum resolution allowed for Lattice is 64") + return {'CANCELLED'} + else: + self.report({'ERROR'}, "The grid mesh is not correct") + return {'CANCELLED'} + + #grid_obj.data = old_grid_data + #print(old_grid_matrix) + #grid_obj.matrix_world = old_grid_matrix + + bpy.ops.object.mode_set(mode='OBJECT') + grid_obj.select = True + lattice.select = False + obj.select = False + bpy.ops.object.delete(use_global=False) + bpy.context.scene.objects.active = lattice + lattice.select = True + if self.high_quality_lattice: bpy.context.object.data.points_w = 8 + else: bpy.context.object.data.use_outside = True + if self.hide_lattice: + bpy.ops.object.hide_view_set(unselected=False) + bpy.context.scene.objects.active = obj + obj.select = True + lattice.select = False + if self.flipNormals: + try: + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.mesh.select_all(action='SELECT') + bpy.ops.mesh.flip_normals() + bpy.ops.object.mode_set(mode='OBJECT') + except: + pass + return {'FINISHED'} + +''' +class lattice_along_surface_panel(bpy.types.Panel): + bl_label = "Modifiers Tools" + bl_category = "Tools" + bl_space_type = "VIEW_3D" + bl_region_type = "TOOLS" + bl_context = (("objectmode")) + + def draw(self, context): + layout = self.layout + col = layout.column(align=True) + try: + col.operator("object.lattice_along_surface", icon="MOD_LATTICE") + except: + pass +''' + + +def register(): + bpy.utils.register_class(lattice_along_surface) + #bpy.utils.register_class(lattice_along_surface_panel) + + +def unregister(): + bpy.utils.unregister_class(lattice_along_surface) + #bpy.utils.unregister_class(lattice_along_surface_panel) + + +if __name__ == "__main__": + register() diff --git a/mesh_tissue/tessellate_numpy.py b/mesh_tissue/tessellate_numpy.py index 65afeee7..adf877fd 100644 --- a/mesh_tissue/tessellate_numpy.py +++ b/mesh_tissue/tessellate_numpy.py @@ -22,7 +22,7 @@ # Creates duplicates of selected mesh to active morphing the shape according # # to target faces. # # # -# (c) Alessandro Zomparelli # +# (c) Alessandro Zomparelli # # (2017) # # # # http://www.co-de-it.com/ # @@ -776,17 +776,20 @@ class tessellate(bpy.types.Operator): bpy.ops.object.mode_set(mode='OBJECT') # MATERIALS - # create materials list - polygon_materials = [p.material_index for p in ob1.data.polygons]*int( - len(new_ob.data.polygons) / len(ob1.data.polygons)) - # assign old material - component_materials = [slot.material for slot in ob1.material_slots] - for i in range(len(component_materials)): - bpy.ops.object.material_slot_add() - bpy.context.object.material_slots[i].material = \ - component_materials[i] - for i in range(len(new_ob.data.polygons)): - new_ob.data.polygons[i].material_index = polygon_materials[i] + try: + # create materials list + polygon_materials = [p.material_index for p in ob1.data.polygons]*int( + len(new_ob.data.polygons) / len(ob1.data.polygons)) + # assign old material + component_materials = [slot.material for slot in ob1.material_slots] + for i in range(len(component_materials)): + bpy.ops.object.material_slot_add() + bpy.context.object.material_slots[i].material = \ + component_materials[i] + for i in range(len(new_ob.data.polygons)): + new_ob.data.polygons[i].material_index = polygon_materials[i] + except: + pass return {'FINISHED'} @@ -871,17 +874,20 @@ class update_tessellate(bpy.types.Operator): bpy.ops.object.mode_set(mode='OBJECT') # MATERIALS - # create materials list - polygon_materials = [p.material_index for p in ob1.data.polygons]*int( - len(ob.data.polygons) / len(ob1.data.polygons)) - # assign old material - component_materials = [slot.material for slot in ob1.material_slots] - for i in range(len(component_materials)): - bpy.ops.object.material_slot_add() - bpy.context.object.material_slots[i].material = \ - component_materials[i] - for i in range(len(ob.data.polygons)): - ob.data.polygons[i].material_index = polygon_materials[i] + try: + # create materials list + polygon_materials = [p.material_index for p in ob1.data.polygons]*int( + len(ob.data.polygons) / len(ob1.data.polygons)) + # assign old material + component_materials = [slot.material for slot in ob1.material_slots] + for i in range(len(component_materials)): + bpy.ops.object.material_slot_add() + bpy.context.object.material_slots[i].material = \ + component_materials[i] + for i in range(len(ob.data.polygons)): + ob.data.polygons[i].material_index = polygon_materials[i] + except: + pass return {'FINISHED'} @@ -1217,17 +1223,21 @@ class settings_tessellate(bpy.types.Operator): bpy.ops.object.mode_set(mode='OBJECT') # MATERIALS - # create materials list - polygon_materials = [p.material_index for p in ob1.data.polygons] * \ - int(len(self.ob.data.polygons) / len(ob1.data.polygons)) - # assign old material - component_materials = [slot.material for slot in ob1.material_slots] - for i in range(len(component_materials)): - bpy.ops.object.material_slot_add() - bpy.context.object.material_slots[i].material = \ - component_materials[i] - for i in range(len(self.ob.data.polygons)): - self.ob.data.polygons[i].material_index = polygon_materials[i] + try: + # create materials list + polygon_materials = [p.material_index for p in ob1.data.polygons] * \ + int(len(self.ob.data.polygons) / len(ob1.data.polygons)) + # assign old material + component_materials = [slot.material for slot in ob1.material_slots] + for i in range(len(component_materials)): + bpy.ops.object.material_slot_add() + bpy.context.object.material_slots[i].material = \ + component_materials[i] + for i in range(len(self.ob.data.polygons)): + self.ob.data.polygons[i].material_index = polygon_materials[i] + except: + pass + return {'FINISHED'} def check(self, context): @@ -1238,21 +1248,26 @@ class settings_tessellate(bpy.types.Operator): class tessellate_panel(bpy.types.Panel): - bl_label = "Tessellate" + bl_label = "Tissue" bl_category = "Create" bl_space_type = "VIEW_3D" bl_region_type = "TOOLS" - #bl_context = "objectmode", "editmode" + bl_options = {'DEFAULT_CLOSED'} + #bl_context = "objectmode" + + @classmethod + def poll(cls, context): + return context.mode in {'OBJECT', 'EDIT_MESH'} def draw(self, context): layout = self.layout col = layout.column(align=True) - col.label(text="Add:") + col.label(text="Tessellate Add:") col.operator("object.tessellate")#, icon="STRANDS") #col.enable = False #col.operator("object.adaptive_duplifaces", icon="MESH_CUBE") col = layout.column(align=True) - col.label(text="Edit:") + col.label(text="Tessellate Edit:") col.operator("object.settings_tessellate") col.operator("object.update_tessellate") col = layout.column(align=True) @@ -1264,6 +1279,11 @@ class tessellate_panel(bpy.types.Panel): if(ob1.name == act.name or ob1.type != 'MESH'): continue sel = ob1 + col.separator() + col.label(text="Add Modifier:") + col.operator("object.lattice_along_surface", icon="OUTLINER_OB_LATTICE") + + class rotate_face(bpy.types.Operator): bl_idname = "mesh.rotate_face" diff --git a/node_wrangler.py b/node_wrangler.py index 4dd88c23..1e242f4b 100644 --- a/node_wrangler.py +++ b/node_wrangler.py @@ -19,8 +19,8 @@ bl_info = { "name": "Node Wrangler", "author": "Bartek Skorupa, Greg Zaal, Sebastian Koenig, Christian Brinkmann", - "version": (3, 33), - "blender": (2, 77, 0), + "version": (3, 34), + "blender": (2, 78, 0), "location": "Node Editor Toolbar or Ctrl-Space", "description": "Various tools to enhance and speed up node-based workflow", "warning": "", @@ -3055,7 +3055,7 @@ class NWAddSequence(Operator, ImportHelper): name_with_hashes = without_num + "#"*count_numbers + '.' + extension bpy.ops.node.add_node('INVOKE_DEFAULT', use_transform=True, type=node_type) - node = context.space_data.node_tree.nodes.active + node = nodes.active node.label = name_with_hashes img = bpy.data.images.load(directory+(without_ext+'.'+extension)) diff --git a/object_skinify.py b/object_skinify.py index 354fedc0..b40d234b 100644 --- a/object_skinify.py +++ b/object_skinify.py @@ -19,7 +19,7 @@ bl_info = { "name": "Skinify Rig", "author": "Albert Makac (karab44)", - "version": (0, 8, 1), + "version": (0, 8, 7), "blender": (2, 7, 8), "location": "Properties > Bone > Skinify Rig (visible on pose mode only)", "description": "Creates a mesh object from selected bones", @@ -44,7 +44,37 @@ from mathutils import ( Euler, ) from bpy.app.handlers import persistent - +from enum import Enum + +#can the armature data properties group_prop and row be fetched directly from the rigify script? +horse_data = (1 , 5 ) ,( 2 , 4 ) ,( 3 , 0 ) ,( 4 , 3 ) ,( 5 , 4 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 7 , 2 ) ,( 8 , 5 ) ,( 9 , 4 ) ,( 7 , 2 ) ,( 8 , 5 ) ,( 9 , 4 ) ,( 10 , 2 ) ,( 11 , 5 ) ,( 12 , 4 ) ,( 10 , 2 ) ,( 11 , 5 ) ,( 12 , 4 ) ,( 13 , 6 ) ,( 1 , 4 ) ,( 14 , 6 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 1 , 0 ) ,( 14 , 1 ) , +shark_data = ( 1 , 5 ), ( 2 , 4 ), ( 1 , 0 ), ( 3 , 3 ), ( 4 , 4 ), ( 5 , 6 ), ( 6 , 5 ), ( 7 , 4 ), ( 6 , 5 ), ( 7 , 4 ), ( 8 , 3 ), ( 9 , 4 ), ( 1 , 0 ), ( 1 , 6 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ) , +bird_data = ( 1 , 6 ), ( 2 , 4 ), ( 1 , 0 ), ( 3 , 3 ), ( 4 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 6 , 5 ), ( 8 , 0 ), ( 7 , 4 ), ( 6 , 5 ), ( 8 , 0 ), ( 7 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 13 , 6 ), ( 14 , 4 ), ( 1 , 0 ), ( 8 , 6 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ), +cat_data = ( 1 , 5 ), ( 2 , 2 ), ( 2 , 3 ), ( 3 , 3 ), ( 4 , 4 ), ( 5 , 6 ), ( 6 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 13 , 3 ), ( 14 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 16 , 1 ), +biped_data = ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 3 , 3 ), ( 4 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ), +human_data = ( 1 , 5 ), ( 2 , 2 ), ( 2 , 3 ), ( 3 , 3 ), ( 4 , 4 ), ( 5 , 6 ), ( 6 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ), +wolf_data = ( 1 , 5 ), ( 2 , 2 ), ( 2 , 3 ), ( 3 , 3 ), ( 4 , 4 ), ( 5 , 6 ), ( 6 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 13 , 6 ), ( 1 , 0 ), ( 13 , 0 ), ( 13 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ), +quadruped_data = ( 1 , 0 ), ( 2 , 0 ), ( 2 , 0 ), ( 3 , 3 ), ( 4 , 4 ), ( 5 , 0 ), ( 6 , 0 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 7 , 2 ), ( 8 , 5 ), ( 9 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 10 , 2 ), ( 11 , 5 ), ( 12 , 4 ), ( 13 , 6 ), ( 1 , 0 ), ( 13 , 0 ), ( 13 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 1 , 0 ), ( 14 , 1 ), + +human_legacy_data = ( 1, None ), ( 1, None ), ( 2, None ), ( 1, None ), ( 3, None ), ( 3, None ), ( 4, None ), ( 5, None ), ( 6, None ), ( 4, None ), ( 5, None ), ( 6, None ), ( 7, None ), ( 8, None ), ( 9, None ), ( 7, None ), ( 8, None ), ( 9, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), +pitchipoy_data = ( 1, None ), ( 2, None), ( 2, None ), ( 3, None ), ( 4, None ), ( 5, None ), ( 6, None ), ( 7, None ), ( 8, None ), ( 9, None ), ( 7, None ), ( 8, None ), ( 9, None ), ( 10, None ), ( 11, None ), ( 12, None ), ( 10, None ), ( 11, None ), ( 12, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), ( 1, None ), + +rigify_data = horse_data, shark_data, bird_data, cat_data, biped_data, human_data, wolf_data, quadruped_data, human_legacy_data, pitchipoy_data + +class Rig_type(Enum): + HORSE = 0 + SHARK = 1 + BIRD = 2 + CAT = 3 + BIPED= 4 + HUMAN = 5 + WOLF = 6 + QUAD = 7 + LEGACY = 8 + PITCHIPOY = 9 + OTHER = 10 + +rig_type = Rig_type.OTHER # initialize properties def init_props(): @@ -79,6 +109,109 @@ def select_vertices(mesh_obj, idx): bpy.ops.object.mode_set(mode=mode) return selectedVerts + +def identify_rig(): + if 'rigify_layers' not in bpy.context.object.data: + return Rig_type.OTHER #non recognized + + LEGACY_LAYERS_SIZE = 28 + layers = bpy.context.object.data['rigify_layers'] + + + for type, rig in enumerate(rigify_data): + index = 0 + + + for props in layers: + if len(layers) == LEGACY_LAYERS_SIZE and 'group_prop' not in props: + + if props['row'] != rig[index][0] or rig[index][1] != None: + break + + elif (props['row'] != rig[index][0]) or (props['group_prop'] != rig[index][1]): + break + + #SUCCESS if reach the end + if index == len(layers) -1: + return Rig_type(type) + + index = index + 1 + + return Rig_type.OTHER + +def prepare_ignore_list(rig_type, bones): + # detect the head, face, hands, breast, heels or other exceptionary bones to exclusion or customization + common_ignore_list = ['eye', 'heel', 'breast', 'root'] + + #edit these lists to suits your taste + + + horse_ignore_list = ['chest', 'belly', 'pelvis', 'jaw', 'nose', 'skull', 'ear.' ] + + shark_ignore_list = ['jaw'] + + bird_ignore_list = ['face', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue', 'beak'] + + cat_ignore_list = ['face', 'belly' 'pelvis.C', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] + + biped_ignore_list = ['pelvis'] + + human_ignore_list = ['face', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] + + wolf_ignore_list = ['face', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] + + quad_ignore_list = ['face', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] + + rigify_legacy_ignore_list = [] + + pitchipoy_ignore_list = ['face', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', + 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] + + other_ignore_list = [] + + ignore_list = common_ignore_list + + if rig_type == Rig_type.HORSE: + ignore_list = ignore_list + horse_ignore_list + print("RIDER OF THE APOCALYPSE") + elif rig_type == Rig_type.SHARK: + ignore_list = ignore_list + shark_ignore_list + print("DEADLY JAWS") + elif rig_type == Rig_type.BIRD: + ignore_list = ignore_list + bird_ignore_list + print("WINGS OF LIBERTY") + elif rig_type == Rig_type.CAT: + ignore_list = ignore_list + cat_ignore_list + print("MEOW") + elif rig_type == Rig_type.BIPED: + ignore_list = ignore_list + biped_ignore_list + print("HUMANOID") + elif rig_type == Rig_type.HUMAN: + ignore_list = ignore_list + human_ignore_list + print("JUST A HUMAN AFTER ALL") + elif rig_type == Rig_type.WOLF: + ignore_list = ignore_list + wolf_ignore_list + print("WHITE FANG") + elif rig_type == Rig_type.QUAD: + ignore_list = ignore_list + quad_ignore_list + print("MYSTERIOUS CREATURE") + elif rig_type == Rig_type.LEGACY: + ignore_list = ignore_list + rigify_legacy_ignore_list + print("LEGACY RIGIFY") + elif rig_type == Rig_type.PITCHIPOY: + ignore_list = ignore_list + pitchipoy_ignore_list + print("PITCHIPOY") + elif rig_type == Rig_type.OTHER: + ignore_list = ignore_list + other_ignore_list + print("rig non recognized...") + + + return ignore_list # generates edges from vertices used by skin modifier def generate_edges(mesh, shape_object, bones, scale, connect_mesh=False, connect_parents=False, @@ -87,42 +220,18 @@ def generate_edges(mesh, shape_object, bones, scale, connect_mesh=False, connect This function adds vertices for all heads and tails """ # scene preferences - # scn = bpy.context.scene - - # detect the head, face, hands, breast, heels or other exceptionary bones to exclusion or customization - common_ignore_list = ['eye', 'heel', 'breast', 'root'] - - # bvh_ignore_list = [] - rigify_ignore_list = [] - pitchipoy_ignore_list = ['face', 'breast', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', - 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] - rigify_new_ignore_list = ['face', 'breast', 'pelvis', 'nose', 'lip', 'jaw', 'chin', 'ear.', 'brow', - 'lid', 'forehead', 'temple', 'cheek', 'teeth', 'tongue'] alternate_scale_list = [] - # rig_type rigify = 1, pitchipoy = 2, rigify_new = 3 - rig_type = 0 + me = mesh verts = [] edges = [] idx = 0 alternate_scale_idx_list = list() - ignore_list = common_ignore_list - # detect rig type - for b in bones: - if b.name == 'hips' and b.rigify_type == 'spine': - ignore_list = ignore_list + rigify_ignore_list - rig_type = 1 - break - if b.name == 'spine' and b.rigify_type == 'pitchipoy.super_torso_turbo': - ignore_list = ignore_list + pitchipoy_ignore_list - rig_type = 2 - break - if b.name == 'spine' and b.rigify_type == 'spines.super_spine': - ignore_list = ignore_list + rigify_new_ignore_list - rig_type = 3 - break + rig_type = identify_rig() + ignore_list = prepare_ignore_list(rig_type, bones) + # edge generator loop for b in bones: @@ -150,10 +259,10 @@ def generate_edges(mesh, shape_object, bones, scale, connect_mesh=False, connect if head_ornaments is False: if b.parent is not None: - if 'head' in b.parent.name.lower() and not rig_type == 3: + if 'head' in b.parent.name.lower() and not rig_type == Rig_type.HUMAN: continue - if 'face' in b.parent.name.lower() and rig_type == 3: + if 'face' in b.parent.name.lower() and rig_type == Rig_type.HUMAN: continue if connect_parents: @@ -185,8 +294,8 @@ def generate_edges(mesh, shape_object, bones, scale, connect_mesh=False, connect idx = idx + 2 # for bvh free floating hips and hips correction for rigify and pitchipoy if ((generate_all is False and 'hip' in b.name.lower()) or - (generate_all is False and (b.name == 'hips' and rig_type == 1) or - (b.name == 'spine' and rig_type == 2) or (b.name == 'spine' and rig_type == 3))): + (generate_all is False and (b.name == 'hips' and rig_type == Rig_type.LEGACY) or + (b.name == 'spine' and rig_type == Rig_type.PITCHIPOY) or (b.name == 'spine' and rig_type == Rig_type.HUMAN) or (b.name == 'spine' and rig_type == Rig_type.BIPED))): continue vert1 = b.head @@ -275,14 +384,14 @@ def generate_mesh(shape_object, size, thickness=0.8, finger_thickness=0.25, sub_ bpy.ops.mesh.remove_doubles() # fix rigify and pitchipoy hands topology - if connect_mesh and connect_parents and generate_all is False and rig_type > 0: + if connect_mesh and connect_parents and generate_all is False and (rig_type == Rig_type.LEGACY or rig_type == Rig_type.PITCHIPOY or rig_type == Rig_type.HUMAN): # thickness will set palm vertex for both hands look pretty corrective_thickness = 2.5 # left hand verts merge_idx = [] - if rig_type == 1: + if rig_type == Rig_type.LEGACY: merge_idx = [7, 8, 13, 17, 22, 27] - else: + elif rig_type == Rig_type.PITCHIPOY or rig_type == Rig_type.HUMAN: merge_idx = [9, 14, 18, 23, 24, 29] select_vertices(shape_object, merge_idx) bpy.ops.mesh.merge(type='CENTER') @@ -295,9 +404,9 @@ def generate_mesh(shape_object, size, thickness=0.8, finger_thickness=0.25, sub_ bpy.ops.mesh.select_all(action='DESELECT') # right hand verts - if rig_type == 1: + if rig_type == Rig_type.LEGACY: merge_idx = [30, 35, 39, 44, 45, 50] - else: + elif rig_type == Rig_type.PITCHIPOY or rig_type == Rig_type.HUMAN: merge_idx = [32, 37, 41, 46, 51, 52] select_vertices(shape_object, merge_idx) @@ -312,10 +421,10 @@ def generate_mesh(shape_object, size, thickness=0.8, finger_thickness=0.25, sub_ # making hands even more pretty bpy.ops.mesh.select_all(action='DESELECT') hands_idx = [] # left and right hand vertices - if rig_type == 1: + if rig_type == Rig_type.LEGACY: # hands_idx = [8, 33] # L and R hands_idx = [6, 29] - else: + elif rig_type == Rig_type.PITCHIPOY or rig_type == Rig_type.HUMAN: # hands_idx = [10, 35] # L and R hands_idx = [8, 31] select_vertices(shape_object, hands_idx) @@ -331,9 +440,9 @@ def generate_mesh(shape_object, size, thickness=0.8, finger_thickness=0.25, sub_ # todo optionally take root from rig's hip tail or head depending on scenario root_idx = [] - if rig_type == 1: + if rig_type == Rig_type.LEGACY: root_idx = [59] - elif rig_type == 2: + elif rig_type == Rig_type.PITCHIPOY or rig_type == Rig_type.HUMAN: root_idx = [56] else: root_idx = [0] diff --git a/presets/operator/mesh.landscape_add/abstract.py b/presets/operator/mesh.landscape_add/abstract.py index 617332b0..8cb663d4 100644 --- a/presets/operator/mesh.landscape_add/abstract.py +++ b/presets/operator/mesh.landscape_add/abstract.py @@ -1,21 +1,27 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = True -op.subdivision_x = 128 +op.subdivision_x = 256 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 3.0 op.random_seed = 387 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 1.0 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 1.0 op.noise_type = 'planet_noise' op.basis_type = '3' op.vl_basis_type = '3' @@ -26,29 +32,28 @@ op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 1.0 +op.offset = 1.0 op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' op.height = 1.0 -op.invert = True -op.offset = 0.0 +op.height_invert = True +op.height_offset = 0.0 op.edge_falloff = '0' -op.falloff_size_x = 4.0 -op.falloff_size_y = 4.0 +op.falloff_x = 4.0 +op.falloff_y = 4.0 op.edge_level = 0.0 op.maximum = 1.0 op.minimum = -1.0 +op.use_vgroup = False op.strata = 5.0 op.strata_type = '3' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/canion.py b/presets/operator/mesh.landscape_add/canion.py index 6ac4ad61..6a97d1f3 100644 --- a/presets/operator/mesh.landscape_add/canion.py +++ b/presets/operator/mesh.landscape_add/canion.py @@ -1,21 +1,27 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 128 op.subdivision_y = 192 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 3.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 3.0 op.random_seed = 1 -op.x_offset = 0.25 -op.y_offset = 0.0 -op.noise_size = 1.5 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.25 +op.noise_size_z = 1.0 +op.noise_size = 1.5 op.noise_type = 'marble_noise' op.basis_type = '0' op.vl_basis_type = '0' @@ -26,29 +32,28 @@ op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 1.0 +op.offset = 1.0 op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '4' op.height = 0.6000000238418579 -op.invert = False -op.offset = -0.059999994933605194 +op.height_invert = False +op.height_offset = 0.0 op.edge_falloff = '2' -op.falloff_size_x = 4.0 -op.falloff_size_y = 10.0 +op.falloff_x = 4.0 +op.falloff_y = 4.0 op.edge_level = 0.15000000596046448 op.maximum = 1.0 op.minimum = -0.20000000298023224 +op.use_vgroup = False op.strata = 4.0 op.strata_type = '2' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/cauliflower_hills.py b/presets/operator/mesh.landscape_add/cauliflower_hills.py index 6063f93e..2371b0d3 100644 --- a/presets/operator/mesh.landscape_add/cauliflower_hills.py +++ b/presets/operator/mesh.landscape_add/cauliflower_hills.py @@ -1,22 +1,28 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 128 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 op.random_seed = 860 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 0.5 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 -op.noise_type = 'fractal' +op.noise_size_z = 1.0 +op.noise_size = 0.5 +op.noise_type = 'multi_fractal' op.basis_type = '3' op.vl_basis_type = '0' op.distortion = 1.0 @@ -26,29 +32,28 @@ op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 5.0 -op.moffset = 1.0 +op.offset = 1.0 op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' -op.height = 0.10000000149011612 -op.invert = True -op.offset = 0.05000000074505806 +op.height = 0.20000000298023224 +op.height_invert = True +op.height_offset = 0.0 op.edge_falloff = '3' -op.falloff_size_x = 6.0 -op.falloff_size_y = 6.0 +op.falloff_x = 8.0 +op.falloff_y = 8.0 op.edge_level = 0.0 op.maximum = 1.0 -op.minimum = -0.10999999940395355 +op.minimum = -1.0 +op.use_vgroup = False op.strata = 5.0 op.strata_type = '0' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/cristaline.py b/presets/operator/mesh.landscape_add/cristaline.py index d8a3dc12..89349846 100644 --- a/presets/operator/mesh.landscape_add/cristaline.py +++ b/presets/operator/mesh.landscape_add/cristaline.py @@ -1,21 +1,27 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = True -op.subdivision_x = 128 +op.subdivision_x = 256 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 op.random_seed = 0 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 1.0 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 1.0 op.noise_type = 'turbulence_vector' op.basis_type = '6' op.vl_basis_type = '0' @@ -26,29 +32,28 @@ op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 1.0 +op.offset = 1.0 op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' op.height = 1.0 -op.invert = False -op.offset = 0.0 +op.height_invert = False +op.height_offset = 0.0 op.edge_falloff = '0' -op.falloff_size_x = 4.0 -op.falloff_size_y = 4.0 +op.falloff_x = 4.0 +op.falloff_y = 4.0 op.edge_level = 0.0 op.maximum = 2.0 op.minimum = -1.0 +op.use_vgroup = False op.strata = 5.0 op.strata_type = '0' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/default.py b/presets/operator/mesh.landscape_add/default.py index 356686f7..1996b561 100644 --- a/presets/operator/mesh.landscape_add/default.py +++ b/presets/operator/mesh.landscape_add/default.py @@ -1,21 +1,27 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 128 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 op.random_seed = 0 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 1.0 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 1.0 op.noise_type = 'hetero_terrain' op.basis_type = '0' op.vl_basis_type = '0' @@ -26,29 +32,28 @@ op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 1.0 +op.offset = 1.0 op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' op.height = 0.5 -op.invert = False -op.offset = 0.0 +op.height_invert = False +op.height_offset = 0.0 op.edge_falloff = '3' -op.falloff_size_x = 4.0 -op.falloff_size_y = 4.0 +op.falloff_x = 4.0 +op.falloff_y = 4.0 op.edge_level = 0.0 op.maximum = 1.0 -op.minimum = -0.10999999940395355 +op.minimum = -1.0 +op.use_vgroup = False op.strata = 5.0 op.strata_type = '0' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/default_large.py b/presets/operator/mesh.landscape_add/default_large.py index adb523bd..2295c1e5 100644 --- a/presets/operator/mesh.landscape_add/default_large.py +++ b/presets/operator/mesh.landscape_add/default_large.py @@ -1,21 +1,27 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 128 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 20.0 -op.meshsize_y = 20.0 +op.mesh_size = 2.0 +op.mesh_size_x = 20.0 +op.mesh_size_y = 20.0 op.random_seed = 0 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 10.0 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 10.0 op.noise_type = 'hetero_terrain' op.basis_type = '0' op.vl_basis_type = '0' @@ -26,29 +32,28 @@ op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 1.0 +op.offset = 1.0 op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' op.height = 5.0 -op.invert = False -op.offset = 0.0 +op.height_invert = False +op.height_offset = 0.0 op.edge_falloff = '3' -op.falloff_size_x = 4.0 -op.falloff_size_y = 4.0 +op.falloff_x = 4.0 +op.falloff_y = 4.0 op.edge_level = 0.0 op.maximum = 10.0 op.minimum = -1.0 +op.use_vgroup = False op.strata = 5.0 op.strata_type = '0' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/flatstone.py b/presets/operator/mesh.landscape_add/flatstone.py index b7e40c83..edf55b7c 100644 --- a/presets/operator/mesh.landscape_add/flatstone.py +++ b/presets/operator/mesh.landscape_add/flatstone.py @@ -1,21 +1,27 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 128 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 op.random_seed = 2 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 0.5 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 0.5 op.noise_type = 'fractal' op.basis_type = '8' op.vl_basis_type = '0' @@ -26,29 +32,28 @@ op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 1.0 +op.offset = 0.009999999776482582 op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' op.height = 0.05000000074505806 -op.invert = False -op.offset = 0.0 +op.height_invert = False +op.height_offset = 0.0 op.edge_falloff = '0' -op.falloff_size_x = 4.0 -op.falloff_size_y = 4.0 +op.falloff_x = 4.0 +op.falloff_y = 4.0 op.edge_level = 0.0 op.maximum = 1.0 op.minimum = 0.0 +op.use_vgroup = False op.strata = 5.0 op.strata_type = '0' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/land_and_water.py b/presets/operator/mesh.landscape_add/land_and_water.py deleted file mode 100644 index 441c6602..00000000 --- a/presets/operator/mesh.landscape_add/land_and_water.py +++ /dev/null @@ -1,54 +0,0 @@ -import bpy -op = bpy.context.active_operator - -op.at_cursor = True -op.smooth_mesh = True -op.tri_face = False -op.sphere_mesh = False -op.subdivision_x = 128 -op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 -op.random_seed = 8 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 1.5 -op.noise_size_x = 1.0 -op.noise_size_y = 1.0 -op.noise_type = 'turbulence_vector' -op.basis_type = '3' -op.vl_basis_type = '0' -op.distortion = 1.0 -op.hard_noise = '1' -op.noise_depth = 8 -op.amplitude = 0.5 -op.frequency = 2.0 -op.dimension = 1.0 -op.lacunarity = 2.0 -op.moffset = 1.0 -op.gain = 1.0 -op.marble_bias = '0' -op.marble_sharp = '0' -op.marble_shape = '0' -op.height = 0.4000000059604645 -op.invert = False -op.offset = -0.20000000298023224 -op.edge_falloff = '3' -op.falloff_size_x = 4.0 -op.falloff_size_y = 4.0 -op.edge_level = 0.0 -op.maximum = 1.0 -op.minimum = -0.10999999940395355 -op.strata = 5.0 -op.strata_type = '0' -op.water_plane = True -op.water_level = -0.019999999552965164 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' -op.show_noise_settings = True -op.show_terrain_settings = True -op.refresh = True -op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/mountain.py b/presets/operator/mesh.landscape_add/mountain.py index 2d551001..2d250498 100644 --- a/presets/operator/mesh.landscape_add/mountain.py +++ b/presets/operator/mesh.landscape_add/mountain.py @@ -1,24 +1,30 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 128 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 op.random_seed = 3 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 0.75 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 0.75 op.noise_type = 'ridged_multi_fractal' op.basis_type = '0' -op.vl_basis_type = '0' +op.vl_basis_type = '7' op.distortion = 1.0 op.hard_noise = '0' op.noise_depth = 12 @@ -26,29 +32,28 @@ op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 0.8500000238418579 -op.gain = 4.5 +op.offset = 0.880000114440918 +op.gain = 4.199997901916504 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' op.height = 0.5 -op.invert = False -op.offset = 0.20000000298023224 +op.height_invert = False +op.height_offset = 0.25 op.edge_falloff = '3' -op.falloff_size_x = 2.0 -op.falloff_size_y = 2.0 +op.falloff_x = 2.0 +op.falloff_y = 2.0 op.edge_level = 0.0 op.maximum = 1.0 -op.minimum = -0.10999999940395355 +op.minimum = -1.0 +op.use_vgroup = False op.strata = 5.0 op.strata_type = '0' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/planet_noise.py b/presets/operator/mesh.landscape_add/planet_noise.py index 7cc1015c..c2be84f6 100644 --- a/presets/operator/mesh.landscape_add/planet_noise.py +++ b/presets/operator/mesh.landscape_add/planet_noise.py @@ -1,21 +1,27 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = True op.sphere_mesh = True op.subdivision_x = 256 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 op.random_seed = 0 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 0.5 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 0.5 op.noise_type = 'planet_noise' op.basis_type = '1' op.vl_basis_type = '0' @@ -26,29 +32,28 @@ op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 1.0 +op.offset = 1.0 op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' op.height = 0.10000000149011612 -op.invert = False -op.offset = 0.0 +op.height_invert = False +op.height_offset = 0.25 op.edge_falloff = '0' -op.falloff_size_x = 4.0 -op.falloff_size_y = 4.0 +op.falloff_x = 2.0 +op.falloff_y = 2.0 op.edge_level = 0.0 op.maximum = 1.0 -op.minimum = -0.10999999940395355 +op.minimum = -1.0 +op.use_vgroup = False op.strata = 5.0 op.strata_type = '0' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/plateau.py b/presets/operator/mesh.landscape_add/plateau.py index e6c378ad..4a0689ae 100644 --- a/presets/operator/mesh.landscape_add/plateau.py +++ b/presets/operator/mesh.landscape_add/plateau.py @@ -1,54 +1,59 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 128 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 -op.random_seed = 285 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 1.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 +op.random_seed = 488 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 -op.noise_type = 'vl_noise_turbulence' -op.basis_type = '0' -op.vl_basis_type = '0' +op.noise_size_z = 1.0 +op.noise_size = 1.0 +op.noise_type = 'shattered_hterrain' +op.basis_type = '3' +op.vl_basis_type = '7' op.distortion = 1.149999976158142 -op.hard_noise = '1' -op.noise_depth = 6 +op.hard_noise = '0' +op.noise_depth = 8 op.amplitude = 0.4000000059604645 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 1.0 -op.gain = 1.5 +op.offset = 1.0 +op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' -op.height = 0.4000000059604645 -op.invert = False -op.offset = 0.05000000074505806 +op.height = 0.5 +op.height_invert = False +op.height_offset = 0.20000000298023224 op.edge_falloff = '3' -op.falloff_size_x = 2.0 -op.falloff_size_y = 2.0 +op.falloff_x = 3.0 +op.falloff_y = 3.0 op.edge_level = 0.0 -op.maximum = 0.20000000298023224 -op.minimum = -0.20000000298023224 -op.strata = 3.0 -op.strata_type = '3' +op.maximum = 0.25 +op.minimum = 0.0 +op.use_vgroup = False +op.strata = 2.25 +op.strata_type = '2' op.water_plane = False op.water_level = -0.07999999821186066 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/slick_rock.py b/presets/operator/mesh.landscape_add/slick_rock.py new file mode 100644 index 00000000..c875b754 --- /dev/null +++ b/presets/operator/mesh.landscape_add/slick_rock.py @@ -0,0 +1,59 @@ +import bpy +op = bpy.context.active_operator + +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' +op.at_cursor = True +op.smooth_mesh = True +op.tri_face = False +op.sphere_mesh = False +op.subdivision_x = 128 +op.subdivision_y = 128 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 +op.random_seed = 75 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 +op.noise_size_x = 1.0 +op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 1.0 +op.noise_type = 'slick_rock' +op.basis_type = '0' +op.vl_basis_type = '7' +op.distortion = 1.0 +op.hard_noise = '0' +op.noise_depth = 8 +op.amplitude = 0.5 +op.frequency = 2.0 +op.dimension = 1.0 +op.lacunarity = 2.0 +op.offset = 1.100000023841858 +op.gain = 2.5 +op.marble_bias = '0' +op.marble_sharp = '0' +op.marble_shape = '0' +op.height = 0.5 +op.height_invert = False +op.height_offset = 0.10000000149011612 +op.edge_falloff = '3' +op.falloff_x = 4.0 +op.falloff_y = 4.0 +op.edge_level = 0.0 +op.maximum = 1.0 +op.minimum = -1.0 +op.use_vgroup = False +op.strata = 5.0 +op.strata_type = '0' +op.water_plane = False +op.water_level = 0.009999999776482582 +op.remove_double = False +op.show_main_settings = True +op.show_noise_settings = True +op.show_displace_settings = True +op.refresh = True +op.auto_refresh = True diff --git a/presets/operator/mesh.landscape_add/smooth_terrain.py b/presets/operator/mesh.landscape_add/smooth_terrain.py index a468e273..1e66fba1 100644 --- a/presets/operator/mesh.landscape_add/smooth_terrain.py +++ b/presets/operator/mesh.landscape_add/smooth_terrain.py @@ -1,21 +1,27 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 128 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 op.random_seed = 11 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 0.8899999260902405 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 0.8899999856948853 op.noise_type = 'hybrid_multi_fractal' op.basis_type = '1' op.vl_basis_type = '0' @@ -26,29 +32,28 @@ op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 0.800000011920929 op.lacunarity = 2.2100000381469727 -op.moffset = 0.6499998569488525 +op.offset = 0.559999942779541 op.gain = 3.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' op.height = 0.2199999988079071 -op.invert = False -op.offset = -0.07999999821186066 +op.height_invert = False +op.height_offset = 0.0 op.edge_falloff = '3' -op.falloff_size_x = 6.0 -op.falloff_size_y = 6.0 +op.falloff_x = 4.0 +op.falloff_y = 4.0 op.edge_level = 0.0 op.maximum = 1.0 op.minimum = -1.0 +op.use_vgroup = False op.strata = 2.0 op.strata_type = '0' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/techno_grid.py b/presets/operator/mesh.landscape_add/techno_grid.py index c3c0edab..da1ac3d8 100644 --- a/presets/operator/mesh.landscape_add/techno_grid.py +++ b/presets/operator/mesh.landscape_add/techno_grid.py @@ -1,54 +1,59 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 128 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 -op.random_seed = 23 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 0.5 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 +op.random_seed = 0 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 0.5 op.noise_type = 'variable_lacunarity' op.basis_type = '9' op.vl_basis_type = '9' -op.distortion = 1.5 +op.distortion = 2.0 op.hard_noise = '0' op.noise_depth = 3 op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 1.0 +op.offset = 1.0 op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' op.height = 0.25 -op.invert = False -op.offset = 0.0 +op.height_invert = False +op.height_offset = 0.0 op.edge_falloff = '0' -op.falloff_size_x = 4.0 -op.falloff_size_y = 4.0 +op.falloff_x = 4.0 +op.falloff_y = 4.0 op.edge_level = 0.0 op.maximum = 1.0 op.minimum = -1.0 +op.use_vgroup = False op.strata = 2.0 op.strata_type = '4' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/terrain_large.py b/presets/operator/mesh.landscape_add/terrain_large.py index 766857fa..20dc3f66 100644 --- a/presets/operator/mesh.landscape_add/terrain_large.py +++ b/presets/operator/mesh.landscape_add/terrain_large.py @@ -1,54 +1,59 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 256 op.subdivision_y = 256 -op.meshsize = 2.0 -op.meshsize_x = 20.0 -op.meshsize_y = 20.0 +op.mesh_size = 2.0 +op.mesh_size_x = 20.0 +op.mesh_size_y = 20.0 op.random_seed = 0 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 3.0 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 3.0 op.noise_type = 'distorted_heteroTerrain' op.basis_type = '0' op.vl_basis_type = '0' -op.distortion = 1.0 +op.distortion = 0.800000011920929 op.hard_noise = '0' op.noise_depth = 8 op.amplitude = 0.5 op.frequency = 2.0 -op.dimension = 1.119999885559082 +op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 0.8799998760223389 +op.offset = 1.0 op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' op.height = 1.0 -op.invert = False -op.offset = 0.0 +op.height_invert = False +op.height_offset = 0.0 op.edge_falloff = '0' -op.falloff_size_x = 6.0 -op.falloff_size_y = 6.0 +op.falloff_x = 4.0 +op.falloff_y = 4.0 op.edge_level = 0.0 op.maximum = 5.0 op.minimum = -0.5 +op.use_vgroup = False op.strata = 5.0 op.strata_type = '0' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/vlnoise_turbulence.py b/presets/operator/mesh.landscape_add/vlnoise_turbulence.py new file mode 100644 index 00000000..832e8318 --- /dev/null +++ b/presets/operator/mesh.landscape_add/vlnoise_turbulence.py @@ -0,0 +1,59 @@ +import bpy +op = bpy.context.active_operator + +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' +op.at_cursor = True +op.smooth_mesh = True +op.tri_face = False +op.sphere_mesh = False +op.subdivision_x = 128 +op.subdivision_y = 128 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 +op.random_seed = 56 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 +op.noise_size_x = 1.0 +op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 1.0 +op.noise_type = 'vl_noise_turbulence' +op.basis_type = '2' +op.vl_basis_type = '3' +op.distortion = 1.5 +op.hard_noise = '0' +op.noise_depth = 3 +op.amplitude = 0.5 +op.frequency = 2.0 +op.dimension = 1.0 +op.lacunarity = 2.0 +op.offset = 0.10000000149011612 +op.gain = 1.0 +op.marble_bias = '0' +op.marble_sharp = '0' +op.marble_shape = '0' +op.height = 0.20999999344348907 +op.height_invert = False +op.height_offset = 0.11999999731779099 +op.edge_falloff = '3' +op.falloff_x = 4.0 +op.falloff_y = 4.0 +op.edge_level = 0.0 +op.maximum = 1.0 +op.minimum = 0.0 +op.use_vgroup = False +op.strata = 5.0 +op.strata_type = '0' +op.water_plane = False +op.water_level = 0.009999999776482582 +op.remove_double = False +op.show_main_settings = True +op.show_noise_settings = True +op.show_displace_settings = True +op.refresh = True +op.auto_refresh = True diff --git a/presets/operator/mesh.landscape_add/voronoi_hills.py b/presets/operator/mesh.landscape_add/voronoi_hills.py index 53ec1515..ccb344c2 100644 --- a/presets/operator/mesh.landscape_add/voronoi_hills.py +++ b/presets/operator/mesh.landscape_add/voronoi_hills.py @@ -1,22 +1,28 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 128 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 op.random_seed = 111 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 0.5 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 -op.noise_type = 'fractal' +op.noise_size_z = 1.0 +op.noise_size = 0.5 +op.noise_type = 'multi_fractal' op.basis_type = '3' op.vl_basis_type = '0' op.distortion = 1.0 @@ -26,29 +32,28 @@ op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 1.0 +op.offset = 1.0 op.gain = 1.0 op.marble_bias = '0' op.marble_sharp = '0' op.marble_shape = '0' -op.height = 0.10000000149011612 -op.invert = True -op.offset = 0.10000000149011612 -op.edge_falloff = '3' -op.falloff_size_x = 8.0 -op.falloff_size_y = 8.0 +op.height = 0.25 +op.height_invert = True +op.height_offset = 0.0 +op.edge_falloff = '0' +op.falloff_x = 4.0 +op.falloff_y = 4.0 op.edge_level = 0.0 op.maximum = 1.0 -op.minimum = -0.10999999940395355 +op.minimum = 0.0 +op.use_vgroup = False op.strata = 5.0 op.strata_type = '0' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/presets/operator/mesh.landscape_add/vulcano.py b/presets/operator/mesh.landscape_add/vulcano.py index 4aea3bbb..d11a7dd7 100644 --- a/presets/operator/mesh.landscape_add/vulcano.py +++ b/presets/operator/mesh.landscape_add/vulcano.py @@ -1,54 +1,59 @@ import bpy op = bpy.context.active_operator +op.ant_terrain_name = 'Landscape' +op.land_material = '' +op.water_material = '' +op.texture_block = '' op.at_cursor = True op.smooth_mesh = True op.tri_face = False op.sphere_mesh = False op.subdivision_x = 128 op.subdivision_y = 128 -op.meshsize = 2.0 -op.meshsize_x = 2.0 -op.meshsize_y = 2.0 +op.mesh_size = 2.0 +op.mesh_size_x = 2.0 +op.mesh_size_y = 2.0 op.random_seed = 7 -op.x_offset = 0.0 -op.y_offset = 0.0 -op.noise_size = 1.0 +op.noise_offset_x = 0.0 +op.noise_offset_y = 0.0 +op.noise_offset_z = 0.0 op.noise_size_x = 1.0 op.noise_size_y = 1.0 +op.noise_size_z = 1.0 +op.noise_size = 1.0 op.noise_type = 'marble_noise' op.basis_type = '0' op.vl_basis_type = '0' op.distortion = 1.5 op.hard_noise = '0' -op.noise_depth = 9 +op.noise_depth = 8 op.amplitude = 0.5 op.frequency = 2.0 op.dimension = 1.0 op.lacunarity = 2.0 -op.moffset = 1.0 +op.offset = 1.0 op.gain = 1.0 op.marble_bias = '2' op.marble_sharp = '3' op.marble_shape = '1' op.height = 0.800000011920929 -op.invert = False -op.offset = 0.0 +op.height_invert = False +op.height_offset = 0.0 op.edge_falloff = '3' -op.falloff_size_x = 2.0 -op.falloff_size_y = 2.0 +op.falloff_x = 2.0 +op.falloff_y = 2.0 op.edge_level = 0.0 op.maximum = 1.0 op.minimum = -1.0 +op.use_vgroup = False op.strata = 5.0 op.strata_type = '0' op.water_plane = False op.water_level = 0.009999999776482582 -op.use_mat = False -op.sel_land_mat = '' -op.sel_water_mat = '' +op.remove_double = False +op.show_main_settings = True op.show_noise_settings = True -op.show_terrain_settings = True +op.show_displace_settings = True op.refresh = True op.auto_refresh = True -op.texture_name = '' diff --git a/render_povray/__init__.py b/render_povray/__init__.py index e66e44c2..b95103b9 100644 --- a/render_povray/__init__.py +++ b/render_povray/__init__.py @@ -2175,6 +2175,7 @@ def register(): bpy.utils.register_module(__name__) bpy.types.INFO_MT_add.prepend(ui.menu_func_add) bpy.types.INFO_MT_file_import.append(ui.menu_func_import) + bpy.types.TEXT_MT_templates.append(ui.menu_func_templates) #used for parametric objects: addon_utils.enable("add_mesh_extra_objects", default_set=False, persistent=True) @@ -2203,6 +2204,7 @@ def unregister(): #bpy.types.TEXTURE_PT_context_texture.remove(TEXTURE_PT_povray_type) addon_utils.disable("add_mesh_extra_objects", default_set=False) + bpy.types.TEXT_MT_templates.remove(ui.menu_func_templates) bpy.types.INFO_MT_file_import.remove(ui.menu_func_import) bpy.types.INFO_MT_add.remove(ui.menu_func_add) bpy.utils.unregister_module(__name__) diff --git a/render_povray/templates_pov/abyss.pov b/render_povray/templates_pov/abyss.pov new file mode 100644 index 00000000..6cb39da8 --- /dev/null +++ b/render_povray/templates_pov/abyss.pov @@ -0,0 +1,834 @@ +// This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a +// letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + +// Persistence Of Vision raytracer sample file. +//============================================ +// The field, new improved version October. 2001 +// Copyright Gilles Tran 2001 +// http://www.oyonale.com +//-------------------------------------------- +// Render with a 2.67 ratio such as 320*120, 640*240, 1024*384, 1280*480 +//-------------------------------------------- +// -w320 -h120 +// -w640 -h240 +a0.1 +// -w768 -h288 +a0.1 +// -w1024 -h384 +a0.1 + +// Uncomment AreaOK=true below to turn on the area light +// This will blur the shadow under the submarine +// but the rendering time will extremely slow + +#version 3.6; + +global_settings{ assumed_gamma 1.0 max_trace_level 15 } + +#declare AreaOK=false; +//#declare AreaOK=true; + +#include "colors.inc" +#include "functions.inc" +//============================================ +// General +//============================================ +//-------------------------------------------- +// Camera +//-------------------------------------------- +#declare PdV=<-20, -20, -400>; +camera{ + location PdV + angle 65 // direction z*2 + up y + right x*image_width/image_height // keep propotions with any aspect ratio //right 8*x/3 + look_at <-20, 30, 0> +} + +//-------------------------------------------- +// reorientation macro +//-------------------------------------------- +#macro mOrient(P1,P2) +#local yV1=vnormalize(P2-P1); +#local xV1=vnormalize(vcross(yV1,z)); +#local zV1=vcross(xV1,yV1); + matrix <xV1.x,xV1.y,xV1.z,yV1.x,yV1.y,yV1.z,zV1.x,zV1.y,zV1.z,P1.x,P1.y,P1.z> +#end + +//-------------------------------------------- +// colors +//-------------------------------------------- +#declare colWater1=rgb<0,79,159>/255; +#declare colWater2=rgb<7,146,217>/255; +#declare colWater3=rgb<82,239,238>/255; +#declare colSub=<7/255,146/255,217/255>; + +//-------------------------------------------- +// lights +//-------------------------------------------- +light_source {<-10, 1000, -10> color colWater2*10 +#if (AreaOK) + area_light x*200,z*200, 3,3 adaptive 1 jitter orient +#end + +} +light_source {<-200, -1000, -300> color colWater2*2 shadowless media_interaction off} +light_source {PdV color colWater2*2 shadowless media_interaction off} + +//-------------------------------------------- +// mine textures +//-------------------------------------------- +#declare txtMine=texture { + pigment{color colWater3*0.1} + finish{ambient 0 diffuse 0.4 specular 0.03 roughness 0.2 reflection 0.05} +} +#declare txtCable=texture { + pigment{color colWater3*0.1} + finish{ambient 0 diffuse 0.1 specular 0.02 roughness 0.2} +} + +//-------------------------------------------- +// sub textures +//-------------------------------------------- +#declare txtSkin=texture{ + pigment{ + function{min(1,max(0,y))} + turbulence 0.01 omega 1.5 lambda 5 poly_wave 1.5 + color_map{[0 Clear][0.25 rgbt<0,0,0,0.7>] [0.4 rgbt<0,0,0,0.3>]} + scale 38 translate -y*17 + } + + finish{ambient 0 diffuse 0.6 specular 0.1 roughness 1/10} +} +#declare trb=0.0001; +#declare pigLettre=pigment{bozo color_map{[0 White*1.3][1 White*0.5]}} +#declare txtLettre=texture{ // submarine name + pigment { + object { + text{ttf "cyrvetic.ttf" "PERSISTENCE" 10, 0.3*x + translate -z*0.5 scale <1,1,10> + } + pigment{color Clear}, pigment{pigLettre} + } + rotate y*90 + scale 1.5 translate <-10,-1,-25> + } + + finish{ambient 0 diffuse 0.4} + +} + +#declare txtSub0=texture { + pigment{rgb colSub*0.2} + finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} +} +// Thanks to Bob H. for the help regarding these textures +#declare txtSubBase=texture { + pigment { + + cells + color_map { + [.45 rgb <colSub.x*0.1,colSub.y*0.1,colSub.z*0.1>] + [.55 rgb <colSub.x,colSub.y,colSub.z>*0.8] + } + scale <100,.125,1> + } + + scale 3 + finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} +} + +#declare txtSubTop= + + texture{txtSubBase} + texture { + pigment { + cells + color_map { + [.25 rgbf <colSub.x*0.1,colSub.y*0.1,colSub.z*0.1,0>] + [.75 rgbf <colSub.x,colSub.y,colSub.z,1>] + } + scale <100,0.75,1> + } + scale 3.5 + finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} + } + + texture { + pigment { + cells + color_map { + [.25 rgbf <colSub.x*0.4,colSub.y*0.4,colSub.z*0.4,0>] + [.75 rgbf <colSub.x,colSub.y,colSub.z,1>] + } + scale <100,0.45,1> + } + scale 2.5 + finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} + } + + texture{txtSkin} + +#declare txtSubBottom= + + texture{txtSubBase} + + texture { + pigment { + cells + color_map { + [.25 rgbf <colSub.x*0.5,colSub.y*0.5,colSub.z*0.5,0>] + [.75 rgbf <colSub.x,colSub.y,colSub.z,1>] + } + scale <100,.75,1> + } + scale 5 + finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} + } + + texture { + pigment { + cells + color_map { + [0 rgbf <colSub.x*0.5,colSub.y*0.5,colSub.z*0.5,.5>] + [1 rgbf <colSub.x,colSub.y,colSub.z,1>] + } + scale <100,0.25,1> + } + scale 5 + translate 1 + finish {ambient 0 diffuse 0.3 specular 0.05 roughness 0.1} + } + + texture{txtLettre} + texture{txtSkin} + + +//============================================ +// Mine +//============================================ +//-------------------------------------------- +// Spikes +//-------------------------------------------- + +#declare Spike = union{ + #declare rSpike1=0.08; + #declare rSpike2=rSpike1*0.3; + #declare ySpike=0.4; + cone{0,rSpike1,y*ySpike,rSpike2} + sphere{0,rSpike2 translate y*ySpike} + sphere{0,rSpike1*1.5 scale <1,0.3,1>} + #declare i=0;#while (i<360) sphere{0,0.015 scale <2,1,2> translate <rSpike1*2.8,-0.04,0> rotate y*i} #declare i=i+30;#end + translate y +} + + + + + +//-------------------------------------------- +// Mine body +//-------------------------------------------- +#declare rd=seed(0); +#declare MineBody=union { + isosurface { + function{x*x+y*y+z*z-1 +f_noise3d(x*10,y*10,z*10)*0.05} + max_gradient 2.492 + contained_by{sphere{0,1}} + } + + #declare i=0; + #while (i<360) + #declare j=0; + #while (j<180) + object{Spike rotate z*(i+rand(rd)*2) rotate y*(j+rand(rd)*2)} + #declare j=j+45; + #end + #declare i=i+45; + #end + + object{Spike rotate 90*y} + object{Spike rotate -90*y} + rotate 360*rand(rd) + +} + +//-------------------------------------------- +// Mine cable and decorative collar +//-------------------------------------------- +#declare rFil=0.03; +#declare yFil=100; +#declare MineCable=isosurface{ + function{f_helix1(x,y,z,3,35,0.35*rFil,0.55*rFil,2,1,0)} + contained_by {box {<-rFil,0,-rFil>,<rFil,yFil,rFil>}} + max_gradient 2.552 + scale <1,-1,1>*3 translate -y +} + + +#declare MineCollar=lathe{ + cubic_spline + 15, + <0.058,0.003>,<0.081,0.000>,<0.101,0.055>,<0.099,0.085>,<0.104,0.132>,<0.066,0.152>, + <0.095,0.169>,<0.089,0.194>,<0.144,0.227>,<0.143,0.281>,<0.145,0.307>,<0.109,0.325>, + <0.067,0.353>,<0.031,0.362>,<0.030,0.363> + translate -y*0.363 +} + +//-------------------------------------------- +// Mine +//-------------------------------------------- +#declare Mine=union{ + object{MineBody} + sphere{0,1 scale <0.4,0.14,0.4> translate -y*0.91} + #declare i=0;#while (i<360) cylinder{0,-y*0.1,0.02 translate <0.35,-0.91,0> rotate y*i} #declare i=i+30;#end + object{MineCollar scale <1.2,2,1.2> translate -y*0.92} + object{MineCollar translate -y*2} + object{MineCable} + texture{txtMine} +} + + + +//============================================ +// Submarine +//============================================ +#declare Sc=3; // general scaling parameter +#declare SX=6*Sc; // x scaling +#declare SYbot=10*Sc;// y scaling for the bottom +#declare SYtop=2*Sc; // y scaling for the top +#declare SZfront=20*Sc; // z scaling for the front +#declare SZrear=100*Sc;// z scaling for the rear + +//-------------------------------------------- +// Main parts +//-------------------------------------------- +#declare Part1=blob{ // bottom front + threshold 0.6 + sphere{0,1,1} + cylinder{-z*2,z,0.04,-1 translate <-0.2,-0.3,1> pigment{Black}} + cylinder{-z*2,z,0.04,-1 translate <-0.17,-0.18,1> pigment{Black}} + sphere{0,1,1 scale <0.1,0.45,1.05>} + sphere{0,1,1 scale <0.3,0.45,0.8>} +} +#declare Part2=blob{ // top front + threshold 0.6 + sphere{0,1,1} + sphere{0,1,1 scale <0.3,0.45,0.8>} + sphere{0,1,1 scale <0.2,1.2,1.05>} +} +#declare Part3=blob{ // bottom rear + threshold 0.6 + sphere{0,1,1} + cylinder{-x,0,1,1 scale <0.5,0.03,0.02> translate <0,-0.05,0.45>} + cylinder{-y,0,1,1 scale <0.03,0.2,0.02> translate <0,-0.05,0.45>} +} +#declare Part4=blob{ // top rear + threshold 0.6 + sphere{0,1,1} + cylinder{-y,y,2,2 scale <0.03,0.3,0.012> translate <0,0.5,0.45>} + sphere{0,1,1 scale <0.2,1.2,0.4>} + + cylinder{-x,0,1,1 scale <0.2,0.2,0.04> rotate x*-10 translate <0,1.5,0.2>} + cylinder{0,y,0.2,2 scale <0.6,2.5,0.4>*0.7 translate <0,-0.05,0.16>} + cylinder{0,y,0.2,2 scale <0.4,2.5,0.4>*0.7 translate <0,-0.05,0.165>} + cylinder{0,y,0.2,2 scale <0.2,2.5,0.4>*0.7 translate <0,-0.05,0.17>} +} + + +//-------------------------------------------- +// Top +//-------------------------------------------- +#declare HalfSubTop=union{ + difference{ + object{Part2} // top front + plane{y,0} + plane{z,0 inverse} + plane{x,0 inverse} + scale <SX,SYtop,SZfront> + } + difference{ + object{Part4} // top rear + plane{y,0} + plane{z,0} + plane{x,0 inverse} + scale <SX,SYtop,SZrear> + } +} +#declare SubTop=union{ + object{HalfSubTop} + object{HalfSubTop scale <-1,1,1>} + texture{txtSubTop} +} +//-------------------------------------------- +// Bottom +//-------------------------------------------- +#declare HalfSubBottom=union{ + difference{ + object{Part1} // bottom front + plane{y,0 inverse} + plane{z,0 inverse} + plane{x,0 inverse} + scale <SX,SYbot,SZfront> + } + difference{ + object{Part3} // bottom rear + plane{y,0 inverse} + plane{z,0} + plane{x,0 inverse} + scale <SX,SYbot,SZrear> + } +} + +#declare SubBottom=union{ + object{HalfSubBottom} + object{HalfSubBottom scale <-1,1,1>} + texture{txtSubBottom} +} +//-------------------------------------------- +// Decorative elements +//-------------------------------------------- +#declare Balustrade=union{ + #declare rB1=0.02; + #declare rB2=0.04; + #declare yB=1; + #declare rB3=yB*6; + #declare rB4=3; + #declare zB=20; + #declare zB2=8; + #declare i=0; + #while (i<zB) + cylinder{0,y*yB,rB1 translate z*i} + #declare i=i+zB/12; + #end + cylinder{0,z*zB,rB2 translate y*yB} + cylinder{0,z*zB,rB2 translate y*yB*0.3} + cylinder{0,z*zB,rB2 translate y*yB*0.6} + union{ + difference{torus{rB3,rB2 rotate z*90} plane{y,0} plane{z,0 inverse} plane{z,0 rotate x*-45}} + cylinder{0,-z*zB*0.1,rB2 translate y*rB3 rotate x*-45} + translate y*(yB-rB3) + } + union{ + difference{torus{rB4,rB2} plane{x,0 inverse} translate <0,yB,0>} + difference{torus{rB4,rB1} plane{x,0 inverse} translate <0,yB*0.5,0>} + #while (i<180) + cylinder{0,y*yB,rB1 translate -z*rB4 rotate y*i} + #declare i=i+180/14; + #end + scale <0.4,1,1> + translate z*(rB4+zB) + } + union{ + difference{torus{rB3,rB2 rotate z*90} plane{y,0} plane{z,0 inverse} plane{z,0 rotate x*-65}} + cylinder{0,-z*zB*0.1,rB2 translate y*rB3 rotate x*-65} + translate y*(yB-rB3) + scale <1,1,-1> + translate z*(zB+rB4*2) + } + +} + + + +//-------------------------------------------- +// guns +//-------------------------------------------- +#declare Guns0=union{ + superellipsoid{<0.3,0.3> translate z scale <0.8,1,4>} + union{ + cone{0,0.4,z*12,0.3} + union{ + cone{0,0.3,z*1.5,0.5} + difference{ + sphere{0,0.5} + cylinder{-z,z,0.3} + translate z*1.5 + } + translate z*12 + } + translate z*8 + } + translate -z*3 +} + +#declare Wheel=blob{ + threshold 0.6 + sphere{0,1.3,1 scale <1,1.2,1>} + cylinder{0,-y*3,0.8,1} + #declare Teta=0; + #while (Teta<360) + cylinder{0,x*3.4,0.4,1 rotate y*Teta} + cylinder{0,y,0.4,1 translate x*3 rotate y*Teta} + sphere{0,0.6,1 translate x*3 rotate y*Teta} + sphere{0,0.4,1 translate x*3 rotate y*(Teta+6)} + sphere{0,0.4,1 translate x*3 rotate y*(Teta+12)} + sphere{0,0.4,1 translate x*3 rotate y*(Teta+18)} + sphere{0,0.4,1 translate x*3 rotate y*(Teta+24)} + sphere{0,0.4,1 translate x*3 rotate y*(Teta+30)} + sphere{0,0.4,1 translate x*3 rotate y*(Teta+36)} + sphere{0,0.4,1 translate x*3 rotate y*(Teta+42)} + sphere{0,0.4,1 translate x*3 rotate y*(Teta+48)} + sphere{0,0.4,1 translate x*3 rotate y*(Teta+54)} + sphere{0,0.5,1 translate x*3 rotate y*(Teta+60)} + sphere{0,0.5,1 translate x*3 rotate y*(Teta+66)} + #declare Teta=Teta+72; + #end +} +#declare Guns1=union{ + object{Guns0} + object{Wheel rotate y*10 scale 0.7 rotate z*90 translate -x*1.5} + +} +#declare Eye=union{ + torus{4.5,0.5} + difference{ + sphere{0,4.3} + box{-5,5 scale <1,1,0.05>} + box{-5,5 scale <1,1,0.05> translate z} + box{-5,5 scale <1,1,0.05> translate z*2} + box{-5,5 scale <1,1,0.05> translate z*3} + box{-5,5 scale <1,1,0.05> translate z*4} + box{-5,5 scale <1,1,0.05> translate -z} + box{-5,5 scale <1,1,0.05> translate -z*2} + box{-5,5 scale <1,1,0.05> translate -z*3} + box{-5,5 scale <1,1,0.05> translate -z*4} + scale <1,0.7,1> + } +} +#declare Ring1=union{ + cylinder{-0.2*x,0.2*x,1.2} + torus{1.1,0.1 rotate z*90 scale <2,1,1> translate -x*0.2} + torus{1.1,0.1 rotate z*90 scale <2,1,1> translate x*0.2} +} +#declare Elbow1=intersection{torus{2,1} plane{z,0 inverse} plane{x,0 inverse} } + + +#declare Thingie=union{ + torus{1.5,0.3 rotate z*90 translate -x} + cylinder{-x,x,1.5} + superellipsoid{<0.2,0.2> scale <1.5,2,2.5> translate x*2.5} + object{Eye scale 1.5/7 rotate -x*90 translate <2.5,0,-2.5>} + object{Eye scale 1.5/7 rotate -x*90 translate <2.5,0,-2.5> scale <1,1,-1>} + sphere{0,1.5 scale <0.5,1,1> translate x*4} + sphere{0,1.5 scale <0.5,1,1> translate x*16} + cylinder{x*4,x*16,1.2} + torus{1.9,0.1 rotate z*90 translate x*16.5} + cylinder{x*16.5,x*17.5,2} + torus{1.9,0.1 rotate z*90 translate x*17.5} + cylinder{x*17.5,x*23,1.5} + union{ + torus{0.5,0.1} + intersection{torus{2.5,0.5 rotate x*90} plane{y,0 inverse} plane{x,0} translate x*2.5} + torus{0.5,0.1 translate -x*2.5 rotate z*-30 translate x*2.5 } + torus{0.5,0.1 translate -x*2.5 rotate z*-60 translate x*2.5 } + torus{0.5,0.1 translate -x*2.5 rotate z*-90 translate x*2.5 } + union{ + cylinder{0,9*x,0.5} + cylinder{2*x,5*x,0.7} + torus{0.5,0.2 rotate z*90 translate x*2} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*2.3} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*2.6} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*2.9} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.2} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.5} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.8} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.1} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.4} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.7} + torus{0.5,0.2 rotate z*90 translate x*5} + torus{0.5,0.3 rotate z*90 translate x*8} + cone{0,0.7,x,0.9 translate x*8} + torus{0.9,0.2 rotate z*90 translate x*9} + translate <2.5,2.5,0> + } + translate <2.5,2,1.7> + } + union{ + torus{0.5,0.1} + intersection{torus{2.5,0.5 rotate x*90} plane{y,0 inverse} plane{x,0} translate x*2.5} + torus{0.5,0.1 translate -x*2.5 rotate z*-30 translate x*2.5 } + torus{0.5,0.1 translate -x*2.5 rotate z*-60 translate x*2.5 } + torus{0.5,0.1 translate -x*2.5 rotate z*-90 translate x*2.5 } + union{ + cylinder{0,9*x,0.5} + cylinder{3*x,6*x,0.7} + torus{0.5,0.2 rotate z*90 translate x*3} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.3} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.6} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*3.9} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.2} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.5} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*4.8} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*5.1} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*5.4} + torus{0.7,0.2 scale <0.2,1,1> rotate z*90 translate x*5.7} + torus{0.5,0.2 rotate z*90 translate x*6} + torus{0.5,0.3 rotate z*90 translate x*8} + cone{0,0.7,x,0.9 translate x*8} + torus{0.9,0.2 rotate z*90 translate x*9} + translate <2.5,2.5,0> + } + translate <2.5,2,-1.7> + } + union{ + superellipsoid{<0.2,0.2> scale <1,1.3,2.6>} + object{Eye scale 1/7 rotate -x*90 translate z*-2.6} + object{Eye scale 1/7 rotate -x*90 translate z*2.6} + object{Eye scale 1/7 rotate y*90 translate <0,1.3,1.7>} + object{Eye scale 1/7 rotate y*90 translate <0,1.3,-1.7>} + cylinder{x,x*3,1} + torus{1,0.2 rotate z*90 translate x*3} + intersection{torus{4.5,1 rotate x*90} plane{y,0 inverse} plane{x,0 inverse} scale <0.5,1,1> translate <3,-4.5,0>} + torus{1,0.3 scale <0.5,4,1> translate <3+2.25,-3,0>} + translate <15,4.5,0> + } + #declare Teta=0; + #while (Teta<360) + union{ + box{<0,-0.1,-0.05>,<12,0.1,0.05> translate <4,1.2,0>} + cylinder{-x,2*x,0.1 translate y*1.5} + sphere{0,0.2 translate <20,1.5,0>} + sphere{0,0.1 translate <16.8,2,0>} + sphere{0,0.1 translate <17.2,2,0> rotate x*10} + cylinder{x*20,x*23,0.18 translate y*1.5} + rotate x*Teta + } + #declare Teta=Teta+20; + #end + + translate x +} +#declare GunSupport=union{ + superellipsoid{<0.6,0.6> translate y scale <0.3,3,1> translate -z*2} + union{ + union{ + superellipsoid{<0.7,0.7> translate y scale <1.5,3.8,1>} + #declare i=0; + #while (i<6) + sphere{0,0.2 translate <-1,i+0.5,0.8>} + sphere{0,0.2 translate <0,i+0.1,1>} + sphere{0,0.2 translate <1,i+0.5,0.8>} + #declare i=i+0.7; + #end + rotate -x*10 translate z*0.6 + } + + cylinder{y*4,y*9,0.6} + sphere{0,1 scale <4,1,4>} + } +} +#declare Guns=union{ + union{ + object{Thingie rotate y*180 scale 0.5 rotate y*-90 rotate z*45 translate <0,4,5>} + superellipsoid{<0.6,0.6> translate -z scale <0.6,1,3> translate -x*0.5} + object{Guns1 translate -x*1.7} + object{Guns1 translate -x*1.7 scale <-1,1,1>} + rotate x*-20 + translate y*10 + } + object{GunSupport} +} + +#declare GunsBack=union{ + union{ + object{Thingie rotate y*180 scale 0.5 rotate y*-90 rotate z*45 translate <0,4,5>} + superellipsoid{<0.6,0.6> translate -z scale <0.6,1,3> translate -x*0.5} + object{Guns1 translate -x*1.7} + object{Guns1 translate -x*1.7 scale <-1,1,1>} + rotate x*-5 + translate y*10 + } + object{GunSupport} +} + +//-------------------------------------------- +// snorkels and vertical thingies +//-------------------------------------------- +#declare Snorkel1=union{ + cone{0,0.3,y*2,0.25} + cone{y*2,0.25,y*3,0.1} + union{ + difference{sphere{0,1 scale<0.3,0.2,0.3>}plane{y,0 inverse}} + difference{sphere{0,1 scale<0.3,0.6,0.3>}plane{y,0}} + translate y*3 + } + scale <0.8,1,0.8> +} +#declare Snorkel2=blob{ + threshold 0.6 + cylinder{-y,y*4,0.2,1} + sphere{0,0.4,1 scale <1,1,2> translate y*3.5} + sphere{0,0.3,1 scale <3,1,1> translate y*2.5} + scale <0.8,1,0.8> + } +#declare Snorkel3=union{ + blob{ + threshold 0.6 + cylinder{0,y*3.4,0.25,1 scale <1,1,3>} + cylinder{0,y*5,0.03,1 translate <0,0,-0.5>} + + } + union{ + cylinder{0,y*4,0.03} + sphere{0,0.1 translate y*4} + translate <-0.1,0,0.5> + } + scale <0.8,1,0.8> +} + +//-------------------------------------------- +// lots of decorative stuff +//-------------------------------------------- +#declare nDeco=13; +#declare Deco=array[nDeco] +#declare Deco[0]=union{ + cylinder{0,y*2,0.2} + torus{1,0.2 rotate x*90 translate y*3} + scale 0.5 +} +#declare Deco[1]=cone{-y*0.5,0.2,y*4,0.1} +#declare Deco[2]=blob{ + threshold 0.6 + cylinder{-x,x,0.25,1 scale <1,1,2>} + cylinder{0,-y,0.21,1 translate -x*0.8} + cylinder{0,-y,0.21,1 translate x*0.8} + translate y*0.7 + scale 1 +} +#declare Deco[3]=object{Deco[2] rotate y*90} +#declare Deco[4]=torus{1,0.2 rotate z*90} +#declare Deco[5]=object{Deco[3] rotate y*90 scale <1,1.4,1>} +#declare Deco[6]=union{ + cylinder{0,y*0.4,0.1} + sphere{0,1 scale <0.1,0.1,0.5> translate y*0.4} +} +#declare Deco[7]=difference{sphere{0,1} cylinder{-z,0,0.8} scale <2,0.5,2>translate -y*0.2} +#declare Deco[8]=difference{sphere{0,1} cylinder{-z,0,0.9} scale <2,0.5,4>translate -y*0.2} +#declare Deco[9]=cone{0,0.08,y*2,0.03 scale <1,1,2>} +#declare Deco[10]=sphere{0,1 scale <0.2,0.1,0.4>} +#declare Deco[11]=object{Deco[4] scale 1.2} +#declare Deco[12]=object{Deco[5] scale 1.3} +#declare Ladder=union{ + #declare i=0; + #while (i<9) + object{Deco[3] scale 0.8 rotate z*90 translate y*i*0.8} + #declare i=i+1; + #end +} + +#declare Decos=union{ + #declare rd=seed(4); + #declare Start0=-40; + #declare End0=40; + #declare nstep=200; + #declare i=0; + #declare k=0; + #while (i<1) + #declare j=i; + #declare Start=<-rand(rd)*5*(mod(k,2)*2-1),1,(1-j)*Start0+j*End0>; + #declare Dir=y; + #declare Norm1=<0,0,0>; + #declare Inter=trace( SubTop, Start, Dir, Norm1); + #if (vlength(Norm1)!=0) + #if (vlength(vcross(Norm1,y))<0.9) + #declare n=int(rand(rd)*nDeco); + object{Deco[n] scale 0.4 mOrient(Inter,Inter+Norm1)} + #end + #end + #declare k=k+1; + #declare i=i+1/nstep; + #end +} + + +#declare Submarine=union{ + union{ + object{SubTop} + object{Decos texture{txtSubTop}} + object{Ladder translate <-1.5,4,40>} + object{Ladder translate <1.5,4,40>} + object{Guns rotate y*180 scale 0.3 translate <0,4,30>} + object{GunsBack scale 0.3 translate <0,4,70>} + union{ + object{Snorkel1 translate z*3} + object{Snorkel2} + object{Snorkel3 translate -z*2} + scale 2*<1,1.1,1> + translate <0,10,50> + } + object{Balustrade scale 2.5 translate <-4,2,5>} + object{Balustrade scale 2.5 translate <-4,2,5> scale <-1,1,1>} + union{ + object{Balustrade scale 2 translate <-3,2,5>} + object{Balustrade scale 2 translate <-3,2,5> scale <-1,1,1>} + rotate y*180 + translate z*100 + } + texture{txtSub0} + scale <1,1.3,1> + } + object{SubBottom} +} + + + +//============================================ +// Final +//============================================ +#declare posSub=<19,5,0>; +#declare rotSub=-15; + +//-------------------------------------------- +// mines +//-------------------------------------------- +union{ + light_group{ + object{Mine rotate y*80 scale 14 } + light_source{<-10,-20,-40> color rgb -4 shadowless} // negative light !!! + translate <-110, 41, -205> + global_lights on + } + light_group{ + object{Mine rotate -y*10 scale 8 } + light_source{<-10,-20,-40> color rgb -2 shadowless} + translate <-75, 25, -165> + global_lights on + } + object{Mine rotate y*125 scale 5 translate <105, -5, -155>} + translate y*-8 +} +union{ + #declare rd=seed(0); + #declare i=0; + #while (i<20) + + object{Mine rotate y*125 scale 3 translate <50+rand(rd)*(200+i*10),(0.5-rand(rd))*60,i*30>} + object{Mine rotate y*150 scale 3 translate <-50-rand(rd)*(200+i*10),(0.5-rand(rd))*60,i*30>} + + object{Mine rotate y*10 scale 3 translate <50+rand(rd)*(200+i*10),(0.5-rand(rd))*140+50+i*10,i*30>} + object{Mine rotate y*37 scale 3 translate <-50-rand(rd)*(200+i*10),(0.5-rand(rd))*140+50+i*10,i*30>} + #declare i=i+1; + #end + rotate y*rotSub translate posSub + translate -z*150 + translate x*30 +} +//-------------------------------------------- +// submarine and media +//-------------------------------------------- +union{ + object{Submarine scale 3/4 translate z*-10 translate y*10} + sphere{0,1 scale 410 hollow + texture{pigment{Clear}finish{ambient 0 diffuse 0}} + interior{ + media{ + scattering {5,0.00034 eccentricity 0.7 extinction 0.8} + absorption <255-23,255-171,255-239>*0.0005/255 + intervals 3 + method 3 + } + } + } + + scale 4 + rotate y*rotSub translate posSub +} diff --git a/render_povray/templates_pov/biscuit.pov b/render_povray/templates_pov/biscuit.pov new file mode 100644 index 00000000..aab90fab --- /dev/null +++ b/render_povray/templates_pov/biscuit.pov @@ -0,0 +1,370 @@ +// This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a +// letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + +//oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo// +// // +// Windows users: to start rendering this image, press Alt+G or the 'Run' // +// button on the toobar. // +// // +// Experienced windows users: try right-clicking on the line below ... // +// // +// +w320 +h240 +// +w800 +h600 +a0.3 +am2 +// // +// See the docs for full explanations of new features such as the above. // +// // +//oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo// + +// Persistence Of Vision raytracer sample file. +// Copyright 2001 Fabien Mosen +// +// Updated: 2013/02/15 for 3.7 +// +#version 3.6; +global_settings{ assumed_gamma 1.3 max_trace_level 5} + +#include "colors.inc" +#include "functions.inc" +#include "logo.inc" + + +camera{ location <20,40,28> + angle 40 // direction 2*z + right x*image_width/image_height // keep propotions with any aspect ratio + look_at <0,2,0> + } + +light_source {<-140,200, 300> rgb <1.0, 1.0, 0.95>*1.5} +light_source {< 140,200,-300> rgb <0.9, 0.9, 1.00>*0.9 shadowless} + +#declare r1 = seed(0); + +//----------------------- THE TABLE +#declare Pig_1 = +pigment { + gradient z + color_map { + [0.00, rgb <0.01, 0.59, 0.81>] + [0.70, rgb <0.01, 0.59, 0.81>] + [0.70, rgb <0.98, 0.98, 0.87>] + [1.00, rgb <0.98, 0.98, 0.87>] + } + frequency 4 +} +#declare Pig_2 = +pigment { + bozo + color_map { + [0.00, rgb <0.35, 0.58, 0.88>*1.0] + [0.25, rgb <0.35, 0.58, 0.88>*1.1] + [0.50, rgb <0.35, 0.58, 0.88>*0.9] + [0.75, rgb <0.35, 0.58, 0.88>*1.0] + [1.00, rgb <0.35, 0.58, 0.88>*0.8] + } + scale 0.1 +} + +#declare Nappe = +cylinder {0,y*-1,50 + texture { + pigment { + gradient x + pigment_map { + [0.0, Pig_1] + [0.5, Pig_1] + [0.5, Pig_2] + [1.0, Pig_2] + } + warp {turbulence .05 octaves 2} + } + normal {quilted 0.6 scale 0.025 warp {turbulence 0.05 octaves 2}} + scale 5 + translate 10 + } +} + +object {Nappe} + +//----------------------- BISCUITS +#declare Tex_Biscuit = +texture { + pigment {color rgb <0.98, 0.83, 0.58>} + normal {dents 1.2 scale 0.01} + finish {phong 0 brilliance 0.7} +} + +#declare Base_Biscuit = +union { + blob { + threshold 0.7 + #declare I = 0; + #while (I < 359) + sphere {<4,0,0>, 1+rand(r1)*0.1, 1 rotate y*I} + #declare I = I+(360/28); + #end + } + cylinder {<0,0,0>, <0,0.5,0>, 4} + texture {Tex_Biscuit} +} + +#declare Chocolate = +union { + difference { + cone {<0,0,0>, 4.2, <0,0.4,0>, 4} + cone {<0,0.1,0>, 3.6, <0,0.401,0>, 3.75} + } + torus { + 3.55, 0.1 + translate y*0.2 + clipped_by {torus {3.55+0.1, 0.1 translate y*0.1}} + } + union { + #declare I = -4; + #while (I < 4) + cylinder {<-4,0.1,I>,<4,0.1,I>, 0.05} + #declare I = I+0.5; + #end + clipped_by {cone {<0,0,0>, 4.2, <0,0.4,0>, 4}} + } + torus {3.96, 0.04 translate y*0.4} + torus {3.79, 0.04 translate y*0.4} +} + +#declare LogoFun = +object{Povray_Logo_Prism rotate x*90 scale 2.2 translate -0.3*z} + +#declare ProjLogo = +blob { + threshold 0.6 + #declare I = 0; + #while (I < 1) + #declare Pos = <-2+rand(r1)*4, 0, -2+rand(r1)*4>; + #if (inside(LogoFun,Pos)) + sphere {Pos, 0.08, 1} + #end + #declare I = I+0.0002; + #end +} + +#declare Black_Chocolate = +texture { + pigment {color rgb <0.24, 0.10, 0.03>} + normal {wrinkles 0.2} + finish {specular 0.3} + } +#declare Milk_Chocolate = +texture { + pigment {color rgb <0.48, 0.26, 0.13>} + normal {wrinkles 0.2} + finish {specular 0.2} +} +#declare White_Chocolate = +texture { + pigment {color rgb <0.96, 0.95, 0.75>} + normal {wrinkles 0.2} + finish {ambient 0.3 specular 0.01} +} + +#declare Icing = texture { + pigment {rgbf <0.95, 0.95, 1.00, 0.1>*1.2} + normal {bumps 0.1} +} + +#declare Biscuit_1 = +union { + object {Base_Biscuit} + object {Chocolate translate y*0.5 texture {Black_Chocolate}} + disc { + <0,0.101,0>, y, 3.6 + translate y*0.5 + texture {Black_Chocolate} normal {bumps 0.3 scale 0.05} + } + object {ProjLogo scale 1.5 rotate y*-90 translate <-0.4,0.6,0.5> texture {Icing}} + translate y*0.5 +} +#declare Biscuit_2 = +union { + object {Base_Biscuit} + object {Chocolate translate y*0.5 texture {Milk_Chocolate}} + disc { + <0,0.101,0>, y, 3.6 + translate y*0.5 + texture {Milk_Chocolate} normal {bumps 0.3 scale 0.05} + } + object {ProjLogo scale 1.5 rotate y*-90 translate <-0.4,0.6,0.5> texture {White_Chocolate}} + translate y*0.5 +} +#declare Biscuit_3 = +union { + object {Base_Biscuit} + object {Chocolate translate y*0.5 texture {White_Chocolate}} + disc { + <0,0.101,0>, y, 3.6 + translate y*0.5 + texture {White_Chocolate} normal {bumps 0.3 scale 0.05} + } + object {ProjLogo scale 1.5 rotate y*-90 translate <-0.4,0.6,0.5> texture {Milk_Chocolate}} + translate y*0.5 +} + +object {Biscuit_2 rotate y*-80 translate <-3.5,0,2>} +object {Biscuit_1 rotate y*-120 translate <3.5,0,-4>} +object {Biscuit_3 rotate x*-4 translate <8.5,0.9,0>} + +#macro SevenBiscuits (Bisc,Num) + union { + #declare I = 0; + #while (I < Num) + object {Bisc translate x*9 rotate y*60*I} + #declare I = I+1; + #end + object {Bisc} + } +#end + +//----------------------- CRUMBS +#declare Fun_Sphere = function {x*x + y*y +z*z} + +#declare Crumb = +isosurface { + function {Fun_Sphere(x,y,z) + f_noise3d(x*2,y*2,z*2)*1} + threshold 1 + max_gradient 3.9 + //max_gradient 15 + accuracy 0.01 + contained_by {box {-1,1}} + scale 0.5 +} + +#declare r1 = seed(0); + +#declare I = 0; +#while (I < 1) + object { + Crumb + rotate rand(r1)*360 + scale 0.2+rand(r1)*0.3 + translate <rand(r1)*10,0,rand(r1)*10> + texture {Tex_Biscuit} + } + object { + Crumb + rotate rand(r1)*360 + scale 0.1+rand(r1)*0.15 + translate <rand(r1)*10,0,rand(r1)*10> + texture {Tex_Biscuit} + } + #declare I = I+0.03; +#end + +//----------------------- METAL BOX +#declare Pig3 = +pigment { + gradient y + color_map { + [0, rgb <0.1, 0.5, 0.7>] + [1, rgb <0.7, 0.6, 0.4>] + } + scale 0.5 +} + +#declare Pig4 = +pigment { + crackle + color_map { + [0, rgb <1.0, 0.5, 0.6>] + [1, rgb <0.0, 0.0, 0.0>] + } + scale 0.2 +} + +#declare MetalBoxPig = +pigment { + radial frequency 60 + pigment_map { + [0.0, Pig3] + [0.5, Pig3] + [0.5, Pig4] + [1.0, Pig4] + } +} + +#declare BiscuitBox = +union { + difference { + cylinder {<0,0,0>, <0,5,0>, 14} + cylinder {<0,0.1,0>, <0,5.1,0>, 13.9} + } + torus {14, 0.1 translate y*5} + torus {14, 0.1 translate y*0.1} + torus {14, 0.1 scale <1,2,1> translate y*4} + cylinder { + <0,0.3,0>,<0,3.5,0>, 14.01 open + pigment {MetalBoxPig} + finish {phong 0.8 reflection {0.01, 0.15}} + } + pigment {Gray60} + finish {phong 0.8 metallic reflection {0.5, 0.7}} +} + +union { + object {BiscuitBox} + object {SevenBiscuits (Biscuit_1,6)} + object {SevenBiscuits (Biscuit_3,6) rotate y*30 translate y*1} + object {SevenBiscuits (Biscuit_2,5) rotate y*0 translate y*2} + rotate y*-75 translate <-18,0,-12> +} + +//-----------------------CUP OF TEA +#declare TeaCup = +union { + difference { + cylinder {<0,1.2,0>, <0,6,0>, 4.2} + cylinder {<0,1,0>, <0,6.2,0>, 3.8} + } + + difference { + cylinder {<0,0.2,0>, <0,2.5,0>, 4} + torus {2.8, 1 translate y*2.5} + torus {4, 1 translate y*0} + cylinder {<0,1.5,0>, <0,2.6,0>, 2.8} + } + + difference { + #declare LiquidLevel = 5; + cylinder {<0,1.4,0>, <0,LiquidLevel,0>, 4} + torus {3.6, 0.2 translate y*LiquidLevel} + cylinder {<0,LiquidLevel-0.2,0>,<0,LiquidLevel+0.3,0>,3.6} + pigment {Orange*0.8 filter 0.6} + finish {phong 0.7 reflection 0.15} + normal {bumps 0.05 scale 1} + } + + torus {4.0, 0.2 translate y*6.0} + torus {4.0, 0.2 translate y*1.2} + torus {2.8, 0.2 translate y*0.2} + + union { + difference { + cylinder {<0.2,0,0>,<-0.2,0,0>,0.5} + torus {0.5, 0.2 rotate z*90 translate x*0.2} + translate y*1.25 + } + difference { + cylinder {<0.2,0,0>,<-0.2,0,0>,0.5} + torus {0.5, 0.2 rotate z*90 translate x*0.2} + translate y*-1.25 + } + torus {1.25, 0.3 rotate x*90 clipped_by {plane {x,0 inverse}} translate x*0.8} + cylinder {<0,-1.25,0>,<0.8,-1.25,0>,0.3} + cylinder {<0,1.25,0>,<0.8,1.25,0>,0.3} + scale <1,1,1.5> translate <4.2,4,0> rotate y*-90 + } + + pigment {White} + normal {bumps 0.05 scale 3} + finish {phong 0.8 reflection 0.1} +} + +object {TeaCup rotate y*50 translate <4,0,-14>} diff --git a/render_povray/templates_pov/bsp_Tango.pov b/render_povray/templates_pov/bsp_Tango.pov new file mode 100644 index 00000000..da5c0945 --- /dev/null +++ b/render_povray/templates_pov/bsp_Tango.pov @@ -0,0 +1,61 @@ +// This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a +// letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + +// Persistence Of Vision Raytracer sample file. +// BSP test scene by Lance Birch - thezone.firewave.com.au +// Render with +BM2 to enable BSP tree bounding (POV-Ray v3.7 beta 12 or later). + +/*************************************************************** + * $File: //depot/povray/smp/distribution/scenes/bsp/Tango.pov $ + * $Revision: #1 $ + * $Change: 5418 $ + * $DateTime: 2011/03/06 09:25:00 $ + * $Author: jholsenback $ + **************************************************************/ + +#version 3.7; + +global_settings {assumed_gamma 1.0} +#default {texture {finish {ambient 0.03}} pigment {rgb 1}} +background {rgb 1} + +camera {ultra_wide_angle location <0,0,-55> look_at <0,0,0> angle 100 rotate <0,32,45> translate <-25,-25,0>} +light_source {0*x color rgb 2.9 area_light <8,0,0> <0,0,8> 8, 8 adaptive 2 jitter circular orient translate <100,0,-100>} + +#declare StrandCorner = difference { + cylinder {<0,0,0> <0,0,.1> 1} + cylinder {<0,0,-0.1> <0,0,.2> .25} + box {<-1.1,1.1,-0.1> <1.1,0,.2>} + box {<-1.1,1.1,-0.1> <0,-1.1,.2>} +}; + +#declare S = seed(12); +#declare CStrand = 1; +#declare CDir = 1; + +#while (CStrand <= 300) + #declare StartOffset = (rand(S)*30)-15; + #declare CHeight = <70-StartOffset,70+StartOffset,-CStrand/10>; + + #while ((CHeight.y > -45) & (CHeight.x > -45)) + #declare CDir = -CDir; + #declare StrandSegLength = floor(rand(S)*12)+1; + #if (CDir = 1) + box {CHeight+<-0.375,0,0> CHeight+<0.375,-StrandSegLength,.1>} + #declare CHeight = CHeight + <-0.625,-(StrandSegLength+0.625),0>; + object {StrandCorner translate CHeight+<0,0.625,0>} + #else + box {CHeight+<0,-0.375,0> CHeight+<-StrandSegLength,0.375,.1>} + #declare CHeight = CHeight + <-(StrandSegLength+0.625),-0.625,0>; + object {StrandCorner rotate <0,0,180> translate CHeight+<0.625,0,0>} + #end + #end + #if (CDir = 1) + object {StrandCorner rotate <0,0,270> translate CHeight+<0,0.625,0>} + #else + object {StrandCorner rotate <0,0,270> translate CHeight+<0.625,0,0>} + #end + + #declare CStrand = CStrand + 1; +#end diff --git a/render_povray/templates_pov/chess2.pov b/render_povray/templates_pov/chess2.pov new file mode 100644 index 00000000..b52070d6 --- /dev/null +++ b/render_povray/templates_pov/chess2.pov @@ -0,0 +1,727 @@ +// This work is licensed under the POV-Ray v3.7 distribution license. +// To view a copy of this license, visit http://www.povray.org/licences/v3.7/. + +// Persistence Of Vision raytracer sample file. +// POV-Ray scene description for chess board. +// By Ville Saari +// Copyright (c) 1991 Ferry Island Pixelboys +// +// This scene has 430 primitives in objects and 41 in bounding shapes and +// it takes over 40 hours to render by standard amiga. +// +// If you do some nice modifications or additions to this file, please send +// me a copy. My Internet address is: vsaari@niksula.hut.fi +// +// -w320 -h240 +// -w800 -h600 +a0.3 + +// Note : CHESS2.POV was created from Ville Saari's chess.pov +// -- Dan Farmer 1996 +// - Cchanged textures +// - Added camera blur and changed focal length +// - Use sky sphere +// - Modularized the code +// - Added felt pads to bottom of pieces + +// remaining manual bounding commented out by Bob Hughes, August 31, 2001 + +#version 3.6; + +global_settings { + assumed_gamma 2.2 + } + +#include "shapes.inc" +#include "colors.inc" +#include "textures.inc" +#include "skies.inc" +#include "metals.inc" +#include "woods.inc" + +#declare FB_Quality_Off = 0; +#declare FB_Quality_Fast = 1; +#declare FB_Quality_Default = 2; +#declare FB_Quality_High = 3; + +#declare FB_Quality= FB_Quality_High; + +camera { + location <59, 20, -55> + direction <0, 0, 2> + up <0, 1, 0> + right x*image_width/image_height // keep propotions with any aspect ratio + look_at <0, -1, 1> + +#if(FB_Quality != FB_Quality_Off) + aperture 2.25 + focal_point <0, 0, 0> +#end + +#switch(FB_Quality) +#case(FB_Quality_Off) + aperture 0 + #debug "\nNo focal blur used...\n" +#break +#case (FB_Quality_Fast) + blur_samples 7 + confidence 0.5 // default is 0.9 + variance 1/64 // default is 1/128 (0.0078125) + #debug "\nFast focal blur used...\n" +#break +#case(FB_Quality_Default) + blur_samples 19 + confidence 0.90 // default is 0.9 + variance 1/128 // default is 1/128 (0.0078125) + #debug "\nDefault focal blur used...\n" +#break +#case(FB_Quality_High) + blur_samples 37 + confidence 0.975 // default is 0.9 + variance 1/255 // default is 1/128 (0.0078125) + #debug "\nHigh Quality focal blur used...\n" +#break +#else + #debug "\nNo focal blur used...\n" +#end +} + +light_source { <800, 600, -200> colour White } + +#declare PawnBase = +union { + intersection { + sphere { <0, 0, 0>, 2.5 } + plane { -y, 0 } + } + cylinder { 0, y*0.35, 2.5 pigment { green 0.65 } } +} + +#declare PieceBase = +union { + intersection { + sphere { <0, 0, 0>, 3 } + plane { -y, 0 } + } + cylinder { 0, y*0.35, 3.0 pigment { green 0.65 } } +} + +#declare Pawn = union { + sphere { <0, 7, 0>, 1.5 } + + sphere { <0, 0, 0>, 1 + scale <1.2, 0.3, 1.2> + translate 5.5*y + } + + intersection { + plane { y, 5.5 } + object { + Hyperboloid_Y + translate 5*y + scale <0.5, 1, 0.5> + } + plane { -y, -2.5 } + } + + sphere { <0, 0, 0>, 1 + scale <2, 0.5, 2> + translate <0, 2.3, 0> + } + object { PawnBase } +} + + +#declare Rook = union { + intersection { + union { + plane { +x, -0.5 } + plane { -x, -0.5 } + plane { y, 9 } + } + + union { + plane { +z, -0.5 } + plane { -z, -0.5 } + plane { y, 9 } + } + + plane { y, 10 } + object { Cylinder_Y scale <2, 1, 2> } + object { Cylinder_Y scale <1.2, 1, 1.2> inverse } + plane { -y, -8 } + } + + intersection { + plane { y, 8 } + object { Hyperboloid_Y + scale <1, 1.5, 1> + translate 5.401924*y + } + plane { -y, -3 } + } + + sphere { <0, 0, 0>, 1 + scale <2.5, 0.5, 2.5> + translate 2.8*y + } + + object { PieceBase } +} + +#declare Knight = union { + intersection { + object { Cylinder_Z + scale <17.875, 17.875, 1> + translate <-18.625, 7, 0> + inverse + } + + object { Cylinder_Z + scale <17.875, 17.875, 1> + translate <18.625, 7, 0> + inverse + } + + object { Cylinder_X + scale <1, 5.1, 5.1> + translate <0, 11.2, -5> + inverse + } + + union { + plane { y, 0 + rotate 30*x + translate 9.15*y + } + plane { z, 0 + rotate -20*x + translate 10*y + } + } + + union { + plane { -y, 0 + rotate 30*x + translate 7.15*y + } + plane { y, 0 + rotate 60*x + translate 7.3*y + } + } + + union { + plane { y, 0 + rotate -45*z + } + plane { y, 0 + rotate 45*z + } + translate 9*y + } + + object { Cylinder_Y scale <2, 1, 2> } + sphere { <0, 7, 0>, 4 } + } + + sphere { <0, 0, 0>, 1 + scale <2.5, 0.5, 2.5> + translate <0, 2.8, 0> + } + + object { PieceBase } +} + +#declare Bishop = union { + sphere { <0, 10.8, 0>, 0.4 } + + intersection { + union { + plane { -z, -0.25 } + plane { +z, -0.25 } + plane { y, 0 } + rotate 30*x + translate 8.5*y + } + + sphere { <0, 0, 0>, 1 + scale <1.4, 2.1, 1.4> + translate 8.4*y + } + + plane { -y, -7 } + } + + sphere { <0, 0, 0>, 1 + scale <1.5, 0.4, 1.5> + translate 7*y + } + + intersection { + plane { y, 7 } + object { + Hyperboloid_Y + scale <0.6, 1.4, 0.6> + translate 7*y + } + plane { -y, -3 } + } + + sphere { <0, 0, 0>, 1 + scale <2.5, 0.5, 2.5> + translate 2.8*y + } + + object { PieceBase } +} + +#declare QueenAndKing = union { + sphere { <0, 10.5, 0>, 1.5 } + + intersection { + union { + sphere { <1.75, 12, 0>, 0.9 rotate 150*y } + sphere { <1.75, 12, 0>, 0.9 rotate 120*y } + sphere { <1.75, 12, 0>, 0.9 rotate 90*y } + sphere { <1.75, 12, 0>, 0.9 rotate 60*y } + sphere { <1.75, 12, 0>, 0.9 rotate 30*y } + sphere { <1.75, 12, 0>, 0.9 } + sphere { <1.75, 12, 0>, 0.9 rotate -30*y } + sphere { <1.75, 12, 0>, 0.9 rotate -60*y } + sphere { <1.75, 12, 0>, 0.9 rotate -90*y } + sphere { <1.75, 12, 0>, 0.9 rotate -120*y } + sphere { <1.75, 12, 0>, 0.9 rotate -150*y } + sphere { <1.75, 12, 0>, 0.9 rotate 180*y } + inverse + } + + plane { y, 11.5 } + + object { QCone_Y + scale <1, 3, 1> + translate 5*y + } + + plane { -y, -8 } + } + + sphere { <0, 0, 0>, 1 + scale <1.8, 0.4, 1.8> + translate 8*y + } + + intersection { + plane { y, 8 } + object { Hyperboloid_Y + scale <0.7, 1.6, 0.7> + translate 7*y + } + plane { -y, -3 } + } + + sphere { <0, 0, 0>, 1 + scale <2.5, 0.5, 2.5> + translate 2.8*y + } + + object { PieceBase } +} + +#declare Queen = union { + sphere { <0, 12.3, 0>, 0.4 } + object { QueenAndKing } +} + +#declare King = union { + intersection { + union { + intersection { + plane { y, 13 } + plane { -y, -12.5 } + } + + intersection { + plane { +x, 0.25 } + plane { -x, 0.25 } + } + } + + plane { +z, 0.25 } + plane { -z, 0.25 } + plane { +x, 0.75 } + plane { -x, 0.75 } + plane { +y, 13.5 } + plane { -y, -11.5 } + } + + object { QueenAndKing } +} + +#declare WWood = texture { + T_Silver_3B +} + +#declare BWood = texture { + T_Gold_3C +} + +#declare WPawn = object { + Pawn + + // bounded_by { sphere { <0, 4, 0>, 4.72 } } + + texture { + WWood + pigment { quick_color red 0.95 green 0.62 } + } +} + +#declare BPawn = object { + Pawn + + // bounded_by { sphere { <0, 4, 0>, 4.72 } } + + texture { + BWood + pigment { quick_color red 0.4 green 0.2 } + } +} + +#declare WRook = object { + Rook + + // bounded_by { sphere { <0, 5, 0>, 5.831 } } + + texture { + WWood + pigment { quick_color red 0.95 green 0.62 } + } +} + +#declare BRook = object { + Rook + + // bounded_by { sphere { <0, 5, 0>, 5.831 } } + + texture { + BWood + pigment { quick_color red 0.4 green 0.2 } + } +} + +#declare WKnight = object { + Knight + + // bounded_by { sphere { <0, 5, 0>, 5.831 } } + + texture { + WWood + pigment { quick_color red 0.95 green 0.62 } + } +} + +#declare BKnight = object { + Knight + rotate 180*y + + // bounded_by { sphere { <0, 5, 0>, 5.831 } } + + texture { + BWood + pigment { quick_color red 0.4 green 0.2 } + } +} + +#declare WBishop = object { + Bishop + + // bounded_by { sphere { <0, 5.5, 0>, 6.265 } } + + texture { + WWood + pigment { quick_color red 0.95 green 0.62 } + } +} + +#declare BBishop = object { + Bishop + rotate 180*y + + // bounded_by { sphere { <0, 5.5 ,0>, 6.265 } } + + texture { + BWood + pigment { quick_color red 0.4 green 0.2 } + } +} + +#declare WQueen = object { + Queen +/* + bounded_by { + intersection { + sphere { <0, 6, 0>, 6.71 } + object { Cylinder_Y scale <3, 1, 3> } + } + } +*/ + texture { + WWood + pigment { quick_color red 0.95 green 0.62 } + } +} + +#declare BQueen = object { + Queen +/* + bounded_by { + intersection { + sphere { <0, 6, 0>, 6.71 } + object { Cylinder_Y scale <3, 1, 3> } + } + } +*/ + texture { + BWood + pigment { quick_color red 0.4 green 0.2 } + } +} + +#declare WKing = object { + King +/* + bounded_by { + intersection { + sphere { <0, 6.5, 0>, 7.16 } + object { Cylinder_Y scale <3, 1, 3> } + } + } +*/ + texture { + WWood + pigment { quick_color red 0.95 green 0.62 } + } +} + +#declare BKing = object { + King +/* + bounded_by { + intersection { + sphere { <0, 6.5, 0>, 7.16 } + object { Cylinder_Y scale <3, 1, 3> } + } + } +*/ + texture { + BWood + pigment { quick_color red 0.4 green 0.2 } + } +} + +/* Sky */ +#declare SkySphere = sky_sphere { S_Cloud1 } + +/* Ground */ +#declare Ground = +plane { y, -80 + pigment { green 0.65 } + finish { + ambient 0.25 + diffuse 0.5 + } +} + +#declare FarSide = +union { + object { BPawn translate <-28, 0, 20> } + object { BPawn translate <-20, 0, 20> } + object { BPawn translate <-12, 0, 20> } + object { BPawn translate < -4, 0, 20> } + object { BPawn translate < 4, 0, 20> } + object { BPawn translate < 12, 0, 20> } + object { BPawn translate < 20, 0, 20> } + object { BPawn translate < 28, 0, 20> } + + object { BRook translate <-28, 0, 28> } + object { BKnight translate <-20, 0, 28> } + object { BBishop translate <-12, 0, 28> } + object { BQueen translate < -4, 0, 28> } + object { BKing translate < 4, 0, 28> } + object { BBishop translate < 12, 0, 28> } + object { BKnight translate < 20, 0, 28> } + object { BRook translate < 28, 0, 28> } +/* + bounded_by { + object { + Cylinder_X + scale <1, 9.56, 9.56> + translate <0, 6.5, 24> + } + } +*/ +} + +#declare NearSide = +union { + object { WPawn translate <-28, 0, -20> } + object { WPawn translate <-20, 0, -20> } + object { WPawn translate <-12, 0, -20> } + object { WPawn translate < -4, 0, -20> } + object { WPawn translate < 4, 0, -20> } + object { WPawn translate < 12, 0, -20> } + object { WPawn translate < 20, 0, -20> } + object { WPawn translate < 28, 0, -20> } + + object { WRook translate <-28, 0, -28> } + object { WKnight translate <-20, 0, -28> } + object { WBishop translate <-12, 0, -28> } + object { WQueen translate < -4, 0, -28> } + object { WKing translate < 4, 0, -28> } + object { WBishop translate < 12, 0, -28> } + object { WKnight translate < 20, 0, -28> } + object { WRook translate < 28, 0, -28> } + + +} + +#declare Pieces = +union { + object { NearSide } + object { FarSide } +/* + bounded_by { + intersection { + plane { y, 13.5 } + sphere { -30*y, 63 } + } + } +*/ +} + +#declare FramePiece = +intersection { + plane { +y, -0.15 } + plane { -y, 3 } + plane { -z, 35 } + plane { <-1, 0, 1>, 0 } // 45 degree bevel + plane { < 1, 0, 1>, 0 } // 45 degree bevel +} + +#declare Frame = +union { + union { + object { FramePiece } + object { FramePiece rotate 180*y } + texture { + T_Wood20 + scale 2 + rotate y*87 + translate x*1 + finish { + specular 1 + roughness 0.02 + ambient 0.35 + } + } + } + + union { + object { FramePiece rotate -90*y } + object { FramePiece rotate 90*y } + texture { + T_Wood20 + scale 2 + rotate y*2 + finish { + specular 1 + roughness 0.02 + ambient 0.35 + } + } + } +} +#declare Board = + box { <-32, -1, -32> <32, 0, 32> + texture { + tiles { + texture { + pigment { + //marble + wrinkles + turbulence 1.0 + colour_map { + [0.0 0.7 colour White + colour White] + [0.7 0.9 colour White + colour red 0.8 green 0.8 blue 0.8] + [0.9 1.0 colour red 0.8 green 0.8 blue 0.8 + colour red 0.5 green 0.5 blue 0.5] + } + scale <0.6, 1, 0.6> + rotate -30*y + } + finish { + specular 1 + roughness 0.02 + reflection 0.25 + } + } // texture + tile2 + texture { + pigment { + granite + scale <0.3, 1, 0.3> + colour_map { + [0 1 colour Black + colour red 0.5 green 0.5 blue 0.5] + } + } + finish { + specular 1 + roughness 0.02 + reflection 0.25 + } + } + } // texture + scale <8, 1, 8> + } //texture + } // intersection + + + +/* Table */ +#declare Table = +union { + intersection { + plane { +y, -3 } + plane { -y, 8 } + sphere { <0, -5.5, 0>, 55 } + } + + intersection { + plane { y, -8 } + object { + Hyperboloid_Y + scale <10, 20, 10> + translate -20*y + } + } + + pigment { + granite + scale 6 + } + finish { + specular 1 + roughness 0.02 + reflection 0.3 + } +} + +object { Pieces } +object { Board } +object { Frame } +object { Ground } +object { Table } +sky_sphere { SkySphere } diff --git a/render_povray/templates_pov/cornell.pov b/render_povray/templates_pov/cornell.pov new file mode 100644 index 00000000..e4b34cd6 --- /dev/null +++ b/render_povray/templates_pov/cornell.pov @@ -0,0 +1,130 @@ +// This work is licensed under the Creative Commons Attribution 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/ +// or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, +// California, 94041, USA. + +// Persistence Of Vision Ray Tracer Scene Description File +// File: cornell.pov +// Desc: Radiosity demo scene. See also http://www.Graphics.Cornell.EDU/online/box/ +// Date: August 2001 +// Auth: Kari Kivisalo + +// +w300 +h300 + +#version 3.7; +global_settings { + assumed_gamma 1.0 + radiosity{ + pretrace_start 0.04 + pretrace_end 0.01 + count 200 + recursion_limit 3 + nearest_count 10 + error_bound 0.5 + } +} + +#declare Finish=finish{diffuse 0.75 ambient 0} + +#declare White=texture{pigment{rgb<1,1,1>} finish{Finish}} +#declare Red=texture{pigment{rgb<0.57,0.025,0.025>} finish{Finish}} +#declare Green=texture{pigment{rgb<0.025,0.236,0.025>} finish{Finish}} + +#declare LightColor=<1,0.67,0.21>; + +#declare N=3; // Divisions per side +#declare DX=13/N; // Dimensions of sub patches +#declare DZ=10.5/N; + +#declare SubPatch= + light_source{ + <27.8,54.88,27.95> + color LightColor*7 + area_light DX*x, DZ*z, 4, 4 jitter adaptive 0 + spotlight radius -90 falloff 90 tightness 1 point_at <27.8,0,27.95> // for cosine falloff + fade_power 2 fade_distance (DX+DZ)/2 + } + +#declare i=0;#while (i<N) + #declare j=0;#while (j<N) + light_source{SubPatch translate<i*DX-(13-DX)/2,0,j*DZ-(10.5-DZ)/2>} + #declare j=j+1;#end +#declare i=i+1;#end + + + + +camera{ + location <27.8, 27.3,-80.0> + direction <0, 0, 1> + up <0, 1, 0> + right <-1, 0, 0> + angle 39.5 +} + + +// ------------------------ OBJECTS ---------------------------- + +// Light Patch + +box{ + <21.3,54.87,33.2><34.3,54.88,22.7> no_shadow + pigment{rgb<1,1,1>} finish{ambient 0.78 diffuse 0} +} + +union{ + // Floor + triangle{<55.28, 0.0, 0.0>,<0.0, 0.0, 0.0>,<0.0, 0.0, 55.92>} + triangle{<55.28, 0.0, 0.0>,<0.0, 0.0, 55.92>,<54.96, 0.0, 55.92>} + // Ceiling + triangle{<55.60, 54.88, 0.0>,<55.60, 54.88, 55.92>,<0.0, 54.88, 55.92>} + triangle{<55.60, 54.88, 0.0>,<0.0, 54.88, 55.92>,<0.0, 54.88, 0.0>} + // Back wall + triangle{<0.0, 54.88, 55.92>,<55.60, 54.88, 55.92>,<54.96, 0.0, 55.92>} + triangle{<0.0, 54.88, 55.92>,<54.96, 0.0, 55.92>,<0.0, 0.0, 55.92>} + texture {White} +} + +union { + // Right wall + triangle{<0.0, 54.88, 0.0>,<0.0, 54.88, 55.92>,<0.0, 0.0, 55.92>} + triangle{<0.0, 54.88, 0.0>,<0.0, 0.0, 55.92>,<0.0, 0.0, 0.0>} + texture {Green} +} + +union { + // Left wall + triangle{<55.28, 0.0, 0.0>,<54.96, 0.0, 55.92>,<55.60, 54.88, 55.92>} + triangle{<55.28, 0.0, 0.0>,<55.60, 54.88, 55.92>,<55.60, 54.88, 0.0>} + texture {Red} +} + +union { + // Short block + triangle{<13.00, 16.50, 6.50>,<8.20, 16.50, 22.50>,<24.00, 16.50, 27.20>} + triangle{<13.00, 16.50, 6.50>,<24.00, 16.50, 27.20>,<29.00, 16.50, 11.40>} + triangle{<29.00, 0.0, 11.40>,<29.00, 16.50, 11.40>,<24.00, 16.50, 27.20>} + triangle{<29.00, 0.0, 11.40>,<24.00, 16.50, 27.20>,<24.00, 0.0, 27.20>} + triangle{<13.00, 0.0, 6.50>,<13.00, 16.50, 6.50>,<29.00, 16.50, 11.40>} + triangle{<13.00, 0.0, 6.50>,<29.00, 16.50, 11.40>,<29.00, 0.0, 11.40>} + triangle{<8.20, 0.0, 22.50>,<8.20, 16.50, 22.50>,<13.00, 16.50, 6.50>} + triangle{<8.20, 0.0, 22.50>,<13.00, 16.50, 6.50>,<13.00, 0.0, 6.50>} + triangle{<24.00, 0.0, 27.20>,<24.00, 16.50, 27.20>,<8.20, 16.50, 22.50>} + triangle{<24.00, 0.0, 27.20>,<8.20, 16.50, 22.50>,<8.20, 0.0, 22.50>} + texture { White } +} + +union { + // Tall block + triangle{<42.30, 33.00, 24.70>,<26.50, 33.00, 29.60>,<31.40, 33.00, 45.60>} + triangle{<42.30, 33.00, 24.70>,<31.40, 33.00, 45.60>,<47.20 33.00 40.60>} + triangle{<42.30, 0.0, 24.70>,<42.30, 33.00, 24.70>,<47.20, 33.00, 40.60>} + triangle{<42.30, 0.0, 24.70>,<47.20, 33.00, 40.60>,<47.20, 0.0, 40.60>} + triangle{<47.20, 0.0, 40.60>,<47.20, 33.00, 40.60>,<31.40, 33.00, 45.60>} + triangle{<47.20, 0.0, 40.60>,<31.40, 33.00, 45.60>,<31.40, 0.0 45.60>} + triangle{<31.40, 0.0, 45.60>,<31.40, 33.00, 45.60>,<26.50, 33.00, 29.60>} + triangle{<31.40, 0.0, 45.60>,<26.50, 33.00, 29.60>,<26.50, 0.0, 29.60>} + triangle{<26.50, 0.0, 29.60>,<26.50, 33.00, 29.60>,<42.30, 33.00, 24.70>} + triangle{<26.50, 0.0, 29.60>,<42.30, 33.00, 24.70>,<42.30, 0.0, 24.70>} + texture {White} +} diff --git a/render_povray/templates_pov/diffract.pov b/render_povray/templates_pov/diffract.pov new file mode 100644 index 00000000..0c7a0228 --- /dev/null +++ b/render_povray/templates_pov/diffract.pov @@ -0,0 +1,195 @@ +// This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a +// letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + +// Persistence Of Vision raytracer sample file. +// +// -w320 -h240 +// -w800 -h600 +a0.3 + +#version 3.6; +global_settings{ assumed_gamma 1.0 max_trace_level 5 } + +#include "colors.inc" +#include "woods.inc" + + +#declare IOR = 1.45; +#declare Fade_Distance = 2; +#declare Fade_Power = 3; + +#declare Texture01 = texture { + pigment { + color rgbf <1, 1, 1, 1> + } + finish { + diffuse 0.000001 + metallic on + ambient 0 + reflection 0.05 + specular 1 + roughness 0.001 + irid { + 0.65 // contribution to overall color + thickness 0.8 // affects frequency, or "busy-ness" + turbulence 0.1 // Variance in film thickness + } + } +} + +#declare Interior01 = + interior { + fade_distance Fade_Distance + fade_power Fade_Power + ior IOR + caustics 1.0 + } + + +#declare Texture02a = texture { + T_Wood1 + scale 2 + rotate x*90 + translate x*5 + finish { + ambient 0.4 + } +} +#declare Texture02 = texture { + pigment { + color rgb<0.800, 0.800, 0.800> + } + finish { + brilliance 0.5 + metallic on + diffuse 0.200 + ambient 0.000 + specular 0.300 + roughness 0.02 + } + +} + +#declare Texture03 = texture { Texture01 } + +//---------------------------------------------------------------------- +// This scene uses a non-standard camera set-up. +// (See CAMERA in the included documentation for details.) +// If you are new to POV-Ray, you might want to try a different demo scene. +//---------------------------------------------------------------------- +camera { // Camera StdCam + angle 45 + location <3.50, -15.00, 3.00> + direction <0.0, 0.0, 1.6542> + sky <0.0, 0.0, 1.0> // Use right handed-system! + up <0.0, 0.0, 1.0> // Where Z is up + right x*image_width/image_height // keep propotions with any aspect ratio + look_at <0.000, 0.000, -2.7500> +} + +#declare Intensity = 20; +#declare L_Fade_Distance = 20; +#declare L_Fade_Power = 2; +#declare ALL = 8; +#declare ALW = 8; +#declare ALR = 6; + +#declare Area_Light=off; + +light_source { // Light1 + <-0.2, 100, 65> + color Cyan * Intensity +#if(Area_Light) + area_light x*ALL, z*ALW, ALR, ALR + adaptive 1 + jitter +#end + fade_distance L_Fade_Distance + fade_power L_Fade_Power +} + +light_source { // Light1 + <0, 95, 65> + color Yellow * Intensity +#if(Area_Light) + area_light x*ALL, z*ALW, ALR, ALR + adaptive 1 + jitter +#end + fade_distance L_Fade_Distance + fade_power L_Fade_Power +} + +light_source { // Light1 + <0.2, 90, 65> + color Magenta * Intensity +#if(Area_Light) + area_light x*ALL, z*ALW, ALR, ALR + adaptive 1 +#end + jitter + fade_distance L_Fade_Distance + fade_power L_Fade_Power +} + +sky_sphere { + pigment { + gradient y + color_map { + [0.0 color Gray10] + [1.0 color Gray30] + } + } +} + +union { + cylinder { <-3,0,0>, <3,0,0>, 0.3 } + torus { 1.0, 0.25 + rotate z*90 + } + texture {Texture01} + interior {Interior01} + translate <0.0, -4.0, -0.5> +} + +box { <-1, -1, -1>, <1, 1, 1> + texture {Texture01} + interior {Interior01} + + scale <3.0, 0.5, 0.5> + translate -1.75*z + rotate x*45 + translate -1.5*y +} + +sphere { <0,0,0>,1 + texture {Texture03} + interior {Interior01} + translate <3, 3, -1> +} +sphere { <0,0,0>,1 + texture {Texture03} + interior {Interior01} + + translate <0,3.0, -0.5> +} +sphere { <0,0,0>,1 + texture {Texture03} + interior {Interior01} + translate <-3.0, 3.0, -1> +} +cone { 0, 1, -2*z, 0 + texture {Texture03} + interior {Interior01} + translate <-4.0, 0.3, 0> +} +cone { 0, 1, -2*z, 0 + texture {Texture03} + interior {Interior01} + translate <4.0, 0.3, 0> +} + +plane { z, -2 + hollow on + pigment { Gray60 } +} diff --git a/render_povray/templates_pov/diffuse_back.pov b/render_povray/templates_pov/diffuse_back.pov new file mode 100644 index 00000000..4aa70aef --- /dev/null +++ b/render_povray/templates_pov/diffuse_back.pov @@ -0,0 +1,251 @@ +// This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a +// letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + +// Persistence of Vision Raytracer Scene Description File +// File: diffuse_back.pov +// Author: Christoph Lipka +// Description: Demonstrates diffuse backside illumination +// +// -w640 -h480 +// -w800 -h600 +a0.3 +// +// Warning: this will take time! + +#version 3.7; + +#declare Photons=on; +#declare Radiosity=on; + +global_settings { + max_trace_level 25 + assumed_gamma 2.2 + #if (Photons) + photons { + count 100000 + } + #end + #if (Radiosity) + radiosity { + pretrace_start 0.04 + pretrace_end 0.005 + count 1000 + nearest_count 10 + error_bound 0.5 + recursion_limit 2 + low_error_factor .25 + gray_threshold 0.0 + minimum_reuse 0.002 + brightness 1 + adc_bailout 0.01/2 + always_sample off + } + #end +} + +#if (Radiosity) + default { + finish { ambient 0 } + } +#else + default { + finish { ambient 0.2 } + } +#end + +// ---------------------------------------- + +#declare OverallBrightness = 8; +#declare OverallScale = 100; + +camera { + right x*image_width/image_height // keep propotions with any aspect ratio + location < 1,1.6,-2.5>*OverallScale + look_at <-2.0,1.2,0>*OverallScale +} + +light_source { + vnormalize(<-500,200,-250>)*1000*OverallScale + color rgb 1.3 * OverallBrightness + area_light x*10*OverallScale,y*10*OverallScale, 9,9 adaptive 1 jitter circular orient + photons { + refraction on + reflection on + } +} + +sky_sphere { + pigment { + gradient y + color_map { + [0.0 rgb <0.6,0.7,1.0>*OverallBrightness*0.5] + [0.7 rgb <0.0,0.1,0.8>*OverallBrightness*0.5] + } + } +} + + +// ---------------------------------------- + +plane { y, -10 + texture { + pigment { color rgb <1.0, 0.8, 0.6> } + finish { diffuse 0.5 } + } +} + +#declare M_SolidWhite= material { + texture { + pigment { rgb 1 } + finish { ambient 0 diffuse 0.8 specular 0.2 reflection { 0.2 } } + } +} + +// Room + +difference { + box { <-3.1,-1,-4>, <3.1,3.5,4> } // solid block + box { <-3,-0.2,-3>, <3,2.5,3> } // main room cutout + box { <-3.2,0.3,-2>, <2.9,2,2> } // window cutout + texture { + pigment { color rgb <0.9, 0.9, 0.9> } + finish { diffuse 1.0 } + } + scale OverallScale +} + +// Window Bars + +union { + cylinder { <-3.05,0, 1>, <-3.05,2, 1>, 0.05 } + cylinder { <-3.05,0,-1>, <-3.05,2,-1>, 0.05 } + material { M_SolidWhite } + scale OverallScale +} + +// Baseboards + +#declare Baseboard = union { + cylinder { <-3,0.1,0>, <3,0.1,0>, 0.025 } + box { <-3,0,0>, <3,0.1,-0.025> } + material { M_SolidWhite } + translate z*3 +} + +union { + object { Baseboard } + object { Baseboard rotate y*90 } + object { Baseboard rotate y*180 } + object { Baseboard rotate y*270 } + scale OverallScale +} + + +box { <-3,0,-3>, <3,-0.1,3> + pigment { color rgb <1.0, 0.8, 0.6> } + scale OverallScale +} + + +// Curtains + +#declare M_Curtains= material { + texture { + pigment { rgb <1.0,0.8,0.6> } + finish { + ambient 0 + diffuse 0.7,0.2 + } + } +} + +#declare Curtain= union { + polygon{ 5, <0,0.1,2.0>, <0,0.1,0.1>, <0,2.45,0.1>, <0,2.45,2.0>, <0,0.1,2.0> material { M_Curtains } } + cylinder { <0,0.1,2.025>, <0,0.1,0.075>, 0.025 material { M_SolidWhite } } + cylinder { <0,2.45,2.025>, <0,2.45,0.075>, 0.025 material { M_SolidWhite } } + translate <-2.8,0,0> + material { M_Curtains } +} + +union { + object { Curtain } + object { Curtain scale <1,1,-1> } + scale OverallScale +} + +// Screen + +#declare M_Screen= material { + texture { + pigment { rgbt <1,1,1, 0.01> } + finish { + ambient 0 + diffuse 0.55,0.45 + specular 0.2 + reflection { 0.2 } + } + } +} + +#declare Screen = cylinder { <0,0,0>, <0,1.0,0>, 0.5 + open + clipped_by { plane { x, 0.1 } } + material { M_Screen } +} + +union { + object { Screen rotate y*45 translate <-2.25,0,2> } + object { Screen rotate y*0 translate <-2.25,0,-1.0> } + scale OverallScale +} + +// Glass Objects + +#declare M_Glass= material { + texture { + pigment {rgbt 1} + finish { + ambient 0.0 + diffuse 0.05 + specular 0.6 + roughness 0.005 + reflection { + 0.1, 1.0 + fresnel on + } + conserve_energy + } + } + interior { + ior 1.5 + fade_power 1001 + fade_distance 0.9 * 10 + fade_color <0.5,0.8,0.6> + } +} + +sphere { + <0,1,0>, 1 + scale 0.2 + translate <-1.8,0,0.5> + material { M_Glass } + photons { // photon block for an object + target 1.0 + refraction on + reflection on + } + scale OverallScale +} + +cylinder { + <0,0.01,0>, <0,2.5,0>, 1 + scale 0.2 + translate <-3.05,0.3,0.4> + material { M_Glass } + photons { // photon block for an object + target 1.0 + refraction on + reflection on + } + scale OverallScale +} diff --git a/render_povray/templates_pov/float5.pov b/render_povray/templates_pov/float5.pov new file mode 100644 index 00000000..2d865cb4 --- /dev/null +++ b/render_povray/templates_pov/float5.pov @@ -0,0 +1,81 @@ +// This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a +// letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + +// Persistence of Vision Raytracer Scene Description File +// File: float5.pov +// Description: Demonstrates various new float math functions and #while loop +// Modified for 3.5: changed "log()" to "ln()". +// +// -w320 -h240 +// -w800 -h600 +a0.3 + +#version 3.6; + +global_settings { + assumed_gamma 1.0 + } + +#include "colors.inc" + +#declare Rad=1/8; +#declare Font="cyrvetic.ttf" + +#declare Xval=-6.0; + +#while (Xval <= 6.0) + sphere{<Xval,exp(Xval),0>,Rad pigment{color rgb<1,0.2,0>}} + + #if (Xval != 0.0) + sphere{<Xval,pow(Xval,-1),0>,Rad pigment{color rgb<0.2,0.7,0>}} + #end + + sphere{<Xval,pow(Xval,2),0>,Rad pigment{Blue}} + sphere{<Xval,pow(Xval,3),0>,Rad pigment{Cyan}} + + #if (Xval > 0.0) + sphere{<Xval,ln(Xval),0>,Rad pigment{Magenta}} + #end + + #declare Xval=Xval+0.02; +#end + + text{ttf Font "Y=exp(X)",0.1,0 translate <-6.5, 0.5,0> pigment{color rgb<1,0.2,0>}} + text{ttf Font "Y=pow(X,-1)",0.1,0 translate <-6.5,-1.5,0> pigment{color rgb<0.2,0.7,0>}} + text{ttf Font "Y=pow(X,2)",0.1,0 translate <-6.5, 3,0> pigment{Blue}} + text{ttf Font "Y=pow(X,3)",0.1,0 translate <-6.5,-4,0> pigment{Cyan}} + text{ttf Font "Y=ln(X)",0.1,0 translate < 2.5, 2,0> pigment{Magenta}} + +camera { + location <0, 0, -120> + angle 7 // direction <0, 0, 12> + right x*image_width/image_height + look_at <0, 0, 0> +} + +light_source { <5000, 10000, -20000> color White} +light_source { <-500, -1000, 2000> color White} +plane { -z, -Rad pigment {checker color rgb <1,1,1>*1.2 color rgb <1,1,.8>} } + +union{ // X-axis + cylinder{-x*5.5,x*5.5,.1} + cone{-x*6.5,0,-x*5.5,.2} + cone{ x*6.5,0, x*5.5,.2} + translate z*Rad + pigment{rgb<1,.8,1>} +} + +union{ // Y-axis + cylinder{-y*4,y*4,.1} + cone{-y*5,0,-y*4,.2} + cone{ y*5,0, y*4,.2} + translate z*Rad + pigment{rgb<.8,1,1>} +} + +union{ // Axes labels + text{ttf Font "X",0.1,0 translate <5.5,-1,0>} + text{ttf Font "Y",0.1,0 translate <-.75,4,0>} + pigment{rgb<1,.4,0>} +} + diff --git a/render_povray/templates_pov/gamma_showcase.pov b/render_povray/templates_pov/gamma_showcase.pov new file mode 100644 index 00000000..d601868f --- /dev/null +++ b/render_povray/templates_pov/gamma_showcase.pov @@ -0,0 +1,189 @@ +// This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a +// letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + +// Persistence of Vision Ray Tracer Scene Description File +// File: gamma_showcase.pov +// Vers: 3.7 +// Desc: Gamma Handling Test Scene - An arrangement of spheres on a marble plane +// Date: 2010-12-21 +// Auth: Christoph Lipka +// MORE INFORMATION: http://wiki.povray.org/content/Documentation:Tutorial_Section_3.3#Gamma_Handling +// + +// +w640 +h480 +a0.3 +am1 +fN -d File_Gamma=sRGB Output_File_Name=gamma_showcase.png +// +w640 +h480 +a0.3 +am1 +fN -d File_Gamma=1.0 Output_File_Name=gamma_showcase_linear.png +// +w320 +h240 +a0.3 +am1 +fN -d File_Gamma=sRGB Output_File_Name=gamma_showcase_ref0.png Declare=Stripes=off +// +w320 +h240 +a0.3 +am1 +fN -d File_Gamma=sRGB Output_File_Name=gamma_showcase_ref1.png Declare=Stripes=off Declare=Gamma=1.2 +// +w320 +h240 +a0.3 +am1 +fN -d File_Gamma=sRGB Output_File_Name=gamma_showcase_ref2.png Declare=Stripes=off Declare=Gamma=0.8 +// +w640 +h480 +a0.3 +am1 -f +d + +#version 3.7; + +#include "colors.inc" +#include "stones.inc" + +#ifndef (Stripes) + #declare Stripes = on; +#end +#ifndef (Gamma) + #declare Gamma = 1.0; +#end + +global_settings { + max_trace_level 5 + assumed_gamma 1.0 + radiosity { + pretrace_start 0.08 + pretrace_end 0.01 + count 35 + nearest_count 5 + error_bound 1.8 + recursion_limit 2 + low_error_factor .5 + gray_threshold 0.0 + minimum_reuse 0.015 + brightness 1 + adc_bailout 0.01/2 + } +} + +#default { + texture { + pigment {rgb 1} + finish { + ambient 0.0 + diffuse 0.6 + specular 0.6 roughness 0.001 + reflection { 0.0 1.0 fresnel on } + conserve_energy + } + } +} + +// ---------------------------------------- + +#local TestRed = rgb <0.5,0.1,0.1>; +#local TestGreen = rgb <0.1,0.5,0.1>; +#local TestBlue = rgb <0.1,0.1,0.5>; + +#local CameraFocus = <0,0.5,0>; +#local CameraDist = 8; +#local CameraDepth = 1.8; +#local CameraTilt = 20; + +camera { + location <0,0,0> + direction z*CameraDepth + right x*image_width/image_height + up y + translate <0,0,-CameraDist> + rotate x*CameraTilt + translate CameraFocus +} + +#macro LightSource(Pos,Color) + light_source { + Pos + color Color + spotlight + point_at <0,0,0> + radius 175/vlength(Pos) + falloff 200/vlength(Pos) + area_light x*vlength(Pos)/10, y*vlength(Pos)/10, 9,9 adaptive 1 jitter circular orient + } + +#end + +LightSource(<-500,500,-500>,TestRed + <0.2,0.2,0.2>) +LightSource(< 0,500,-500>,TestGreen + <0.2,0.2,0.2>) +LightSource(< 500,500,-500>,TestBlue + <0.2,0.2,0.2>) + +// ---------------------------------------- + +#macro DarkStripeBW(TargetBrightness) + #if (TargetBrightness < 0.5) + (0.0) + #else + (TargetBrightness*2 - 1.0) + #end +#end + +#macro BrightStripeBW(TargetBrightness) + #if (TargetBrightness < 0.5) + (TargetBrightness*2) + #else + (1.0) + #end +#end + +#macro DarkStripeRGB(TargetColor) + <DarkStripeBW(TargetColor.red),DarkStripeBW(TargetColor.green),DarkStripeBW(TargetColor.blue)> +#end + +#macro BrightStripeRGB(TargetColor) + <BrightStripeBW(TargetColor.red),BrightStripeBW(TargetColor.green),BrightStripeBW(TargetColor.blue)> +#end + +#macro StripedPigment(TargetColor) + #if (Stripes) + function { abs(mod(abs(image_height*CameraDepth*y/z+0.5),2.0)-1.0) } + color_map { + [0.5 color rgb DarkStripeRGB(TargetColor) ] + [0.5 color rgb BrightStripeRGB(TargetColor) ] + } + translate <0,0,-CameraDist> + rotate x*CameraTilt + translate CameraFocus + #else + color TargetColor + #end +#end + + +plane { + y, 0 + texture { T_Stone11 } + interior { ior 1.5 } +} + +#macro GammaAdjust(C,G) + #local C2 = color rgbft <pow(C.red,G),pow(C.green,G),pow(C.blue,G),pow(C.filter,G),pow(C.transmit,G)>; + (C2) +#end + +#macro TestSphere(Pos,Radius,TargetColor,Split) + sphere { + Pos + y*Radius, Radius + texture { pigment { color GammaAdjust(TargetColor,Gamma) } } + interior { ior 1.5 } + } + #if (Split) + sphere { + Pos + y*Radius + x*0.001, Radius + texture { pigment { StripedPigment(TargetColor) } } + interior { ior 1.5 } + } + #end +#end + +TestSphere(<-2,0,1>, 1, TestRed, true) +TestSphere(< 0,0,1>, 1, TestGreen, true) +TestSphere(< 2,0,1>, 1, TestBlue, true) + +#local Steps = 6; +#for(I,0,1,1/Steps) + #if (I < 0.5) + #local Color2 = TestRed; + #else + #local Color2 = TestBlue; + #end + #local P = abs(I-0.5)*2; + TestSphere(<I*4-2,0,-0.5>, 2/Steps, (1-P)*TestGreen + P*Color2, true) +#end + +#local Steps = 8; +#for(I,0,1,1/Steps) + TestSphere(<I*4-2,0,-1.5>, 2/Steps, rgb I, true) + TestSphere(<I*4-2,0,-2.0>, 2/Steps, GammaAdjust(rgb I, 2.2*Gamma), false) +#end diff --git a/render_povray/templates_pov/grenadine.pov b/render_povray/templates_pov/grenadine.pov new file mode 100644 index 00000000..1c409b13 --- /dev/null +++ b/render_povray/templates_pov/grenadine.pov @@ -0,0 +1,375 @@ +// This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a +// letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + +// Persistence of Vision Ray Tracer Scene Description File +// File: grenadine.pov +// Desc: Glass with liquid +// Date: 1999/06/04 +// Auth: Ingo Janssen +// Updated: 2013/02/15 for 3.7 +// +// -w320 -h240 +// -w800 -h600 +a0.3 + +#version 3.7; + +#include "glass.inc" + + +global_settings { + assumed_gamma 1.0 + max_trace_level 5 + photons { + spacing 0.01 // higher value 'lower' quality, faster parsing. + autostop 0 + jitter 0.5 + max_trace_level 15 + } +} + +light_source { + <500, 550, -100> + rgb <1, 1, 1> + spotlight + radius 1 + falloff 1.1 + tightness 1 + point_at <-19,-4,7> +} + +camera { + location <-0.5, 2.5, -7.0> + right x*image_width/image_height // keep propotions with any aspect ratio + look_at <-0.5, 0.5, 0.0> +} + +sky_sphere { + pigment { + gradient y + color_map { [0.0 rgb <0.2,0,1>] [1.0 color rgb 1] } + } +} + +union { //plane & background + difference { + box {<-20,-1,0>,<20,13,13>} + cylinder{<-21,13,0>,<21,13,0>,13} + } + plane {y, 0} + translate <0,-1.9999,7> + pigment {rgb .5} + finish {diffuse .5 ambient 0} +} + +//====== The Lemon ====== +#declare SS=seed(7); +#declare R_uit= 3; +#declare R_in=2.9; + +#declare Ring = difference { + cylinder {< 0 , 0, 0>, <1 , 0, 0>, R_uit} + cylinder {<-0.1, 0, 0>, <1.1, 0, 0>, R_in} +} + +#declare R2_uit= 0.8; +#declare R2_in=0.7; + +#declare Ring2 = difference { + cylinder {< 0 , 0, 0>, < 1 , 0, 0>, R2_uit} + cylinder {<-0.1, 0, 0>, < 1.1, 0, 0>, R2_in} +} + +#declare LemonOut= intersection { + merge { + difference { + merge { + object {Ring translate < 0.01, 0, (R_uit+R_in)/2>} + object {Ring translate <-1.01, 0,-(R_uit+R_in)/2>} + } + box {<-1.1, 0.1,-1>, <1.1, 2, 1>} + } + difference { + box {<-1, 0,-(R_uit-R_in)/2>, < 1, 1.1, (R_uit-R_in)/2>} + box { + <-2.5, 0,-1>, <2.5, 2, 1> + translate <0, 0.5, 0> + rotate <0, 0,-20> + } + } + difference{ + object { + Ring2 + translate <-0.5, 0, 0> + scale <2.2, 1, 1> + translate < 0, 0, (R2_uit+R2_in)/2> + } + box {<-2.1, 0,-1>,<2.1,-3, 1>} + translate <0, 0.499999, 0> + rotate <0, 0,-20> + } + } + merge { + cylinder {<0, 0,-0.5>, <0, 0, 0.5>, 0.8} + torus {0.8, 0.2 scale <1, 1.1, 1> rotate <90, 0, 0>} + } +} + +#declare BS1= array[24] { + < 24.8, 49.8>, < 13.0, 31.4>, < 4.0, 8.8>, < 0.1, 9.4> + < 0.1, 9.4>, <- 7.4, 10.7>, <-12.5, 30.4>, <-21.1, 49.8> + <-21.1, 49.8>, <-33.3, 76.9>, <-39.8, 87.0>, <-29.2, 91.4> + <-29.2, 91.4>, <-20.0, 95.3>, <-10.0, 95.9>, < 0.0, 95.9> + < 0.0, 95.9>, < 10.0, 95.9>, < 21.3, 95.8>, < 30.0, 90.7> + < 30.0, 90.7>, < 41.3, 84.0>, < 45.1, 86.5>, < 24.8, 49.8> +} + +#declare BS2= array[24] { + < 24.8, 55.8>, < 13.0, 31.4>, < 4.0, 8.8>, < 0.1, 15.0> + < 0.1, 15.0>, <- 7.4, 10.7>, <-12.5, 30.4>, <-21.1, 49.8> + <-21.1, 49.8>, <-33.3, 76.9>, <-39.8, 87.0>, <-29.2, 91.4> + <-29.2, 91.4>, <-20.0, 95.3>, <-10.0, 95.9>, < 0.0, 95.9> + < 0.0, 95.9>, < 10.0, 95.9>, < 21.3, 95.8>, < 30.0, 90.7> + < 30.0, 90.7>, < 41.3, 84.0>, < 45.1, 86.5>, < 24.8, 55.8> +} + + +#declare BS3= array[24] { + < 23.0, 49.8>, < 13.0, 31.4>, < 4.0, 8.8>, < 0.1, 6.0> + < 0.1, 6.0>, <- 7.4, 10.7>, <-12.5, 30.4>, <-21.1, 49.8> + <-21.1, 49.8>, <-33.3, 76.9>, <-39.8, 87.0>, <-29.2, 91.4> + <-29.2, 91.4>, <-20.0, 95.3>, <-10.0, 95.9>, < 0.0, 95.9> + < 0.0, 95.9>, < 10.0, 95.9>, < 21.3, 95.8>, < 30.0, 90.7> + < 30.0, 90.7>, < 41.3, 84.0>, < 45.1, 85.0>, < 23.0, 49.8> +} + + +#declare BS4= array[24] { + < 24.8, 49.8>, < 13.0, 31.4>, < 4.0, 11.8>, < 0.1, 9.0> + < 0.1, 9.0>, <- 7.4, 13.7>, <-12.5, 30.4>, <-21.1, 49.8> + <-21.1, 49.8>, <-33.3, 76.9>, <-39.8, 87.0>, <-21.2, 91.4> + <-21.2, 91.4>, <-20.0, 95.3>, <-10.0, 95.9>, < 0.0, 95.9> + < 0.0, 95.9>, < 10.0, 95.9>, < 21.3, 95.8>, < 30.0, 90.7> + < 30.0, 90.7>, < 41.3, 84.0>, < 45.1, 86.5>, < 24.8, 49.8> +} + +#declare J=0; +#declare Part1= prism { + bezier_spline + -0.5, 0.5, 24, + #while (J<24) + #declare P= BS1[J]; + P + #declare J=J+1; + #end + scale < 0.0095, 1, 0.0095> +} + +#declare J=0; +#declare Part2= prism { + bezier_spline + -0.5, 0.5, 24, + #while (J<24) + #declare P= BS2[J]; + P + #declare J=J+1; + #end + scale < 0.0095, 1, 0.0095> +} + +#declare J=0; +#declare Part3= prism { + bezier_spline + -0.5, 0.5, 24, + #while (J<24) + #declare P= BS3[J]; + P + #declare J=J+1; + #end + scale < 0.0095, 1, 0.0095> +} + +#declare J=0; +#declare Part4= prism { + bezier_spline + -0.5, 0.5, 24, + #while (J<24) + #declare P= BS4[J]; + P + #declare J=J+1; + #end + scale < 0.0095, 1, 0.0095> +} + +#declare LemonTex= texture { + pigment { + granite + scale <0.2,5,1> + colour_map { + [0.4 rgbf <1,0.65,0,0.4>] + [0.6 rgbf <1,0.8,0,0.4>] + [0.7 rgbf <1,0.9,0,0.6>] + [0.9 rgb <1,0.7,0>*1.5 ] + } + } + normal {granite -0.1 turbulence 0.3 scale <0.2,5,1>} + finish { + specular .9 + roughness 0.01 + } +} + +#declare Parts= union { + object {Part1 } + object {Part2 rotate <0, 360/7 ,0>} + object {Part3 rotate <0,2*(360/7),0>} + object {Part4 rotate <0,3*(360/7),0>} + object {Part1 rotate <0,4*(360/7),0>} + object {Part2 rotate <0,5*(360/7),0>} + object {Part3 rotate <0,6*(360/7),0>} + rotate <90,0,0> +} + +#declare LemonSlice = union { + intersection { + object {LemonOut} + object {Part1 rotate <90,0,0>} + texture {LemonTex rotate <90,0,0> translate rand(SS)*5} + } + intersection { + object {LemonOut} + object {Part2 rotate <0,360/7,0> rotate <90,0,0>} + texture {LemonTex rotate <0,360/7,0> rotate <90,0,0> translate rand(SS)*5} + } + intersection { + object {LemonOut} + object {Part3 rotate <0,2*(360/7),0> rotate <90,0,0>} + texture {LemonTex rotate <0,2*(360/7),0> rotate <90,0,0> translate rand(SS)*5} + } + intersection { + object {LemonOut} + object {Part4 rotate <0,3*(360/7),0> rotate <90,0,0>} + texture {LemonTex rotate <0,3*(360/7),0> rotate <90,0,0> translate rand(SS)*5} + } + intersection { + object {LemonOut} + object {Part1 rotate <0,4*(360/7),0> rotate <90,0,0>} + texture {LemonTex rotate <0,4*(360/7),0> rotate <90,0,0> translate rand(SS)*5} + } + intersection { + object {LemonOut} + object {Part2 rotate <0,5*(360/7),0> rotate <90,0,0>} + texture {LemonTex rotate <0,5*(360/7),0> rotate <90,0,0> translate rand(SS)*5} + } + intersection { + object {LemonOut} + object {Part3 rotate <0,6*(360/7),0> rotate <90,0,0>} + texture {LemonTex rotate <0,6*(360/7),0> rotate <90,0,0> translate rand(SS)*5} + } + + difference { //outside + object {LemonOut} + object {Parts} + texture { + cylindrical + rotate <90,0,0> + texture_map { + [0.05, pigment {rgb <1,0.8,0>} + normal {granite .1 scale 0.1} + finish {phong 0.8 phong_size 20} + ] + [0.06, pigment {rgb <1,0.9,0.7>} + normal {granite .07 scale 0.5} + ] + } + } + } +} + +//====== The Glass ====== + +#declare Ri=0.95; + +#declare Glass= merge { + difference { + cylinder { -y*2,y*2,1 } + sphere {-y*0.8,Ri} + cylinder { -y*0.8,y*2.01,Ri} + sphere {-y*1.9,0.1} + } + torus {0.975, 0.026 translate <0,2,0>} + // texture {T_Glass1} + // interior {ior 1.5} + // converted to material 26Sep2008 (jh) + material { + texture { + pigment {color rgbf<1.0, 1.0, 1.0, 0.7>} + finish {F_Glass1} + } + interior {ior 1.5} + } +} + + +//====== The bubbles and the juce ====== + +#declare Bubble= difference { + sphere {0,0.1} + sphere {0,0.09999999} +} + +#declare S= seed(7); +#declare I=0; +#declare Bubbles= intersection { + union { + #while (I<60) + object { + Bubble + scale rand(S) + scale <1,0.7,1> + translate <1,0.6,0> + rotate <0,360*rand(S),0> + } + object { + Bubble + scale rand(S)*0.5 + translate <rand(S),0.58,0> + rotate <0,360*rand(S),0> + } + #declare I=I+1; + #end //while + } + cylinder{y*0.5,y*0.85,Ri+0.00000001} +} + +#declare Liquid= merge { + sphere {-y*0.8,Ri+0.00000001} + cylinder {-y*0.8,y*0.6,Ri+0.00000001} + object {Bubbles} + pigment {rgbf <0.9, 0.1, 0.2, 0.95>} + finish {reflection 0.3} + interior{ior 1.2} +} + +//====== The glass and juice ===== +union { + object {Glass} + object {Liquid} + photons { + target + refraction on + reflection on + collect off + } +} + +object { + LemonSlice + scale <0.8,0.8,1> + translate <-0.99,0,0> + rotate <0,-30,0> + translate <0,2,0> + photons { + pass_through + } +}
\ No newline at end of file diff --git a/render_povray/templates_pov/isocacti.pov b/render_povray/templates_pov/isocacti.pov new file mode 100644 index 00000000..c0e8cde0 --- /dev/null +++ b/render_povray/templates_pov/isocacti.pov @@ -0,0 +1,242 @@ +// This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a +// letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + +// Persistence Of Vision raytracer sample file. +// Updated: Feb-2013 for 3.7 +// +// -w320 -h240 +// -w800 -h600 +a0.3 + +#version 3.7; +global_settings { assumed_gamma 1.3 } + +#include "stdinc.inc" +#include "arrays.inc" + + + +sky_sphere { + pigment {gradient y + color_map { + [0 color Blue*0.6] + [1 color White] + } + } +} + +#default {finish {ambient 0}} +#declare RS = seed(464786); +//---------------------------------------- +#declare CamLoc = < 5, 10,-10>; +camera { + location CamLoc + right x*image_width/image_height // keep propotions with any aspect ratio + angle 45 + look_at <0, 0, 0> +} + +light_source {<-20, 30, -30>*3 color White*1.5} +light_source {CamLoc color rgb 0.3} +//---------------------------------------- + +#declare Ground = +isosurface { + function {y - f_snoise3d(x/7, 0, z/2)*0.5} + threshold 0 + max_gradient 1.1 + contained_by {box {<-100,-3,-100>, < 100, 1, 100>}} + +/* texture { + pigment {color rgb < 1, 0.9, 0.65>} + normal {granite bump_size 0.1 scale 0.01} + }*/ + texture{ + pigment{ + color rgb <.518, .339, .138> + } + normal{ + bumps 5 + scale 0.05 + } + finish{ + specular .3 + roughness .8 + } + } + + texture{ + pigment{ + wrinkles + scale 0.05 + color_map{ + [0.0 color rgbt <1, .847, .644, 0>] + [0.2 color rgbt <.658, .456, .270, 1>] + [0.4 color rgbt <.270, .191, .067, .25>] + [0.6 color rgbt <.947, .723, .468, 0>] + [0.8 color rgbt <.356, .250, .047, 1>] + [1.0 color rgbt <.171, .136, .1, 1>] + } + } + + } +} +object {Ground} + +#declare RockColors = array[5] +{ + color rgb < 0.5, 0.4, 0.35>, + color rgb < 0.4, 0.5, 0.4>, + color rgb < 0.8, 0.75, 0.65>, + color rgb 0.8, + color rgb 0.5 +} + +#declare CtrlPtrn = function {pattern {bozo scale < 7, 1, 2>}} +#declare L = 0; +#while(L < 750) + #declare Pt = trace(Ground, < rand(RS)*25 - 15, 10, rand(RS)*25 - 10>, -y); + #if(rand(RS) > CtrlPtrn(Pt.x, Pt.y, Pt.z)) +// sphere {o, 0.03 + pow(rand(RS), 2)*0.15 + isosurface { + function {f_r(x, y, z) - 1 + f_noise3d(x, y, z)*0.5} + threshold 0 + contained_by {sphere {o, 1}} + #if(rand(RS) < 0.5) scale VRand_In_Box(< 1, 0.9, 1>, < 2, 1, 3>, RS) #end + rotate y*rand(RS)*360 + translate -y*0.35 + scale 0.03 + pow(rand(RS),2)*0.35 + texture { + pigment {Rand_Array_Item(RockColors, RS)*RRand(0.1, 1, RS)} + normal {granite bump_size 0.5 scale 0.01} + } + translate Pt + } + #declare L = L + 1; + #end +#end + +#macro MakeSpineBunch(Pt, Dir, Jitter, Len, BaseRad, Num) + #local L = 0; + #while(L < Num) + #local NewDir = vnormalize(Dir + Jitter*(< rand(RS), rand(RS), rand(RS)>*2 - 1)); + cone {Pt, BaseRad, Pt + NewDir*Len, 0} + #local L = L + 1; + #end +#end +#macro MakeSpineRows(Body, Stretch, AltJitter, Ridges, Bunches, Spines, SpineJitter, SpineLen, SpineRad) + #declare J = 0; + #local AltDelta = 180/Bunches; + union { + #while(J < Ridges) + #declare K = 0; + #while(K < Bunches) + #declare Orig = vrotate(-y*50, x*(K + rand(RS)*AltJitter)*AltDelta); + #declare Orig = vrotate(Orig, y*(360*J/Ridges + 360/(Ridges*4)))*Stretch; + #declare PtNorm = y; + #declare Pt = trace(Body, Orig,-Orig, PtNorm); + MakeSpineBunch(Pt, PtNorm, SpineJitter, SpineLen, SpineRad, Spines) + #declare K = K + 1; + #end + #declare J = J + 1; + #end + } +#end + +#declare sinw = function (x) {(sin(x) + 1)/2} + +#declare Ridges = 40; +#declare RidgeDepth = 0.075; + +#declare cactus1Body = +isosurface { + function {sqrt(x*x + pow(y - sqrt((x*x/4) + (z*z/4))*1.5, 2) + z*z) - 1 - + (sin(atan2(x, z)*Ridges)*0.5*RidgeDepth) + } + threshold 0 + max_gradient 5 + + contained_by {sphere {< 0, 0, 0>, 3.1}} + texture { + pigment {radial + color_map { + [0.00 color rgb < 0.3, 0.65, 0.4>*0.8] + [0.65 color rgb < 0.3, 0.65, 0.4>*0.8] + [1.00 color rgb < 0.3, 0.65, 0.4>*0.2] + } + frequency Ridges sine_wave + } + normal {dents 0.1 poly_wave 2 scale < 1, 0.15, 1>} + } +} +#declare Cactus1 = +union { + object {cactus1Body} + object {MakeSpineRows(cactus1Body, 1, 0.2, Ridges, 24, 3, 0.5, 1, 0.01) + texture {pigment {color rgb < 0.98, 0.98, 0.5>}} + } + scale < 1, 0.75, 1> + translate y*0.35 +} + + +#declare Ridges = 32; +#declare RidgeDepth = 0.1; +#declare cactus2Body = + +isosurface { + function { + f_r(x, y*0.35, z) - 1 - sqrt(x*x + z*z)*0.2 + - (sinw(atan2(x, z)*Ridges)*RidgeDepth) + } + threshold 0 + max_gradient 5 + contained_by {sphere {< 0, 0, 0>, 3.1}} + texture { + pigment {color rgb < 0.3, 0.65, 0.4>} + normal {bozo 0.1 scale < 1, 0.15, 1>} + } +} + +#declare Cactus2 = +union { + object {cactus2Body} + object {MakeSpineRows(cactus2Body, < 1, 3, 1>, 1, Ridges, 64, 3, 1, 0.5, 0.01) + texture {pigment {color rgb < 0.98, 0.98, 0.5>}} + } + translate y*2 +} + + + +#declare Ridges = 75; +#declare RidgeDepth = 0.05; +#declare cactus3Body = + +isosurface { + function { + sqrt(x*x + pow((y/1.5),2) + z*z) - 1 - sqrt(x*x + z*z)*0.2 + - (sinw(atan2(x, z)*Ridges)*RidgeDepth) + } + threshold 0 + max_gradient 5 + contained_by {sphere {< 0, 0, 0>, 3.1}} + texture { + pigment {color rgb < 0.1, 0.5, 0.25>} + normal {bozo 0.1 scale 0.15} + } +} +#declare Cactus3 = +union { + object {cactus3Body} + object {MakeSpineRows(cactus3Body, < 1, 1.5, 1>, 1, Ridges, 24, 5, 1, 0.35, 0.01) + texture {pigment {color rgb < 0.98, 0.98, 0.85>}} + } + translate y*1.25 +} + +object {Cactus1 translate < 3, 0,-3>} +object {Cactus2} +object {Cactus3 translate <-2, 0,-3.5>} + +//---------------------------------------- diff --git a/render_povray/templates_pov/mediasky.pov b/render_povray/templates_pov/mediasky.pov new file mode 100644 index 00000000..9347424e --- /dev/null +++ b/render_povray/templates_pov/mediasky.pov @@ -0,0 +1,147 @@ +// This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a +// letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + +// Persistence of Vision Raytracer Scene Description File +// File: mediasky.pov +// Author: Chris Huff +// Description: This file demonstrates the use of scattering media +// to create a sky with clouds. It attempts to simulate an actual +// atmosphere: there is an outer shell of media that scatters blue +// light, and an inner cloud shell that scatters white. The scattered +// light from the outer shell makes the sky appear blue, and the light +// that passes through is tinted orange by its passage, giving the +// clouds an orange color. +// +// Updated: 2013/02/15 for 3.7 +// +// -w320 -h180 +// +w640 +h360 +a0.3 +// use 16:9 aspect ratio +// +//******************************************* + +#version 3.7; + +#include "colors.inc" + +global_settings { + assumed_gamma 1.0 + max_trace_level 5 +} + +#declare CamPos = <-5, 1,-25>; + +camera { + location CamPos + up y + right x*image_width/image_height // keep propotions with any aspect ratio + look_at < 0, 7.5, 0> + angle 90 +} + +light_source {CamPos, color Gray30 media_interaction off} +//light_source {vrotate(z, <-1, 8, 0>)*500000, color rgb < 1, 0.8, 0.65>} + +#declare SunPos = vrotate(z, <-12, 8, 0>)*1000000; +light_source {SunPos, color White*2} +sphere {SunPos, 75000 + texture { + pigment {color White} + finish {ambient 10 diffuse 0} + } + no_shadow +} + + +#declare PlanetSize = 50000; + +//the ocean +sphere {< 0, 0, 0>, 1 + scale PlanetSize + translate -y*PlanetSize + hollow + texture { +// pigment {color rgb < 1, 1, 1>} + pigment {color rgbf < 1, 1, 1, 1>} + finish { + ambient 0 diffuse 0.7 + reflection {0.5, 1 + fresnel//use the fresnel form of angle-dependant reflection + metallic//use metallic reflection + } + conserve_energy + metallic//use metallic highlights + } + normal {bumps bump_size 0.075 scale < 4, 1, 1>*0.025} + } + interior { + ior 1.33//required for fresnel reflection + media { + method 3 + samples 2 intervals 1 + absorption color rgb < 0.75, 0.5, 0.25>*0.005 + } + } +} +//the ocean floor +sphere {< 0, 0, 0>, 1 + scale PlanetSize - 100 + translate -y*PlanetSize + texture { + pigment {color rgb 1} + } +} + +#macro SkyShell(minAlt, maxAlt, Int) + difference { + sphere {< 0, 0, 0>, 1 scale (PlanetSize + maxAlt)} + sphere {< 0, 0, 0>, 1 scale (PlanetSize + minAlt)} + hollow + texture {pigment {color rgbf 1}} + translate -y*PlanetSize + interior {Int} + } +#end + +//A much more realistic sky could be done using multiple layers +//of clouds to simulate clouds of different densities and with +//different altitudes. Of course, this would render a lot slower... + +//the "cloud shell", creates clouds. +SkyShell(1000, 1300, + interior { + media { + method 3 aa_threshold 0.1 aa_level 3 + samples 4 intervals 1 + scattering {2, color White*0.0075 extinction 1} + density {wrinkles + scale < 5, 2, 2>*200 + warp {turbulence 2} + color_map { + [0 color rgb 1] + [0.5 color rgb 0.85] + [0.55 color rgb 0.035] + [1 color rgb 0.035] + } + } + } +/* media { + method 3 + samples 2 intervals 1 + scattering {2, color White*0.0075*0.015 extinction 1} + }*/ + } +) + +//the "atmosphere shell", creates the blue sky and orange light. +SkyShell(1001, 2200, + interior { + media { + method 3 + samples 2 intervals 1 + scattering {4, color rgb < 0.25, 0.6, 0.9>*0.00075 extinction 1} + } + } +) + diff --git a/render_povray/templates_pov/patio-radio.pov b/render_povray/templates_pov/patio-radio.pov new file mode 100644 index 00000000..a5a0a0ca --- /dev/null +++ b/render_povray/templates_pov/patio-radio.pov @@ -0,0 +1,292 @@ +// This work is licensed under the Creative Commons Attribution 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/ +// or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, +// California, 94041, USA. + +// Persistence Of Vision raytracer sample file. +// +// -w320 -h240 +// -w800 -h600 +a0.3 + +//===================== RENAISSANCE PATIO ===================================== + +//===================== RADIANCE AND ENVIRONMENT SETTINGS ===================== +#version 3.7; +#declare Rad_Quality = 2; + +global_settings { + assumed_gamma 1.0 + +#switch (Rad_Quality) + #case (1) + radiosity { // --- Settings 1 (fast) --- + pretrace_start 0.08 + pretrace_end 0.02 + count 50 + error_bound 0.5 + recursion_limit 1 + } + #break + #case (2) + radiosity { // --- Settings 2 (medium quality) --- + pretrace_start 0.08 + pretrace_end 0.01 + count 120 + error_bound 0.25 + recursion_limit 1 + } + #break + #case (3) + radiosity { // --- Settings 3 (high quality) --- + pretrace_start 0.08 + pretrace_end 0.005 + count 400 + error_bound 0.1 + recursion_limit 1 + } + #break + #case (4) + radiosity { // --- Settings 4 (medium quality, recursion_limit 2) --- + pretrace_start 0.08 + pretrace_end 0.005 + count 350 + error_bound 0.15 + recursion_limit 2 + } + #break + #end + +} + +fog { + fog_type 2 + fog_alt 1.3 + fog_offset 0 + color rgb <0.7, 0.8, 0.9> + distance 800 +} + +light_source {<1000, 10000, -15000> color rgb <1.0, 0.9, 0.78>*2.3} + +sphere { // --- Sky --- + <0, 0, 0>, 1 + texture { + pigment { + gradient y + color_map { + [0.0 color rgb < 1.0, 1.0, 1.0 >] + [0.3 color rgb < 0.5, 0.6, 1.0 >] + } + } + finish { diffuse 0 #if (version < 3.7) ambient 1 #else emission 1 #end } + } + scale 10000 + hollow on + no_shadow +} + +//===================== THE SCENERY ITSELF ==================================== + +#include "colors.inc" + +camera { location <500,150,0> + angle 65 // direction z + right x*image_width/image_height + look_at <0,150,320> + } + +plane {y,0 pigment {color rgb <0.776,0.706,0.706>}} + +#declare Arch_01 = +union { + difference { + cylinder {<-20,0,0>,<20,0,0>,140} + cylinder {<-21,0,0>,<21,0,0>,130} + torus {130 2 rotate z*90 translate x*20} + torus {130 2 rotate z*90 translate x*-20} + } + difference { + cylinder {<-18,0,0>,<18,0,0>,130} + cylinder {<-21,0,0>,<21,0,0>,125} + } + torus {139 1 rotate z*90 translate x*20} + torus {136 1 rotate z*90 translate x*20} + torus {139 1 rotate z*90 translate x*-20} + torus {136 1 rotate z*90 translate x*-20} +clipped_by {plane {y,0 inverse}} +} + +#macro SphereBox (Radius) + #local SpRad = sqrt (Radius*Radius + Radius*Radius); + intersection { + sphere {0,SpRad} + box {<-Radius,0,-Radius>,<Radius,Radius,Radius>} + } +#end + +#declare Column_01 = union { + box {<-40,0,-40>,<40,50,40>} + box {<-35,50,-35>,<35,60,35>} + cylinder {<0,60,0>,<0,66,0>,28} + torus {28 3 translate y*63} + difference { + cylinder {<0,66,0>,<0,70,0>,25} + torus {25 2 translate y*68} + } + cylinder {<0,70,0>,<0,74,0>,25} + torus {25 2 translate y*72} + cylinder {<0,74,0>,<0,76,0>,25} + sphere {<0,0,0>,23 scale <1,15,1> translate y*76 clipped_by {cylinder {<0,76,0>,<0,265,0>,30}}} + torus {20 2 translate y*255} + torus {19 2 translate y*258} + object {SphereBox (20) rotate z*180 translate y*(260+22)} + box {<-25,282,-25>,<25,285,25>} + box {<-20,285,-22>,<20,295,22>} + difference { + cylinder {<-22,290,0>,<22,290,0>,5} + cylinder {<-23,290,0>,<23,290,0>,3} + } + box {<-23,295,-23>,<23,298,23>} + box {<-28,298,-28>,<28,300,28>} +} + +#declare Vault_01 = +difference { + box {<-160,0,-160>,<160,250,160>} + cylinder {<-170,0,0>,<170,0,0>,130} + cylinder {<-170,0,0>,<170,0,0>,130 rotate y*90} +} + +#declare Vault_02 = //(vault de coin) +difference { + union { + box {<-180,0,-160>,<180,250,160>} + box {<-160,0,-180>,<160,250,180>} + } + cylinder {<-190,0,0>,<190,0,0>,130} + cylinder {<-190,0,0>,<190,0,0>,130 rotate y*90} +} + +#declare Spindle_01 = +lathe{ + cubic_spline + 12, + <0.017005,-0.005668>, + <0.117619,-0.004251>, + <0.123287,0.072272>, + <0.068020,0.124704>, + <0.076523,0.195559>, + <0.141709,0.444967>, + <0.075106,0.524324>, + <0.138875,0.616435>, + <0.055267,0.916859>, + <0.137458,0.973543>, + <0.161549,1.000468>, + <0.204061,0.991965> +} + +#declare Band_01 = +union { + box {<0,0,-25>,<-1,60,25>} + box {<0,0,-25>,<5,2,25>} + box {<0,8,-25>,<3,2,25>} + box {<0,8,-25>,<6,15,25>} + box {<0,8,-10>,<6,15,-8>} + box {<0,8,10>,<6,15,8>} + box {<0,20,-25>,<3,19,25>} + box {<0,50,-25>,<5,60,25>} + box {<0,50,-25>,<3,55,25>} + box {<0,20,-2>,<3,40,-4>} + box {<0,20,-6>,<3,40,-8>} + box {<0,20,2>,<3,40,4>} + box {<0,20,6>,<3,40,8>} + box {<0,42,-25>,<6,40,25>} + box {<0,0,-2>,<7,8,-4>} + box {<0,0,-6>,<7,8,-8>} + box {<0,0,2>,<7,8,4>} + box {<0,0,6>,<7,8,8>} +} + +#declare Balcony_01 = union { + box {<-10,0,-.5>,<10,10,.5>} + cylinder {<-10,5,-.5>,<-10,5,.5>,4} + cylinder {<10,5,-.5>,<10,5,.5>,4} +} + +#declare Group1 = union { + object {Arch_01 translate <-490,300,0>} + object {Arch_01 translate <-490,300,300>} + object {Arch_01 translate <-490,300,-300>} + + object {Column_01 translate <-490,0,150>} + object {Column_01 translate <-490,0,-150>} + object {Column_01 translate <-490,0,-450>} + object {Column_01 translate <-490,0,450>} + + object {Column_01 translate <-790,0,150>} + object {Column_01 translate <-790,0,-150>} + object {Column_01 translate <-790,0,-450>} + object {Column_01 translate <-790,0,450>} + object {Column_01 translate <-790,0,-450-40>} + object {Column_01 translate <-790,0,450+40>} + + object {Arch_01 rotate y*90 translate <-490-150,300,150>} + object {Arch_01 rotate y*90 translate <-490-150,300,-150>} + object {Arch_01 rotate y*90 translate <-490-150,300,450>} + object {Arch_01 rotate y*90 translate <-490-150,300,-450>} + object {Arch_01 rotate y*90 translate <-490-150,300,450+40>}//doubleaux + object {Arch_01 rotate y*90 translate <-490-150,300,-450-40>} + + object {Vault_01 translate <-640,300,0>} + object {Vault_01 translate <-640,300,300>} + object {Vault_01 translate <-640,300,-300>} + object {Vault_02 translate <-640,300,640>}//coin + + #declare I=0; + #while (I < 1000) + object {Band_01 translate <-480,500,(-470 + I)>} + #declare I=I+50; + #end + + #declare I=0; + #while (I < 1000) + object {Spindle_01 scale <60,60,60> translate <-500,550,(-500 + I)>} + #declare I=I+40; + #end + + object {Balcony_01 scale <1,1,1020> translate <-500,610,0>} + object {Balcony_01 scale <1,1,1020> translate <-500,610,0> rotate y*90} + object {Balcony_01 scale <1,1,1020> translate <-500,610,0> rotate y*180} + object {Balcony_01 scale <1,1,1020> translate <-500,610,0> rotate y*270} + + box {<-790,0,-810>,<-810,450,810>} + +} + +#declare PatioComplete = union { + object {Group1} + object {Group1 rotate y*90} + object {Group1 rotate y*180} + object {Group1 rotate y*270} +} + +object {PatioComplete + pigment {Wheat} + finish {ambient 0.0 diffuse 0.6} +} + +#declare Paving_01 = +union { + box {<-40,0,-490>,<40,.1,490> translate x*150} + box {<-40,0,-490>,<40,.1,490> translate x*-150} + box {<-40,0,-490>,<40,.1,490> translate x*490} + box {<-40,0,-490>,<40,.1,490> translate x*-480} + + texture { + pigment {color rgb <0.706,0.714,0.776>*.8} + finish {ambient 0.0 diffuse 0.6} + } +} + +object {Paving_01 translate <-10,0,0>} +object {Paving_01 rotate y*90 translate <-10,0,0>} diff --git a/render_povray/templates_pov/subsurface.pov b/render_povray/templates_pov/subsurface.pov new file mode 100644 index 00000000..088ba102 --- /dev/null +++ b/render_povray/templates_pov/subsurface.pov @@ -0,0 +1,176 @@ +// This work is licensed under the Creative Commons Attribution 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/ +// or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, +// California, 94041, USA. + +// Persistence of Vision Ray Tracer Scene Description File +// File: subsurface.pov +// Vers: 3.7 +// Desc: Subsurface Scattering Demo - Candle on a Checkered Plane +// Date: 2011-02-25 +// Auth: Christoph Lipka +// +// Recommended settings: +// +W640 +H480 +A0.3 +// Rendering time: +// ~4 min on a 2.3GHz AMD Phenom X4 9650 QuadCore + +#version 3.7; + +#include "colors.inc" + +global_settings { + assumed_gamma 1.0 + mm_per_unit 40 + subsurface { samples 400, 40 } + ambient_light 0.3 +} + +// ---------------------------------------- + +camera { + location <0.0, 2.5, -4.0> + angle 50 // direction 1.5*z + right x*image_width/image_height + look_at <0.5, 1.0, 0.0> +} + +sky_sphere { + pigment { + gradient y + color_map { + [0.0 rgb <0.6,0.7,1.0>] + [0.7 rgb <0.0,0.1,0.8>] + } + } +} + +light_source { + <-30, 30, -30> + color rgb <1,1,1> +} + +// ---------------------------------------- + +// a checkered white/"black" marble plane +plane { + y, -0.01 + texture { + checker + texture { + // marble parameters derived from Jensen et al. "A Practical Model for Subsurface Light Transport", Siggraph 2001 + pigment { + crackle + turbulence 0.7 + color_map { + [0.5 color rgb <0.83,0.79,0.75>*1.0] + [0.9 color rgb <0.83,0.79,0.75>*0.8] + [1.0 color rgb <1.00,0.75,0.70>*0.5] + } + scale 0.3 + } + normal { + agate 0.085 + turbulence 2 + } + finish{ + diffuse 0.8 + specular 0.6 + reflection { 0.2 fresnel } + conserve_energy + subsurface { translucency <0.4562, 0.3811,0.3325> } + } + } + texture { + pigment{ crackle turbulence 0.25 + form <-1,1,0.05> + color_map { [0.00 color rgb<1,1,1>] + [0.025 color rgb<0.252,0.482,0.372>] + [0.05 color rgb<0.082,0.092,0.072>] + [0.15 color rgb<0.05,0.09,0.06>] + [0.52 color rgb<0.008,0.019,0.012>] + [0.65 color rgb<0.0025,0.0029,0.0014>] + [0.75 color rgb<0.0060,0.0084,0.0065>] + [1.00 color rgb<0.008,0.012,0.012>] + } + } + normal { + agate 0.085 + turbulence 2 + } + finish{ + diffuse 0.8 + specular 0.6 + reflection { 0.2 fresnel } + conserve_energy + subsurface { translucency <0.4562, 0.3811,0.3325> } + } + } + scale 4 + translate <0.7,0,1> + } + interior { ior 1.5 } +} + +// the classic chrome sphere +sphere { <1.5,0.7,1>, 0.7 + pigment { color rgb 1 } + finish { + ambient 0 diffuse 0 + specular 0.7 roughness 0.01 + conserve_energy + reflection { 0.7 metallic } + } +} + +// a candle... +blob { + threshold 0.5 + cylinder { <0.0, 0.0, 0.0>, + <0.0, 2.0, 0.0>, 1.0, 1.0 } // candle "body" + sphere { <0.0, 2.5, 0.0>, 0.8, -2.0 } // (used to shape the candle top) + sphere { <0.0,-0.52, 0.0>, 0.8, -2.0 } // (used to shape the candle bottom) + sphere { <0.0, 2.0, -0.5>, 0.1, -0.2 } // the "notch" where wax runs over + cylinder { <0.0, 1.88,-0.52>, + <0.0, 1.5, -0.52>, 0.05, 0.2 } // a streak of wax running over + sphere { <0.0, 1.5, -0.55>, 0.07, 0.2 } // a drop of of wax running over + texture { + // bees' wax + pigment { color rgb <0.8,0.50,0.01> } + finish{ + diffuse 0.6 specular 0.6 roughness 0.1 + subsurface { translucency <5,3,1>*0.5 } + } + } + interior { ior 1.45 } + rotate -y*45 +} + +// ... and the wick +intersection { + box { <-1,-1,-1>, <0,1,1> } + torus { 0.15, 0.03 } + rotate x*90 + translate <0.15, 1.95, 0.0> + pigment { color rgb 0 } + finish { ambient 0 diffuse 1 specular 0 } + no_shadow +} + +// a classic-textured slab for comparison +superellipsoid { + <0.1,0.1> + texture { + pigment { color rgb <0.9,0.6,0.6> } + finish{ + diffuse 1.0 + specular 0.6 + reflection { 0.2 fresnel } + conserve_energy + } + } + interior { ior 1.45 } + scale <0.25,0.05,0.25> + rotate y*30 + translate <1.2,0.05,0.25> +} diff --git a/render_povray/templates_pov/wallstucco.pov b/render_povray/templates_pov/wallstucco.pov new file mode 100644 index 00000000..b6231266 --- /dev/null +++ b/render_povray/templates_pov/wallstucco.pov @@ -0,0 +1,186 @@ +// This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +// To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a +// letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + +// Persistence Of Vision Ray Tracer Scene Description File +// Desc: Brick wall & Stucco +// Date: 2000/03/14 +// Updated: 2001/07/26 +// Auth: Ingo Janssen +// Updated: 2013/02/15 for 3.7 +// +// -w320 -h240 +// -w800 -h600 +a0.3 +// + +#version 3.7; +global_settings { assumed_gamma 1.0 + noise_generator 1 } // change to 2 or 3. + +light_source { + < 500, 500,500> + rgb 1 +} + +camera { + location <0.2, 0.0,-25.0> + look_at <0.0, 0.0, 0.0> + right x*image_width/image_height // keep propotions with any aspect ratio + angle 65 +} + +//====== Doing the Stucco ====== + +#declare L2=0.55; //clock; //Set amount of decay of stucco, higher value is more decay. animate +#declare PWrink= pigment { //Mortar + wrinkles + scale 0.25 + colour_map { + [0, rgb 0.5] + [L2, rgb 0.96] + } +} +#declare Stucco= pigment { //Stucco + granite + scale 0.05 + colour_map { + [0, rgb 0.96] + [1, rgb 1] + } +} + +#declare StuMor= pigment { //Stucco & Mortar + pigment_pattern{ + wrinkles + scale 0.25 + } + pigment_map { + [L2, PWrink] + [L2, Stucco] + } +} + +#declare HF_Stucco=height_field { //Turn it into a hightfield + function 500, 500{ //500,500 for test higher is better, but watch the memory + pigment{StuMor } + } + translate -0.5 + rotate -90*x + scale <20,20,2> + pigment { //Use the mortar to colour up the stucco + pigment_pattern { + wrinkles + scale 0.25 + } + color_map { + [L2, rgb 0.5] + [L2, rgb <1,1,0.95>] + } + warp {planar z, 0} + translate <-0.5, -0.5, 0> + rotate <180,0,0> + scale <20,20,2> + } +} + +//====== Lay some Bricks ====== + +//Size : dimension of the brick in a vector x, y, z +//Mortar : width of the joint. +//Turbulence etc : control the stone deformation. +#macro BrickWall(Size, Mortar, Turbulence, Octaves, Lambda, Omega) + + #local Brick= pigment { + boxed // one single brick ... + scale <Size.x/2,Size.y/2,Size.z/2> + translate <Size.x/2+Mortar,Size.y/2+Mortar,0> + warp {repeat x*(Size.x+Mortar)} // ... repeated over and over again. + warp {repeat y*(2*(Size.y+Mortar))} + } + + #declare FBrickWall= function { + pigment { + pigment_pattern { + gradient y + warp {repeat y} + scale <1,2*(Size.y+Mortar),1> + } + pigment_map { + [0.5, Brick + warp { // deforming the bricks ... + turbulence Turbulence + octaves Octaves + lambda Lambda + omega Omega + } + translate <0,-(Mortar/2),0> + ] + [0.5, Brick // ... row by row. + warp { + turbulence Turbulence + octaves Octaves + lambda Lambda + omega Omega + } + translate <(Size.x/2)+Mortar,(Size.y+(Mortar/2)),0> + ] + } + } + } +#end + +#declare Wall=pigment { + BrickWall(<4,1,1>,0.2,<0.05,0.1,0>,6,0.5,0.5) + function{FBrickWall(x,y,z).gray} + pigment_map { // give some stucture to the joint ... + [0, granite + scale 0.1 + colour_map { + [0, rgb 0][1, rgb 0.3] + } + ] + [0.05, crackle // ... and the bricks. + scale <3,1,1> + turbulence 0.5 + colour_map { + [0, rgb 0.34][1, rgb 0.5] + } + ] + } + scale 0.04 +} + +#declare HF_Wall=height_field { // Build the wall + function 500, 500 { //500,500, for test, higher is better & slower. Watch the memory use. + pigment{Wall} + } + smooth + translate -0.5 + rotate <-90,0,0> + scale <33,33,1> + pigment { + Wall + pigment_map { + [0, rgb 0.6] + [0.05, wrinkles + turbulence 0.3 + scale <2,0.3,1> + colour_map { + [0.0, rgb <0.5,0.3,0.25>] + [0.15, rgb <0.5,0.3,0.25>/1.3] + [0.3, rgb <0.5,0.3,0.25>] + [0.6, rgb <0.6,0.3,0.25>/1.6] + [0.8, rgb <0.5,0.3,0.25>] + [1.0, rgb <0.5,0.3,0.35>/2] + } + ] + } + translate <-0.5, -0.5, 0> + rotate -90*x + warp {planar y, 0} + scale <33,33,1> + } +} + +object {HF_Stucco} +object {HF_Wall translate <0,0,-0.8>} diff --git a/render_povray/ui.py b/render_povray/ui.py index ba763871..0feecec9 100644 --- a/render_povray/ui.py +++ b/render_povray/ui.py @@ -1755,3 +1755,25 @@ class TEXT_PT_povray_custom_code(TextButtonsPanel, bpy.types.Panel): if text: layout.prop(text.pov, "custom_code", text="Add as POV code") + +###############################################" +# Text editor templates. + +class TEXT_MT_templates_pov(bpy.types.Menu): + bl_label = "POV-Ray" + + # We list templates on file evaluation, we can assume they are static data, + # and better avoid running this on every draw call. + import os + template_paths = [os.path.join(os.path.dirname(__file__), "templates_pov")] + + def draw(self, context): + self.path_menu( + self.template_paths, + "text.open", + props_default={"internal": True}, + ) + +def menu_func_templates(self, context): + # Do not depend on POV-Ray being active renderer here... + self.layout.menu("TEXT_MT_templates_pov") diff --git a/rigify/CREDITS b/rigify/CREDITS deleted file mode 100644 index 38f6de46..00000000 --- a/rigify/CREDITS +++ /dev/null @@ -1,32 +0,0 @@ -A big thank you to all the people listed here for supporting Rigify. - -Original prototyping and development, and Python API support: -- Campbell Barton - -Development: -- PitchiPoy Animation Productions -- Kfir Merlaub -- Tamir Lousky - -General financial support: -- Benjamin Tolputt -- Nesterenko Viktoriya -- Jeff Hogan -- PitchiPoy Animation Productions - -IK/FK snapping financial support: -- Benjamin Tolputt -- Nesterenko Viktoriya -- Leslie Chih -- Isaac Ah-Loe -- Casey "TheLorax" Jones - -### Rigify Version 0.5 ### -Development: -- Lucio Rossi - -Design: -- Ivan Cappiello - -General financial support: -- Mad Entertainment Animation
\ No newline at end of file diff --git a/rigify/README b/rigify/README deleted file mode 100644 index f8cb7656..00000000 --- a/rigify/README +++ /dev/null @@ -1,250 +0,0 @@ -INTRODUCTION ------------- -Rigify is an auto-rigging system based on a "building blocks" paradigm. The -user can create a rig by putting together any combination of rig types, in any -configuration that they want. - -A rig type is something like "biped arm" or "spine" or "finger". - -The input to the Rigify system is something called a "metarig". It is an -armature that contains data about how to construct the rig. In particular, it -contains bones in the basic configuration of the rig, with some bones tagged -to indicate the rig type. - -For example, a metarig might contain a chain of three bones, the root-most of -which is tagged as being a biped arm. When given as input to Rigify, Rigify -will then generate a fully-featured biped arm rig in the same position and -proportions as the 3-bone chain. - -One could also have another chain of bones, the root-most of which is tagged as -being a spine. And the root-most bone of the arm chain could be the child of -any of those spine bones. Then the rig that Rigify generates would be a -spine rig with an arm rig attached to it. - - -THE GUTS OF RIGIFY, SUMMARIZED ------------------------------- -The concept behind rigify is fairly simple. It recieves an armature as input -with some of the bones tagged as being certain rig types (arm, leg, etc.) - -When Rigify recieves that armature as input, the first thing it does is -duplicate the armature. From here on out, the original armature is totally -ignored. Only the duplicate is used. And this duplicate armature object will -become the generated rig. - -Rigify next prepends "ORG-" to all of the bones. These are the "original" -bones of the metarig, and they are used as the glue between rig types, as I -will explain later. - -Rigify then generates the rig in two passes. The first pass is the -"information gathering" stage. - -The information gathering stage doesn't modify the armature at all. It simply -gathers information about it. Or, rather, it lets the rig types gather -information about it. -It traverses the bones in a root-most to leaf-most order, and whenever it -stumbles upon a bone that has a rig type tagged on it, it creates a rig-type -python object (rig types will be explained further down) for that rig type, -and executes the resulting python object's information gathering code. - -At the end of the information gathering stage, Rigify has a collection of -python objects, each of which know all the information they need to generate -their own bit of the rig. - -The next stage is the rig generation stage. This part is pretty simple. All -Rigify does is it loops over all of the rig-type python objects that it created -in the previous stage (also in root-most to leaf-most order), and executes -their rig-generate code. All of the actual rig generation happens in the -rig-type python objects. - -And that's pretty much it. As you can see, most of the important code is -actually in the rig types themselves, not in Rigify. Rigify is pretty sparse -when it comes right down to it. - -There is one final stage to rig generation. Rigify checks all of the bones -for "DEF-", "MCH-", and "ORG-" prefixes, and moves those bones to their own -layers. It also sets all of the "DEF-" bones to deform, and sets all other -bones to _not_ deform. And finally, it looks for any bone that does not have -a parent, and sets the root bone (which Rigify creates) as their parent. - - -THE GUTS OF A RIG TYPE, BASIC ------------------------------ -A rig type is simply a python module containing a class named "Rig", and some -optional module functions. The Rig class has only two methods: -__init__() and generate() - -__init__() is the "information gathering" code for the rig type. When Rigify -loops through the bones and finds a tagged bone, it will create a python -object from the Rig class, executing this method. -In addition to the default "self" parameter, __init__() needs to take the -armature object, the name of the bone that was tagged, and a parameters object. - -A proper rig-type __init__() will look like this: - - def __init__(self, obj, bone_name, params): - # code goes here - -At the bare minimum, you are going to want to store the object and bone name -in the rig type object for later reference in the generate() method. So: - - def __init__(self, obj, bone_name, params): - self.obj = obj - self.org_bone = bone_name - -Most rig types involve more than just that one bone, though, so you will also -want to store the names of any other relevant bones. For example, maybe the -parent of the tagged bone is important to the rig type: - - def __init__(self, obj, bone_name, params): - self.obj = obj - self.org_bone = bone_name - self.org_parent = obj.data.bones[bone_name].parent.name - -It is important that you store the _names_ of the bones, and not direct -references. Due to the inner workings of Blender's armature system, direct -edit-bone and pose-bone references are lost when flipping in and out of -armature edit mode. (Arg...) - -Remember that it is critical that the information-gathering method does _not_ -modify the armature in any way. This way all of the rig type's info-gathering -methods can execute on a clean armature. Many rig types depend on traversing -parent-child relationships to figure out what bones are relevant to them, for -example. - - -Next is the generate() method. This is the method that Rigify calls to -actually generate the rig. It takes the form: - - def generate(self): - # code goes here - -It doesn't take any parameters beyond "self". So you have to store any -information you need with the __init__() method. - -generate() pretty much has free reign to do whatever it wants, with the exception -of two simple rules: -1. Other than the "ORG-" bones, do not touch anything that is not created by -the rig type (this prevents rig types from messing each other up). -2. Even with "ORG-" bones, the only thing you are allowed to do is add children -and add constraints. Do not rename them, do not remove children or -constraints, and especially do not change their parents. (Adding constraints -and adding children are encouraged, though. ;-)) This is because the "ORG-" -bones are the glue that holds everything together, and changing them beyond -adding children/constraints ruins the glue, so to speak. - -In short: with the exception of adding children/constraints to "ORG-" -bones, only mess with things that you yourself create. - -It is also generally a good idea (though not strictly required) that the rig -type add constraints to the "ORG-" bones it was generated from so that the -"ORG-" bones move with the animation controls. -For example, if I make a simple arm rig type, the controls that the animator -uses should also move the "ORG-" bones. That way, any other rig-types that are -children of those "ORG-" bones will move along with them. For example, any -fingers on the end of the arm. - -Also, any bones that the animator should not directly animate with should have -their names prefixed with "DEF-" or "MCH-". The former if it is a bone that -is intended to deform the mesh, the latter if it is not. -It should be obvious, then, that a bone cannot be both an animation control and -a deforming bone in Rigify. This is on purpose. - -Also note that there are convenience functions in utils.py for prepending -"DEF-" and "MCH-" to bone names: deformer() and mch() -There is also a convenience function for stripping "ORG-" from a bone name: -strip_org() -Which is useful for removing "ORG-" from bones you create by duplicating -the "ORG-" bones. -I recommend you use these functions instead of manually adding/stripping -these prefixes. That way if the prefixes are changed, it can be changed in -one place (those functions) and all the rig types will still work. - - -THE GUTS OF A RIG TYPE, ADVANCED --------------------------------- -If you look at any of the rig types included with Rigify, you'll note that they -have several functions outside of the Rig class. -THESE ADDITIONAL FUNCTIONS ARE _NOT_ REQUIRED for a rig type to function. But -they can add some nifty functionality to your rig. - -Here are the additional functions relevant to Rigify, with brief decriptions of -what they are for: - - -RIG PARAMETERS --------------- -For many rig types, it is handy for the user to be able to tweak how they are -generated. For example, the included biped arm rig allows the user to specify -the axis of rotation for the elbow. - -There are two functions necessary to give a rig type user-tweakable parameters: -add_parameters() -parameters_ui() - -add_parameters() takes an IDPropertyGroup as input, and adds its parameters -to that group as RNA properties. For example: - - def add_parameters(params): - params.toggle_param = bpy.props.BoolProperty(name="Test toggle:", default=False, description="Just a test, not really used for anything.") - -parameters_ui() recieves a Blender UILayout object and an IDPropertyGroup -containing the parameters added by add_parameters(). It creates a GUI in the -UILayout for the user to tweak those parameters. For example: - - def parameters_ui(layout, params): - r = layout.row() - r.prop(params, "toggle_param") - - -SAMPLE METARIG --------------- -It is a good idea for all rig types to have a sample metarig that the user can -add to their own metarig. This is what the create_sample() function is for. - -create_sample() takes the current armature object as input, and adds the bones -for its rig-type's metarig. For example: - - def create_sample(obj): - bpy.ops.object.mode_set(mode='EDIT') - arm = obj.data - - bone = arm.edit_bones.new('Bone') - bone.head[:] = 0.0000, 0.0000, 0.0000 - bone.tail[:] = 0.0000, 0.0000, 1.0000 - bone.roll = 0.0000 - bone.use_connect = False - - bpy.ops.object.mode_set(mode='OBJECT') - pbone = obj.pose.bones[bone] - pbone.rigify_type = 'copy' - pbone.rigify_parameters.add() - -Obviously, this isn't something that you generally want to hand-code, -especially with more complex samples. When in edit-mode on an armature, -there is a "Rigify Dev Tools" panel in the View3d tools panel containing a -button labeled "Encode Sample to Python". This button will generate the python -code for create_sample() from the armature you are editing. The generated code -appears in a text block called "metarig_sample.py" - -IMPLEMENTATION RIGS -------------------- -Starting from version 0.5 you can create a Rig class as an implementation of a wrapper class. -This happens for limb rigs for example, where super_limb is kind of a wrapper class for arm, leg and paws. -To declare a class as an implementation just declare an IMPLEMENTATION constant in the module and set it to True. -Implementation classes are shown in the metarig samples list and generate a sample if a proper create_sample function is implemented, but cannot be directly assigned as a rigify type. - -GENERATING A PYTHON UI ----------------------- -The generate() method can also, optionally, return python code as a single -string. This python code is added to the "rig properties" panel that gets -auto-generated along with the rig. This is useful for exposing things like -IK/FK switches in a nice way to the animator. - -The string must be returned in a list, e.g.: - -return ["my python code"] - -The reason it needs to be put in a list is to leave room for expanding the API -in the future, for returning additional information. - diff --git a/rigify/__init__.py b/rigify/__init__.py index 2e7953b1..b86b7038 100644 --- a/rigify/__init__.py +++ b/rigify/__init__.py @@ -286,6 +286,38 @@ def register(): IDStore.rigify_types = bpy.props.CollectionProperty(type=RigifyName) IDStore.rigify_active_type = bpy.props.IntProperty(name="Rigify Active Type", description="The selected rig type") + IDStore.rigify_advanced_generation = bpy.props.BoolProperty(name="Advanced Options", + description="Enables/disables advanced options for Rigify rig generation", + default=False) + + def update_mode(self, context): + if self.rigify_generate_mode == 'new': + self.rigify_force_widget_update = False + + IDStore.rigify_generate_mode = bpy.props.EnumProperty(name="Rigify Generate Rig Mode", + description="'Generate Rig' mode. In 'overwrite' mode the features of the target rig will be updated as defined by the metarig. In 'new' mode a new rig will be created as defined by the metarig. Current mode", + update=update_mode, + items=(('overwrite', 'overwrite', ''), + ('new', 'new', ''))) + + IDStore.rigify_force_widget_update = bpy.props.BoolProperty(name="Force Widget Update", + description="Forces Rigify to delete and rebuild all the rig widgets. if unset, only missing widgets will be created", + default=False) + + IDStore.rigify_target_rigs = bpy.props.CollectionProperty(type=RigifyName) + IDStore.rigify_target_rig = bpy.props.StringProperty(name="Rigify Target Rig", + description="Defines which rig to overwrite. If unset, a new one called 'rig' will be created.", + default="") + + IDStore.rigify_rig_uis = bpy.props.CollectionProperty(type=RigifyName) + IDStore.rigify_rig_ui = bpy.props.StringProperty(name="Rigify Target Rig UI", + description="Defines the UI to overwrite. It should always be the same as the target rig. If unset, 'rig_ui.py' will be used", + default="") + + IDStore.rigify_rig_basename = bpy.props.StringProperty(name="Rigify Rig Name", + description="Defines the name of the Rig. If unset, in 'new' mode 'rig' will be used, in 'overwrite' mode the target rig name will be used", + default="") + if (ui and 'legacy' in str(ui)) or bpy.context.user_preferences.addons['rigify'].preferences.legacy_mode: # update legacy on restart or reload bpy.context.user_preferences.addons['rigify'].preferences.legacy_mode = True @@ -307,6 +339,14 @@ def unregister(): del IDStore.rigify_collection del IDStore.rigify_types del IDStore.rigify_active_type + del IDStore.rigify_advanced_generation + del IDStore.rigify_generate_mode + del IDStore.rigify_force_widget_update + del IDStore.rigify_target_rig + del IDStore.rigify_target_rigs + del IDStore.rigify_rig_uis + del IDStore.rigify_rig_ui + del IDStore.rigify_rig_basename bpy.utils.unregister_class(RigifyName) bpy.utils.unregister_class(RigifyParameters) diff --git a/rigify/generate.py b/rigify/generate.py index 66971a7e..01e5de28 100644 --- a/rigify/generate.py +++ b/rigify/generate.py @@ -31,6 +31,7 @@ from .utils import RIG_DIR from .utils import create_root_widget from .utils import random_id from .utils import copy_attributes +from .utils import gamma_correct from .rig_ui_template import UI_SLIDERS, layers_ui, UI_REGISTER @@ -71,7 +72,7 @@ def generate_rig(context, metarig): bpy.ops.object.mode_set(mode='OBJECT') scene = context.scene - + id_store = context.window_manager #------------------------------------------ # Create/find the rig object and set it up @@ -79,18 +80,31 @@ def generate_rig(context, metarig): # regenerate in the same object. If not, create a new # object to generate the rig in. print("Fetch rig.") - try: - name = metarig["rig_object_name"] - except KeyError: - name = "rig" - try: - obj = scene.objects[name] - except KeyError: - obj = bpy.data.objects.new(name, bpy.data.armatures.new(name)) + rig_new_name = "" + rig_old_name = "" + if id_store.rigify_rig_basename: + rig_new_name = id_store.rigify_rig_basename + "_rig" + + if id_store.rigify_generate_mode == 'overwrite': + name = id_store.rigify_target_rig or "rig" + try: + obj = scene.objects[name] + rig_old_name = name + obj.name = rig_new_name or name + except KeyError: + rig_old_name = name + name = rig_new_name or name + obj = bpy.data.objects.new(name, bpy.data.armatures.new(name)) + obj.draw_type = 'WIRE' + scene.objects.link(obj) + else: + name = rig_new_name or "rig" + obj = bpy.data.objects.new(name, bpy.data.armatures.new(name)) # in case name 'rig' exists it will be rig.001 obj.draw_type = 'WIRE' scene.objects.link(obj) + id_store.rigify_target_rig = obj.name obj.data.pose_position = 'POSE' # Get rid of anim data in case the rig already existed @@ -102,6 +116,24 @@ def generate_rig(context, metarig): obj.select = True scene.objects.active = obj + # Remove wgts if force update is set + wgts_group_name = "WGTS_" + (rig_old_name or obj.name) + if wgts_group_name in scene.objects and id_store.rigify_force_widget_update: + bpy.ops.object.select_all(action='DESELECT') + for i, lyr in enumerate(WGT_LAYERS): + if lyr: + context.scene.layers[i] = True + for wgt in bpy.data.objects[wgts_group_name].children: + wgt.select = True + bpy.ops.object.delete(use_global=False) + for i, lyr in enumerate(WGT_LAYERS): + if lyr: + context.scene.layers[i] = False + if rig_old_name: + bpy.data.objects[wgts_group_name].name = "WGTS_" + obj.name + + wgts_group_name = "WGTS_" + obj.name + # Remove all bones from the generated rig armature. bpy.ops.object.mode_set(mode='EDIT') for bone in obj.data.edit_bones: @@ -269,7 +301,7 @@ def generate_rig(context, metarig): t.tick("Create root bone: ") # Create Group widget - wgts_group_name = "WGTS" + # wgts_group_name = "WGTS" if wgts_group_name not in scene.objects: if wgts_group_name in bpy.data.objects: bpy.data.objects[wgts_group_name].user_clear() @@ -279,6 +311,18 @@ def generate_rig(context, metarig): scene.objects.link(wgts_obj) wgts_obj.layers = WGT_LAYERS t.tick("Create main WGTS: ") + # + # if id_store.rigify_generate_mode == 'new': + # bpy.ops.object.select_all(action='DESELECT') + # for wgt in bpy.data.objects[wgts_group_name].children: + # wgt.select = True + # for i, lyr in enumerate(WGT_LAYERS): + # if lyr: + # context.scene.layers[i] = True + # bpy.ops.object.make_single_user(obdata=True) + # for i, lyr in enumerate(WGT_LAYERS): + # if lyr: + # context.scene.layers[i] = False #---------------------------------- try: @@ -398,7 +442,7 @@ def generate_rig(context, metarig): # Assign shapes to bones # Object's with name WGT-<bone_name> get used as that bone's shape. for bone in bones: - wgt_name = (WGT_PREFIX + obj.data.bones[bone].name)[:63] # Object names are limited to 63 characters... arg + wgt_name = (WGT_PREFIX + obj.name + '_' + obj.data.bones[bone].name)[:63] # Object names are limited to 63 characters... arg if wgt_name in context.scene.objects: # Weird temp thing because it won't let me index by object name for ob in context.scene.objects: @@ -423,15 +467,28 @@ def generate_rig(context, metarig): # Create list of layer name/row pairs layer_layout = [] for l in metarig.data.rigify_layers: - print( l.name ) + print(l.name) layer_layout += [(l.name, l.row)] # Generate the UI script - if "rig_ui.py" in bpy.data.texts: - script = bpy.data.texts["rig_ui.py"] + if id_store.rigify_generate_mode == 'overwrite': + rig_ui_name = id_store.rigify_rig_ui or 'rig_ui.py' + else: + rig_ui_name = 'rig_ui.py' + + if id_store.rigify_generate_mode == 'overwrite' and rig_ui_name in bpy.data.texts.keys(): + script = bpy.data.texts[rig_ui_name] script.clear() else: script = bpy.data.texts.new("rig_ui.py") + + rig_ui_old_name = "" + if id_store.rigify_rig_basename: + rig_ui_old_name = script.name + script.name = id_store.rigify_rig_basename + "_rig_ui.py" + + id_store.rigify_rig_ui = script.name + script.write(UI_SLIDERS % rig_id) for s in ui_scripts: script.write("\n " + s.replace("\n", "\n ") + "\n") @@ -451,14 +508,15 @@ def generate_rig(context, metarig): # Add rig_ui to logic skip = False ctrls = obj.game.controllers + for c in ctrls: - if 'Python' in c.name and c.text.name == 'rig_ui.py': + if 'Python' in c.name and c.text.name == script.name: skip = True break if not skip: bpy.ops.logic.controller_add(type='PYTHON', object=obj.name) ctrl = obj.game.controllers[-1] - ctrl.text = bpy.data.texts['rig_ui.py'] + ctrl.text = bpy.data.texts[script.name] t.tick("The rest: ") @@ -521,9 +579,9 @@ def create_bone_groups(obj, metarig): if name not in obj.pose.bone_groups.keys(): bg = obj.pose.bone_groups.new(name) bg.color_set = 'CUSTOM' - bg.colors.normal = groups[g_id].normal - bg.colors.select = groups[g_id].select - bg.colors.active = groups[g_id].active + bg.colors.normal = gamma_correct(groups[g_id].normal) + bg.colors.select = gamma_correct(groups[g_id].select) + bg.colors.active = gamma_correct(groups[g_id].active) for b in pb: try: diff --git a/rigify/legacy/utils.py b/rigify/legacy/utils.py index c718f146..65838b7d 100644 --- a/rigify/legacy/utils.py +++ b/rigify/legacy/utils.py @@ -151,7 +151,7 @@ def copy_bone_simple(obj, bone_name, assign_name=''): edit_bone_1 = obj.data.edit_bones[bone_name] edit_bone_2 = obj.data.edit_bones.new(assign_name) bone_name_1 = bone_name - bone_name_2 = edit_bone_2.name + bone_name_2 = edit_bone_2.name # Copy edit bone attributes edit_bone_2.layers = list(edit_bone_1.layers) diff --git a/rigify/metarig_menu.py b/rigify/metarig_menu.py index 0c917c40..6b12abad 100644 --- a/rigify/metarig_menu.py +++ b/rigify/metarig_menu.py @@ -86,6 +86,7 @@ def make_metarig_add_execute(m): bpy.ops.object.armature_add() obj = context.active_object obj.name = "metarig" + obj.data.name = "metarig" # Remove default bone bpy.ops.object.mode_set(mode='EDIT') @@ -117,7 +118,6 @@ def make_submenu_func(bl_idname, text): # Get the metarig modules metarigs_dict = get_metarig_list("") -print(metarigs_dict) armature_submenus = [] # Create metarig add Operators @@ -137,24 +137,27 @@ for metarig_class in metarigs_dict: metarig_ops[metarig_class].append((T, name)) menu_funcs = [] -for metarig_class in metarigs_dict: + +for mop, name in metarig_ops[utils.METARIG_DIR]: + text = capwords(name.replace("_", " ")) + " (Meta-Rig)" + menu_funcs += [make_metarig_menu_func(mop.bl_idname, text)] + +metarigs_dict.pop(utils.METARIG_DIR) + +metarig_classes = list(metarigs_dict.keys()) +metarig_classes.sort() +for metarig_class in metarig_classes: # Create menu functions - if metarig_class != utils.METARIG_DIR: - armature_submenus.append(type('Class_' + metarig_class + '_submenu', (ArmatureSubMenu,), {})) - armature_submenus[-1].bl_label = metarig_class + ' (submenu)' - armature_submenus[-1].bl_idname = 'ARMATURE_MT_%s_class' % metarig_class - armature_submenus[-1].operators = [] - menu_funcs += [make_submenu_func(armature_submenus[-1].bl_idname, metarig_class)] + + armature_submenus.append(type('Class_' + metarig_class + '_submenu', (ArmatureSubMenu,), {})) + armature_submenus[-1].bl_label = metarig_class + ' (submenu)' + armature_submenus[-1].bl_idname = 'ARMATURE_MT_%s_class' % metarig_class + armature_submenus[-1].operators = [] + menu_funcs += [make_submenu_func(armature_submenus[-1].bl_idname, metarig_class)] for mop, name in metarig_ops[metarig_class]: - print(metarig_class) - print(metarig_ops[metarig_class]) - if metarig_class != utils.METARIG_DIR: - arm_sub = next((e for e in armature_submenus if e.bl_label == metarig_class + ' (submenu)'), '') - arm_sub.operators.append((mop.bl_idname, name,)) - else: - text = capwords(name.replace("_", " ")) + " (Meta-Rig)" - menu_funcs += [make_metarig_menu_func(mop.bl_idname, text)] + arm_sub = next((e for e in armature_submenus if e.bl_label == metarig_class + ' (submenu)'), '') + arm_sub.operators.append((mop.bl_idname, name,)) def register(): for cl in metarig_ops: diff --git a/rigify/metarigs/Animals/__init__.py b/rigify/metarigs/Animals/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/rigify/metarigs/Animals/__init__.py diff --git a/rigify/metarigs/Animals/bird.py b/rigify/metarigs/Animals/bird.py new file mode 100644 index 00000000..0c4f7d31 --- /dev/null +++ b/rigify/metarigs/Animals/bird.py @@ -0,0 +1,1494 @@ +import bpy + + +from mathutils import Color + + +def create(obj): + # generated by rigify.utils.write_metarig + bpy.ops.object.mode_set(mode='EDIT') + arm = obj.data + + for i in range(6): + arm.rigify_colors.add() + + arm.rigify_colors[0].name = "Root" + arm.rigify_colors[0].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[0].normal = Color((0.4352940022945404, 0.18431399762630463, 0.4156860113143921)) + arm.rigify_colors[0].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[0].standard_colors_lock = True + arm.rigify_colors[1].name = "IK" + arm.rigify_colors[1].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[1].normal = Color((0.6039220094680786, 0.0, 0.0)) + arm.rigify_colors[1].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[1].standard_colors_lock = True + arm.rigify_colors[2].name = "Special" + arm.rigify_colors[2].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[2].normal = Color((0.9568629860877991, 0.7882350087165833, 0.04705899953842163)) + arm.rigify_colors[2].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[2].standard_colors_lock = True + arm.rigify_colors[3].name = "Tweak" + arm.rigify_colors[3].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[3].normal = Color((0.03921600058674812, 0.21176500618457794, 0.5803920030593872)) + arm.rigify_colors[3].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[3].standard_colors_lock = True + arm.rigify_colors[4].name = "FK" + arm.rigify_colors[4].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[4].normal = Color((0.11764699965715408, 0.5686269998550415, 0.035294000059366226)) + arm.rigify_colors[4].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[4].standard_colors_lock = True + arm.rigify_colors[5].name = "Extra" + arm.rigify_colors[5].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[5].normal = Color((0.9686279892921448, 0.2509799897670746, 0.09411799907684326)) + arm.rigify_colors[5].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[5].standard_colors_lock = True + + for i in range(29): + arm.rigify_layers.add() + + arm.rigify_layers[0].name = "Face" + arm.rigify_layers[0].row = 1 + arm.rigify_layers[0].set = False + arm.rigify_layers[0].group = 6 + arm.rigify_layers[1].name = "Face (Tweak)" + arm.rigify_layers[1].row = 2 + arm.rigify_layers[1].set = False + arm.rigify_layers[1].group = 4 + arm.rigify_layers[2].name = " " + arm.rigify_layers[2].row = 1 + arm.rigify_layers[2].set = False + arm.rigify_layers[2].group = 0 + arm.rigify_layers[3].name = "Spine" + arm.rigify_layers[3].row = 3 + arm.rigify_layers[3].set = False + arm.rigify_layers[3].group = 3 + arm.rigify_layers[4].name = "Spine (Tweak)" + arm.rigify_layers[4].row = 4 + arm.rigify_layers[4].set = False + arm.rigify_layers[4].group = 4 + arm.rigify_layers[5].name = " " + arm.rigify_layers[5].row = 1 + arm.rigify_layers[5].set = False + arm.rigify_layers[5].group = 0 + arm.rigify_layers[6].name = " " + arm.rigify_layers[6].row = 1 + arm.rigify_layers[6].set = False + arm.rigify_layers[6].group = 0 + arm.rigify_layers[7].name = "Wing.L" + arm.rigify_layers[7].row = 6 + arm.rigify_layers[7].set = False + arm.rigify_layers[7].group = 5 + arm.rigify_layers[8].name = "" + arm.rigify_layers[8].row = 8 + arm.rigify_layers[8].set = False + arm.rigify_layers[8].group = 0 + arm.rigify_layers[9].name = "Wing.L (Tweak)" + arm.rigify_layers[9].row = 7 + arm.rigify_layers[9].set = False + arm.rigify_layers[9].group = 4 + arm.rigify_layers[10].name = "Wing.R" + arm.rigify_layers[10].row = 6 + arm.rigify_layers[10].set = False + arm.rigify_layers[10].group = 5 + arm.rigify_layers[11].name = "" + arm.rigify_layers[11].row = 8 + arm.rigify_layers[11].set = False + arm.rigify_layers[11].group = 0 + arm.rigify_layers[12].name = "Wing.R (Tweak)" + arm.rigify_layers[12].row = 7 + arm.rigify_layers[12].set = False + arm.rigify_layers[12].group = 4 + arm.rigify_layers[13].name = "Leg.L (IK)" + arm.rigify_layers[13].row = 10 + arm.rigify_layers[13].set = False + arm.rigify_layers[13].group = 2 + arm.rigify_layers[14].name = "Leg.L (FK)" + arm.rigify_layers[14].row = 11 + arm.rigify_layers[14].set = False + arm.rigify_layers[14].group = 5 + arm.rigify_layers[15].name = "Leg.L (Tweak)" + arm.rigify_layers[15].row = 12 + arm.rigify_layers[15].set = False + arm.rigify_layers[15].group = 4 + arm.rigify_layers[16].name = " Leg.R (IK)" + arm.rigify_layers[16].row = 10 + arm.rigify_layers[16].set = False + arm.rigify_layers[16].group = 2 + arm.rigify_layers[17].name = " Leg.R (FK)" + arm.rigify_layers[17].row = 11 + arm.rigify_layers[17].set = False + arm.rigify_layers[17].group = 5 + arm.rigify_layers[18].name = " Leg.R (Tweak)" + arm.rigify_layers[18].row = 12 + arm.rigify_layers[18].set = False + arm.rigify_layers[18].group = 4 + arm.rigify_layers[19].name = " " + arm.rigify_layers[19].row = 1 + arm.rigify_layers[19].set = False + arm.rigify_layers[19].group = 0 + arm.rigify_layers[20].name = " " + arm.rigify_layers[20].row = 1 + arm.rigify_layers[20].set = False + arm.rigify_layers[20].group = 0 + arm.rigify_layers[21].name = "Claws" + arm.rigify_layers[21].row = 13 + arm.rigify_layers[21].set = False + arm.rigify_layers[21].group = 6 + arm.rigify_layers[22].name = "Claws (Tweak)" + arm.rigify_layers[22].row = 14 + arm.rigify_layers[22].set = False + arm.rigify_layers[22].group = 4 + arm.rigify_layers[23].name = " " + arm.rigify_layers[23].row = 1 + arm.rigify_layers[23].set = False + arm.rigify_layers[23].group = 0 + arm.rigify_layers[24].name = "Feathers" + arm.rigify_layers[24].row = 8 + arm.rigify_layers[24].set = False + arm.rigify_layers[24].group = 6 + arm.rigify_layers[25].name = " " + arm.rigify_layers[25].row = 1 + arm.rigify_layers[25].set = False + arm.rigify_layers[25].group = 0 + arm.rigify_layers[26].name = " " + arm.rigify_layers[26].row = 1 + arm.rigify_layers[26].set = False + arm.rigify_layers[26].group = 0 + arm.rigify_layers[27].name = " " + arm.rigify_layers[27].row = 1 + arm.rigify_layers[27].set = False + arm.rigify_layers[27].group = 0 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 14 + arm.rigify_layers[28].set = False + arm.rigify_layers[28].group = 1 + + bones = {} + + bone = arm.edit_bones.new('spine') + bone.head[:] = -0.0000, 0.1371, 0.0894 + bone.tail[:] = -0.0000, 0.1039, 0.0907 + bone.roll = 0.0000 + bone.use_connect = False + bones['spine'] = bone.name + bone = arm.edit_bones.new('spine.001') + bone.head[:] = -0.0000, 0.1039, 0.0907 + bone.tail[:] = -0.0000, 0.0757, 0.0880 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine']] + bones['spine.001'] = bone.name + bone = arm.edit_bones.new('t_feather.L') + bone.head[:] = 0.0112, 0.1017, 0.0907 + bone.tail[:] = 0.0167, 0.1345, 0.0894 + bone.roll = 0.0032 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['t_feather.L'] = bone.name + bone = arm.edit_bones.new('t_feather.R') + bone.head[:] = -0.0112, 0.1017, 0.0907 + bone.tail[:] = -0.0167, 0.1345, 0.0894 + bone.roll = -0.0032 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['t_feather.R'] = bone.name + bone = arm.edit_bones.new('spine.002') + bone.head[:] = -0.0000, 0.0757, 0.0880 + bone.tail[:] = -0.0000, 0.0451, 0.0845 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.001']] + bones['spine.002'] = bone.name + bone = arm.edit_bones.new('spine.003') + bone.head[:] = -0.0000, 0.0451, 0.0845 + bone.tail[:] = -0.0000, 0.0192, 0.0888 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.002']] + bones['spine.003'] = bone.name + bone = arm.edit_bones.new('spine.004') + bone.head[:] = -0.0000, 0.0192, 0.0888 + bone.tail[:] = -0.0000, -0.0106, 0.0979 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.003']] + bones['spine.004'] = bone.name + bone = arm.edit_bones.new('spine.005') + bone.head[:] = -0.0000, -0.0106, 0.0979 + bone.tail[:] = -0.0000, -0.0298, 0.1158 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.004']] + bones['spine.005'] = bone.name + bone = arm.edit_bones.new('pelvis.L') + bone.head[:] = -0.0000, 0.0192, 0.0888 + bone.tail[:] = 0.0250, 0.0070, 0.0782 + bone.roll = -0.0369 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.004']] + bones['pelvis.L'] = bone.name + bone = arm.edit_bones.new('pelvis.R') + bone.head[:] = 0.0000, 0.0192, 0.0888 + bone.tail[:] = -0.0250, 0.0070, 0.0782 + bone.roll = 0.0369 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.004']] + bones['pelvis.R'] = bone.name + bone = arm.edit_bones.new('thigh.L') + bone.head[:] = 0.0149, 0.0063, 0.0739 + bone.tail[:] = 0.0149, 0.0143, 0.0391 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.004']] + bones['thigh.L'] = bone.name + bone = arm.edit_bones.new('thigh.R') + bone.head[:] = -0.0149, 0.0063, 0.0739 + bone.tail[:] = -0.0149, 0.0143, 0.0391 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.004']] + bones['thigh.R'] = bone.name + bone = arm.edit_bones.new('shoulder.L') + bone.head[:] = 0.0014, -0.0217, 0.0893 + bone.tail[:] = 0.0076, -0.0020, 0.1179 + bone.roll = 1.3977 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['shoulder.L'] = bone.name + bone = arm.edit_bones.new('spine.006') + bone.head[:] = -0.0000, -0.0298, 0.1158 + bone.tail[:] = -0.0000, -0.0417, 0.1348 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.005']] + bones['spine.006'] = bone.name + bone = arm.edit_bones.new('shoulder.R') + bone.head[:] = -0.0014, -0.0217, 0.0893 + bone.tail[:] = -0.0076, -0.0020, 0.1179 + bone.roll = -1.3977 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['shoulder.R'] = bone.name + bone = arm.edit_bones.new('shin.L') + bone.head[:] = 0.0149, 0.0143, 0.0391 + bone.tail[:] = 0.0149, 0.0015, 0.0074 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.L']] + bones['shin.L'] = bone.name + bone = arm.edit_bones.new('shin.R') + bone.head[:] = -0.0149, 0.0143, 0.0391 + bone.tail[:] = -0.0149, 0.0015, 0.0074 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.R']] + bones['shin.R'] = bone.name + bone = arm.edit_bones.new('Wing.L') + bone.head[:] = 0.0089, 0.0141, 0.1157 + bone.tail[:] = 0.0485, 0.0107, 0.1163 + bone.roll = 2.8221 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.L']] + bones['Wing.L'] = bone.name + bone = arm.edit_bones.new('neck.001') + bone.head[:] = -0.0000, -0.0417, 0.1348 + bone.tail[:] = -0.0000, -0.0458, 0.1429 + bone.roll = 0.0001 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.006']] + bones['neck.001'] = bone.name + bone = arm.edit_bones.new('Wing.R') + bone.head[:] = -0.0089, 0.0141, 0.1157 + bone.tail[:] = -0.0485, 0.0107, 0.1163 + bone.roll = -2.8221 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.R']] + bones['Wing.R'] = bone.name + bone = arm.edit_bones.new('foot.L') + bone.head[:] = 0.0149, 0.0015, 0.0074 + bone.tail[:] = 0.0149, -0.0033, 0.0045 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.L']] + bones['foot.L'] = bone.name + bone = arm.edit_bones.new('foot.R') + bone.head[:] = -0.0149, 0.0015, 0.0074 + bone.tail[:] = -0.0149, -0.0033, 0.0045 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.R']] + bones['foot.R'] = bone.name + bone = arm.edit_bones.new('Wing.001.L') + bone.head[:] = 0.0485, 0.0107, 0.1163 + bone.tail[:] = 0.0919, 0.0021, 0.1191 + bone.roll = 2.7596 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['Wing.L']] + bones['Wing.001.L'] = bone.name + bone = arm.edit_bones.new('w_feather.004.L') + bone.head[:] = 0.0382, 0.0253, 0.1081 + bone.tail[:] = 0.0553, 0.0878, 0.0901 + bone.roll = 3.0872 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['Wing.L']] + bones['w_feather.004.L'] = bone.name + bone = arm.edit_bones.new('neck.002') + bone.head[:] = -0.0000, -0.0458, 0.1429 + bone.tail[:] = -0.0000, -0.0483, 0.1498 + bone.roll = 0.0001 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['neck.001']] + bones['neck.002'] = bone.name + bone = arm.edit_bones.new('Wing.001.R') + bone.head[:] = -0.0485, 0.0107, 0.1163 + bone.tail[:] = -0.0919, 0.0021, 0.1191 + bone.roll = -2.7596 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['Wing.R']] + bones['Wing.001.R'] = bone.name + bone = arm.edit_bones.new('w_feather.004.R') + bone.head[:] = -0.0382, 0.0253, 0.1081 + bone.tail[:] = -0.0553, 0.0878, 0.0901 + bone.roll = -3.0872 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['Wing.R']] + bones['w_feather.004.R'] = bone.name + bone = arm.edit_bones.new('toe.L') + bone.head[:] = 0.0149, -0.0033, 0.0045 + bone.tail[:] = 0.0149, -0.0404, 0.0006 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.L']] + bones['toe.L'] = bone.name + bone = arm.edit_bones.new('toe.R') + bone.head[:] = -0.0149, -0.0033, 0.0045 + bone.tail[:] = -0.0149, -0.0404, 0.0006 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.R']] + bones['toe.R'] = bone.name + bone = arm.edit_bones.new('Wing.002.L') + bone.head[:] = 0.0919, 0.0021, 0.1191 + bone.tail[:] = 0.2128, 0.0178, 0.1159 + bone.roll = 2.8565 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['Wing.001.L']] + bones['Wing.002.L'] = bone.name + bone = arm.edit_bones.new('w_feather.003.L') + bone.head[:] = 0.0754, 0.0212, 0.1122 + bone.tail[:] = 0.1342, 0.0830, 0.0901 + bone.roll = 3.0993 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['Wing.001.L']] + bones['w_feather.003.L'] = bone.name + bone = arm.edit_bones.new('head') + bone.head[:] = -0.0000, -0.0483, 0.1498 + bone.tail[:] = -0.0000, -0.1026, 0.1815 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['neck.002']] + bones['head'] = bone.name + bone = arm.edit_bones.new('Wing.002.R') + bone.head[:] = -0.0919, 0.0021, 0.1191 + bone.tail[:] = -0.2128, 0.0178, 0.1159 + bone.roll = -2.8565 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['Wing.001.R']] + bones['Wing.002.R'] = bone.name + bone = arm.edit_bones.new('w_feather.003.R') + bone.head[:] = -0.0754, 0.0212, 0.1122 + bone.tail[:] = -0.1342, 0.0830, 0.0901 + bone.roll = -3.0993 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['Wing.001.R']] + bones['w_feather.003.R'] = bone.name + bone = arm.edit_bones.new('toes_parent.L') + bone.head[:] = 0.0149, -0.0033, 0.0045 + bone.tail[:] = 0.0149, -0.0096, 0.0037 + bone.roll = 3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.L']] + bones['toes_parent.L'] = bone.name + bone = arm.edit_bones.new('t_thumb.001.L') + bone.head[:] = 0.0136, 0.0051, 0.0022 + bone.tail[:] = 0.0131, 0.0142, 0.0026 + bone.roll = 3.1406 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.L']] + bones['t_thumb.001.L'] = bone.name + bone = arm.edit_bones.new('toes_parent.R') + bone.head[:] = -0.0149, -0.0033, 0.0045 + bone.tail[:] = -0.0149, -0.0096, 0.0037 + bone.roll = -3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.R']] + bones['toes_parent.R'] = bone.name + bone = arm.edit_bones.new('t_thumb.001.R') + bone.head[:] = -0.0136, 0.0051, 0.0022 + bone.tail[:] = -0.0131, 0.0142, 0.0026 + bone.roll = -3.1406 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.R']] + bones['t_thumb.001.R'] = bone.name + bone = arm.edit_bones.new('w_feather.001.L') + bone.head[:] = 0.1595, -0.0062, 0.1163 + bone.tail[:] = 0.2489, -0.0055, 0.1224 + bone.roll = 2.9290 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['Wing.002.L']] + bones['w_feather.001.L'] = bone.name + bone = arm.edit_bones.new('w_feather.002.L') + bone.head[:] = 0.1218, 0.0331, 0.1099 + bone.tail[:] = 0.1812, 0.0495, 0.1068 + bone.roll = 2.8770 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['Wing.002.L']] + bones['w_feather.002.L'] = bone.name + bone = arm.edit_bones.new('beak.001.T') + bone.head[:] = -0.0000, -0.0703, 0.1580 + bone.tail[:] = -0.0000, -0.0927, 0.1597 + bone.roll = 0.0001 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['head']] + bones['beak.001.T'] = bone.name + bone = arm.edit_bones.new('beak_001.B') + bone.head[:] = -0.0000, -0.0703, 0.1556 + bone.tail[:] = -0.0000, -0.0914, 0.1555 + bone.roll = 0.0001 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['head']] + bones['beak_001.B'] = bone.name + bone = arm.edit_bones.new('eye.L') + bone.head[:] = 0.0055, -0.0647, 0.1615 + bone.tail[:] = 0.0198, -0.0675, 0.1615 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['head']] + bones['eye.L'] = bone.name + bone = arm.edit_bones.new('eye.R') + bone.head[:] = -0.0055, -0.0647, 0.1615 + bone.tail[:] = -0.0198, -0.0675, 0.1615 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['head']] + bones['eye.R'] = bone.name + bone = arm.edit_bones.new('n_feather.001.L') + bone.head[:] = 0.0098, -0.0390, 0.1566 + bone.tail[:] = 0.0131, -0.0247, 0.1430 + bone.roll = -0.0380 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['head']] + bones['n_feather.001.L'] = bone.name + bone = arm.edit_bones.new('n_feather.001.R') + bone.head[:] = -0.0098, -0.0390, 0.1566 + bone.tail[:] = -0.0131, -0.0247, 0.1430 + bone.roll = 0.0380 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['head']] + bones['n_feather.001.R'] = bone.name + bone = arm.edit_bones.new('skull.006.L') + bone.head[:] = 0.0033, -0.0587, 0.1538 + bone.tail[:] = 0.0162, -0.0666, 0.1509 + bone.roll = 1.6532 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['head']] + bones['skull.006.L'] = bone.name + bone = arm.edit_bones.new('skull.006.R') + bone.head[:] = -0.0033, -0.0587, 0.1538 + bone.tail[:] = -0.0162, -0.0666, 0.1509 + bone.roll = -1.6532 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['head']] + bones['skull.006.R'] = bone.name + bone = arm.edit_bones.new('w_feather.001.R') + bone.head[:] = -0.1595, -0.0062, 0.1163 + bone.tail[:] = -0.2489, -0.0055, 0.1224 + bone.roll = -2.9290 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['Wing.002.R']] + bones['w_feather.001.R'] = bone.name + bone = arm.edit_bones.new('w_feather.002.R') + bone.head[:] = -0.1218, 0.0331, 0.1099 + bone.tail[:] = -0.1812, 0.0495, 0.1068 + bone.roll = -2.8770 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['Wing.002.R']] + bones['w_feather.002.R'] = bone.name + bone = arm.edit_bones.new('t_ring.001.L') + bone.head[:] = 0.0183, -0.0026, 0.0034 + bone.tail[:] = 0.0216, -0.0129, 0.0038 + bone.roll = 6.0340 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toes_parent.L']] + bones['t_ring.001.L'] = bone.name + bone = arm.edit_bones.new('t_index.001.L') + bone.head[:] = 0.0122, -0.0026, 0.0034 + bone.tail[:] = 0.0093, -0.0130, 0.0038 + bone.roll = 6.5631 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toes_parent.L']] + bones['t_index.001.L'] = bone.name + bone = arm.edit_bones.new('t_middle.001.L') + bone.head[:] = 0.0149, -0.0050, 0.0034 + bone.tail[:] = 0.0149, -0.0207, 0.0040 + bone.roll = 3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toes_parent.L']] + bones['t_middle.001.L'] = bone.name + bone = arm.edit_bones.new('t_thumb.002.L') + bone.head[:] = 0.0131, 0.0142, 0.0026 + bone.tail[:] = 0.0126, 0.0241, 0.0003 + bone.roll = 3.1472 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_thumb.001.L']] + bones['t_thumb.002.L'] = bone.name + bone = arm.edit_bones.new('t_ring.001.R') + bone.head[:] = -0.0183, -0.0026, 0.0034 + bone.tail[:] = -0.0216, -0.0129, 0.0038 + bone.roll = -6.0340 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toes_parent.R']] + bones['t_ring.001.R'] = bone.name + bone = arm.edit_bones.new('t_index.001.R') + bone.head[:] = -0.0122, -0.0026, 0.0034 + bone.tail[:] = -0.0093, -0.0130, 0.0038 + bone.roll = -6.5631 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toes_parent.R']] + bones['t_index.001.R'] = bone.name + bone = arm.edit_bones.new('t_middle.001.R') + bone.head[:] = -0.0149, -0.0050, 0.0034 + bone.tail[:] = -0.0149, -0.0207, 0.0040 + bone.roll = -3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toes_parent.R']] + bones['t_middle.001.R'] = bone.name + bone = arm.edit_bones.new('t_thumb.002.R') + bone.head[:] = -0.0131, 0.0142, 0.0026 + bone.tail[:] = -0.0126, 0.0241, 0.0003 + bone.roll = -3.1472 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_thumb.001.R']] + bones['t_thumb.002.R'] = bone.name + bone = arm.edit_bones.new('beak.002.T') + bone.head[:] = -0.0000, -0.0927, 0.1597 + bone.tail[:] = -0.0000, -0.1131, 0.1533 + bone.roll = 0.0001 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['beak.001.T']] + bones['beak.002.T'] = bone.name + bone = arm.edit_bones.new('beak.002.B') + bone.head[:] = -0.0000, -0.0914, 0.1555 + bone.tail[:] = -0.0000, -0.1084, 0.1519 + bone.roll = 0.0001 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['beak_001.B']] + bones['beak.002.B'] = bone.name + bone = arm.edit_bones.new('tongue.001.L') + bone.head[:] = -0.0000, -0.0792, 0.1536 + bone.tail[:] = -0.0000, -0.0840, 0.1555 + bone.roll = 0.0001 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['beak_001.B']] + bones['tongue.001.L'] = bone.name + bone = arm.edit_bones.new('t_ring.002.L') + bone.head[:] = 0.0216, -0.0129, 0.0038 + bone.tail[:] = 0.0237, -0.0195, 0.0032 + bone.roll = 0.5806 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_ring.001.L']] + bones['t_ring.002.L'] = bone.name + bone = arm.edit_bones.new('t_index.002.L') + bone.head[:] = 0.0093, -0.0130, 0.0038 + bone.tail[:] = 0.0067, -0.0223, 0.0032 + bone.roll = -0.4957 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_index.001.L']] + bones['t_index.002.L'] = bone.name + bone = arm.edit_bones.new('t_middle.002.L') + bone.head[:] = 0.0149, -0.0207, 0.0040 + bone.tail[:] = 0.0149, -0.0308, 0.0031 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_middle.001.L']] + bones['t_middle.002.L'] = bone.name + bone = arm.edit_bones.new('t_ring.002.R') + bone.head[:] = -0.0216, -0.0129, 0.0038 + bone.tail[:] = -0.0237, -0.0195, 0.0032 + bone.roll = -0.5806 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_ring.001.R']] + bones['t_ring.002.R'] = bone.name + bone = arm.edit_bones.new('t_index.002.R') + bone.head[:] = -0.0093, -0.0130, 0.0038 + bone.tail[:] = -0.0067, -0.0223, 0.0032 + bone.roll = 0.4957 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_index.001.R']] + bones['t_index.002.R'] = bone.name + bone = arm.edit_bones.new('t_middle.002.R') + bone.head[:] = -0.0149, -0.0207, 0.0040 + bone.tail[:] = -0.0149, -0.0308, 0.0031 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_middle.001.R']] + bones['t_middle.002.R'] = bone.name + bone = arm.edit_bones.new('tongue.002.L') + bone.head[:] = -0.0000, -0.0840, 0.1555 + bone.tail[:] = -0.0000, -0.0874, 0.1553 + bone.roll = 0.0001 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tongue.001.L']] + bones['tongue.002.L'] = bone.name + bone = arm.edit_bones.new('t_ring.003.L') + bone.head[:] = 0.0237, -0.0195, 0.0032 + bone.tail[:] = 0.0261, -0.0270, 0.0009 + bone.roll = 1.5954 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_ring.002.L']] + bones['t_ring.003.L'] = bone.name + bone = arm.edit_bones.new('t_index.003.L') + bone.head[:] = 0.0067, -0.0223, 0.0032 + bone.tail[:] = 0.0038, -0.0327, 0.0009 + bone.roll = 4.8853 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_index.002.L']] + bones['t_index.003.L'] = bone.name + bone = arm.edit_bones.new('t_middle.003.L') + bone.head[:] = 0.0149, -0.0308, 0.0031 + bone.tail[:] = 0.0149, -0.0421, -0.0003 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_middle.002.L']] + bones['t_middle.003.L'] = bone.name + bone = arm.edit_bones.new('t_ring.003.R') + bone.head[:] = -0.0237, -0.0195, 0.0032 + bone.tail[:] = -0.0261, -0.0270, 0.0009 + bone.roll = -1.5954 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_ring.002.R']] + bones['t_ring.003.R'] = bone.name + bone = arm.edit_bones.new('t_index.003.R') + bone.head[:] = -0.0067, -0.0223, 0.0032 + bone.tail[:] = -0.0038, -0.0327, 0.0009 + bone.roll = -4.8853 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_index.002.R']] + bones['t_index.003.R'] = bone.name + bone = arm.edit_bones.new('t_middle.003.R') + bone.head[:] = -0.0149, -0.0308, 0.0031 + bone.tail[:] = -0.0149, -0.0421, -0.0003 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['t_middle.002.R']] + bones['t_middle.003.R'] = bone.name + bone = arm.edit_bones.new('tongue.003.L') + bone.head[:] = -0.0000, -0.0874, 0.1553 + bone.tail[:] = -0.0000, -0.0898, 0.1553 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tongue.002.L']] + bones['tongue.003.L'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['spine']] + pbone.rigify_type = 'spines.super_spine' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.use_tail = True + except AttributeError: + pass + try: + pbone.rigify_parameters.tail_pos = 3 + except AttributeError: + pass + try: + pbone.rigify_parameters.pivot_pos = 4 + except AttributeError: + pass + try: + pbone.rigify_parameters.neck_pos = 8 + except AttributeError: + pass + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_feather.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['t_feather.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.005']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['pelvis.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['pelvis.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['thigh.L']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['thigh.R']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['shoulder.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.006']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shoulder.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['shin.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shin.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['Wing.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['neck.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['Wing.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['foot.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['foot.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['Wing.001.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['w_feather.004.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['neck.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['Wing.001.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['w_feather.004.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['toe.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['toe.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['Wing.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['w_feather.003.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['head']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['Wing.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['w_feather.003.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['toes_parent.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_thumb.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['toes_parent.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_thumb.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['w_feather.001.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['w_feather.002.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['beak.001.T']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['beak_001.B']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['eye.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['eye.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['n_feather.001.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['n_feather.001.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['skull.006.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['skull.006.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['w_feather.001.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['w_feather.002.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['t_ring.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['t_index.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['t_middle.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['t_thumb.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_ring.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['t_index.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['t_middle.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['t_thumb.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['beak.002.T']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['beak.002.B']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['tongue.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_ring.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_index.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_middle.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_ring.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_index.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_middle.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['tongue.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_ring.003.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_index.003.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_middle.003.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_ring.003.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_index.003.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['t_middle.003.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['tongue.003.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + + bpy.ops.object.mode_set(mode='EDIT') + for bone in arm.edit_bones: + bone.select = False + bone.select_head = False + bone.select_tail = False + for b in bones: + bone = arm.edit_bones[bones[b]] + bone.select = True + bone.select_head = True + bone.select_tail = True + arm.edit_bones.active = bone + + arm.layers = [(x in [0, 3, 7, 10, 13, 16, 21, 24]) for x in range(32)] + +if __name__ == "__main__": + create(bpy.context.active_object)
\ No newline at end of file diff --git a/rigify/metarigs/Animals/cat.py b/rigify/metarigs/Animals/cat.py new file mode 100644 index 00000000..a084ca36 --- /dev/null +++ b/rigify/metarigs/Animals/cat.py @@ -0,0 +1,2979 @@ +import bpy + + +from mathutils import Color + + +def create(obj): + # generated by rigify.utils.write_metarig + bpy.ops.object.mode_set(mode='EDIT') + arm = obj.data + + for i in range(6): + arm.rigify_colors.add() + + arm.rigify_colors[0].name = "Root" + arm.rigify_colors[0].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[0].normal = Color((0.4352940022945404, 0.18431399762630463, 0.4156860113143921)) + arm.rigify_colors[0].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[0].standard_colors_lock = True + arm.rigify_colors[1].name = "IK" + arm.rigify_colors[1].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[1].normal = Color((0.6039220094680786, 0.0, 0.0)) + arm.rigify_colors[1].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[1].standard_colors_lock = True + arm.rigify_colors[2].name = "Special" + arm.rigify_colors[2].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[2].normal = Color((0.9568629860877991, 0.7882350087165833, 0.04705899953842163)) + arm.rigify_colors[2].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[2].standard_colors_lock = True + arm.rigify_colors[3].name = "Tweak" + arm.rigify_colors[3].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[3].normal = Color((0.03921600058674812, 0.21176500618457794, 0.5803920030593872)) + arm.rigify_colors[3].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[3].standard_colors_lock = True + arm.rigify_colors[4].name = "FK" + arm.rigify_colors[4].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[4].normal = Color((0.11764699965715408, 0.5686269998550415, 0.035294000059366226)) + arm.rigify_colors[4].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[4].standard_colors_lock = True + arm.rigify_colors[5].name = "Extra" + arm.rigify_colors[5].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[5].normal = Color((0.9686279892921448, 0.2509799897670746, 0.09411799907684326)) + arm.rigify_colors[5].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[5].standard_colors_lock = True + + for i in range(29): + arm.rigify_layers.add() + + arm.rigify_layers[0].name = "Face" + arm.rigify_layers[0].row = 1 + arm.rigify_layers[0].set = False + arm.rigify_layers[0].group = 5 + arm.rigify_layers[1].name = "Face (Primary)" + arm.rigify_layers[1].row = 2 + arm.rigify_layers[1].set = False + arm.rigify_layers[1].group = 2 + arm.rigify_layers[2].name = "Face (Secondary)" + arm.rigify_layers[2].row = 2 + arm.rigify_layers[2].set = False + arm.rigify_layers[2].group = 3 + arm.rigify_layers[3].name = "Spine" + arm.rigify_layers[3].row = 3 + arm.rigify_layers[3].set = False + arm.rigify_layers[3].group = 3 + arm.rigify_layers[4].name = "Spine (Tweak)" + arm.rigify_layers[4].row = 4 + arm.rigify_layers[4].set = False + arm.rigify_layers[4].group = 4 + arm.rigify_layers[5].name = "Paws" + arm.rigify_layers[5].row = 5 + arm.rigify_layers[5].set = False + arm.rigify_layers[5].group = 6 + arm.rigify_layers[6].name = "Paws (Tweak)" + arm.rigify_layers[6].row = 6 + arm.rigify_layers[6].set = False + arm.rigify_layers[6].group = 4 + arm.rigify_layers[7].name = "Arm.L (IK)" + arm.rigify_layers[7].row = 7 + arm.rigify_layers[7].set = False + arm.rigify_layers[7].group = 2 + arm.rigify_layers[8].name = "Arm.L (FK)" + arm.rigify_layers[8].row = 8 + arm.rigify_layers[8].set = False + arm.rigify_layers[8].group = 5 + arm.rigify_layers[9].name = "Arm,L (Tweak)" + arm.rigify_layers[9].row = 9 + arm.rigify_layers[9].set = False + arm.rigify_layers[9].group = 4 + arm.rigify_layers[10].name = "Arm.R (IK)" + arm.rigify_layers[10].row = 7 + arm.rigify_layers[10].set = False + arm.rigify_layers[10].group = 2 + arm.rigify_layers[11].name = "Arm.R (FK)" + arm.rigify_layers[11].row = 8 + arm.rigify_layers[11].set = False + arm.rigify_layers[11].group = 5 + arm.rigify_layers[12].name = "Arm.R (Tweak)" + arm.rigify_layers[12].row = 9 + arm.rigify_layers[12].set = False + arm.rigify_layers[12].group = 4 + arm.rigify_layers[13].name = "Leg.L (IK)" + arm.rigify_layers[13].row = 10 + arm.rigify_layers[13].set = False + arm.rigify_layers[13].group = 2 + arm.rigify_layers[14].name = "Leg.L (FK)" + arm.rigify_layers[14].row = 11 + arm.rigify_layers[14].set = False + arm.rigify_layers[14].group = 5 + arm.rigify_layers[15].name = "Leg.L (Tweak)" + arm.rigify_layers[15].row = 12 + arm.rigify_layers[15].set = False + arm.rigify_layers[15].group = 4 + arm.rigify_layers[16].name = "Leg.R (IK)" + arm.rigify_layers[16].row = 10 + arm.rigify_layers[16].set = False + arm.rigify_layers[16].group = 2 + arm.rigify_layers[17].name = "Leg.R (FK)" + arm.rigify_layers[17].row = 11 + arm.rigify_layers[17].set = False + arm.rigify_layers[17].group = 5 + arm.rigify_layers[18].name = "Leg.R (Tweak)" + arm.rigify_layers[18].row = 12 + arm.rigify_layers[18].set = False + arm.rigify_layers[18].group = 4 + arm.rigify_layers[19].name = "Tail" + arm.rigify_layers[19].row = 13 + arm.rigify_layers[19].set = False + arm.rigify_layers[19].group = 3 + arm.rigify_layers[20].name = "Tail (Tweaks)" + arm.rigify_layers[20].row = 14 + arm.rigify_layers[20].set = False + arm.rigify_layers[20].group = 4 + arm.rigify_layers[21].name = " " + arm.rigify_layers[21].row = 1 + arm.rigify_layers[21].set = False + arm.rigify_layers[21].group = 0 + arm.rigify_layers[22].name = " " + arm.rigify_layers[22].row = 1 + arm.rigify_layers[22].set = False + arm.rigify_layers[22].group = 0 + arm.rigify_layers[23].name = " " + arm.rigify_layers[23].row = 1 + arm.rigify_layers[23].set = False + arm.rigify_layers[23].group = 0 + arm.rigify_layers[24].name = " " + arm.rigify_layers[24].row = 1 + arm.rigify_layers[24].set = False + arm.rigify_layers[24].group = 0 + arm.rigify_layers[25].name = " " + arm.rigify_layers[25].row = 1 + arm.rigify_layers[25].set = False + arm.rigify_layers[25].group = 0 + arm.rigify_layers[26].name = " " + arm.rigify_layers[26].row = 1 + arm.rigify_layers[26].set = False + arm.rigify_layers[26].group = 0 + arm.rigify_layers[27].name = " " + arm.rigify_layers[27].row = 1 + arm.rigify_layers[27].set = False + arm.rigify_layers[27].group = 0 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 16 + arm.rigify_layers[28].set = False + arm.rigify_layers[28].group = 1 + + bones = {} + + bone = arm.edit_bones.new('tail.004') + bone.head[:] = -0.0000, 0.5531, 0.2488 + bone.tail[:] = -0.0000, 0.4543, 0.2321 + bone.roll = 0.0000 + bone.use_connect = False + bones['tail.004'] = bone.name + bone = arm.edit_bones.new('tail.003') + bone.head[:] = -0.0000, 0.4543, 0.2321 + bone.tail[:] = -0.0000, 0.3513, 0.2284 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tail.004']] + bones['tail.003'] = bone.name + bone = arm.edit_bones.new('tail.002') + bone.head[:] = -0.0000, 0.3513, 0.2284 + bone.tail[:] = -0.0000, 0.2460, 0.2324 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tail.003']] + bones['tail.002'] = bone.name + bone = arm.edit_bones.new('tail.001') + bone.head[:] = -0.0000, 0.2460, 0.2324 + bone.tail[:] = 0.0000, 0.1499, 0.2500 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tail.002']] + bones['tail.001'] = bone.name + bone = arm.edit_bones.new('spine') + bone.head[:] = 0.0000, 0.1499, 0.2500 + bone.tail[:] = 0.0000, 0.0769, 0.2272 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tail.001']] + bones['spine'] = bone.name + bone = arm.edit_bones.new('spine.001') + bone.head[:] = 0.0000, 0.0769, 0.2272 + bone.tail[:] = 0.0000, 0.0180, 0.2240 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine']] + bones['spine.001'] = bone.name + bone = arm.edit_bones.new('pelvis.L') + bone.head[:] = 0.0000, 0.1499, 0.2500 + bone.tail[:] = 0.0391, 0.1124, 0.2699 + bone.roll = 2.3502 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['pelvis.L'] = bone.name + bone = arm.edit_bones.new('pelvis.R') + bone.head[:] = 0.0000, 0.1499, 0.2500 + bone.tail[:] = -0.0391, 0.1124, 0.2699 + bone.roll = -2.3502 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['pelvis.R'] = bone.name + bone = arm.edit_bones.new('pelvis.C') + bone.head[:] = 0.0000, 0.1499, 0.2500 + bone.tail[:] = 0.0000, 0.1344, 0.1727 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['pelvis.C'] = bone.name + bone = arm.edit_bones.new('spine.002') + bone.head[:] = 0.0000, 0.0180, 0.2240 + bone.tail[:] = 0.0000, -0.0513, 0.2271 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.001']] + bones['spine.002'] = bone.name + bone = arm.edit_bones.new('thigh.L') + bone.head[:] = 0.0291, 0.1181, 0.2460 + bone.tail[:] = 0.0293, 0.1107, 0.1682 + bone.roll = 3.1383 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['pelvis.L']] + bones['thigh.L'] = bone.name + bone = arm.edit_bones.new('thigh.R') + bone.head[:] = -0.0291, 0.1181, 0.2460 + bone.tail[:] = -0.0293, 0.1107, 0.1682 + bone.roll = -3.1383 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['pelvis.R']] + bones['thigh.R'] = bone.name + bone = arm.edit_bones.new('spine.003') + bone.head[:] = 0.0000, -0.0513, 0.2271 + bone.tail[:] = 0.0000, -0.1571, 0.2355 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.002']] + bones['spine.003'] = bone.name + bone = arm.edit_bones.new('belly.C') + bone.head[:] = 0.0000, -0.0142, 0.1779 + bone.tail[:] = 0.0000, -0.0142, 0.1333 + bone.roll = 6.2832 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.002']] + bones['belly.C'] = bone.name + bone = arm.edit_bones.new('shin.L') + bone.head[:] = 0.0293, 0.1107, 0.1682 + bone.tail[:] = 0.0293, 0.1684, 0.1073 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.L']] + bones['shin.L'] = bone.name + bone = arm.edit_bones.new('shin.R') + bone.head[:] = -0.0293, 0.1107, 0.1682 + bone.tail[:] = -0.0293, 0.1684, 0.1073 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.R']] + bones['shin.R'] = bone.name + bone = arm.edit_bones.new('spine.004') + bone.head[:] = 0.0000, -0.1571, 0.2355 + bone.tail[:] = 0.0000, -0.1736, 0.2395 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.003']] + bones['spine.004'] = bone.name + bone = arm.edit_bones.new('Breast.C') + bone.head[:] = 0.0000, -0.1169, 0.1866 + bone.tail[:] = 0.0000, -0.1279, 0.1479 + bone.roll = -6.2832 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.003']] + bones['Breast.C'] = bone.name + bone = arm.edit_bones.new('shoulder.L') + bone.head[:] = 0.0070, -0.0868, 0.2502 + bone.tail[:] = 0.0346, -0.1117, 0.2857 + bone.roll = -1.0756 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.003']] + bones['shoulder.L'] = bone.name + bone = arm.edit_bones.new('shoulder.R') + bone.head[:] = -0.0070, -0.0868, 0.2502 + bone.tail[:] = -0.0346, -0.1117, 0.2857 + bone.roll = 1.0756 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.003']] + bones['shoulder.R'] = bone.name + bone = arm.edit_bones.new('foot.L') + bone.head[:] = 0.0293, 0.1684, 0.1073 + bone.tail[:] = 0.0293, 0.1530, 0.0167 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.L']] + bones['foot.L'] = bone.name + bone = arm.edit_bones.new('foot.R') + bone.head[:] = -0.0293, 0.1684, 0.1073 + bone.tail[:] = -0.0293, 0.1530, 0.0167 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.R']] + bones['foot.R'] = bone.name + bone = arm.edit_bones.new('spine.005') + bone.head[:] = 0.0000, -0.1736, 0.2395 + bone.tail[:] = 0.0000, -0.1860, 0.2445 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.004']] + bones['spine.005'] = bone.name + bone = arm.edit_bones.new('upper_arm.L') + bone.head[:] = 0.0313, -0.1149, 0.2257 + bone.tail[:] = 0.0313, -0.0871, 0.1235 + bone.roll = 3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.L']] + bones['upper_arm.L'] = bone.name + bone = arm.edit_bones.new('upper_arm.R') + bone.head[:] = -0.0313, -0.1149, 0.2257 + bone.tail[:] = -0.0313, -0.0871, 0.1235 + bone.roll = -3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.R']] + bones['upper_arm.R'] = bone.name + bone = arm.edit_bones.new('r_toe.L') + bone.head[:] = 0.0293, 0.1530, 0.0167 + bone.tail[:] = 0.0293, 0.1300, 0.0167 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.L']] + bones['r_toe.L'] = bone.name + bone = arm.edit_bones.new('r_toe.R') + bone.head[:] = -0.0293, 0.1530, 0.0167 + bone.tail[:] = -0.0293, 0.1300, 0.0167 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.R']] + bones['r_toe.R'] = bone.name + bone = arm.edit_bones.new('spine.006') + bone.head[:] = 0.0000, -0.1860, 0.2445 + bone.tail[:] = 0.0000, -0.2599, 0.2789 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.005']] + bones['spine.006'] = bone.name + bone = arm.edit_bones.new('forearm.L') + bone.head[:] = 0.0313, -0.0871, 0.1235 + bone.tail[:] = 0.0313, -0.1111, 0.0248 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['upper_arm.L']] + bones['forearm.L'] = bone.name + bone = arm.edit_bones.new('forearm.R') + bone.head[:] = -0.0313, -0.0871, 0.1235 + bone.tail[:] = -0.0313, -0.1111, 0.0248 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['upper_arm.R']] + bones['forearm.R'] = bone.name + bone = arm.edit_bones.new('r_palm.001.L') + bone.head[:] = 0.0220, 0.1457, 0.0123 + bone.tail[:] = 0.0215, 0.1401, 0.0123 + bone.roll = 0.0014 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.L']] + bones['r_palm.001.L'] = bone.name + bone = arm.edit_bones.new('r_palm.002.L') + bone.head[:] = 0.0297, 0.1458, 0.0123 + bone.tail[:] = 0.0311, 0.1393, 0.0123 + bone.roll = -0.0005 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.L']] + bones['r_palm.002.L'] = bone.name + bone = arm.edit_bones.new('r_palm.003.L') + bone.head[:] = 0.0363, 0.1473, 0.0123 + bone.tail[:] = 0.0376, 0.1407, 0.0123 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.L']] + bones['r_palm.003.L'] = bone.name + bone = arm.edit_bones.new('r_palm.004.L') + bone.head[:] = 0.0449, 0.1501, 0.0123 + bone.tail[:] = 0.0466, 0.1479, 0.0123 + bone.roll = -0.0004 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.L']] + bones['r_palm.004.L'] = bone.name + bone = arm.edit_bones.new('r_palm.001.R') + bone.head[:] = -0.0220, 0.1457, 0.0123 + bone.tail[:] = -0.0215, 0.1401, 0.0123 + bone.roll = -0.0014 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.R']] + bones['r_palm.001.R'] = bone.name + bone = arm.edit_bones.new('r_palm.002.R') + bone.head[:] = -0.0297, 0.1458, 0.0123 + bone.tail[:] = -0.0311, 0.1393, 0.0123 + bone.roll = 0.0005 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.R']] + bones['r_palm.002.R'] = bone.name + bone = arm.edit_bones.new('r_palm.003.R') + bone.head[:] = -0.0363, 0.1473, 0.0123 + bone.tail[:] = -0.0376, 0.1407, 0.0123 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.R']] + bones['r_palm.003.R'] = bone.name + bone = arm.edit_bones.new('r_palm.004.R') + bone.head[:] = -0.0449, 0.1501, 0.0123 + bone.tail[:] = -0.0466, 0.1479, 0.0123 + bone.roll = 0.0004 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.R']] + bones['r_palm.004.R'] = bone.name + bone = arm.edit_bones.new('face') + bone.head[:] = 0.0000, -0.1860, 0.2445 + bone.tail[:] = 0.0000, -0.1860, 0.3056 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.006']] + bones['face'] = bone.name + bone = arm.edit_bones.new('hand.L') + bone.head[:] = 0.0313, -0.1111, 0.0248 + bone.tail[:] = 0.0313, -0.1297, 0.0094 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['forearm.L']] + bones['hand.L'] = bone.name + bone = arm.edit_bones.new('hand.R') + bone.head[:] = -0.0313, -0.1111, 0.0248 + bone.tail[:] = -0.0313, -0.1297, 0.0094 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['forearm.R']] + bones['hand.R'] = bone.name + bone = arm.edit_bones.new('r_index.001.L') + bone.head[:] = 0.0215, 0.1367, 0.0087 + bone.tail[:] = 0.0217, 0.1325, 0.0070 + bone.roll = -0.3427 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.001.L']] + bones['r_index.001.L'] = bone.name + bone = arm.edit_bones.new('r_middle.001.L') + bone.head[:] = 0.0311, 0.1358, 0.0117 + bone.tail[:] = 0.0324, 0.1297, 0.0092 + bone.roll = -1.0029 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.002.L']] + bones['r_middle.001.L'] = bone.name + bone = arm.edit_bones.new('r_ring.001.L') + bone.head[:] = 0.0376, 0.1372, 0.0117 + bone.tail[:] = 0.0389, 0.1311, 0.0092 + bone.roll = -1.0029 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.003.L']] + bones['r_ring.001.L'] = bone.name + bone = arm.edit_bones.new('r_pinky.001.L') + bone.head[:] = 0.0466, 0.1444, 0.0083 + bone.tail[:] = 0.0476, 0.1412, 0.0074 + bone.roll = -1.7551 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.004.L']] + bones['r_pinky.001.L'] = bone.name + bone = arm.edit_bones.new('r_index.001.R') + bone.head[:] = -0.0215, 0.1367, 0.0087 + bone.tail[:] = -0.0217, 0.1325, 0.0070 + bone.roll = 0.3427 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.001.R']] + bones['r_index.001.R'] = bone.name + bone = arm.edit_bones.new('r_middle.001.R') + bone.head[:] = -0.0311, 0.1358, 0.0117 + bone.tail[:] = -0.0324, 0.1297, 0.0092 + bone.roll = 1.0029 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.002.R']] + bones['r_middle.001.R'] = bone.name + bone = arm.edit_bones.new('r_ring.001.R') + bone.head[:] = -0.0376, 0.1372, 0.0117 + bone.tail[:] = -0.0389, 0.1311, 0.0092 + bone.roll = 1.0029 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.003.R']] + bones['r_ring.001.R'] = bone.name + bone = arm.edit_bones.new('r_pinky.001.R') + bone.head[:] = -0.0466, 0.1444, 0.0083 + bone.tail[:] = -0.0476, 0.1412, 0.0074 + bone.roll = 1.7551 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.004.R']] + bones['r_pinky.001.R'] = bone.name + bone = arm.edit_bones.new('nose') + bone.head[:] = 0.0000, -0.2709, 0.2463 + bone.tail[:] = 0.0000, -0.2705, 0.2315 + bone.roll = -0.0018 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['nose'] = bone.name + bone = arm.edit_bones.new('lip.T.L') + bone.head[:] = 0.0000, -0.2762, 0.2076 + bone.tail[:] = 0.0142, -0.2683, 0.2053 + bone.roll = 0.0739 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.T.L'] = bone.name + bone = arm.edit_bones.new('lip.B.L') + bone.head[:] = 0.0000, -0.2748, 0.2025 + bone.tail[:] = 0.0102, -0.2676, 0.2025 + bone.roll = 0.0154 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.B.L'] = bone.name + bone = arm.edit_bones.new('jaw') + bone.head[:] = 0.0000, -0.2126, 0.2015 + bone.tail[:] = 0.0000, -0.2524, 0.1977 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['jaw'] = bone.name + bone = arm.edit_bones.new('ear.L') + bone.head[:] = 0.0361, -0.2279, 0.2662 + bone.tail[:] = 0.0259, -0.2360, 0.2749 + bone.roll = -2.7956 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['ear.L'] = bone.name + bone = arm.edit_bones.new('ear.R') + bone.head[:] = -0.0361, -0.2279, 0.2662 + bone.tail[:] = -0.0259, -0.2360, 0.2749 + bone.roll = 2.7956 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['ear.R'] = bone.name + bone = arm.edit_bones.new('lip.T.R') + bone.head[:] = 0.0000, -0.2762, 0.2076 + bone.tail[:] = -0.0142, -0.2683, 0.2053 + bone.roll = -0.0739 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.T.R'] = bone.name + bone = arm.edit_bones.new('lip.B.R') + bone.head[:] = 0.0000, -0.2748, 0.2025 + bone.tail[:] = -0.0102, -0.2676, 0.2025 + bone.roll = -0.0154 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.B.R'] = bone.name + bone = arm.edit_bones.new('brow.B.L') + bone.head[:] = 0.0450, -0.2472, 0.2375 + bone.tail[:] = 0.0336, -0.2577, 0.2472 + bone.roll = -0.4810 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['brow.B.L'] = bone.name + bone = arm.edit_bones.new('lid.T.L') + bone.head[:] = 0.0398, -0.2525, 0.2396 + bone.tail[:] = 0.0327, -0.2600, 0.2432 + bone.roll = -0.4405 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lid.T.L'] = bone.name + bone = arm.edit_bones.new('brow.B.R') + bone.head[:] = -0.0450, -0.2472, 0.2375 + bone.tail[:] = -0.0336, -0.2577, 0.2472 + bone.roll = 0.4810 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['brow.B.R'] = bone.name + bone = arm.edit_bones.new('lid.T.R') + bone.head[:] = -0.0398, -0.2525, 0.2396 + bone.tail[:] = -0.0327, -0.2600, 0.2432 + bone.roll = 0.4405 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lid.T.R'] = bone.name + bone = arm.edit_bones.new('forehead.L') + bone.head[:] = 0.0103, -0.2600, 0.2669 + bone.tail[:] = 0.0097, -0.2694, 0.2527 + bone.roll = 1.6514 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['forehead.L'] = bone.name + bone = arm.edit_bones.new('forehead.R') + bone.head[:] = -0.0103, -0.2600, 0.2669 + bone.tail[:] = -0.0097, -0.2694, 0.2527 + bone.roll = -1.6514 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['forehead.R'] = bone.name + bone = arm.edit_bones.new('eye.L') + bone.head[:] = 0.0170, -0.2441, 0.2385 + bone.tail[:] = 0.0170, -0.2738, 0.2385 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['eye.L'] = bone.name + bone = arm.edit_bones.new('eye.R') + bone.head[:] = -0.0170, -0.2441, 0.2385 + bone.tail[:] = -0.0170, -0.2738, 0.2385 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['eye.R'] = bone.name + bone = arm.edit_bones.new('cheek.T.L') + bone.head[:] = 0.0450, -0.2472, 0.2375 + bone.tail[:] = 0.0308, -0.2584, 0.2187 + bone.roll = 0.3924 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['cheek.T.L'] = bone.name + bone = arm.edit_bones.new('cheek.T.R') + bone.head[:] = -0.0450, -0.2472, 0.2375 + bone.tail[:] = -0.0308, -0.2584, 0.2187 + bone.roll = -0.3924 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['cheek.T.R'] = bone.name + bone = arm.edit_bones.new('teeth.T') + bone.head[:] = 0.0000, -0.2724, 0.2129 + bone.tail[:] = 0.0000, -0.2477, 0.2129 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['teeth.T'] = bone.name + bone = arm.edit_bones.new('teeth.B') + bone.head[:] = 0.0000, -0.2709, 0.2076 + bone.tail[:] = 0.0000, -0.2463, 0.2076 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['teeth.B'] = bone.name + bone = arm.edit_bones.new('tongue') + bone.head[:] = 0.0000, -0.2693, 0.2091 + bone.tail[:] = 0.0000, -0.2610, 0.2098 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['tongue'] = bone.name + bone = arm.edit_bones.new('f_toe.L') + bone.head[:] = 0.0313, -0.1297, 0.0094 + bone.tail[:] = 0.0313, -0.1530, 0.0094 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['hand.L']] + bones['f_toe.L'] = bone.name + bone = arm.edit_bones.new('f_toe.R') + bone.head[:] = -0.0313, -0.1297, 0.0094 + bone.tail[:] = -0.0313, -0.1530, 0.0094 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['hand.R']] + bones['f_toe.R'] = bone.name + bone = arm.edit_bones.new('r_index.002.L') + bone.head[:] = 0.0217, 0.1325, 0.0070 + bone.tail[:] = 0.0221, 0.1271, 0.0038 + bone.roll = -0.2465 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_index.001.L']] + bones['r_index.002.L'] = bone.name + bone = arm.edit_bones.new('r_middle.002.L') + bone.head[:] = 0.0324, 0.1297, 0.0092 + bone.tail[:] = 0.0343, 0.1210, 0.0039 + bone.roll = -0.7479 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_middle.001.L']] + bones['r_middle.002.L'] = bone.name + bone = arm.edit_bones.new('r_ring.002.L') + bone.head[:] = 0.0389, 0.1311, 0.0092 + bone.tail[:] = 0.0407, 0.1229, 0.0042 + bone.roll = -0.7479 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_ring.001.L']] + bones['r_ring.002.L'] = bone.name + bone = arm.edit_bones.new('r_pinky.002.L') + bone.head[:] = 0.0476, 0.1412, 0.0074 + bone.tail[:] = 0.0494, 0.1351, 0.0032 + bone.roll = -0.8965 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_pinky.001.L']] + bones['r_pinky.002.L'] = bone.name + bone = arm.edit_bones.new('r_index.002.R') + bone.head[:] = -0.0217, 0.1325, 0.0070 + bone.tail[:] = -0.0221, 0.1271, 0.0038 + bone.roll = 0.2465 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_index.001.R']] + bones['r_index.002.R'] = bone.name + bone = arm.edit_bones.new('r_middle.002.R') + bone.head[:] = -0.0324, 0.1297, 0.0092 + bone.tail[:] = -0.0343, 0.1210, 0.0039 + bone.roll = 0.7479 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_middle.001.R']] + bones['r_middle.002.R'] = bone.name + bone = arm.edit_bones.new('r_ring.002.R') + bone.head[:] = -0.0389, 0.1311, 0.0092 + bone.tail[:] = -0.0407, 0.1229, 0.0042 + bone.roll = 0.7479 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_ring.001.R']] + bones['r_ring.002.R'] = bone.name + bone = arm.edit_bones.new('r_pinky.002.R') + bone.head[:] = -0.0476, 0.1412, 0.0074 + bone.tail[:] = -0.0494, 0.1351, 0.0032 + bone.roll = 0.8965 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_pinky.001.R']] + bones['r_pinky.002.R'] = bone.name + bone = arm.edit_bones.new('nose.001') + bone.head[:] = 0.0000, -0.2705, 0.2315 + bone.tail[:] = 0.0000, -0.2804, 0.2205 + bone.roll = 0.0253 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose']] + bones['nose.001'] = bone.name + bone = arm.edit_bones.new('lip.T.L.001') + bone.head[:] = 0.0142, -0.2683, 0.2053 + bone.tail[:] = 0.0314, -0.2428, 0.2103 + bone.roll = -0.0306 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.T.L']] + bones['lip.T.L.001'] = bone.name + bone = arm.edit_bones.new('lip.B.L.001') + bone.head[:] = 0.0102, -0.2676, 0.2025 + bone.tail[:] = 0.0314, -0.2428, 0.2103 + bone.roll = 0.1360 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.B.L']] + bones['lip.B.L.001'] = bone.name + bone = arm.edit_bones.new('chin') + bone.head[:] = 0.0000, -0.2524, 0.1977 + bone.tail[:] = 0.0000, -0.2681, 0.1948 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw']] + bones['chin'] = bone.name + bone = arm.edit_bones.new('ear.L.001') + bone.head[:] = 0.0259, -0.2360, 0.2749 + bone.tail[:] = 0.0367, -0.2346, 0.2792 + bone.roll = 1.1038 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L']] + bones['ear.L.001'] = bone.name + bone = arm.edit_bones.new('ear.R.001') + bone.head[:] = -0.0259, -0.2360, 0.2749 + bone.tail[:] = -0.0367, -0.2346, 0.2792 + bone.roll = -1.1038 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R']] + bones['ear.R.001'] = bone.name + bone = arm.edit_bones.new('lip.T.R.001') + bone.head[:] = -0.0142, -0.2683, 0.2053 + bone.tail[:] = -0.0314, -0.2428, 0.2103 + bone.roll = 0.0306 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.T.R']] + bones['lip.T.R.001'] = bone.name + bone = arm.edit_bones.new('lip.B.R.001') + bone.head[:] = -0.0102, -0.2676, 0.2025 + bone.tail[:] = -0.0314, -0.2428, 0.2103 + bone.roll = -0.1360 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.B.R']] + bones['lip.B.R.001'] = bone.name + bone = arm.edit_bones.new('brow.B.L.001') + bone.head[:] = 0.0336, -0.2577, 0.2472 + bone.tail[:] = 0.0242, -0.2642, 0.2478 + bone.roll = -0.0715 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.L']] + bones['brow.B.L.001'] = bone.name + bone = arm.edit_bones.new('lid.T.L.001') + bone.head[:] = 0.0327, -0.2600, 0.2432 + bone.tail[:] = 0.0236, -0.2656, 0.2440 + bone.roll = 0.1058 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L']] + bones['lid.T.L.001'] = bone.name + bone = arm.edit_bones.new('brow.B.R.001') + bone.head[:] = -0.0336, -0.2577, 0.2472 + bone.tail[:] = -0.0242, -0.2642, 0.2478 + bone.roll = 0.0715 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.R']] + bones['brow.B.R.001'] = bone.name + bone = arm.edit_bones.new('lid.T.R.001') + bone.head[:] = -0.0327, -0.2600, 0.2432 + bone.tail[:] = -0.0236, -0.2656, 0.2440 + bone.roll = -0.1058 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R']] + bones['lid.T.R.001'] = bone.name + bone = arm.edit_bones.new('forehead.L.001') + bone.head[:] = 0.0287, -0.2477, 0.2649 + bone.tail[:] = 0.0241, -0.2601, 0.2567 + bone.roll = 2.1575 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.L']] + bones['forehead.L.001'] = bone.name + bone = arm.edit_bones.new('forehead.R.001') + bone.head[:] = -0.0287, -0.2477, 0.2649 + bone.tail[:] = -0.0241, -0.2601, 0.2567 + bone.roll = -2.1575 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.R']] + bones['forehead.R.001'] = bone.name + bone = arm.edit_bones.new('cheek.T.L.001') + bone.head[:] = 0.0308, -0.2584, 0.2187 + bone.tail[:] = 0.0121, -0.2695, 0.2220 + bone.roll = -0.5048 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.L']] + bones['cheek.T.L.001'] = bone.name + bone = arm.edit_bones.new('cheek.T.R.001') + bone.head[:] = -0.0308, -0.2584, 0.2187 + bone.tail[:] = -0.0121, -0.2695, 0.2220 + bone.roll = 0.5048 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.R']] + bones['cheek.T.R.001'] = bone.name + bone = arm.edit_bones.new('tongue.001') + bone.head[:] = 0.0000, -0.2610, 0.2098 + bone.tail[:] = 0.0000, -0.2461, 0.2100 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tongue']] + bones['tongue.001'] = bone.name + bone = arm.edit_bones.new('f_palm.004.L') + bone.head[:] = 0.0393, -0.1278, 0.0100 + bone.tail[:] = 0.0406, -0.1304, 0.0100 + bone.roll = -0.0006 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_toe.L']] + bones['f_palm.004.L'] = bone.name + bone = arm.edit_bones.new('f_palm.001.L') + bone.head[:] = 0.0216, -0.1278, 0.0100 + bone.tail[:] = 0.0199, -0.1331, 0.0100 + bone.roll = 0.0004 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_toe.L']] + bones['f_palm.001.L'] = bone.name + bone = arm.edit_bones.new('f_palm.002.L') + bone.head[:] = 0.0273, -0.1278, 0.0100 + bone.tail[:] = 0.0273, -0.1345, 0.0100 + bone.roll = 3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_toe.L']] + bones['f_palm.002.L'] = bone.name + bone = arm.edit_bones.new('f_palm.003.L') + bone.head[:] = 0.0341, -0.1278, 0.0100 + bone.tail[:] = 0.0340, -0.1345, 0.0100 + bone.roll = 0.0101 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_toe.L']] + bones['f_palm.003.L'] = bone.name + bone = arm.edit_bones.new('f_palm.004.R') + bone.head[:] = -0.0393, -0.1278, 0.0100 + bone.tail[:] = -0.0406, -0.1304, 0.0100 + bone.roll = 0.0006 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_toe.R']] + bones['f_palm.004.R'] = bone.name + bone = arm.edit_bones.new('f_palm.001.R') + bone.head[:] = -0.0216, -0.1278, 0.0100 + bone.tail[:] = -0.0199, -0.1331, 0.0100 + bone.roll = -0.0004 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_toe.R']] + bones['f_palm.001.R'] = bone.name + bone = arm.edit_bones.new('f_palm.002.R') + bone.head[:] = -0.0273, -0.1278, 0.0100 + bone.tail[:] = -0.0273, -0.1345, 0.0100 + bone.roll = -3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_toe.R']] + bones['f_palm.002.R'] = bone.name + bone = arm.edit_bones.new('f_palm.003.R') + bone.head[:] = -0.0341, -0.1278, 0.0100 + bone.tail[:] = -0.0340, -0.1345, 0.0100 + bone.roll = -0.0101 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_toe.R']] + bones['f_palm.003.R'] = bone.name + bone = arm.edit_bones.new('nose.002') + bone.head[:] = 0.0000, -0.2804, 0.2205 + bone.tail[:] = 0.0000, -0.2787, 0.2155 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.001']] + bones['nose.002'] = bone.name + bone = arm.edit_bones.new('chin.001') + bone.head[:] = 0.0000, -0.2681, 0.1948 + bone.tail[:] = 0.0000, -0.2749, 0.2015 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['chin']] + bones['chin.001'] = bone.name + bone = arm.edit_bones.new('ear.L.002') + bone.head[:] = 0.0367, -0.2346, 0.2792 + bone.tail[:] = 0.0513, -0.2371, 0.2879 + bone.roll = 1.6702 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L.001']] + bones['ear.L.002'] = bone.name + bone = arm.edit_bones.new('ear.R.002') + bone.head[:] = -0.0367, -0.2346, 0.2792 + bone.tail[:] = -0.0513, -0.2371, 0.2879 + bone.roll = -1.6702 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R.001']] + bones['ear.R.002'] = bone.name + bone = arm.edit_bones.new('brow.B.L.002') + bone.head[:] = 0.0242, -0.2642, 0.2478 + bone.tail[:] = 0.0131, -0.2694, 0.2432 + bone.roll = -0.1515 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.L.001']] + bones['brow.B.L.002'] = bone.name + bone = arm.edit_bones.new('lid.T.L.002') + bone.head[:] = 0.0236, -0.2656, 0.2440 + bone.tail[:] = 0.0137, -0.2665, 0.2401 + bone.roll = -0.1882 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L.001']] + bones['lid.T.L.002'] = bone.name + bone = arm.edit_bones.new('brow.B.R.002') + bone.head[:] = -0.0242, -0.2642, 0.2478 + bone.tail[:] = -0.0131, -0.2694, 0.2432 + bone.roll = 0.1515 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.R.001']] + bones['brow.B.R.002'] = bone.name + bone = arm.edit_bones.new('lid.T.R.002') + bone.head[:] = -0.0236, -0.2656, 0.2440 + bone.tail[:] = -0.0137, -0.2665, 0.2401 + bone.roll = 0.1882 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R.001']] + bones['lid.T.R.002'] = bone.name + bone = arm.edit_bones.new('forehead.L.002') + bone.head[:] = 0.0405, -0.2354, 0.2607 + bone.tail[:] = 0.0402, -0.2481, 0.2487 + bone.roll = 0.5185 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.L.001']] + bones['forehead.L.002'] = bone.name + bone = arm.edit_bones.new('forehead.R.002') + bone.head[:] = -0.0405, -0.2354, 0.2607 + bone.tail[:] = -0.0402, -0.2481, 0.2487 + bone.roll = -0.5185 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.R.001']] + bones['forehead.R.002'] = bone.name + bone = arm.edit_bones.new('nose.L') + bone.head[:] = 0.0121, -0.2695, 0.2220 + bone.tail[:] = 0.0062, -0.2742, 0.2210 + bone.roll = 2.5249 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.L.001']] + bones['nose.L'] = bone.name + bone = arm.edit_bones.new('nose.R') + bone.head[:] = -0.0121, -0.2695, 0.2220 + bone.tail[:] = -0.0062, -0.2742, 0.2210 + bone.roll = -2.5249 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.R.001']] + bones['nose.R'] = bone.name + bone = arm.edit_bones.new('tongue.002') + bone.head[:] = 0.0000, -0.2461, 0.2100 + bone.tail[:] = 0.0000, -0.2309, 0.2083 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tongue.001']] + bones['tongue.002'] = bone.name + bone = arm.edit_bones.new('f_pinky.001.L') + bone.head[:] = 0.0406, -0.1304, 0.0074 + bone.tail[:] = 0.0408, -0.1337, 0.0065 + bone.roll = -0.6234 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.004.L']] + bones['f_pinky.001.L'] = bone.name + bone = arm.edit_bones.new('f_index.001.L') + bone.head[:] = 0.0199, -0.1331, 0.0077 + bone.tail[:] = 0.0193, -0.1372, 0.0060 + bone.roll = 0.7154 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.001.L']] + bones['f_index.001.L'] = bone.name + bone = arm.edit_bones.new('f_middle.001.L') + bone.head[:] = 0.0273, -0.1345, 0.0107 + bone.tail[:] = 0.0273, -0.1407, 0.0082 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.002.L']] + bones['f_middle.001.L'] = bone.name + bone = arm.edit_bones.new('f_ring.001.L') + bone.head[:] = 0.0340, -0.1345, 0.0107 + bone.tail[:] = 0.0340, -0.1407, 0.0082 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.003.L']] + bones['f_ring.001.L'] = bone.name + bone = arm.edit_bones.new('f_pinky.001.R') + bone.head[:] = -0.0406, -0.1304, 0.0074 + bone.tail[:] = -0.0408, -0.1337, 0.0065 + bone.roll = 0.6234 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.004.R']] + bones['f_pinky.001.R'] = bone.name + bone = arm.edit_bones.new('f_index.001.R') + bone.head[:] = -0.0199, -0.1331, 0.0077 + bone.tail[:] = -0.0193, -0.1372, 0.0060 + bone.roll = -0.7154 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.001.R']] + bones['f_index.001.R'] = bone.name + bone = arm.edit_bones.new('f_middle.001.R') + bone.head[:] = -0.0273, -0.1345, 0.0107 + bone.tail[:] = -0.0273, -0.1407, 0.0082 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.002.R']] + bones['f_middle.001.R'] = bone.name + bone = arm.edit_bones.new('f_ring.001.R') + bone.head[:] = -0.0340, -0.1345, 0.0107 + bone.tail[:] = -0.0340, -0.1407, 0.0082 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.003.R']] + bones['f_ring.001.R'] = bone.name + bone = arm.edit_bones.new('nose.003') + bone.head[:] = 0.0000, -0.2787, 0.2155 + bone.tail[:] = 0.0000, -0.2788, 0.2123 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.002']] + bones['nose.003'] = bone.name + bone = arm.edit_bones.new('ear.L.003') + bone.head[:] = 0.0513, -0.2371, 0.2879 + bone.tail[:] = 0.0498, -0.2277, 0.2690 + bone.roll = -2.2767 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L.002']] + bones['ear.L.003'] = bone.name + bone = arm.edit_bones.new('ear.R.003') + bone.head[:] = -0.0513, -0.2371, 0.2879 + bone.tail[:] = -0.0498, -0.2277, 0.2690 + bone.roll = 2.2767 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R.002']] + bones['ear.R.003'] = bone.name + bone = arm.edit_bones.new('brow.B.L.003') + bone.head[:] = 0.0131, -0.2694, 0.2432 + bone.tail[:] = 0.0086, -0.2691, 0.2358 + bone.roll = -0.2157 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.L.002']] + bones['brow.B.L.003'] = bone.name + bone = arm.edit_bones.new('lid.T.L.003') + bone.head[:] = 0.0137, -0.2665, 0.2401 + bone.tail[:] = 0.0097, -0.2657, 0.2291 + bone.roll = -0.4253 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L.002']] + bones['lid.T.L.003'] = bone.name + bone = arm.edit_bones.new('brow.B.R.003') + bone.head[:] = -0.0131, -0.2694, 0.2432 + bone.tail[:] = -0.0086, -0.2691, 0.2358 + bone.roll = 0.2157 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.R.002']] + bones['brow.B.R.003'] = bone.name + bone = arm.edit_bones.new('lid.T.R.003') + bone.head[:] = -0.0137, -0.2665, 0.2401 + bone.tail[:] = -0.0097, -0.2657, 0.2291 + bone.roll = 0.4253 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R.002']] + bones['lid.T.R.003'] = bone.name + bone = arm.edit_bones.new('temple.L') + bone.head[:] = 0.0367, -0.2123, 0.2525 + bone.tail[:] = 0.0380, -0.2135, 0.2277 + bone.roll = -0.0789 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.L.002']] + bones['temple.L'] = bone.name + bone = arm.edit_bones.new('temple.R') + bone.head[:] = -0.0367, -0.2123, 0.2525 + bone.tail[:] = -0.0380, -0.2135, 0.2277 + bone.roll = 0.0789 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.R.002']] + bones['temple.R'] = bone.name + bone = arm.edit_bones.new('nose.L.001') + bone.head[:] = 0.0062, -0.2742, 0.2210 + bone.tail[:] = 0.0000, -0.2804, 0.2205 + bone.roll = 0.1646 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.L']] + bones['nose.L.001'] = bone.name + bone = arm.edit_bones.new('nose.R.001') + bone.head[:] = -0.0062, -0.2742, 0.2210 + bone.tail[:] = 0.0000, -0.2804, 0.2205 + bone.roll = -0.1646 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.R']] + bones['nose.R.001'] = bone.name + bone = arm.edit_bones.new('f_pinky.002.L') + bone.head[:] = 0.0408, -0.1337, 0.0065 + bone.tail[:] = 0.0413, -0.1400, 0.0023 + bone.roll = -0.2560 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_pinky.001.L']] + bones['f_pinky.002.L'] = bone.name + bone = arm.edit_bones.new('f_index.002.L') + bone.head[:] = 0.0193, -0.1372, 0.0060 + bone.tail[:] = 0.0186, -0.1427, 0.0028 + bone.roll = 0.5229 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_index.001.L']] + bones['f_index.002.L'] = bone.name + bone = arm.edit_bones.new('f_middle.002.L') + bone.head[:] = 0.0273, -0.1407, 0.0082 + bone.tail[:] = 0.0273, -0.1496, 0.0030 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_middle.001.L']] + bones['f_middle.002.L'] = bone.name + bone = arm.edit_bones.new('f_ring.002.L') + bone.head[:] = 0.0340, -0.1407, 0.0082 + bone.tail[:] = 0.0340, -0.1491, 0.0033 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_ring.001.L']] + bones['f_ring.002.L'] = bone.name + bone = arm.edit_bones.new('f_pinky.002.R') + bone.head[:] = -0.0408, -0.1337, 0.0065 + bone.tail[:] = -0.0413, -0.1400, 0.0023 + bone.roll = 0.2560 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_pinky.001.R']] + bones['f_pinky.002.R'] = bone.name + bone = arm.edit_bones.new('f_index.002.R') + bone.head[:] = -0.0193, -0.1372, 0.0060 + bone.tail[:] = -0.0186, -0.1427, 0.0028 + bone.roll = -0.5229 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_index.001.R']] + bones['f_index.002.R'] = bone.name + bone = arm.edit_bones.new('f_middle.002.R') + bone.head[:] = -0.0273, -0.1407, 0.0082 + bone.tail[:] = -0.0273, -0.1496, 0.0030 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_middle.001.R']] + bones['f_middle.002.R'] = bone.name + bone = arm.edit_bones.new('f_ring.002.R') + bone.head[:] = -0.0340, -0.1407, 0.0082 + bone.tail[:] = -0.0340, -0.1491, 0.0033 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_ring.001.R']] + bones['f_ring.002.R'] = bone.name + bone = arm.edit_bones.new('nose.004') + bone.head[:] = 0.0000, -0.2788, 0.2123 + bone.tail[:] = 0.0000, -0.2785, 0.2091 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.003']] + bones['nose.004'] = bone.name + bone = arm.edit_bones.new('ear.L.004') + bone.head[:] = 0.0498, -0.2277, 0.2690 + bone.tail[:] = 0.0361, -0.2279, 0.2662 + bone.roll = -3.8181 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L.003']] + bones['ear.L.004'] = bone.name + bone = arm.edit_bones.new('ear.R.004') + bone.head[:] = -0.0498, -0.2277, 0.2690 + bone.tail[:] = -0.0361, -0.2279, 0.2662 + bone.roll = 3.8181 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R.003']] + bones['ear.R.004'] = bone.name + bone = arm.edit_bones.new('lid.B.L') + bone.head[:] = 0.0097, -0.2657, 0.2291 + bone.tail[:] = 0.0150, -0.2661, 0.2277 + bone.roll = 0.0693 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L.003']] + bones['lid.B.L'] = bone.name + bone = arm.edit_bones.new('lid.B.R') + bone.head[:] = -0.0097, -0.2657, 0.2291 + bone.tail[:] = -0.0150, -0.2661, 0.2277 + bone.roll = -0.0693 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R.003']] + bones['lid.B.R'] = bone.name + bone = arm.edit_bones.new('jaw.L') + bone.head[:] = 0.0380, -0.2135, 0.2277 + bone.tail[:] = 0.0284, -0.2162, 0.2076 + bone.roll = 0.1964 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['temple.L']] + bones['jaw.L'] = bone.name + bone = arm.edit_bones.new('jaw.R') + bone.head[:] = -0.0380, -0.2135, 0.2277 + bone.tail[:] = -0.0284, -0.2162, 0.2076 + bone.roll = -0.1964 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['temple.R']] + bones['jaw.R'] = bone.name + bone = arm.edit_bones.new('lid.B.L.001') + bone.head[:] = 0.0150, -0.2661, 0.2277 + bone.tail[:] = 0.0221, -0.2652, 0.2262 + bone.roll = 0.1759 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.L']] + bones['lid.B.L.001'] = bone.name + bone = arm.edit_bones.new('lid.B.R.001') + bone.head[:] = -0.0150, -0.2661, 0.2277 + bone.tail[:] = -0.0221, -0.2652, 0.2262 + bone.roll = -0.1759 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.R']] + bones['lid.B.R.001'] = bone.name + bone = arm.edit_bones.new('jaw.L.001') + bone.head[:] = 0.0284, -0.2162, 0.2076 + bone.tail[:] = 0.0235, -0.2371, 0.2014 + bone.roll = -0.0005 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.L']] + bones['jaw.L.001'] = bone.name + bone = arm.edit_bones.new('jaw.R.001') + bone.head[:] = -0.0284, -0.2162, 0.2076 + bone.tail[:] = -0.0235, -0.2371, 0.2014 + bone.roll = 0.0005 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.R']] + bones['jaw.R.001'] = bone.name + bone = arm.edit_bones.new('lid.B.L.002') + bone.head[:] = 0.0221, -0.2652, 0.2262 + bone.tail[:] = 0.0333, -0.2602, 0.2291 + bone.roll = 0.0161 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.L.001']] + bones['lid.B.L.002'] = bone.name + bone = arm.edit_bones.new('lid.B.R.002') + bone.head[:] = -0.0221, -0.2652, 0.2262 + bone.tail[:] = -0.0333, -0.2602, 0.2291 + bone.roll = -0.0161 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.R.001']] + bones['lid.B.R.002'] = bone.name + bone = arm.edit_bones.new('chin.L') + bone.head[:] = 0.0235, -0.2371, 0.2014 + bone.tail[:] = 0.0287, -0.2395, 0.2103 + bone.roll = 0.4176 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.L.001']] + bones['chin.L'] = bone.name + bone = arm.edit_bones.new('chin.R') + bone.head[:] = -0.0235, -0.2371, 0.2014 + bone.tail[:] = -0.0287, -0.2395, 0.2103 + bone.roll = -0.4176 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.R.001']] + bones['chin.R'] = bone.name + bone = arm.edit_bones.new('lid.B.L.003') + bone.head[:] = 0.0333, -0.2602, 0.2291 + bone.tail[:] = 0.0398, -0.2525, 0.2396 + bone.roll = -0.0675 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.L.002']] + bones['lid.B.L.003'] = bone.name + bone = arm.edit_bones.new('lid.B.R.003') + bone.head[:] = -0.0333, -0.2602, 0.2291 + bone.tail[:] = -0.0398, -0.2525, 0.2396 + bone.roll = 0.0675 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.R.002']] + bones['lid.B.R.003'] = bone.name + bone = arm.edit_bones.new('cheek.B.L') + bone.head[:] = 0.0287, -0.2395, 0.2103 + bone.tail[:] = 0.0448, -0.2396, 0.2234 + bone.roll = -0.3125 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['chin.L']] + bones['cheek.B.L'] = bone.name + bone = arm.edit_bones.new('cheek.B.R') + bone.head[:] = -0.0287, -0.2395, 0.2103 + bone.tail[:] = -0.0448, -0.2396, 0.2234 + bone.roll = 0.3125 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['chin.R']] + bones['cheek.B.R'] = bone.name + bone = arm.edit_bones.new('cheek.B.L.001') + bone.head[:] = 0.0448, -0.2396, 0.2234 + bone.tail[:] = 0.0478, -0.2312, 0.2379 + bone.roll = -0.0215 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.L']] + bones['cheek.B.L.001'] = bone.name + bone = arm.edit_bones.new('cheek.B.R.001') + bone.head[:] = -0.0448, -0.2396, 0.2234 + bone.tail[:] = -0.0478, -0.2312, 0.2379 + bone.roll = 0.0215 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.R']] + bones['cheek.B.R.001'] = bone.name + bone = arm.edit_bones.new('brow.T.L') + bone.head[:] = 0.0478, -0.2312, 0.2379 + bone.tail[:] = 0.0402, -0.2481, 0.2487 + bone.roll = -0.6301 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.L.001']] + bones['brow.T.L'] = bone.name + bone = arm.edit_bones.new('brow.T.R') + bone.head[:] = -0.0478, -0.2312, 0.2379 + bone.tail[:] = -0.0402, -0.2481, 0.2487 + bone.roll = 0.6301 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.R.001']] + bones['brow.T.R'] = bone.name + bone = arm.edit_bones.new('brow.T.L.001') + bone.head[:] = 0.0402, -0.2481, 0.2487 + bone.tail[:] = 0.0241, -0.2601, 0.2567 + bone.roll = 0.3622 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.L']] + bones['brow.T.L.001'] = bone.name + bone = arm.edit_bones.new('brow.T.R.001') + bone.head[:] = -0.0402, -0.2481, 0.2487 + bone.tail[:] = -0.0241, -0.2601, 0.2567 + bone.roll = -0.3622 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.R']] + bones['brow.T.R.001'] = bone.name + bone = arm.edit_bones.new('brow.T.L.002') + bone.head[:] = 0.0241, -0.2601, 0.2567 + bone.tail[:] = 0.0097, -0.2694, 0.2527 + bone.roll = 0.0684 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.L.001']] + bones['brow.T.L.002'] = bone.name + bone = arm.edit_bones.new('brow.T.R.002') + bone.head[:] = -0.0241, -0.2601, 0.2567 + bone.tail[:] = -0.0097, -0.2694, 0.2527 + bone.roll = -0.0684 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.R.001']] + bones['brow.T.R.002'] = bone.name + bone = arm.edit_bones.new('brow.T.L.003') + bone.head[:] = 0.0097, -0.2694, 0.2527 + bone.tail[:] = 0.0000, -0.2709, 0.2463 + bone.roll = 0.0020 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.L.002']] + bones['brow.T.L.003'] = bone.name + bone = arm.edit_bones.new('brow.T.R.003') + bone.head[:] = -0.0097, -0.2694, 0.2527 + bone.tail[:] = 0.0000, -0.2709, 0.2463 + bone.roll = -0.0020 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.R.002']] + bones['brow.T.R.003'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['tail.004']] + pbone.rigify_type = 'spines.super_spine' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.use_tail = True + except AttributeError: + pass + try: + pbone.rigify_parameters.pivot_pos = 6 + except AttributeError: + pass + try: + pbone.rigify_parameters.neck_pos = 9 + except AttributeError: + pass + try: + pbone.rigify_parameters.tail_pos = 4 + except AttributeError: + pass + try: + pbone.rigify_parameters.copy_rotation_axes = [True, True, True] + except AttributeError: + pass + pbone = obj.pose.bones[bones['tail.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['tail.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['tail.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.neck_pos = 5 + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['pelvis.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['pelvis.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['pelvis.C']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['thigh.L']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.segments = 2 + except AttributeError: + pass + pbone = obj.pose.bones[bones['thigh.R']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['belly.C']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shin.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shin.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['Breast.C']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shoulder.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_control = True + except AttributeError: + pass + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['shoulder.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_control = True + except AttributeError: + pass + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['foot.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['foot.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.005']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['upper_arm.L']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['upper_arm.R']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_toe.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_toe.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.006']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forearm.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forearm.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.001.L']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.003.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.004.L']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.001.R']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.003.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.004.R']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['face']] + pbone.rigify_type = 'faces.super_face' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.secondary_layers = [False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['hand.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['hand.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_index.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_middle.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_ring.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_pinky.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_index.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_middle.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_ring.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_pinky.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['nose']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.T.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.B.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.T.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.B.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['eye.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['eye.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.T.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.T.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['teeth.T']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['teeth.B']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['tongue']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_toe.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_toe.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_index.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_middle.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_ring.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_pinky.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_index.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_middle.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_ring.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_pinky.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.T.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.B.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['chin']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.T.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.B.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.T.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.T.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['tongue.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.004.L']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.001.L']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.003.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.004.R']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.001.R']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.003.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['chin.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['tongue.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_pinky.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_index.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_middle.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_ring.001.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_pinky.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_index.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_middle.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_ring.001.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['nose.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.L.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.R.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.L.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.L.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.R.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.R.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['temple.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['temple.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_pinky.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_index.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_middle.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_ring.002.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_pinky.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_index.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_middle.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_ring.002.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.L.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.R.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['chin.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['chin.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.L.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.R.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.B.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.B.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.B.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.B.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.L.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.R.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + + bpy.ops.object.mode_set(mode='EDIT') + for bone in arm.edit_bones: + bone.select = False + bone.select_head = False + bone.select_tail = False + for b in bones: + bone = arm.edit_bones[bones[b]] + bone.select = True + bone.select_head = True + bone.select_tail = True + arm.edit_bones.active = bone + + arm.layers = [(x in [0, 3, 5, 7, 10, 13, 16, 19]) for x in range(32)] + +if __name__ == "__main__": + create(bpy.context.active_object)
\ No newline at end of file diff --git a/rigify/metarigs/Animals/horse.py b/rigify/metarigs/Animals/horse.py new file mode 100644 index 00000000..e85be5fd --- /dev/null +++ b/rigify/metarigs/Animals/horse.py @@ -0,0 +1,1372 @@ +import bpy + + +from mathutils import Color + + +def create(obj): + # generated by rigify.utils.write_metarig + bpy.ops.object.mode_set(mode='EDIT') + arm = obj.data + + for i in range(6): + arm.rigify_colors.add() + + arm.rigify_colors[0].name = "Root" + arm.rigify_colors[0].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[0].normal = Color((0.4352940022945404, 0.18431399762630463, 0.4156860113143921)) + arm.rigify_colors[0].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[0].standard_colors_lock = True + arm.rigify_colors[1].name = "IK" + arm.rigify_colors[1].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[1].normal = Color((0.6039220094680786, 0.0, 0.0)) + arm.rigify_colors[1].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[1].standard_colors_lock = True + arm.rigify_colors[2].name = "Special" + arm.rigify_colors[2].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[2].normal = Color((0.9568629860877991, 0.7882350087165833, 0.04705899953842163)) + arm.rigify_colors[2].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[2].standard_colors_lock = True + arm.rigify_colors[3].name = "Tweak" + arm.rigify_colors[3].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[3].normal = Color((0.03921600058674812, 0.21176500618457794, 0.5803920030593872)) + arm.rigify_colors[3].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[3].standard_colors_lock = True + arm.rigify_colors[4].name = "FK" + arm.rigify_colors[4].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[4].normal = Color((0.11764699965715408, 0.5686269998550415, 0.035294000059366226)) + arm.rigify_colors[4].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[4].standard_colors_lock = True + arm.rigify_colors[5].name = "Extra" + arm.rigify_colors[5].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[5].normal = Color((0.9686279892921448, 0.2509799897670746, 0.09411799907684326)) + arm.rigify_colors[5].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[5].standard_colors_lock = True + + for i in range(29): + arm.rigify_layers.add() + + arm.rigify_layers[0].name = "Face" + arm.rigify_layers[0].row = 1 + arm.rigify_layers[0].set = False + arm.rigify_layers[0].group = 5 + arm.rigify_layers[1].name = "Face (Primary)" + arm.rigify_layers[1].row = 2 + arm.rigify_layers[1].set = False + arm.rigify_layers[1].group = 4 + arm.rigify_layers[2].name = " " + arm.rigify_layers[2].row = 3 + arm.rigify_layers[2].set = False + arm.rigify_layers[2].group = 0 + arm.rigify_layers[3].name = "Spine" + arm.rigify_layers[3].row = 4 + arm.rigify_layers[3].set = False + arm.rigify_layers[3].group = 3 + arm.rigify_layers[4].name = "Spine (Tweak)" + arm.rigify_layers[4].row = 5 + arm.rigify_layers[4].set = False + arm.rigify_layers[4].group = 4 + arm.rigify_layers[5].name = " " + arm.rigify_layers[5].row = 1 + arm.rigify_layers[5].set = False + arm.rigify_layers[5].group = 0 + arm.rigify_layers[6].name = " " + arm.rigify_layers[6].row = 1 + arm.rigify_layers[6].set = False + arm.rigify_layers[6].group = 0 + arm.rigify_layers[7].name = "Arm.L (IK)" + arm.rigify_layers[7].row = 7 + arm.rigify_layers[7].set = False + arm.rigify_layers[7].group = 2 + arm.rigify_layers[8].name = "Arm.L (FK)" + arm.rigify_layers[8].row = 8 + arm.rigify_layers[8].set = False + arm.rigify_layers[8].group = 5 + arm.rigify_layers[9].name = "Arm.L (Tweak)" + arm.rigify_layers[9].row = 9 + arm.rigify_layers[9].set = False + arm.rigify_layers[9].group = 4 + arm.rigify_layers[10].name = "Arm.R (IK)" + arm.rigify_layers[10].row = 7 + arm.rigify_layers[10].set = False + arm.rigify_layers[10].group = 2 + arm.rigify_layers[11].name = "Arm.R (FK)" + arm.rigify_layers[11].row = 8 + arm.rigify_layers[11].set = False + arm.rigify_layers[11].group = 5 + arm.rigify_layers[12].name = "Arm.R (Tweak)" + arm.rigify_layers[12].row = 9 + arm.rigify_layers[12].set = False + arm.rigify_layers[12].group = 4 + arm.rigify_layers[13].name = "Leg.L (IK)" + arm.rigify_layers[13].row = 10 + arm.rigify_layers[13].set = False + arm.rigify_layers[13].group = 2 + arm.rigify_layers[14].name = "Leg.L (FK)" + arm.rigify_layers[14].row = 11 + arm.rigify_layers[14].set = False + arm.rigify_layers[14].group = 5 + arm.rigify_layers[15].name = "Leg.L (Tweak)" + arm.rigify_layers[15].row = 12 + arm.rigify_layers[15].set = False + arm.rigify_layers[15].group = 4 + arm.rigify_layers[16].name = "Leg.R (IK)" + arm.rigify_layers[16].row = 10 + arm.rigify_layers[16].set = False + arm.rigify_layers[16].group = 2 + arm.rigify_layers[17].name = "Leg.R (FK)" + arm.rigify_layers[17].row = 11 + arm.rigify_layers[17].set = False + arm.rigify_layers[17].group = 5 + arm.rigify_layers[18].name = "Leg.R (Tweak)" + arm.rigify_layers[18].row = 12 + arm.rigify_layers[18].set = False + arm.rigify_layers[18].group = 4 + arm.rigify_layers[19].name = "Tail" + arm.rigify_layers[19].row = 13 + arm.rigify_layers[19].set = False + arm.rigify_layers[19].group = 6 + arm.rigify_layers[20].name = " " + arm.rigify_layers[20].row = 1 + arm.rigify_layers[20].set = False + arm.rigify_layers[20].group = 4 + arm.rigify_layers[21].name = "Hair" + arm.rigify_layers[21].row = 14 + arm.rigify_layers[21].set = False + arm.rigify_layers[21].group = 6 + arm.rigify_layers[22].name = " " + arm.rigify_layers[22].row = 1 + arm.rigify_layers[22].set = False + arm.rigify_layers[22].group = 0 + arm.rigify_layers[23].name = " " + arm.rigify_layers[23].row = 1 + arm.rigify_layers[23].set = False + arm.rigify_layers[23].group = 0 + arm.rigify_layers[24].name = " " + arm.rigify_layers[24].row = 1 + arm.rigify_layers[24].set = False + arm.rigify_layers[24].group = 0 + arm.rigify_layers[25].name = " " + arm.rigify_layers[25].row = 1 + arm.rigify_layers[25].set = False + arm.rigify_layers[25].group = 0 + arm.rigify_layers[26].name = " " + arm.rigify_layers[26].row = 1 + arm.rigify_layers[26].set = False + arm.rigify_layers[26].group = 0 + arm.rigify_layers[27].name = " " + arm.rigify_layers[27].row = 1 + arm.rigify_layers[27].set = False + arm.rigify_layers[27].group = 0 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 14 + arm.rigify_layers[28].set = False + arm.rigify_layers[28].group = 1 + + + bones = {} + + bone = arm.edit_bones.new('spine') + bone.head[:] = -0.0000, 1.7610, 1.1153 + bone.tail[:] = -0.0000, 1.5754, 1.1088 + bone.roll = -0.0000 + bone.use_connect = False + bones['spine'] = bone.name + bone = arm.edit_bones.new('spine.001') + bone.head[:] = -0.0000, 1.5754, 1.1088 + bone.tail[:] = -0.0000, 1.3779, 1.1589 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine']] + bones['spine.001'] = bone.name + bone = arm.edit_bones.new('spine.002') + bone.head[:] = -0.0000, 1.3779, 1.1589 + bone.tail[:] = -0.0000, 1.1423, 1.3128 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.001']] + bones['spine.002'] = bone.name + bone = arm.edit_bones.new('spine.003') + bone.head[:] = -0.0000, 1.1423, 1.3128 + bone.tail[:] = -0.0000, 1.0291, 1.4191 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.002']] + bones['spine.003'] = bone.name + bone = arm.edit_bones.new('spine.004') + bone.head[:] = -0.0000, 1.0291, 1.4191 + bone.tail[:] = -0.0000, 0.9228, 1.4526 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.003']] + bones['spine.004'] = bone.name + bone = arm.edit_bones.new('spine.005') + bone.head[:] = -0.0000, 0.9228, 1.4526 + bone.tail[:] = -0.0000, 0.6989, 1.4910 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.004']] + bones['spine.005'] = bone.name + bone = arm.edit_bones.new('spine.006') + bone.head[:] = -0.0000, 0.6989, 1.4910 + bone.tail[:] = -0.0000, 0.3824, 1.3801 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.005']] + bones['spine.006'] = bone.name + bone = arm.edit_bones.new('spine.007') + bone.head[:] = -0.0000, 0.3824, 1.3801 + bone.tail[:] = -0.0000, 0.1316, 1.3086 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.006']] + bones['spine.007'] = bone.name + bone = arm.edit_bones.new('pelvis.L') + bone.head[:] = 0.0503, 0.6868, 1.3205 + bone.tail[:] = 0.1803, 0.4418, 1.5783 + bone.roll = 0.7837 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.006']] + bones['pelvis.L'] = bone.name + bone = arm.edit_bones.new('thigh.L') + bone.head[:] = 0.1922, 0.7048, 1.4330 + bone.tail[:] = 0.1933, 0.5712, 1.0272 + bone.roll = 3.1380 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.006']] + bones['thigh.L'] = bone.name + bone = arm.edit_bones.new('pelvis.R') + bone.head[:] = -0.0503, 0.6868, 1.3205 + bone.tail[:] = -0.1803, 0.4418, 1.5783 + bone.roll = -0.7837 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.006']] + bones['pelvis.R'] = bone.name + bone = arm.edit_bones.new('thigh.R') + bone.head[:] = -0.1922, 0.7048, 1.4330 + bone.tail[:] = -0.1933, 0.5712, 1.0272 + bone.roll = -3.1380 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.006']] + bones['thigh.R'] = bone.name + bone = arm.edit_bones.new('pelvis') + bone.head[:] = 0.0000, 0.6845, 1.3200 + bone.tail[:] = -0.0000, 0.4276, 1.0452 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.006']] + bones['pelvis'] = bone.name + bone = arm.edit_bones.new('spine.008') + bone.head[:] = -0.0000, 0.1316, 1.3086 + bone.tail[:] = -0.0000, -0.1712, 1.2964 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.007']] + bones['spine.008'] = bone.name + bone = arm.edit_bones.new('shin.L') + bone.head[:] = 0.1933, 0.5712, 1.0272 + bone.tail[:] = 0.1933, 0.7355, 0.6045 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.L']] + bones['shin.L'] = bone.name + bone = arm.edit_bones.new('shin.R') + bone.head[:] = -0.1933, 0.5712, 1.0272 + bone.tail[:] = -0.1933, 0.7355, 0.6045 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.R']] + bones['shin.R'] = bone.name + bone = arm.edit_bones.new('spine.009') + bone.head[:] = -0.0000, -0.1712, 1.2964 + bone.tail[:] = -0.0000, -0.4908, 1.3031 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.008']] + bones['spine.009'] = bone.name + bone = arm.edit_bones.new('belly') + bone.head[:] = -0.0000, 0.1503, 1.2207 + bone.tail[:] = -0.0000, 0.1802, 0.9332 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.008']] + bones['belly'] = bone.name + bone = arm.edit_bones.new('foot.L') + bone.head[:] = 0.1933, 0.7355, 0.6045 + bone.tail[:] = 0.1933, 0.6771, 0.1732 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.L']] + bones['foot.L'] = bone.name + bone = arm.edit_bones.new('foot.R') + bone.head[:] = -0.1933, 0.7355, 0.6045 + bone.tail[:] = -0.1933, 0.6771, 0.1732 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.R']] + bones['foot.R'] = bone.name + bone = arm.edit_bones.new('spine.010') + bone.head[:] = -0.0000, -0.4908, 1.3031 + bone.tail[:] = -0.0000, -0.7593, 1.3786 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.009']] + bones['spine.010'] = bone.name + bone = arm.edit_bones.new('shoulder.L') + bone.head[:] = 0.0936, -0.5035, 1.5783 + bone.tail[:] = 0.1868, -0.6452, 1.0858 + bone.roll = -0.2398 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.009']] + bones['shoulder.L'] = bone.name + bone = arm.edit_bones.new('breast.L') + bone.head[:] = 0.0905, -0.5541, 1.0931 + bone.tail[:] = 0.0905, -0.8316, 0.9879 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.009']] + bones['breast.L'] = bone.name + bone = arm.edit_bones.new('shoulder.R') + bone.head[:] = -0.0936, -0.5035, 1.5783 + bone.tail[:] = -0.1868, -0.6452, 1.0858 + bone.roll = 0.2398 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.009']] + bones['shoulder.R'] = bone.name + bone = arm.edit_bones.new('breast.R') + bone.head[:] = -0.0905, -0.5541, 1.0931 + bone.tail[:] = -0.0905, -0.8316, 0.9879 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.009']] + bones['breast.R'] = bone.name + bone = arm.edit_bones.new('chest') + bone.head[:] = -0.0000, -0.2180, 1.2173 + bone.tail[:] = -0.0000, -0.2239, 0.8383 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.009']] + bones['chest'] = bone.name + bone = arm.edit_bones.new('r_toe.L') + bone.head[:] = 0.1933, 0.6771, 0.1732 + bone.tail[:] = 0.1933, 0.5818, 0.0198 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.L']] + bones['r_toe.L'] = bone.name + bone = arm.edit_bones.new('r_toe.R') + bone.head[:] = -0.1933, 0.6771, 0.1732 + bone.tail[:] = -0.1933, 0.5818, 0.0198 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.R']] + bones['r_toe.R'] = bone.name + bone = arm.edit_bones.new('spine.011') + bone.head[:] = -0.0000, -0.7593, 1.3786 + bone.tail[:] = -0.0000, -0.9004, 1.5475 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.010']] + bones['spine.011'] = bone.name + bone = arm.edit_bones.new('hair_base.05') + bone.head[:] = -0.0000, -0.6120, 1.6888 + bone.tail[:] = -0.0000, -0.5782, 1.7371 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.010']] + bones['hair_base.05'] = bone.name + bone = arm.edit_bones.new('upper_arm.L') + bone.head[:] = 0.1639, -0.5751, 0.9953 + bone.tail[:] = 0.1639, -0.5538, 0.5130 + bone.roll = -3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.L']] + bones['upper_arm.L'] = bone.name + bone = arm.edit_bones.new('upper_arm.R') + bone.head[:] = -0.1639, -0.5751, 0.9953 + bone.tail[:] = -0.1639, -0.5538, 0.5130 + bone.roll = 3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.R']] + bones['upper_arm.R'] = bone.name + bone = arm.edit_bones.new('spine.012') + bone.head[:] = -0.0000, -0.9004, 1.5475 + bone.tail[:] = 0.0000, -1.0348, 1.7032 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.011']] + bones['spine.012'] = bone.name + bone = arm.edit_bones.new('hair_base.04') + bone.head[:] = 0.0000, -0.7885, 1.7610 + bone.tail[:] = -0.0000, -0.7366, 1.8394 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.011']] + bones['hair_base.04'] = bone.name + bone = arm.edit_bones.new('hair_top.05') + bone.head[:] = -0.0000, -0.5782, 1.7371 + bone.tail[:] = -0.0000, -0.5444, 1.7855 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['hair_base.05']] + bones['hair_top.05'] = bone.name + bone = arm.edit_bones.new('forearm.L') + bone.head[:] = 0.1639, -0.5538, 0.5130 + bone.tail[:] = 0.1639, -0.5133, 0.1885 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['upper_arm.L']] + bones['forearm.L'] = bone.name + bone = arm.edit_bones.new('forearm.R') + bone.head[:] = -0.1639, -0.5538, 0.5130 + bone.tail[:] = -0.1639, -0.5133, 0.1885 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['upper_arm.R']] + bones['forearm.R'] = bone.name + bone = arm.edit_bones.new('spine.014') + bone.head[:] = 0.0000, -1.0348, 1.7032 + bone.tail[:] = 0.0000, -1.1618, 1.7694 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.012']] + bones['spine.014'] = bone.name + bone = arm.edit_bones.new('hair_base.03') + bone.head[:] = 0.0000, -0.9627, 1.8513 + bone.tail[:] = 0.0000, -0.9211, 1.9357 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.012']] + bones['hair_base.03'] = bone.name + bone = arm.edit_bones.new('hair_top.04') + bone.head[:] = -0.0000, -0.7366, 1.8394 + bone.tail[:] = -0.0000, -0.6847, 1.9178 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['hair_base.04']] + bones['hair_top.04'] = bone.name + bone = arm.edit_bones.new('hand.L') + bone.head[:] = 0.1639, -0.5133, 0.1885 + bone.tail[:] = 0.1639, -0.5844, 0.0665 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['forearm.L']] + bones['hand.L'] = bone.name + bone = arm.edit_bones.new('hand.R') + bone.head[:] = -0.1639, -0.5133, 0.1885 + bone.tail[:] = -0.1639, -0.5844, 0.0665 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['forearm.R']] + bones['hand.R'] = bone.name + bone = arm.edit_bones.new('spine.015') + bone.head[:] = 0.0000, -1.1618, 1.7694 + bone.tail[:] = -0.0000, -1.2836, 1.7841 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.014']] + bones['spine.015'] = bone.name + bone = arm.edit_bones.new('hair_base.02') + bone.head[:] = 0.0000, -1.1437, 1.9124 + bone.tail[:] = 0.0000, -1.1217, 2.0038 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.014']] + bones['hair_base.02'] = bone.name + bone = arm.edit_bones.new('hair_top.03') + bone.head[:] = 0.0000, -0.9211, 1.9357 + bone.tail[:] = -0.0000, -0.8795, 2.0200 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['hair_base.03']] + bones['hair_top.03'] = bone.name + bone = arm.edit_bones.new('f_toe.L') + bone.head[:] = 0.1639, -0.5844, 0.0665 + bone.tail[:] = 0.1639, -0.6564, 0.0185 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['hand.L']] + bones['f_toe.L'] = bone.name + bone = arm.edit_bones.new('f_toe.R') + bone.head[:] = -0.1639, -0.5844, 0.0665 + bone.tail[:] = -0.1639, -0.6564, 0.0185 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['hand.R']] + bones['f_toe.R'] = bone.name + bone = arm.edit_bones.new('spine.016') + bone.head[:] = -0.0000, -1.2836, 1.7841 + bone.tail[:] = 0.0000, -1.5974, 1.9308 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.015']] + bones['spine.016'] = bone.name + bone = arm.edit_bones.new('hair_base.01') + bone.head[:] = 0.0000, -1.3074, 1.9345 + bone.tail[:] = 0.0000, -1.3182, 2.0279 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.015']] + bones['hair_base.01'] = bone.name + bone = arm.edit_bones.new('hair_base.06') + bone.head[:] = 0.0000, -1.4117, 1.9184 + bone.tail[:] = 0.0000, -1.4566, 1.9477 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.015']] + bones['hair_base.06'] = bone.name + bone = arm.edit_bones.new('hair_top.02') + bone.head[:] = 0.0000, -1.1217, 2.0038 + bone.tail[:] = 0.0000, -1.0996, 2.0953 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['hair_base.02']] + bones['hair_top.02'] = bone.name + bone = arm.edit_bones.new('spine.013') + bone.head[:] = -0.0000, -1.3014, 1.8284 + bone.tail[:] = 0.0000, -1.6749, 1.3100 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.016']] + bones['spine.013'] = bone.name + bone = arm.edit_bones.new('ear.L') + bone.head[:] = 0.0664, -1.3623, 1.8612 + bone.tail[:] = 0.1056, -1.4118, 1.9537 + bone.roll = 0.6751 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.016']] + bones['ear.L'] = bone.name + bone = arm.edit_bones.new('ear.R') + bone.head[:] = -0.0664, -1.3623, 1.8612 + bone.tail[:] = -0.1056, -1.4118, 1.9537 + bone.roll = -0.6751 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.016']] + bones['ear.R'] = bone.name + bone = arm.edit_bones.new('jaw') + bone.head[:] = 0.0000, -1.3507, 1.5819 + bone.tail[:] = 0.0000, -1.4799, 1.4569 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.016']] + bones['jaw'] = bone.name + bone = arm.edit_bones.new('hair_top.01') + bone.head[:] = 0.0000, -1.3182, 2.0279 + bone.tail[:] = 0.0000, -1.3290, 2.1213 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['hair_base.01']] + bones['hair_top.01'] = bone.name + bone = arm.edit_bones.new('hair_top.06') + bone.head[:] = 0.0000, -1.4566, 1.9477 + bone.tail[:] = -0.0000, -1.5014, 1.9770 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['hair_base.06']] + bones['hair_top.06'] = bone.name + bone = arm.edit_bones.new('skull.L') + bone.head[:] = 0.0000, -1.3014, 1.8284 + bone.tail[:] = 0.1564, -1.4143, 1.5755 + bone.roll = -0.7698 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.013']] + bones['skull.L'] = bone.name + bone = arm.edit_bones.new('skull.R') + bone.head[:] = -0.0000, -1.3014, 1.8284 + bone.tail[:] = -0.1564, -1.4143, 1.5755 + bone.roll = 0.7698 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.013']] + bones['skull.R'] = bone.name + bone = arm.edit_bones.new('ear.L.001') + bone.head[:] = 0.1056, -1.4118, 1.9537 + bone.tail[:] = 0.1448, -1.4613, 2.0462 + bone.roll = 0.6751 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L']] + bones['ear.L.001'] = bone.name + bone = arm.edit_bones.new('eye.L') + bone.head[:] = 0.0988, -1.4596, 1.7351 + bone.tail[:] = 0.1990, -1.4668, 1.7420 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['ear.L']] + bones['eye.L'] = bone.name + bone = arm.edit_bones.new('nose.L') + bone.head[:] = 0.0450, -1.6240, 1.4228 + bone.tail[:] = 0.1039, -1.6613, 1.4269 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['ear.L']] + bones['nose.L'] = bone.name + bone = arm.edit_bones.new('eye.R') + bone.head[:] = -0.0988, -1.4596, 1.7351 + bone.tail[:] = -0.1990, -1.4668, 1.7420 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['ear.L']] + bones['eye.R'] = bone.name + bone = arm.edit_bones.new('nose.R') + bone.head[:] = -0.0450, -1.6240, 1.4228 + bone.tail[:] = -0.1039, -1.6613, 1.4269 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['ear.L']] + bones['nose.R'] = bone.name + bone = arm.edit_bones.new('ear.R.001') + bone.head[:] = -0.1056, -1.4118, 1.9537 + bone.tail[:] = -0.1448, -1.4613, 2.0462 + bone.roll = -0.6751 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R']] + bones['ear.R.001'] = bone.name + bone = arm.edit_bones.new('jaw.001') + bone.head[:] = 0.0000, -1.4799, 1.4569 + bone.tail[:] = 0.0000, -1.5599, 1.3210 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw']] + bones['jaw.001'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['spine']] + pbone.rigify_type = 'spines.super_spine' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.neck_pos = 12 + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.use_tail = True + except AttributeError: + pass + try: + pbone.rigify_parameters.pivot_pos = 8 + except AttributeError: + pass + try: + pbone.rigify_parameters.tail_pos = 5 + except AttributeError: + pass + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.005']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.006']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.007']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['pelvis.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['thigh.L']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.segments = 2 + except AttributeError: + pass + pbone = obj.pose.bones[bones['pelvis.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['thigh.R']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.segments = 2 + except AttributeError: + pass + pbone = obj.pose.bones[bones['pelvis']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.008']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shin.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shin.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.009']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['belly']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['foot.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['foot.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.010']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shoulder.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['breast.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shoulder.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['breast.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['chest']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_toe.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_toe.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.011']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['hair_base.05']] + pbone.rigify_type = 'limbs.super_finger' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + try: + pbone.rigify_parameters.primary_rotation_axis = "Z" + except AttributeError: + pass + pbone = obj.pose.bones[bones['upper_arm.L']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['upper_arm.R']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.012']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['hair_base.04']] + pbone.rigify_type = 'limbs.super_finger' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + try: + pbone.rigify_parameters.primary_rotation_axis = "Z" + except AttributeError: + pass + pbone = obj.pose.bones[bones['hair_top.05']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forearm.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forearm.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.014']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['hair_base.03']] + pbone.rigify_type = 'limbs.super_finger' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + try: + pbone.rigify_parameters.primary_rotation_axis = "Z" + except AttributeError: + pass + pbone = obj.pose.bones[bones['hair_top.04']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['hand.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['hand.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.015']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['hair_base.02']] + pbone.rigify_type = 'limbs.super_finger' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + try: + pbone.rigify_parameters.primary_rotation_axis = "Z" + except AttributeError: + pass + pbone = obj.pose.bones[bones['hair_top.03']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_toe.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_toe.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.016']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['hair_base.01']] + pbone.rigify_type = 'limbs.super_finger' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + try: + pbone.rigify_parameters.primary_rotation_axis = "Z" + except AttributeError: + pass + pbone = obj.pose.bones[bones['hair_base.06']] + pbone.rigify_type = 'limbs.super_finger' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + try: + pbone.rigify_parameters.primary_rotation_axis = "Z" + except AttributeError: + pass + pbone = obj.pose.bones[bones['hair_top.02']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.013']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['ear.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + pbone = obj.pose.bones[bones['ear.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + pbone = obj.pose.bones[bones['jaw']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + try: + pbone.rigify_parameters.copy_rotation_axes = [False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['hair_top.01']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['hair_top.06']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['skull.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['skull.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['ear.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['eye.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['eye.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + + bpy.ops.object.mode_set(mode='EDIT') + for bone in arm.edit_bones: + bone.select = False + bone.select_head = False + bone.select_tail = False + for b in bones: + bone = arm.edit_bones[bones[b]] + bone.select = True + bone.select_head = True + bone.select_tail = True + arm.edit_bones.active = bone + + arm.layers = [(x in [0, 3, 4, 7, 10, 13, 16, 19, 21]) for x in range(32)] + +if __name__ == "__main__": + create(bpy.context.active_object)
\ No newline at end of file diff --git a/rigify/metarigs/Animals/shark.py b/rigify/metarigs/Animals/shark.py new file mode 100644 index 00000000..dc3fb8bf --- /dev/null +++ b/rigify/metarigs/Animals/shark.py @@ -0,0 +1,794 @@ +import bpy + + +from mathutils import Color + + +def create(obj): + # generated by rigify.utils.write_metarig + bpy.ops.object.mode_set(mode='EDIT') + arm = obj.data + + for i in range(6): + arm.rigify_colors.add() + + arm.rigify_colors[0].name = "Root" + arm.rigify_colors[0].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[0].normal = Color((0.4352940022945404, 0.18431399762630463, 0.4156860113143921)) + arm.rigify_colors[0].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[0].standard_colors_lock = True + arm.rigify_colors[1].name = "IK" + arm.rigify_colors[1].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[1].normal = Color((0.6039220094680786, 0.0, 0.0)) + arm.rigify_colors[1].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[1].standard_colors_lock = True + arm.rigify_colors[2].name = "Specials" + arm.rigify_colors[2].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[2].normal = Color((0.9568629860877991, 0.7882350087165833, 0.04705899953842163)) + arm.rigify_colors[2].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[2].standard_colors_lock = True + arm.rigify_colors[3].name = "Tweak" + arm.rigify_colors[3].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[3].normal = Color((0.03921600058674812, 0.21176500618457794, 0.5803920030593872)) + arm.rigify_colors[3].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[3].standard_colors_lock = True + arm.rigify_colors[4].name = "FK" + arm.rigify_colors[4].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[4].normal = Color((0.11764699965715408, 0.5686269998550415, 0.035294000059366226)) + arm.rigify_colors[4].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[4].standard_colors_lock = True + arm.rigify_colors[5].name = "Extra" + arm.rigify_colors[5].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[5].normal = Color((0.9686279892921448, 0.2509799897670746, 0.09411799907684326)) + arm.rigify_colors[5].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[5].standard_colors_lock = True + + for i in range(29): + arm.rigify_layers.add() + + arm.rigify_layers[0].name = "Face" + arm.rigify_layers[0].row = 1 + arm.rigify_layers[0].set = False + arm.rigify_layers[0].group = 5 + arm.rigify_layers[1].name = "Face (Tweak)" + arm.rigify_layers[1].row = 2 + arm.rigify_layers[1].set = False + arm.rigify_layers[1].group = 4 + arm.rigify_layers[2].name = " " + arm.rigify_layers[2].row = 1 + arm.rigify_layers[2].set = False + arm.rigify_layers[2].group = 0 + arm.rigify_layers[3].name = "Spine" + arm.rigify_layers[3].row = 3 + arm.rigify_layers[3].set = False + arm.rigify_layers[3].group = 3 + arm.rigify_layers[4].name = "Spine (Tweak)" + arm.rigify_layers[4].row = 4 + arm.rigify_layers[4].set = False + arm.rigify_layers[4].group = 4 + arm.rigify_layers[5].name = "Tail" + arm.rigify_layers[5].row = 5 + arm.rigify_layers[5].set = False + arm.rigify_layers[5].group = 6 + arm.rigify_layers[6].name = "Fins.L" + arm.rigify_layers[6].row = 6 + arm.rigify_layers[6].set = False + arm.rigify_layers[6].group = 5 + arm.rigify_layers[7].name = "Fins.L (Tweak)" + arm.rigify_layers[7].row = 7 + arm.rigify_layers[7].set = False + arm.rigify_layers[7].group = 4 + arm.rigify_layers[8].name = "Fins.R" + arm.rigify_layers[8].row = 6 + arm.rigify_layers[8].set = False + arm.rigify_layers[8].group = 5 + arm.rigify_layers[9].name = "Fins.R (Tweak)" + arm.rigify_layers[9].row = 7 + arm.rigify_layers[9].set = False + arm.rigify_layers[9].group = 4 + arm.rigify_layers[10].name = "Fins" + arm.rigify_layers[10].row = 8 + arm.rigify_layers[10].set = False + arm.rigify_layers[10].group = 3 + arm.rigify_layers[11].name = "Fins (Tweak)" + arm.rigify_layers[11].row = 9 + arm.rigify_layers[11].set = False + arm.rigify_layers[11].group = 4 + arm.rigify_layers[12].name = " " + arm.rigify_layers[12].row = 1 + arm.rigify_layers[12].set = False + arm.rigify_layers[12].group = 0 + arm.rigify_layers[13].name = " " + arm.rigify_layers[13].row = 1 + arm.rigify_layers[13].set = False + arm.rigify_layers[13].group = 6 + arm.rigify_layers[14].name = " " + arm.rigify_layers[14].row = 1 + arm.rigify_layers[14].set = False + arm.rigify_layers[14].group = 0 + arm.rigify_layers[15].name = " " + arm.rigify_layers[15].row = 1 + arm.rigify_layers[15].set = False + arm.rigify_layers[15].group = 0 + arm.rigify_layers[16].name = " " + arm.rigify_layers[16].row = 1 + arm.rigify_layers[16].set = False + arm.rigify_layers[16].group = 0 + arm.rigify_layers[17].name = " " + arm.rigify_layers[17].row = 1 + arm.rigify_layers[17].set = False + arm.rigify_layers[17].group = 0 + arm.rigify_layers[18].name = " " + arm.rigify_layers[18].row = 1 + arm.rigify_layers[18].set = False + arm.rigify_layers[18].group = 0 + arm.rigify_layers[19].name = " " + arm.rigify_layers[19].row = 1 + arm.rigify_layers[19].set = False + arm.rigify_layers[19].group = 0 + arm.rigify_layers[20].name = " " + arm.rigify_layers[20].row = 1 + arm.rigify_layers[20].set = False + arm.rigify_layers[20].group = 0 + arm.rigify_layers[21].name = " " + arm.rigify_layers[21].row = 1 + arm.rigify_layers[21].set = False + arm.rigify_layers[21].group = 0 + arm.rigify_layers[22].name = " " + arm.rigify_layers[22].row = 1 + arm.rigify_layers[22].set = False + arm.rigify_layers[22].group = 0 + arm.rigify_layers[23].name = " " + arm.rigify_layers[23].row = 1 + arm.rigify_layers[23].set = False + arm.rigify_layers[23].group = 0 + arm.rigify_layers[24].name = " " + arm.rigify_layers[24].row = 1 + arm.rigify_layers[24].set = False + arm.rigify_layers[24].group = 0 + arm.rigify_layers[25].name = " " + arm.rigify_layers[25].row = 1 + arm.rigify_layers[25].set = False + arm.rigify_layers[25].group = 0 + arm.rigify_layers[26].name = " " + arm.rigify_layers[26].row = 1 + arm.rigify_layers[26].set = False + arm.rigify_layers[26].group = 0 + arm.rigify_layers[27].name = " " + arm.rigify_layers[27].row = 1 + arm.rigify_layers[27].set = False + arm.rigify_layers[27].group = 0 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 14 + arm.rigify_layers[28].set = False + arm.rigify_layers[28].group = 1 + + bones = {} + + bone = arm.edit_bones.new('spine') + bone.head[:] = -0.0000, 1.3362, 0.4776 + bone.tail[:] = -0.0000, 1.0816, 0.4540 + bone.roll = 0.0000 + bone.use_connect = False + bones['spine'] = bone.name + bone = arm.edit_bones.new('spine.001') + bone.head[:] = -0.0000, 1.0816, 0.4540 + bone.tail[:] = -0.0000, 0.7152, 0.4305 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine']] + bones['spine.001'] = bone.name + bone = arm.edit_bones.new('back_fin.T.Bk') + bone.head[:] = 0.0000, 1.2501, 0.5345 + bone.tail[:] = 0.0000, 1.5211, 0.7594 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['back_fin.T.Bk'] = bone.name + bone = arm.edit_bones.new('back_fin.B.Bk') + bone.head[:] = 0.0000, 1.2305, 0.4158 + bone.tail[:] = 0.0000, 1.3289, 0.2452 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['back_fin.B.Bk'] = bone.name + bone = arm.edit_bones.new('spine.002') + bone.head[:] = -0.0000, 0.7152, 0.4305 + bone.tail[:] = -0.0000, 0.3182, 0.4031 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.001']] + bones['spine.002'] = bone.name + bone = arm.edit_bones.new('mid_fin.Top') + bone.head[:] = 0.0000, 0.7296, 0.5396 + bone.tail[:] = 0.0000, 0.7709, 0.6351 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.001']] + bones['mid_fin.Top'] = bone.name + bone = arm.edit_bones.new('mid_fin.Bot') + bone.head[:] = 0.0000, 0.7296, 0.3505 + bone.tail[:] = 0.0000, 0.8233, 0.2684 + bone.roll = 1.5708 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.001']] + bones['mid_fin.Bot'] = bone.name + bone = arm.edit_bones.new('back_fin.T.001.Bk') + bone.head[:] = 0.0000, 1.5211, 0.7594 + bone.tail[:] = 0.0000, 1.7667, 0.9633 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['back_fin.T.Bk']] + bones['back_fin.T.001.Bk'] = bone.name + bone = arm.edit_bones.new('back_fin.B.001.Bk') + bone.head[:] = 0.0000, 1.3289, 0.2452 + bone.tail[:] = 0.0000, 1.3818, 0.1513 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['back_fin.B.Bk']] + bones['back_fin.B.001.Bk'] = bone.name + bone = arm.edit_bones.new('spine.003') + bone.head[:] = -0.0000, 0.3182, 0.4031 + bone.tail[:] = -0.0000, 0.0152, 0.3904 + bone.roll = 0.0001 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.002']] + bones['spine.003'] = bone.name + bone = arm.edit_bones.new('back_fin.T.002.Bk') + bone.head[:] = 0.0000, 1.7667, 0.9633 + bone.tail[:] = 0.0000, 1.9489, 1.1145 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['back_fin.T.001.Bk']] + bones['back_fin.T.002.Bk'] = bone.name + bone = arm.edit_bones.new('spine.008') + bone.head[:] = -0.0000, 0.0152, 0.3904 + bone.tail[:] = 0.0000, -0.3259, 0.3967 + bone.roll = 0.0001 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.003']] + bones['spine.008'] = bone.name + bone = arm.edit_bones.new('spine.004') + bone.head[:] = 0.0000, -0.3259, 0.3967 + bone.tail[:] = 0.0000, -0.5947, 0.4044 + bone.roll = -0.0001 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.008']] + bones['spine.004'] = bone.name + bone = arm.edit_bones.new('chest_fin.Bot.L') + bone.head[:] = 0.0889, 0.2605, 0.2866 + bone.tail[:] = 0.1731, 0.3299, 0.1901 + bone.roll = -2.3171 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.008']] + bones['chest_fin.Bot.L'] = bone.name + bone = arm.edit_bones.new('chest_fin.Bot.R') + bone.head[:] = -0.0889, 0.2605, 0.2866 + bone.tail[:] = -0.1731, 0.3299, 0.1901 + bone.roll = 2.3171 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.008']] + bones['chest_fin.Bot.R'] = bone.name + bone = arm.edit_bones.new('spine.005') + bone.head[:] = 0.0000, -0.5947, 0.4044 + bone.tail[:] = 0.0000, -1.2084, 0.4328 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.004']] + bones['spine.005'] = bone.name + bone = arm.edit_bones.new('top_fin') + bone.head[:] = 0.0000, -0.2777, 0.5550 + bone.tail[:] = 0.0000, -0.1962, 0.7053 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.004']] + bones['top_fin'] = bone.name + bone = arm.edit_bones.new('spine.006') + bone.head[:] = 0.0000, -1.2084, 0.4328 + bone.tail[:] = 0.0000, -1.5634, 0.4275 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.005']] + bones['spine.006'] = bone.name + bone = arm.edit_bones.new('shoulder.L') + bone.head[:] = 0.0729, -0.9648, 0.3756 + bone.tail[:] = 0.2649, -0.9648, 0.3157 + bone.roll = 3.4558 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['shoulder.L'] = bone.name + bone = arm.edit_bones.new('shoulder.R') + bone.head[:] = -0.0729, -0.9648, 0.3756 + bone.tail[:] = -0.2649, -0.9648, 0.3157 + bone.roll = -3.4558 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['shoulder.R'] = bone.name + bone = arm.edit_bones.new('top_fin.001') + bone.head[:] = 0.0000, -0.1962, 0.7053 + bone.tail[:] = 0.0000, -0.1362, 0.8158 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['top_fin']] + bones['top_fin.001'] = bone.name + bone = arm.edit_bones.new('spine.007') + bone.head[:] = 0.0000, -1.5634, 0.4275 + bone.tail[:] = 0.0000, -2.0661, 0.4364 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.006']] + bones['spine.007'] = bone.name + bone = arm.edit_bones.new('side_fin.L') + bone.head[:] = 0.2140, -0.9624, 0.2213 + bone.tail[:] = 0.5220, -0.9078, -0.1343 + bone.roll = -2.3170 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.L']] + bones['side_fin.L'] = bone.name + bone = arm.edit_bones.new('side_fin.R') + bone.head[:] = -0.2140, -0.9624, 0.2213 + bone.tail[:] = -0.5220, -0.9078, -0.1343 + bone.roll = 2.3170 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.R']] + bones['side_fin.R'] = bone.name + bone = arm.edit_bones.new('eye.L') + bone.head[:] = 0.1405, -1.6860, 0.4161 + bone.tail[:] = 0.3684, -1.6810, 0.4156 + bone.roll = 3.1352 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.007']] + bones['eye.L'] = bone.name + bone = arm.edit_bones.new('eye.R') + bone.head[:] = -0.1405, -1.6860, 0.4161 + bone.tail[:] = -0.3684, -1.6810, 0.4156 + bone.roll = -3.1352 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.007']] + bones['eye.R'] = bone.name + bone = arm.edit_bones.new('jaw.master') + bone.head[:] = -0.0000, -1.5791, 0.2788 + bone.tail[:] = 0.0000, -1.9421, 0.3386 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.007']] + bones['jaw.master'] = bone.name + bone = arm.edit_bones.new('side_fin.L.001') + bone.head[:] = 0.5220, -0.9078, -0.1343 + bone.tail[:] = 0.7928, -0.7598, -0.4802 + bone.roll = -2.2826 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['side_fin.L']] + bones['side_fin.L.001'] = bone.name + bone = arm.edit_bones.new('side_fin.R.001') + bone.head[:] = -0.5220, -0.9078, -0.1343 + bone.tail[:] = -0.7928, -0.7598, -0.4802 + bone.roll = 2.2826 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['side_fin.R']] + bones['side_fin.R.001'] = bone.name + bone = arm.edit_bones.new('jaw') + bone.head[:] = -0.0000, -1.5791, 0.2788 + bone.tail[:] = 0.0000, -1.7326, 0.3041 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['jaw.master']] + bones['jaw'] = bone.name + bone = arm.edit_bones.new('jaw.002.L') + bone.head[:] = 0.0891, -1.5791, 0.2894 + bone.tail[:] = 0.1110, -1.7198, 0.3129 + bone.roll = 1.4894 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['jaw.master']] + bones['jaw.002.L'] = bone.name + bone = arm.edit_bones.new('jaw.002.R') + bone.head[:] = -0.0891, -1.5791, 0.2894 + bone.tail[:] = -0.1110, -1.7198, 0.3129 + bone.roll = -1.4894 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['jaw.master']] + bones['jaw.002.R'] = bone.name + bone = arm.edit_bones.new('jaw.001') + bone.head[:] = 0.0000, -1.7326, 0.3041 + bone.tail[:] = 0.0000, -1.8860, 0.3294 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw']] + bones['jaw.001'] = bone.name + bone = arm.edit_bones.new('jaw.003.L') + bone.head[:] = 0.1110, -1.7198, 0.3129 + bone.tail[:] = 0.1260, -1.8159, 0.3326 + bone.roll = 1.2807 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.002.L']] + bones['jaw.003.L'] = bone.name + bone = arm.edit_bones.new('jaw.003.R') + bone.head[:] = -0.1110, -1.7198, 0.3129 + bone.tail[:] = -0.1260, -1.8159, 0.3326 + bone.roll = -1.2807 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.002.R']] + bones['jaw.003.R'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['spine']] + pbone.rigify_type = 'spines.super_spine' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.neck_pos = 8 + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tail_pos = 3 + except AttributeError: + pass + try: + pbone.rigify_parameters.pivot_pos = 5 + except AttributeError: + pass + try: + pbone.rigify_parameters.use_tail = True + except AttributeError: + pass + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['back_fin.T.Bk']] + pbone.rigify_type = 'limbs.super_finger' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.primary_rotation_axis = "Z" + except AttributeError: + pass + pbone = obj.pose.bones[bones['back_fin.B.Bk']] + pbone.rigify_type = 'limbs.super_finger' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.primary_rotation_axis = "Z" + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['mid_fin.Top']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['mid_fin.Bot']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['back_fin.T.001.Bk']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['back_fin.B.001.Bk']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['back_fin.T.002.Bk']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.008']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['chest_fin.Bot.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['chest_fin.Bot.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.005']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['top_fin']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.006']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shoulder.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['shoulder.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['top_fin.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.007']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['side_fin.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['side_fin.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['eye.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['eye.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.master']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + try: + pbone.rigify_parameters.make_deform = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['side_fin.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['side_fin.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.002.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.002.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.003.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.003.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + + bpy.ops.object.mode_set(mode='EDIT') + for bone in arm.edit_bones: + bone.select = False + bone.select_head = False + bone.select_tail = False + for b in bones: + bone = arm.edit_bones[bones[b]] + bone.select = True + bone.select_head = True + bone.select_tail = True + arm.edit_bones.active = bone + + arm.layers = [(x in [0, 3, 5, 6, 8, 10]) for x in range(32)] + +if __name__ == "__main__": + create(bpy.context.active_object)
\ No newline at end of file diff --git a/rigify/metarigs/Animals/wolf.py b/rigify/metarigs/Animals/wolf.py new file mode 100644 index 00000000..26c02d77 --- /dev/null +++ b/rigify/metarigs/Animals/wolf.py @@ -0,0 +1,3227 @@ +import bpy + + +from mathutils import Color + + +def create(obj): + # generated by rigify.utils.write_metarig + bpy.ops.object.mode_set(mode='EDIT') + arm = obj.data + + for i in range(6): + arm.rigify_colors.add() + + arm.rigify_colors[0].name = "Root" + arm.rigify_colors[0].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[0].normal = Color((0.4352940022945404, 0.18431399762630463, 0.4156860113143921)) + arm.rigify_colors[0].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[0].standard_colors_lock = True + arm.rigify_colors[1].name = "IK" + arm.rigify_colors[1].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[1].normal = Color((0.6039220094680786, 0.0, 0.0)) + arm.rigify_colors[1].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[1].standard_colors_lock = True + arm.rigify_colors[2].name = "Special" + arm.rigify_colors[2].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[2].normal = Color((0.9568629860877991, 0.7882350087165833, 0.04705899953842163)) + arm.rigify_colors[2].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[2].standard_colors_lock = True + arm.rigify_colors[3].name = "Tweak" + arm.rigify_colors[3].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[3].normal = Color((0.03921600058674812, 0.21176500618457794, 0.5803920030593872)) + arm.rigify_colors[3].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[3].standard_colors_lock = True + arm.rigify_colors[4].name = "FK" + arm.rigify_colors[4].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[4].normal = Color((0.11764699965715408, 0.5686269998550415, 0.035294000059366226)) + arm.rigify_colors[4].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[4].standard_colors_lock = True + arm.rigify_colors[5].name = "Extra" + arm.rigify_colors[5].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[5].normal = Color((0.9686279892921448, 0.2509799897670746, 0.09411799907684326)) + arm.rigify_colors[5].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[5].standard_colors_lock = True + + for i in range(29): + arm.rigify_layers.add() + + arm.rigify_layers[0].name = "Face" + arm.rigify_layers[0].row = 1 + arm.rigify_layers[0].set = False + arm.rigify_layers[0].group = 5 + arm.rigify_layers[1].name = "Face (Primary)" + arm.rigify_layers[1].row = 2 + arm.rigify_layers[1].set = False + arm.rigify_layers[1].group = 2 + arm.rigify_layers[2].name = "Face (Secondary)" + arm.rigify_layers[2].row = 2 + arm.rigify_layers[2].set = False + arm.rigify_layers[2].group = 3 + arm.rigify_layers[3].name = "Spine" + arm.rigify_layers[3].row = 3 + arm.rigify_layers[3].set = False + arm.rigify_layers[3].group = 3 + arm.rigify_layers[4].name = "Spine (Tweak)" + arm.rigify_layers[4].row = 4 + arm.rigify_layers[4].set = False + arm.rigify_layers[4].group = 4 + arm.rigify_layers[5].name = "Paws" + arm.rigify_layers[5].row = 5 + arm.rigify_layers[5].set = False + arm.rigify_layers[5].group = 6 + arm.rigify_layers[6].name = "Paws (Tweak)" + arm.rigify_layers[6].row = 6 + arm.rigify_layers[6].set = False + arm.rigify_layers[6].group = 4 + arm.rigify_layers[7].name = "Arm.L (IK)" + arm.rigify_layers[7].row = 7 + arm.rigify_layers[7].set = False + arm.rigify_layers[7].group = 2 + arm.rigify_layers[8].name = "Arm.L (FK)" + arm.rigify_layers[8].row = 8 + arm.rigify_layers[8].set = False + arm.rigify_layers[8].group = 5 + arm.rigify_layers[9].name = "Arm.L (Tweak)" + arm.rigify_layers[9].row = 9 + arm.rigify_layers[9].set = False + arm.rigify_layers[9].group = 4 + arm.rigify_layers[10].name = "Arm.R (IK)" + arm.rigify_layers[10].row = 7 + arm.rigify_layers[10].set = False + arm.rigify_layers[10].group = 2 + arm.rigify_layers[11].name = "Arm.R (FK)" + arm.rigify_layers[11].row = 8 + arm.rigify_layers[11].set = False + arm.rigify_layers[11].group = 5 + arm.rigify_layers[12].name = "Arm.R (Tweak)" + arm.rigify_layers[12].row = 9 + arm.rigify_layers[12].set = False + arm.rigify_layers[12].group = 4 + arm.rigify_layers[13].name = "Leg.L (IK)" + arm.rigify_layers[13].row = 10 + arm.rigify_layers[13].set = False + arm.rigify_layers[13].group = 2 + arm.rigify_layers[14].name = "Leg.L (FK)" + arm.rigify_layers[14].row = 11 + arm.rigify_layers[14].set = False + arm.rigify_layers[14].group = 5 + arm.rigify_layers[15].name = "Leg.L (Tweak)" + arm.rigify_layers[15].row = 12 + arm.rigify_layers[15].set = False + arm.rigify_layers[15].group = 4 + arm.rigify_layers[16].name = "Leg.R (IK)" + arm.rigify_layers[16].row = 10 + arm.rigify_layers[16].set = False + arm.rigify_layers[16].group = 2 + arm.rigify_layers[17].name = "Leg.R (FK)" + arm.rigify_layers[17].row = 11 + arm.rigify_layers[17].set = False + arm.rigify_layers[17].group = 5 + arm.rigify_layers[18].name = "Leg.R (Tweak)" + arm.rigify_layers[18].row = 12 + arm.rigify_layers[18].set = False + arm.rigify_layers[18].group = 4 + arm.rigify_layers[19].name = "Tail" + arm.rigify_layers[19].row = 13 + arm.rigify_layers[19].set = False + arm.rigify_layers[19].group = 6 + arm.rigify_layers[20].name = "" + arm.rigify_layers[20].row = 1 + arm.rigify_layers[20].set = False + arm.rigify_layers[20].group = 0 + arm.rigify_layers[21].name = "" + arm.rigify_layers[21].row = 13 + arm.rigify_layers[21].set = False + arm.rigify_layers[21].group = 0 + arm.rigify_layers[22].name = "" + arm.rigify_layers[22].row = 13 + arm.rigify_layers[22].set = False + arm.rigify_layers[22].group = 0 + arm.rigify_layers[23].name = "" + arm.rigify_layers[23].row = 1 + arm.rigify_layers[23].set = False + arm.rigify_layers[23].group = 0 + arm.rigify_layers[24].name = "" + arm.rigify_layers[24].row = 1 + arm.rigify_layers[24].set = False + arm.rigify_layers[24].group = 0 + arm.rigify_layers[25].name = "" + arm.rigify_layers[25].row = 1 + arm.rigify_layers[25].set = False + arm.rigify_layers[25].group = 0 + arm.rigify_layers[26].name = "" + arm.rigify_layers[26].row = 1 + arm.rigify_layers[26].set = False + arm.rigify_layers[26].group = 0 + arm.rigify_layers[27].name = "" + arm.rigify_layers[27].row = 1 + arm.rigify_layers[27].set = False + arm.rigify_layers[27].group = 0 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 14 + arm.rigify_layers[28].set = False + arm.rigify_layers[28].group = 1 + + bones = {} + + bone = arm.edit_bones.new('spine') + bone.head[:] = 0.0000, 1.1044, 0.7633 + bone.tail[:] = 0.0000, 0.9624, 0.7412 + bone.roll = 0.0000 + bone.use_connect = False + bones['spine'] = bone.name + bone = arm.edit_bones.new('spine.001') + bone.head[:] = 0.0000, 0.9624, 0.7412 + bone.tail[:] = 0.0000, 0.7755, 0.7418 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine']] + bones['spine.001'] = bone.name + bone = arm.edit_bones.new('spine.002') + bone.head[:] = 0.0000, 0.7755, 0.7418 + bone.tail[:] = 0.0000, 0.5547, 0.7568 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.001']] + bones['spine.002'] = bone.name + bone = arm.edit_bones.new('spine.003') + bone.head[:] = 0.0000, 0.5547, 0.7568 + bone.tail[:] = 0.0000, 0.4418, 0.7954 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.002']] + bones['spine.003'] = bone.name + bone = arm.edit_bones.new('spine.004') + bone.head[:] = 0.0000, 0.4418, 0.7954 + bone.tail[:] = 0.0000, 0.3546, 0.8059 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.003']] + bones['spine.004'] = bone.name + bone = arm.edit_bones.new('spine.005') + bone.head[:] = 0.0000, 0.3546, 0.8059 + bone.tail[:] = 0.0000, 0.1803, 0.7782 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.004']] + bones['spine.005'] = bone.name + bone = arm.edit_bones.new('spine.006') + bone.head[:] = 0.0000, 0.1803, 0.7782 + bone.tail[:] = 0.0000, 0.0319, 0.7731 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.005']] + bones['spine.006'] = bone.name + bone = arm.edit_bones.new('pelvis.L') + bone.head[:] = 0.0000, 0.3757, 0.6043 + bone.tail[:] = 0.0751, 0.2755, 0.8544 + bone.roll = -1.5841 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['pelvis.L'] = bone.name + bone = arm.edit_bones.new('pelvis.R') + bone.head[:] = -0.0000, 0.3757, 0.6043 + bone.tail[:] = -0.0751, 0.2755, 0.8544 + bone.roll = 1.5841 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['pelvis.R'] = bone.name + bone = arm.edit_bones.new('thigh.L') + bone.head[:] = 0.1249, 0.3419, 0.7379 + bone.tail[:] = 0.1249, 0.2712, 0.4731 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['thigh.L'] = bone.name + bone = arm.edit_bones.new('thigh.R') + bone.head[:] = -0.1249, 0.3419, 0.7379 + bone.tail[:] = -0.1249, 0.2712, 0.4731 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['thigh.R'] = bone.name + bone = arm.edit_bones.new('spine.007') + bone.head[:] = 0.0000, 0.0319, 0.7731 + bone.tail[:] = 0.0000, -0.0980, 0.7945 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.006']] + bones['spine.007'] = bone.name + bone = arm.edit_bones.new('shin.L') + bone.head[:] = 0.1249, 0.2712, 0.4731 + bone.tail[:] = 0.1114, 0.4766, 0.2473 + bone.roll = 0.0195 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.L']] + bones['shin.L'] = bone.name + bone = arm.edit_bones.new('shin.R') + bone.head[:] = -0.1249, 0.2712, 0.4731 + bone.tail[:] = -0.1114, 0.4766, 0.2473 + bone.roll = -0.0195 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.R']] + bones['shin.R'] = bone.name + bone = arm.edit_bones.new('spine.008') + bone.head[:] = 0.0000, -0.0980, 0.7945 + bone.tail[:] = 0.0000, -0.3618, 0.8375 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.007']] + bones['spine.008'] = bone.name + bone = arm.edit_bones.new('foot.L') + bone.head[:] = 0.1114, 0.4766, 0.2473 + bone.tail[:] = 0.1088, 0.4138, 0.0411 + bone.roll = 0.0165 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.L']] + bones['foot.L'] = bone.name + bone = arm.edit_bones.new('foot.R') + bone.head[:] = -0.1114, 0.4766, 0.2473 + bone.tail[:] = -0.1088, 0.4138, 0.0411 + bone.roll = -0.0165 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.R']] + bones['foot.R'] = bone.name + bone = arm.edit_bones.new('spine.009') + bone.head[:] = 0.0000, -0.3618, 0.8375 + bone.tail[:] = 0.0000, -0.4253, 0.8585 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.008']] + bones['spine.009'] = bone.name + bone = arm.edit_bones.new('shoulder.L') + bone.head[:] = 0.0596, -0.2578, 0.8876 + bone.tail[:] = 0.1249, -0.3418, 0.7153 + bone.roll = -0.3526 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.008']] + bones['shoulder.L'] = bone.name + bone = arm.edit_bones.new('shoulder.R') + bone.head[:] = -0.0596, -0.2578, 0.8876 + bone.tail[:] = -0.1249, -0.3418, 0.7153 + bone.roll = 0.3526 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.008']] + bones['shoulder.R'] = bone.name + bone = arm.edit_bones.new('breast.L') + bone.head[:] = 0.0340, -0.1694, 0.6676 + bone.tail[:] = 0.0340, -0.3139, 0.5296 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.008']] + bones['breast.L'] = bone.name + bone = arm.edit_bones.new('breast.R') + bone.head[:] = -0.0340, -0.1694, 0.6676 + bone.tail[:] = -0.0340, -0.3139, 0.5296 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.008']] + bones['breast.R'] = bone.name + bone = arm.edit_bones.new('toe.L') + bone.head[:] = 0.1088, 0.4138, 0.0411 + bone.tail[:] = 0.1088, 0.2808, 0.0000 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.L']] + bones['toe.L'] = bone.name + bone = arm.edit_bones.new('toe.R') + bone.head[:] = -0.1088, 0.4138, 0.0411 + bone.tail[:] = -0.1088, 0.2808, 0.0000 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.R']] + bones['toe.R'] = bone.name + bone = arm.edit_bones.new('spine.010') + bone.head[:] = 0.0000, -0.4253, 0.8585 + bone.tail[:] = 0.0000, -0.4888, 0.8796 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.009']] + bones['spine.010'] = bone.name + bone = arm.edit_bones.new('front_thigh.L') + bone.head[:] = 0.1249, -0.3161, 0.6902 + bone.tail[:] = 0.1249, -0.2245, 0.4418 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.L']] + bones['front_thigh.L'] = bone.name + bone = arm.edit_bones.new('front_thigh.R') + bone.head[:] = -0.1249, -0.3161, 0.6902 + bone.tail[:] = -0.1249, -0.2245, 0.4418 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.R']] + bones['front_thigh.R'] = bone.name + bone = arm.edit_bones.new('r_palm.04.L') + bone.head[:] = 0.1140, 0.4168, 0.0282 + bone.tail[:] = 0.1337, 0.3749, 0.0253 + bone.roll = -2.8623 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.L']] + bones['r_palm.04.L'] = bone.name + bone = arm.edit_bones.new('r_palm.03.L') + bone.head[:] = 0.1053, 0.4151, 0.0282 + bone.tail[:] = 0.1150, 0.3664, 0.0377 + bone.roll = 1.5833 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.L']] + bones['r_palm.03.L'] = bone.name + bone = arm.edit_bones.new('r_palm.02.L') + bone.head[:] = 0.0964, 0.4152, 0.0282 + bone.tail[:] = 0.0894, 0.3664, 0.0377 + bone.roll = -1.2317 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.L']] + bones['r_palm.02.L'] = bone.name + bone = arm.edit_bones.new('r_palm.01.L') + bone.head[:] = 0.0845, 0.4178, 0.0282 + bone.tail[:] = 0.0702, 0.3781, 0.0253 + bone.roll = 2.8333 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.L']] + bones['r_palm.01.L'] = bone.name + bone = arm.edit_bones.new('r_palm.04.R') + bone.head[:] = -0.1140, 0.4168, 0.0282 + bone.tail[:] = -0.1337, 0.3749, 0.0253 + bone.roll = 2.8623 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.R']] + bones['r_palm.04.R'] = bone.name + bone = arm.edit_bones.new('r_palm.03.R') + bone.head[:] = -0.1053, 0.4151, 0.0282 + bone.tail[:] = -0.1150, 0.3664, 0.0377 + bone.roll = -1.5833 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.R']] + bones['r_palm.03.R'] = bone.name + bone = arm.edit_bones.new('r_palm.02.R') + bone.head[:] = -0.0964, 0.4152, 0.0282 + bone.tail[:] = -0.0894, 0.3664, 0.0377 + bone.roll = 1.2317 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.R']] + bones['r_palm.02.R'] = bone.name + bone = arm.edit_bones.new('r_palm.01.R') + bone.head[:] = -0.0845, 0.4178, 0.0282 + bone.tail[:] = -0.0702, 0.3781, 0.0253 + bone.roll = -2.8333 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['toe.R']] + bones['r_palm.01.R'] = bone.name + bone = arm.edit_bones.new('spine.011') + bone.head[:] = 0.0000, -0.4888, 0.8796 + bone.tail[:] = 0.0000, -0.6590, 0.9809 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.010']] + bones['spine.011'] = bone.name + bone = arm.edit_bones.new('front_shin.L') + bone.head[:] = 0.1249, -0.2245, 0.4418 + bone.tail[:] = 0.1114, -0.2147, 0.1698 + bone.roll = 0.0098 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_thigh.L']] + bones['front_shin.L'] = bone.name + bone = arm.edit_bones.new('front_shin.R') + bone.head[:] = -0.1249, -0.2245, 0.4418 + bone.tail[:] = -0.1114, -0.2147, 0.1698 + bone.roll = -0.0098 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_thigh.R']] + bones['front_shin.R'] = bone.name + bone = arm.edit_bones.new('r_pinky.01.L') + bone.head[:] = 0.1337, 0.3749, 0.0253 + bone.tail[:] = 0.1388, 0.3551, 0.0222 + bone.roll = -2.0928 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.04.L']] + bones['r_pinky.01.L'] = bone.name + bone = arm.edit_bones.new('r_ring.01.L') + bone.head[:] = 0.1150, 0.3664, 0.0377 + bone.tail[:] = 0.1166, 0.3467, 0.0317 + bone.roll = -0.5451 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.03.L']] + bones['r_ring.01.L'] = bone.name + bone = arm.edit_bones.new('r_middle.01.L') + bone.head[:] = 0.0894, 0.3664, 0.0377 + bone.tail[:] = 0.0866, 0.3467, 0.0317 + bone.roll = 0.9401 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.02.L']] + bones['r_middle.01.L'] = bone.name + bone = arm.edit_bones.new('r_index.01.L') + bone.head[:] = 0.0702, 0.3781, 0.0253 + bone.tail[:] = 0.0660, 0.3581, 0.0222 + bone.roll = 1.9945 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.01.L']] + bones['r_index.01.L'] = bone.name + bone = arm.edit_bones.new('r_pinky.01.R') + bone.head[:] = -0.1337, 0.3749, 0.0253 + bone.tail[:] = -0.1388, 0.3551, 0.0222 + bone.roll = 2.0928 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.04.R']] + bones['r_pinky.01.R'] = bone.name + bone = arm.edit_bones.new('r_ring.01.R') + bone.head[:] = -0.1150, 0.3664, 0.0377 + bone.tail[:] = -0.1166, 0.3467, 0.0317 + bone.roll = 0.5451 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.03.R']] + bones['r_ring.01.R'] = bone.name + bone = arm.edit_bones.new('r_middle.01.R') + bone.head[:] = -0.0894, 0.3664, 0.0377 + bone.tail[:] = -0.0866, 0.3467, 0.0317 + bone.roll = -0.9401 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.02.R']] + bones['r_middle.01.R'] = bone.name + bone = arm.edit_bones.new('r_index.01.R') + bone.head[:] = -0.0702, 0.3781, 0.0253 + bone.tail[:] = -0.0660, 0.3581, 0.0222 + bone.roll = -1.9945 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.01.R']] + bones['r_index.01.R'] = bone.name + bone = arm.edit_bones.new('face') + bone.head[:] = -0.0000, -0.6484, 0.8273 + bone.tail[:] = -0.0000, -0.6484, 0.8890 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.011']] + bones['face'] = bone.name + bone = arm.edit_bones.new('front_foot.L') + bone.head[:] = 0.1114, -0.2147, 0.1698 + bone.tail[:] = 0.1088, -0.2462, 0.0411 + bone.roll = 0.0272 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_shin.L']] + bones['front_foot.L'] = bone.name + bone = arm.edit_bones.new('front_foot.R') + bone.head[:] = -0.1114, -0.2147, 0.1698 + bone.tail[:] = -0.1088, -0.2462, 0.0411 + bone.roll = -0.0272 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_shin.R']] + bones['front_foot.R'] = bone.name + bone = arm.edit_bones.new('r_pinky.02.L') + bone.head[:] = 0.1388, 0.3551, 0.0222 + bone.tail[:] = 0.1431, 0.3382, 0.0170 + bone.roll = -1.4292 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_pinky.01.L']] + bones['r_pinky.02.L'] = bone.name + bone = arm.edit_bones.new('r_ring.02.L') + bone.head[:] = 0.1166, 0.3467, 0.0317 + bone.tail[:] = 0.1188, 0.3297, 0.0224 + bone.roll = -0.5100 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_ring.01.L']] + bones['r_ring.02.L'] = bone.name + bone = arm.edit_bones.new('r_middle.02.L') + bone.head[:] = 0.0866, 0.3467, 0.0317 + bone.tail[:] = 0.0851, 0.3297, 0.0224 + bone.roll = 0.4076 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_middle.01.L']] + bones['r_middle.02.L'] = bone.name + bone = arm.edit_bones.new('r_index.02.L') + bone.head[:] = 0.0660, 0.3581, 0.0222 + bone.tail[:] = 0.0623, 0.3410, 0.0170 + bone.roll = 1.3847 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_index.01.L']] + bones['r_index.02.L'] = bone.name + bone = arm.edit_bones.new('r_pinky.02.R') + bone.head[:] = -0.1388, 0.3551, 0.0222 + bone.tail[:] = -0.1431, 0.3382, 0.0170 + bone.roll = 1.4292 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_pinky.01.R']] + bones['r_pinky.02.R'] = bone.name + bone = arm.edit_bones.new('r_ring.02.R') + bone.head[:] = -0.1166, 0.3467, 0.0317 + bone.tail[:] = -0.1188, 0.3297, 0.0224 + bone.roll = 0.5100 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_ring.01.R']] + bones['r_ring.02.R'] = bone.name + bone = arm.edit_bones.new('r_middle.02.R') + bone.head[:] = -0.0866, 0.3467, 0.0317 + bone.tail[:] = -0.0851, 0.3297, 0.0224 + bone.roll = -0.4076 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_middle.01.R']] + bones['r_middle.02.R'] = bone.name + bone = arm.edit_bones.new('r_index.02.R') + bone.head[:] = -0.0660, 0.3581, 0.0222 + bone.tail[:] = -0.0623, 0.3410, 0.0170 + bone.roll = -1.3847 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_index.01.R']] + bones['r_index.02.R'] = bone.name + bone = arm.edit_bones.new('nose') + bone.head[:] = 0.0000, -0.7082, 0.9031 + bone.tail[:] = 0.0000, -0.7989, 0.8595 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['nose'] = bone.name + bone = arm.edit_bones.new('lip.T.L') + bone.head[:] = 0.0000, -0.8212, 0.7930 + bone.tail[:] = 0.0353, -0.7614, 0.7866 + bone.roll = 0.0551 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.T.L'] = bone.name + bone = arm.edit_bones.new('lip.B.L') + bone.head[:] = 0.0000, -0.7962, 0.7788 + bone.tail[:] = 0.0258, -0.7624, 0.7742 + bone.roll = 0.0255 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.B.L'] = bone.name + bone = arm.edit_bones.new('jaw') + bone.head[:] = 0.0000, -0.6191, 0.7820 + bone.tail[:] = 0.0000, -0.6960, 0.7733 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['jaw'] = bone.name + bone = arm.edit_bones.new('ear.L') + bone.head[:] = 0.0949, -0.5457, 0.9545 + bone.tail[:] = 0.0524, -0.5459, 0.9899 + bone.roll = -1.1774 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['ear.L'] = bone.name + bone = arm.edit_bones.new('ear.R') + bone.head[:] = -0.0949, -0.5457, 0.9545 + bone.tail[:] = -0.0524, -0.5459, 0.9899 + bone.roll = 1.1774 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['ear.R'] = bone.name + bone = arm.edit_bones.new('lip.T.R') + bone.head[:] = 0.0000, -0.8212, 0.7930 + bone.tail[:] = -0.0353, -0.7614, 0.7866 + bone.roll = -0.0551 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.T.R'] = bone.name + bone = arm.edit_bones.new('lip.B.R') + bone.head[:] = 0.0000, -0.7962, 0.7788 + bone.tail[:] = -0.0258, -0.7624, 0.7742 + bone.roll = -0.0255 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.B.R'] = bone.name + bone = arm.edit_bones.new('brow.B.L') + bone.head[:] = 0.0745, -0.6532, 0.9192 + bone.tail[:] = 0.0659, -0.6703, 0.9324 + bone.roll = 0.7673 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['brow.B.L'] = bone.name + bone = arm.edit_bones.new('lid.T.L') + bone.head[:] = 0.0621, -0.6644, 0.9197 + bone.tail[:] = 0.0588, -0.6755, 0.9223 + bone.roll = 0.0733 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lid.T.L'] = bone.name + bone = arm.edit_bones.new('brow.B.R') + bone.head[:] = -0.0745, -0.6532, 0.9192 + bone.tail[:] = -0.0659, -0.6703, 0.9324 + bone.roll = -0.7673 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['brow.B.R'] = bone.name + bone = arm.edit_bones.new('lid.T.R') + bone.head[:] = -0.0621, -0.6644, 0.9197 + bone.tail[:] = -0.0588, -0.6755, 0.9223 + bone.roll = -0.0733 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lid.T.R'] = bone.name + bone = arm.edit_bones.new('forehead.L') + bone.head[:] = 0.0208, -0.6604, 0.9808 + bone.tail[:] = 0.0160, -0.7017, 0.9527 + bone.roll = 1.9432 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['forehead.L'] = bone.name + bone = arm.edit_bones.new('forehead.R') + bone.head[:] = -0.0208, -0.6604, 0.9808 + bone.tail[:] = -0.0160, -0.7017, 0.9527 + bone.roll = -1.9432 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['forehead.R'] = bone.name + bone = arm.edit_bones.new('eye.L') + bone.head[:] = 0.0388, -0.6496, 0.9149 + bone.tail[:] = 0.0388, -0.7010, 0.9149 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['eye.L'] = bone.name + bone = arm.edit_bones.new('eye.R') + bone.head[:] = -0.0388, -0.6496, 0.9149 + bone.tail[:] = -0.0388, -0.7010, 0.9149 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['eye.R'] = bone.name + bone = arm.edit_bones.new('cheek.T.L') + bone.head[:] = 0.0906, -0.6428, 0.9032 + bone.tail[:] = 0.0660, -0.6881, 0.8704 + bone.roll = -0.0634 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['cheek.T.L'] = bone.name + bone = arm.edit_bones.new('cheek.T.R') + bone.head[:] = -0.0906, -0.6428, 0.9032 + bone.tail[:] = -0.0660, -0.6881, 0.8704 + bone.roll = 0.0634 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['cheek.T.R'] = bone.name + bone = arm.edit_bones.new('teeth.T') + bone.head[:] = 0.0004, -0.7594, 0.8194 + bone.tail[:] = 0.0004, -0.7302, 0.8292 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['teeth.T'] = bone.name + bone = arm.edit_bones.new('teeth.B') + bone.head[:] = 0.0004, -0.7504, 0.7968 + bone.tail[:] = 0.0004, -0.7204, 0.8041 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['teeth.B'] = bone.name + bone = arm.edit_bones.new('tongue') + bone.head[:] = 0.0004, -0.7646, 0.7930 + bone.tail[:] = 0.0004, -0.7476, 0.7967 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['tongue'] = bone.name + bone = arm.edit_bones.new('front_toe.L') + bone.head[:] = 0.1088, -0.2462, 0.0411 + bone.tail[:] = 0.1088, -0.3707, 0.0000 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_foot.L']] + bones['front_toe.L'] = bone.name + bone = arm.edit_bones.new('front_toe.R') + bone.head[:] = -0.1088, -0.2462, 0.0411 + bone.tail[:] = -0.1088, -0.3707, 0.0000 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_foot.R']] + bones['front_toe.R'] = bone.name + bone = arm.edit_bones.new('r_pinky.03.L') + bone.head[:] = 0.1431, 0.3382, 0.0170 + bone.tail[:] = 0.1455, 0.3175, 0.0129 + bone.roll = -1.0952 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_pinky.02.L']] + bones['r_pinky.03.L'] = bone.name + bone = arm.edit_bones.new('r_ring.03.L') + bone.head[:] = 0.1188, 0.3297, 0.0224 + bone.tail[:] = 0.1239, 0.2905, 0.0129 + bone.roll = -0.9905 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_ring.02.L']] + bones['r_ring.03.L'] = bone.name + bone = arm.edit_bones.new('r_middle.03.L') + bone.head[:] = 0.0851, 0.3297, 0.0224 + bone.tail[:] = 0.0813, 0.2904, 0.0129 + bone.roll = 0.8084 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_middle.02.L']] + bones['r_middle.03.L'] = bone.name + bone = arm.edit_bones.new('r_index.03.L') + bone.head[:] = 0.0623, 0.3410, 0.0170 + bone.tail[:] = 0.0552, 0.3214, 0.0129 + bone.roll = 2.2048 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_index.02.L']] + bones['r_index.03.L'] = bone.name + bone = arm.edit_bones.new('r_pinky.03.R') + bone.head[:] = -0.1431, 0.3382, 0.0170 + bone.tail[:] = -0.1455, 0.3175, 0.0129 + bone.roll = 1.0952 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_pinky.02.R']] + bones['r_pinky.03.R'] = bone.name + bone = arm.edit_bones.new('r_ring.03.R') + bone.head[:] = -0.1188, 0.3297, 0.0224 + bone.tail[:] = -0.1239, 0.2905, 0.0129 + bone.roll = 0.9905 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_ring.02.R']] + bones['r_ring.03.R'] = bone.name + bone = arm.edit_bones.new('r_middle.03.R') + bone.head[:] = -0.0851, 0.3297, 0.0224 + bone.tail[:] = -0.0813, 0.2904, 0.0129 + bone.roll = -0.8084 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_middle.02.R']] + bones['r_middle.03.R'] = bone.name + bone = arm.edit_bones.new('r_index.03.R') + bone.head[:] = -0.0623, 0.3410, 0.0170 + bone.tail[:] = -0.0552, 0.3214, 0.0129 + bone.roll = -2.2048 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_index.02.R']] + bones['r_index.03.R'] = bone.name + bone = arm.edit_bones.new('nose.001') + bone.head[:] = 0.0000, -0.7989, 0.8595 + bone.tail[:] = 0.0000, -0.8391, 0.8371 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose']] + bones['nose.001'] = bone.name + bone = arm.edit_bones.new('lip.T.L.001') + bone.head[:] = 0.0353, -0.7614, 0.7866 + bone.tail[:] = 0.0482, -0.6927, 0.7995 + bone.roll = 0.1558 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.T.L']] + bones['lip.T.L.001'] = bone.name + bone = arm.edit_bones.new('lip.B.L.001') + bone.head[:] = 0.0258, -0.7624, 0.7742 + bone.tail[:] = 0.0482, -0.6927, 0.7995 + bone.roll = 0.4650 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.B.L']] + bones['lip.B.L.001'] = bone.name + bone = arm.edit_bones.new('chin') + bone.head[:] = 0.0000, -0.6960, 0.7733 + bone.tail[:] = 0.0000, -0.7687, 0.7625 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw']] + bones['chin'] = bone.name + bone = arm.edit_bones.new('ear.L.001') + bone.head[:] = 0.0524, -0.5459, 0.9899 + bone.tail[:] = 0.0727, -0.5682, 1.0212 + bone.roll = 0.2280 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L']] + bones['ear.L.001'] = bone.name + bone = arm.edit_bones.new('ear.R.001') + bone.head[:] = -0.0524, -0.5459, 0.9899 + bone.tail[:] = -0.0727, -0.5682, 1.0212 + bone.roll = -0.2280 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R']] + bones['ear.R.001'] = bone.name + bone = arm.edit_bones.new('lip.T.R.001') + bone.head[:] = -0.0353, -0.7614, 0.7866 + bone.tail[:] = -0.0482, -0.6927, 0.7995 + bone.roll = -0.1558 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.T.R']] + bones['lip.T.R.001'] = bone.name + bone = arm.edit_bones.new('lip.B.R.001') + bone.head[:] = -0.0258, -0.7624, 0.7742 + bone.tail[:] = -0.0482, -0.6927, 0.7995 + bone.roll = -0.4650 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.B.R']] + bones['lip.B.R.001'] = bone.name + bone = arm.edit_bones.new('brow.B.L.001') + bone.head[:] = 0.0659, -0.6703, 0.9324 + bone.tail[:] = 0.0507, -0.6764, 0.9344 + bone.roll = 0.0953 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.L']] + bones['brow.B.L.001'] = bone.name + bone = arm.edit_bones.new('lid.T.L.001') + bone.head[:] = 0.0588, -0.6755, 0.9223 + bone.tail[:] = 0.0503, -0.6779, 0.9257 + bone.roll = 0.4801 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L']] + bones['lid.T.L.001'] = bone.name + bone = arm.edit_bones.new('brow.B.R.001') + bone.head[:] = -0.0659, -0.6703, 0.9324 + bone.tail[:] = -0.0507, -0.6764, 0.9344 + bone.roll = -0.0953 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.R']] + bones['brow.B.R.001'] = bone.name + bone = arm.edit_bones.new('lid.T.R.001') + bone.head[:] = -0.0588, -0.6755, 0.9223 + bone.tail[:] = -0.0503, -0.6779, 0.9257 + bone.roll = -0.4801 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R']] + bones['lid.T.R.001'] = bone.name + bone = arm.edit_bones.new('forehead.L.001') + bone.head[:] = 0.0418, -0.6520, 0.9749 + bone.tail[:] = 0.0510, -0.6773, 0.9561 + bone.roll = 0.5278 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.L']] + bones['forehead.L.001'] = bone.name + bone = arm.edit_bones.new('forehead.R.001') + bone.head[:] = -0.0418, -0.6520, 0.9749 + bone.tail[:] = -0.0510, -0.6773, 0.9561 + bone.roll = -0.5278 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.R']] + bones['forehead.R.001'] = bone.name + bone = arm.edit_bones.new('cheek.T.L.001') + bone.head[:] = 0.0660, -0.6881, 0.8704 + bone.tail[:] = 0.0389, -0.7093, 0.8768 + bone.roll = -0.5772 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.L']] + bones['cheek.T.L.001'] = bone.name + bone = arm.edit_bones.new('cheek.T.R.001') + bone.head[:] = -0.0660, -0.6881, 0.8704 + bone.tail[:] = -0.0389, -0.7093, 0.8768 + bone.roll = 0.5772 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.R']] + bones['cheek.T.R.001'] = bone.name + bone = arm.edit_bones.new('tongue.001') + bone.head[:] = 0.0004, -0.7476, 0.7967 + bone.tail[:] = 0.0004, -0.7246, 0.8052 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tongue']] + bones['tongue.001'] = bone.name + bone = arm.edit_bones.new('f_palm.04.L') + bone.head[:] = 0.1229, -0.2329, 0.0282 + bone.tail[:] = 0.1426, -0.2749, 0.0253 + bone.roll = -2.8623 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['front_toe.L']] + bones['f_palm.04.L'] = bone.name + bone = arm.edit_bones.new('f_palm.03.L') + bone.head[:] = 0.1142, -0.2346, 0.0282 + bone.tail[:] = 0.1239, -0.2833, 0.0377 + bone.roll = 1.5833 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['front_toe.L']] + bones['f_palm.03.L'] = bone.name + bone = arm.edit_bones.new('f_palm.02.L') + bone.head[:] = 0.1053, -0.2345, 0.0282 + bone.tail[:] = 0.0983, -0.2834, 0.0377 + bone.roll = -1.2317 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['front_toe.L']] + bones['f_palm.02.L'] = bone.name + bone = arm.edit_bones.new('f_palm.01.L') + bone.head[:] = 0.0934, -0.2319, 0.0282 + bone.tail[:] = 0.0791, -0.2716, 0.0253 + bone.roll = 2.8333 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['front_toe.L']] + bones['f_palm.01.L'] = bone.name + bone = arm.edit_bones.new('f_palm.04.R') + bone.head[:] = -0.1229, -0.2329, 0.0282 + bone.tail[:] = -0.1426, -0.2749, 0.0253 + bone.roll = 2.8623 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['front_toe.R']] + bones['f_palm.04.R'] = bone.name + bone = arm.edit_bones.new('f_palm.03.R') + bone.head[:] = -0.1142, -0.2346, 0.0282 + bone.tail[:] = -0.1239, -0.2833, 0.0377 + bone.roll = -1.5833 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['front_toe.R']] + bones['f_palm.03.R'] = bone.name + bone = arm.edit_bones.new('f_palm.02.R') + bone.head[:] = -0.1053, -0.2345, 0.0282 + bone.tail[:] = -0.0983, -0.2834, 0.0377 + bone.roll = 1.2317 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['front_toe.R']] + bones['f_palm.02.R'] = bone.name + bone = arm.edit_bones.new('f_palm.01.R') + bone.head[:] = -0.0934, -0.2319, 0.0282 + bone.tail[:] = -0.0791, -0.2716, 0.0253 + bone.roll = -2.8333 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['front_toe.R']] + bones['f_palm.01.R'] = bone.name + bone = arm.edit_bones.new('nose.002') + bone.head[:] = 0.0000, -0.8391, 0.8371 + bone.tail[:] = 0.0000, -0.8452, 0.8281 + bone.roll = -0.0162 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.001']] + bones['nose.002'] = bone.name + bone = arm.edit_bones.new('chin.001') + bone.head[:] = 0.0000, -0.7687, 0.7625 + bone.tail[:] = 0.0000, -0.7926, 0.7756 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['chin']] + bones['chin.001'] = bone.name + bone = arm.edit_bones.new('ear.L.002') + bone.head[:] = 0.0727, -0.5682, 1.0212 + bone.tail[:] = 0.1158, -0.5606, 1.0358 + bone.roll = -1.9007 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L.001']] + bones['ear.L.002'] = bone.name + bone = arm.edit_bones.new('ear.R.002') + bone.head[:] = -0.0727, -0.5682, 1.0212 + bone.tail[:] = -0.1158, -0.5606, 1.0358 + bone.roll = 1.9007 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R.001']] + bones['ear.R.002'] = bone.name + bone = arm.edit_bones.new('brow.B.L.002') + bone.head[:] = 0.0507, -0.6764, 0.9344 + bone.tail[:] = 0.0362, -0.6871, 0.9343 + bone.roll = 0.2604 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.L.001']] + bones['brow.B.L.002'] = bone.name + bone = arm.edit_bones.new('lid.T.L.002') + bone.head[:] = 0.0503, -0.6779, 0.9257 + bone.tail[:] = 0.0361, -0.6798, 0.9241 + bone.roll = 0.0945 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L.001']] + bones['lid.T.L.002'] = bone.name + bone = arm.edit_bones.new('brow.B.R.002') + bone.head[:] = -0.0507, -0.6764, 0.9344 + bone.tail[:] = -0.0362, -0.6871, 0.9343 + bone.roll = -0.2604 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.R.001']] + bones['brow.B.R.002'] = bone.name + bone = arm.edit_bones.new('lid.T.R.002') + bone.head[:] = -0.0503, -0.6779, 0.9257 + bone.tail[:] = -0.0361, -0.6798, 0.9241 + bone.roll = -0.0945 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R.001']] + bones['lid.T.R.002'] = bone.name + bone = arm.edit_bones.new('forehead.L.002') + bone.head[:] = 0.0581, -0.6362, 0.9723 + bone.tail[:] = 0.0774, -0.6567, 0.9438 + bone.roll = -0.3374 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.L.001']] + bones['forehead.L.002'] = bone.name + bone = arm.edit_bones.new('forehead.R.002') + bone.head[:] = -0.0581, -0.6362, 0.9723 + bone.tail[:] = -0.0774, -0.6567, 0.9438 + bone.roll = 0.3374 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.R.001']] + bones['forehead.R.002'] = bone.name + bone = arm.edit_bones.new('nose.L') + bone.head[:] = 0.0389, -0.7093, 0.8768 + bone.tail[:] = 0.0360, -0.7993, 0.8371 + bone.roll = -2.8274 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.L.001']] + bones['nose.L'] = bone.name + bone = arm.edit_bones.new('nose.R') + bone.head[:] = -0.0389, -0.7093, 0.8768 + bone.tail[:] = -0.0360, -0.7993, 0.8371 + bone.roll = 2.8274 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.R.001']] + bones['nose.R'] = bone.name + bone = arm.edit_bones.new('tongue.002') + bone.head[:] = 0.0004, -0.7246, 0.8052 + bone.tail[:] = 0.0004, -0.6900, 0.8003 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tongue.001']] + bones['tongue.002'] = bone.name + bone = arm.edit_bones.new('f_pinky.01.L') + bone.head[:] = 0.1426, -0.2749, 0.0253 + bone.tail[:] = 0.1477, -0.2946, 0.0222 + bone.roll = -2.0928 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.04.L']] + bones['f_pinky.01.L'] = bone.name + bone = arm.edit_bones.new('f_ring.01.L') + bone.head[:] = 0.1239, -0.2833, 0.0377 + bone.tail[:] = 0.1255, -0.3031, 0.0317 + bone.roll = -0.5451 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.03.L']] + bones['f_ring.01.L'] = bone.name + bone = arm.edit_bones.new('f_middle.01.L') + bone.head[:] = 0.0983, -0.2834, 0.0377 + bone.tail[:] = 0.0955, -0.3030, 0.0317 + bone.roll = 0.9401 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.02.L']] + bones['f_middle.01.L'] = bone.name + bone = arm.edit_bones.new('f_index.01.L') + bone.head[:] = 0.0791, -0.2716, 0.0253 + bone.tail[:] = 0.0749, -0.2916, 0.0222 + bone.roll = 1.9945 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.01.L']] + bones['f_index.01.L'] = bone.name + bone = arm.edit_bones.new('f_pinky.01.R') + bone.head[:] = -0.1426, -0.2749, 0.0253 + bone.tail[:] = -0.1477, -0.2946, 0.0222 + bone.roll = 2.0928 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.04.R']] + bones['f_pinky.01.R'] = bone.name + bone = arm.edit_bones.new('f_ring.01.R') + bone.head[:] = -0.1239, -0.2833, 0.0377 + bone.tail[:] = -0.1255, -0.3031, 0.0317 + bone.roll = 0.5451 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.03.R']] + bones['f_ring.01.R'] = bone.name + bone = arm.edit_bones.new('f_middle.01.R') + bone.head[:] = -0.0983, -0.2834, 0.0377 + bone.tail[:] = -0.0955, -0.3030, 0.0317 + bone.roll = -0.9401 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.02.R']] + bones['f_middle.01.R'] = bone.name + bone = arm.edit_bones.new('f_index.01.R') + bone.head[:] = -0.0791, -0.2716, 0.0253 + bone.tail[:] = -0.0749, -0.2916, 0.0222 + bone.roll = -1.9945 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['f_palm.01.R']] + bones['f_index.01.R'] = bone.name + bone = arm.edit_bones.new('nose.003') + bone.head[:] = 0.0000, -0.8452, 0.8281 + bone.tail[:] = 0.0000, -0.8349, 0.8089 + bone.roll = -0.0248 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.002']] + bones['nose.003'] = bone.name + bone = arm.edit_bones.new('ear.L.003') + bone.head[:] = 0.1158, -0.5606, 1.0358 + bone.tail[:] = 0.1130, -0.5379, 0.9935 + bone.roll = 2.4141 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L.002']] + bones['ear.L.003'] = bone.name + bone = arm.edit_bones.new('ear.R.003') + bone.head[:] = -0.1158, -0.5606, 1.0358 + bone.tail[:] = -0.1130, -0.5379, 0.9935 + bone.roll = -2.4141 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R.002']] + bones['ear.R.003'] = bone.name + bone = arm.edit_bones.new('brow.B.L.003') + bone.head[:] = 0.0362, -0.6871, 0.9343 + bone.tail[:] = 0.0269, -0.6936, 0.9293 + bone.roll = 0.2912 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.L.002']] + bones['brow.B.L.003'] = bone.name + bone = arm.edit_bones.new('lid.T.L.003') + bone.head[:] = 0.0361, -0.6798, 0.9241 + bone.tail[:] = 0.0281, -0.6756, 0.9088 + bone.roll = -0.3539 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L.002']] + bones['lid.T.L.003'] = bone.name + bone = arm.edit_bones.new('brow.B.R.003') + bone.head[:] = -0.0362, -0.6871, 0.9343 + bone.tail[:] = -0.0269, -0.6936, 0.9293 + bone.roll = -0.2912 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.R.002']] + bones['brow.B.R.003'] = bone.name + bone = arm.edit_bones.new('lid.T.R.003') + bone.head[:] = -0.0361, -0.6798, 0.9241 + bone.tail[:] = -0.0281, -0.6756, 0.9088 + bone.roll = 0.3539 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R.002']] + bones['lid.T.R.003'] = bone.name + bone = arm.edit_bones.new('temple.L') + bone.head[:] = 0.0590, -0.5870, 0.9758 + bone.tail[:] = 0.0931, -0.5866, 0.8642 + bone.roll = -0.4594 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.L.002']] + bones['temple.L'] = bone.name + bone = arm.edit_bones.new('temple.R') + bone.head[:] = -0.0590, -0.5870, 0.9758 + bone.tail[:] = -0.0931, -0.5866, 0.8642 + bone.roll = 0.4594 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.R.002']] + bones['temple.R'] = bone.name + bone = arm.edit_bones.new('nose.L.001') + bone.head[:] = 0.0360, -0.7993, 0.8371 + bone.tail[:] = 0.0000, -0.8391, 0.8371 + bone.roll = 2.9287 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.L']] + bones['nose.L.001'] = bone.name + bone = arm.edit_bones.new('nose.R.001') + bone.head[:] = -0.0360, -0.7993, 0.8371 + bone.tail[:] = 0.0000, -0.8391, 0.8371 + bone.roll = -2.9287 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.R']] + bones['nose.R.001'] = bone.name + bone = arm.edit_bones.new('f_pinky.02.L') + bone.head[:] = 0.1477, -0.2946, 0.0222 + bone.tail[:] = 0.1520, -0.3116, 0.0170 + bone.roll = -1.4292 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_pinky.01.L']] + bones['f_pinky.02.L'] = bone.name + bone = arm.edit_bones.new('f_ring.02.L') + bone.head[:] = 0.1255, -0.3031, 0.0317 + bone.tail[:] = 0.1278, -0.3200, 0.0224 + bone.roll = -0.5100 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_ring.01.L']] + bones['f_ring.02.L'] = bone.name + bone = arm.edit_bones.new('f_middle.02.L') + bone.head[:] = 0.0955, -0.3030, 0.0317 + bone.tail[:] = 0.0940, -0.3200, 0.0224 + bone.roll = 0.4076 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_middle.01.L']] + bones['f_middle.02.L'] = bone.name + bone = arm.edit_bones.new('f_index.02.L') + bone.head[:] = 0.0749, -0.2916, 0.0222 + bone.tail[:] = 0.0712, -0.3087, 0.0170 + bone.roll = 1.3847 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_index.01.L']] + bones['f_index.02.L'] = bone.name + bone = arm.edit_bones.new('f_pinky.02.R') + bone.head[:] = -0.1477, -0.2946, 0.0222 + bone.tail[:] = -0.1520, -0.3116, 0.0170 + bone.roll = 1.4292 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_pinky.01.R']] + bones['f_pinky.02.R'] = bone.name + bone = arm.edit_bones.new('f_ring.02.R') + bone.head[:] = -0.1255, -0.3031, 0.0317 + bone.tail[:] = -0.1278, -0.3200, 0.0224 + bone.roll = 0.5100 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_ring.01.R']] + bones['f_ring.02.R'] = bone.name + bone = arm.edit_bones.new('f_middle.02.R') + bone.head[:] = -0.0955, -0.3030, 0.0317 + bone.tail[:] = -0.0940, -0.3200, 0.0224 + bone.roll = -0.4076 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_middle.01.R']] + bones['f_middle.02.R'] = bone.name + bone = arm.edit_bones.new('f_index.02.R') + bone.head[:] = -0.0749, -0.2916, 0.0222 + bone.tail[:] = -0.0712, -0.3087, 0.0170 + bone.roll = -1.3847 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_index.01.R']] + bones['f_index.02.R'] = bone.name + bone = arm.edit_bones.new('nose.004') + bone.head[:] = 0.0000, -0.8349, 0.8089 + bone.tail[:] = 0.0000, -0.8159, 0.7913 + bone.roll = 0.0082 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.003']] + bones['nose.004'] = bone.name + bone = arm.edit_bones.new('ear.L.004') + bone.head[:] = 0.1130, -0.5379, 0.9935 + bone.tail[:] = 0.0949, -0.5457, 0.9545 + bone.roll = -2.3814 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L.003']] + bones['ear.L.004'] = bone.name + bone = arm.edit_bones.new('ear.R.004') + bone.head[:] = -0.1130, -0.5379, 0.9935 + bone.tail[:] = -0.0949, -0.5457, 0.9545 + bone.roll = 2.3814 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R.003']] + bones['ear.R.004'] = bone.name + bone = arm.edit_bones.new('lid.B.L') + bone.head[:] = 0.0281, -0.6756, 0.9088 + bone.tail[:] = 0.0382, -0.6786, 0.9040 + bone.roll = 0.2941 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L.003']] + bones['lid.B.L'] = bone.name + bone = arm.edit_bones.new('lid.B.R') + bone.head[:] = -0.0281, -0.6756, 0.9088 + bone.tail[:] = -0.0382, -0.6786, 0.9040 + bone.roll = -0.2941 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R.003']] + bones['lid.B.R'] = bone.name + bone = arm.edit_bones.new('jaw.L') + bone.head[:] = 0.0931, -0.5866, 0.8642 + bone.tail[:] = 0.0694, -0.6211, 0.8005 + bone.roll = 0.0983 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['temple.L']] + bones['jaw.L'] = bone.name + bone = arm.edit_bones.new('jaw.R') + bone.head[:] = -0.0931, -0.5866, 0.8642 + bone.tail[:] = -0.0694, -0.6211, 0.8005 + bone.roll = -0.0983 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['temple.R']] + bones['jaw.R'] = bone.name + bone = arm.edit_bones.new('f_pinky.03.L') + bone.head[:] = 0.1520, -0.3116, 0.0170 + bone.tail[:] = 0.1544, -0.3323, 0.0129 + bone.roll = -1.0952 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_pinky.02.L']] + bones['f_pinky.03.L'] = bone.name + bone = arm.edit_bones.new('f_ring.03.L') + bone.head[:] = 0.1278, -0.3200, 0.0224 + bone.tail[:] = 0.1328, -0.3592, 0.0129 + bone.roll = -0.9905 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_ring.02.L']] + bones['f_ring.03.L'] = bone.name + bone = arm.edit_bones.new('f_middle.03.L') + bone.head[:] = 0.0940, -0.3200, 0.0224 + bone.tail[:] = 0.0902, -0.3593, 0.0129 + bone.roll = 0.8084 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_middle.02.L']] + bones['f_middle.03.L'] = bone.name + bone = arm.edit_bones.new('f_index.03.L') + bone.head[:] = 0.0712, -0.3087, 0.0170 + bone.tail[:] = 0.0641, -0.3283, 0.0129 + bone.roll = 2.2048 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_index.02.L']] + bones['f_index.03.L'] = bone.name + bone = arm.edit_bones.new('f_pinky.03.R') + bone.head[:] = -0.1520, -0.3116, 0.0170 + bone.tail[:] = -0.1544, -0.3323, 0.0129 + bone.roll = 1.0952 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_pinky.02.R']] + bones['f_pinky.03.R'] = bone.name + bone = arm.edit_bones.new('f_ring.03.R') + bone.head[:] = -0.1278, -0.3200, 0.0224 + bone.tail[:] = -0.1328, -0.3592, 0.0129 + bone.roll = 0.9905 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_ring.02.R']] + bones['f_ring.03.R'] = bone.name + bone = arm.edit_bones.new('f_middle.03.R') + bone.head[:] = -0.0940, -0.3200, 0.0224 + bone.tail[:] = -0.0902, -0.3593, 0.0129 + bone.roll = -0.8084 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_middle.02.R']] + bones['f_middle.03.R'] = bone.name + bone = arm.edit_bones.new('f_index.03.R') + bone.head[:] = -0.0712, -0.3087, 0.0170 + bone.tail[:] = -0.0641, -0.3283, 0.0129 + bone.roll = -2.2048 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_index.02.R']] + bones['f_index.03.R'] = bone.name + bone = arm.edit_bones.new('lid.B.L.001') + bone.head[:] = 0.0382, -0.6786, 0.9040 + bone.tail[:] = 0.0476, -0.6772, 0.9036 + bone.roll = 0.0266 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.L']] + bones['lid.B.L.001'] = bone.name + bone = arm.edit_bones.new('lid.B.R.001') + bone.head[:] = -0.0382, -0.6786, 0.9040 + bone.tail[:] = -0.0476, -0.6772, 0.9036 + bone.roll = -0.0266 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.R']] + bones['lid.B.R.001'] = bone.name + bone = arm.edit_bones.new('jaw.L.001') + bone.head[:] = 0.0694, -0.6211, 0.8005 + bone.tail[:] = 0.0481, -0.6715, 0.7849 + bone.roll = 0.2993 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.L']] + bones['jaw.L.001'] = bone.name + bone = arm.edit_bones.new('jaw.R.001') + bone.head[:] = -0.0694, -0.6211, 0.8005 + bone.tail[:] = -0.0481, -0.6715, 0.7849 + bone.roll = -0.2993 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.R']] + bones['jaw.R.001'] = bone.name + bone = arm.edit_bones.new('lid.B.L.002') + bone.head[:] = 0.0476, -0.6772, 0.9036 + bone.tail[:] = 0.0570, -0.6724, 0.9082 + bone.roll = -0.1195 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.L.001']] + bones['lid.B.L.002'] = bone.name + bone = arm.edit_bones.new('lid.B.R.002') + bone.head[:] = -0.0476, -0.6772, 0.9036 + bone.tail[:] = -0.0570, -0.6724, 0.9082 + bone.roll = 0.1195 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.R.001']] + bones['lid.B.R.002'] = bone.name + bone = arm.edit_bones.new('chin.L') + bone.head[:] = 0.0481, -0.6715, 0.7849 + bone.tail[:] = 0.0482, -0.6927, 0.7995 + bone.roll = 3.1083 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.L.001']] + bones['chin.L'] = bone.name + bone = arm.edit_bones.new('chin.R') + bone.head[:] = -0.0481, -0.6715, 0.7849 + bone.tail[:] = -0.0482, -0.6927, 0.7995 + bone.roll = -3.1083 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.R.001']] + bones['chin.R'] = bone.name + bone = arm.edit_bones.new('lid.B.L.003') + bone.head[:] = 0.0570, -0.6724, 0.9082 + bone.tail[:] = 0.0621, -0.6644, 0.9197 + bone.roll = -0.1171 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.L.002']] + bones['lid.B.L.003'] = bone.name + bone = arm.edit_bones.new('lid.B.R.003') + bone.head[:] = -0.0570, -0.6724, 0.9082 + bone.tail[:] = -0.0621, -0.6644, 0.9197 + bone.roll = 0.1171 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.R.002']] + bones['lid.B.R.003'] = bone.name + bone = arm.edit_bones.new('cheek.B.L') + bone.head[:] = 0.0482, -0.6927, 0.7995 + bone.tail[:] = 0.0707, -0.6771, 0.8294 + bone.roll = -0.1207 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['chin.L']] + bones['cheek.B.L'] = bone.name + bone = arm.edit_bones.new('cheek.B.R') + bone.head[:] = -0.0482, -0.6927, 0.7995 + bone.tail[:] = -0.0707, -0.6771, 0.8294 + bone.roll = 0.1207 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['chin.R']] + bones['cheek.B.R'] = bone.name + bone = arm.edit_bones.new('cheek.B.L.001') + bone.head[:] = 0.0707, -0.6771, 0.8294 + bone.tail[:] = 0.0906, -0.6428, 0.9032 + bone.roll = 0.0640 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.L']] + bones['cheek.B.L.001'] = bone.name + bone = arm.edit_bones.new('cheek.B.R.001') + bone.head[:] = -0.0707, -0.6771, 0.8294 + bone.tail[:] = -0.0906, -0.6428, 0.9032 + bone.roll = -0.0640 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.R']] + bones['cheek.B.R.001'] = bone.name + bone = arm.edit_bones.new('brow.T.L') + bone.head[:] = 0.0906, -0.6428, 0.9032 + bone.tail[:] = 0.0774, -0.6567, 0.9438 + bone.roll = 0.1270 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.L.001']] + bones['brow.T.L'] = bone.name + bone = arm.edit_bones.new('brow.T.R') + bone.head[:] = -0.0906, -0.6428, 0.9032 + bone.tail[:] = -0.0774, -0.6567, 0.9438 + bone.roll = -0.1270 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.R.001']] + bones['brow.T.R'] = bone.name + bone = arm.edit_bones.new('brow.T.L.001') + bone.head[:] = 0.0774, -0.6567, 0.9438 + bone.tail[:] = 0.0510, -0.6773, 0.9561 + bone.roll = -2.7274 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.L']] + bones['brow.T.L.001'] = bone.name + bone = arm.edit_bones.new('brow.T.R.001') + bone.head[:] = -0.0774, -0.6567, 0.9438 + bone.tail[:] = -0.0510, -0.6773, 0.9561 + bone.roll = 2.7274 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.R']] + bones['brow.T.R.001'] = bone.name + bone = arm.edit_bones.new('brow.T.L.002') + bone.head[:] = 0.0510, -0.6773, 0.9561 + bone.tail[:] = 0.0160, -0.7017, 0.9527 + bone.roll = 0.4172 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.L.001']] + bones['brow.T.L.002'] = bone.name + bone = arm.edit_bones.new('brow.T.R.002') + bone.head[:] = -0.0510, -0.6773, 0.9561 + bone.tail[:] = -0.0160, -0.7017, 0.9527 + bone.roll = -0.4172 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.R.001']] + bones['brow.T.R.002'] = bone.name + bone = arm.edit_bones.new('brow.T.L.003') + bone.head[:] = 0.0160, -0.7017, 0.9527 + bone.tail[:] = 0.0000, -0.7082, 0.9031 + bone.roll = -0.6706 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.L.002']] + bones['brow.T.L.003'] = bone.name + bone = arm.edit_bones.new('brow.T.R.003') + bone.head[:] = -0.0160, -0.7017, 0.9527 + bone.tail[:] = 0.0000, -0.7082, 0.9031 + bone.roll = 0.6706 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.R.002']] + bones['brow.T.R.003'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['spine']] + pbone.rigify_type = 'spines.super_spine' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.use_tail = True + except AttributeError: + pass + try: + pbone.rigify_parameters.tail_pos = 4 + except AttributeError: + pass + try: + pbone.rigify_parameters.pivot_pos = 8 + except AttributeError: + pass + try: + pbone.rigify_parameters.neck_pos = 10 + except AttributeError: + pass + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_extra_layers = False + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.005']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.neck_pos = 5 + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.006']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['pelvis.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['pelvis.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['thigh.L']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['thigh.R']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.007']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shin.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shin.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.008']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['foot.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['foot.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.009']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shoulder.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['shoulder.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['breast.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['breast.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['toe.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + pbone = obj.pose.bones[bones['toe.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.010']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['front_thigh.L']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['front_thigh.R']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_palm.04.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.03.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.01.L']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.04.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.03.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.02.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_palm.01.R']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.011']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['front_shin.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['front_shin.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_pinky.01.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_ring.01.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_middle.01.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_index.01.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_pinky.01.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_ring.01.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_middle.01.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_index.01.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['face']] + pbone.rigify_type = 'faces.super_face' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.secondary_layers = [False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['front_foot.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['front_foot.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_pinky.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_ring.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_middle.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_index.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_pinky.02.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_ring.02.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_middle.02.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_index.02.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.T.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.B.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.T.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.B.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['eye.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['eye.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.T.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.T.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['teeth.T']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['teeth.B']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['tongue']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['front_toe.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + pbone = obj.pose.bones[bones['front_toe.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.rotation_axis = "x" + except AttributeError: + pass + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_pinky.03.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_ring.03.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_middle.03.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_index.03.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_pinky.03.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_ring.03.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_middle.03.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['r_index.03.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.T.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.B.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['chin']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.T.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lip.B.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.T.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.T.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['tongue.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.04.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.03.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.01.L']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.04.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.03.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.02.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_palm.01.R']] + pbone.rigify_type = 'limbs.super_palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['chin.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forehead.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['tongue.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_pinky.01.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_ring.01.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_middle.01.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_index.01.L']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_pinky.01.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_ring.01.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_middle.01.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_index.01.R']] + pbone.rigify_type = 'limbs.simple_tentacle' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['nose.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.L.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.R.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.L.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.L.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.B.R.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.T.R.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['temple.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['temple.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_pinky.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_ring.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_middle.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_index.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_pinky.02.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_ring.02.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_middle.02.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_index.02.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['nose.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.L.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['ear.R.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_pinky.03.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_ring.03.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_middle.03.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_index.03.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_pinky.03.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_ring.03.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_middle.03.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_index.03.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['jaw.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['chin.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['chin.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.L.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['lid.B.R.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.B.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.B.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.B.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['cheek.B.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.L.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.R.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.L.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.R.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.L.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['brow.T.R.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + + bpy.ops.object.mode_set(mode='EDIT') + for bone in arm.edit_bones: + bone.select = False + bone.select_head = False + bone.select_tail = False + for b in bones: + bone = arm.edit_bones[bones[b]] + bone.select = True + bone.select_head = True + bone.select_tail = True + arm.edit_bones.active = bone + + arm.layers = [(x in [0, 3, 4, 5, 7, 10, 13, 16, 19]) for x in range(32)] + +if __name__ == "__main__": + create(bpy.context.active_object)
\ No newline at end of file diff --git a/rigify/metarigs/Basic/basic_human.py b/rigify/metarigs/Basic/basic_human.py new file mode 100644 index 00000000..221809e7 --- /dev/null +++ b/rigify/metarigs/Basic/basic_human.py @@ -0,0 +1,684 @@ +import bpy + + +from mathutils import Color + + +def create(obj): + # generated by rigify.utils.write_metarig + bpy.ops.object.mode_set(mode='EDIT') + arm = obj.data + + for i in range(6): + arm.rigify_colors.add() + + arm.rigify_colors[0].name = "Root" + arm.rigify_colors[0].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[0].normal = Color((0.43529415130615234, 0.18431372940540314, 0.41568630933761597)) + arm.rigify_colors[0].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[0].standard_colors_lock = True + arm.rigify_colors[1].name = "IK" + arm.rigify_colors[1].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[1].normal = Color((0.6039215922355652, 0.0, 0.0)) + arm.rigify_colors[1].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[1].standard_colors_lock = True + arm.rigify_colors[2].name = "Special" + arm.rigify_colors[2].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[2].normal = Color((0.9568628072738647, 0.7882353663444519, 0.0470588281750679)) + arm.rigify_colors[2].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[2].standard_colors_lock = True + arm.rigify_colors[3].name = "Tweak" + arm.rigify_colors[3].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[3].normal = Color((0.03921568766236305, 0.21176472306251526, 0.5803921818733215)) + arm.rigify_colors[3].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[3].standard_colors_lock = True + arm.rigify_colors[4].name = "FK" + arm.rigify_colors[4].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[4].normal = Color((0.11764706671237946, 0.5686274766921997, 0.03529411926865578)) + arm.rigify_colors[4].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[4].standard_colors_lock = True + arm.rigify_colors[5].name = "Extra" + arm.rigify_colors[5].active = Color((0.5490000247955322, 1.0, 1.0)) + arm.rigify_colors[5].normal = Color((0.9686275124549866, 0.250980406999588, 0.0941176563501358)) + arm.rigify_colors[5].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + arm.rigify_colors[5].standard_colors_lock = True + + for i in range(29): + arm.rigify_layers.add() + + arm.rigify_layers[0].name = " " + arm.rigify_layers[0].row = 1 + arm.rigify_layers[0].set = False + arm.rigify_layers[0].group = 0 + arm.rigify_layers[1].name = " " + arm.rigify_layers[1].row = 1 + arm.rigify_layers[1].set = False + arm.rigify_layers[1].group = 0 + arm.rigify_layers[2].name = " " + arm.rigify_layers[2].row = 1 + arm.rigify_layers[2].set = False + arm.rigify_layers[2].group = 0 + arm.rigify_layers[3].name = "Torso" + arm.rigify_layers[3].row = 3 + arm.rigify_layers[3].set = False + arm.rigify_layers[3].group = 3 + arm.rigify_layers[4].name = "Torso (Tweak)" + arm.rigify_layers[4].row = 4 + arm.rigify_layers[4].set = False + arm.rigify_layers[4].group = 4 + arm.rigify_layers[5].name = " " + arm.rigify_layers[5].row = 1 + arm.rigify_layers[5].set = False + arm.rigify_layers[5].group = 0 + arm.rigify_layers[6].name = " " + arm.rigify_layers[6].row = 1 + arm.rigify_layers[6].set = False + arm.rigify_layers[6].group = 0 + arm.rigify_layers[7].name = "Arm.L (IK)" + arm.rigify_layers[7].row = 7 + arm.rigify_layers[7].set = False + arm.rigify_layers[7].group = 2 + arm.rigify_layers[8].name = "Arm.L (FK)" + arm.rigify_layers[8].row = 8 + arm.rigify_layers[8].set = False + arm.rigify_layers[8].group = 5 + arm.rigify_layers[9].name = "Arm.L (Tweak)" + arm.rigify_layers[9].row = 9 + arm.rigify_layers[9].set = False + arm.rigify_layers[9].group = 4 + arm.rigify_layers[10].name = "Arm.R (IK)" + arm.rigify_layers[10].row = 7 + arm.rigify_layers[10].set = False + arm.rigify_layers[10].group = 2 + arm.rigify_layers[11].name = "Arm.R (FK)" + arm.rigify_layers[11].row = 8 + arm.rigify_layers[11].set = False + arm.rigify_layers[11].group = 5 + arm.rigify_layers[12].name = "Arm.R (Tweak)" + arm.rigify_layers[12].row = 9 + arm.rigify_layers[12].set = False + arm.rigify_layers[12].group = 4 + arm.rigify_layers[13].name = "Leg.L (IK)" + arm.rigify_layers[13].row = 10 + arm.rigify_layers[13].set = False + arm.rigify_layers[13].group = 2 + arm.rigify_layers[14].name = "Leg.L (FK)" + arm.rigify_layers[14].row = 11 + arm.rigify_layers[14].set = False + arm.rigify_layers[14].group = 5 + arm.rigify_layers[15].name = "Leg.L (Tweak)" + arm.rigify_layers[15].row = 12 + arm.rigify_layers[15].set = False + arm.rigify_layers[15].group = 4 + arm.rigify_layers[16].name = "Leg.R (IK)" + arm.rigify_layers[16].row = 10 + arm.rigify_layers[16].set = False + arm.rigify_layers[16].group = 2 + arm.rigify_layers[17].name = "Leg.R (FK)" + arm.rigify_layers[17].row = 11 + arm.rigify_layers[17].set = False + arm.rigify_layers[17].group = 5 + arm.rigify_layers[18].name = "Leg.R (Tweak)" + arm.rigify_layers[18].row = 12 + arm.rigify_layers[18].set = False + arm.rigify_layers[18].group = 4 + arm.rigify_layers[19].name = "" + arm.rigify_layers[19].row = 1 + arm.rigify_layers[19].set = False + arm.rigify_layers[19].group = 0 + arm.rigify_layers[20].name = "" + arm.rigify_layers[20].row = 1 + arm.rigify_layers[20].set = False + arm.rigify_layers[20].group = 0 + arm.rigify_layers[21].name = "" + arm.rigify_layers[21].row = 1 + arm.rigify_layers[21].set = False + arm.rigify_layers[21].group = 0 + arm.rigify_layers[22].name = "" + arm.rigify_layers[22].row = 1 + arm.rigify_layers[22].set = False + arm.rigify_layers[22].group = 0 + arm.rigify_layers[23].name = "" + arm.rigify_layers[23].row = 1 + arm.rigify_layers[23].set = False + arm.rigify_layers[23].group = 0 + arm.rigify_layers[24].name = "" + arm.rigify_layers[24].row = 1 + arm.rigify_layers[24].set = False + arm.rigify_layers[24].group = 0 + arm.rigify_layers[25].name = "" + arm.rigify_layers[25].row = 1 + arm.rigify_layers[25].set = False + arm.rigify_layers[25].group = 0 + arm.rigify_layers[26].name = "" + arm.rigify_layers[26].row = 1 + arm.rigify_layers[26].set = False + arm.rigify_layers[26].group = 0 + arm.rigify_layers[27].name = "" + arm.rigify_layers[27].row = 1 + arm.rigify_layers[27].set = False + arm.rigify_layers[27].group = 0 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 14 + arm.rigify_layers[28].set = False + arm.rigify_layers[28].group = 1 + + bones = {} + + bone = arm.edit_bones.new('spine') + bone.head[:] = 0.0000, 0.0552, 1.0099 + bone.tail[:] = 0.0000, 0.0172, 1.1573 + bone.roll = 0.0000 + bone.use_connect = False + bones['spine'] = bone.name + bone = arm.edit_bones.new('spine.001') + bone.head[:] = 0.0000, 0.0172, 1.1573 + bone.tail[:] = 0.0000, 0.0004, 1.2929 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine']] + bones['spine.001'] = bone.name + bone = arm.edit_bones.new('pelvis.L') + bone.head[:] = 0.0000, 0.0552, 1.0099 + bone.tail[:] = 0.1112, -0.0451, 1.1533 + bone.roll = -1.0756 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['pelvis.L'] = bone.name + bone = arm.edit_bones.new('pelvis.R') + bone.head[:] = -0.0000, 0.0552, 1.0099 + bone.tail[:] = -0.1112, -0.0451, 1.1533 + bone.roll = 1.0756 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['pelvis.R'] = bone.name + bone = arm.edit_bones.new('thigh.L') + bone.head[:] = 0.0980, 0.0124, 1.0720 + bone.tail[:] = 0.0980, -0.0286, 0.5372 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['thigh.L'] = bone.name + bone = arm.edit_bones.new('thigh.R') + bone.head[:] = -0.0980, 0.0124, 1.0720 + bone.tail[:] = -0.0980, -0.0286, 0.5372 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['thigh.R'] = bone.name + bone = arm.edit_bones.new('spine.002') + bone.head[:] = 0.0000, 0.0004, 1.2929 + bone.tail[:] = 0.0000, 0.0059, 1.4657 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.001']] + bones['spine.002'] = bone.name + bone = arm.edit_bones.new('shin.L') + bone.head[:] = 0.0980, -0.0286, 0.5372 + bone.tail[:] = 0.0980, 0.0162, 0.0852 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.L']] + bones['shin.L'] = bone.name + bone = arm.edit_bones.new('shin.R') + bone.head[:] = -0.0980, -0.0286, 0.5372 + bone.tail[:] = -0.0980, 0.0162, 0.0852 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.R']] + bones['shin.R'] = bone.name + bone = arm.edit_bones.new('spine.003') + bone.head[:] = 0.0000, 0.0059, 1.4657 + bone.tail[:] = 0.0000, 0.0114, 1.6582 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.002']] + bones['spine.003'] = bone.name + bone = arm.edit_bones.new('foot.L') + bone.head[:] = 0.0980, 0.0162, 0.0852 + bone.tail[:] = 0.0980, -0.0934, 0.0167 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.L']] + bones['foot.L'] = bone.name + bone = arm.edit_bones.new('foot.R') + bone.head[:] = -0.0980, 0.0162, 0.0852 + bone.tail[:] = -0.0980, -0.0934, 0.0167 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.R']] + bones['foot.R'] = bone.name + bone = arm.edit_bones.new('spine.004') + bone.head[:] = 0.0000, 0.0114, 1.6582 + bone.tail[:] = 0.0000, -0.0130, 1.7197 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.003']] + bones['spine.004'] = bone.name + bone = arm.edit_bones.new('shoulder.L') + bone.head[:] = 0.0183, -0.0684, 1.6051 + bone.tail[:] = 0.1694, 0.0205, 1.6050 + bone.roll = 0.0004 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.003']] + bones['shoulder.L'] = bone.name + bone = arm.edit_bones.new('shoulder.R') + bone.head[:] = -0.0183, -0.0684, 1.6051 + bone.tail[:] = -0.1694, 0.0205, 1.6050 + bone.roll = -0.0004 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.003']] + bones['shoulder.R'] = bone.name + bone = arm.edit_bones.new('breast.L') + bone.head[:] = 0.1184, 0.0485, 1.4596 + bone.tail[:] = 0.1184, -0.0907, 1.4596 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.003']] + bones['breast.L'] = bone.name + bone = arm.edit_bones.new('breast.R') + bone.head[:] = -0.1184, 0.0485, 1.4596 + bone.tail[:] = -0.1184, -0.0907, 1.4596 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.003']] + bones['breast.R'] = bone.name + bone = arm.edit_bones.new('toe.L') + bone.head[:] = 0.0980, -0.0934, 0.0167 + bone.tail[:] = 0.0980, -0.1606, 0.0167 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.L']] + bones['toe.L'] = bone.name + bone = arm.edit_bones.new('heel.02.L') + bone.head[:] = 0.0600, 0.0459, 0.0000 + bone.tail[:] = 0.1400, 0.0459, 0.0000 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['foot.L']] + bones['heel.02.L'] = bone.name + bone = arm.edit_bones.new('toe.R') + bone.head[:] = -0.0980, -0.0934, 0.0167 + bone.tail[:] = -0.0980, -0.1606, 0.0167 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.R']] + bones['toe.R'] = bone.name + bone = arm.edit_bones.new('heel.02.R') + bone.head[:] = -0.0600, 0.0459, 0.0000 + bone.tail[:] = -0.1400, 0.0459, 0.0000 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['foot.R']] + bones['heel.02.R'] = bone.name + bone = arm.edit_bones.new('spine.005') + bone.head[:] = 0.0000, -0.0130, 1.7197 + bone.tail[:] = 0.0000, -0.0247, 1.7813 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.004']] + bones['spine.005'] = bone.name + bone = arm.edit_bones.new('upper_arm.L') + bone.head[:] = 0.1953, 0.0267, 1.5846 + bone.tail[:] = 0.4424, 0.0885, 1.4491 + bone.roll = 2.0724 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.L']] + bones['upper_arm.L'] = bone.name + bone = arm.edit_bones.new('upper_arm.R') + bone.head[:] = -0.1953, 0.0267, 1.5846 + bone.tail[:] = -0.4424, 0.0885, 1.4491 + bone.roll = -2.0724 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.R']] + bones['upper_arm.R'] = bone.name + bone = arm.edit_bones.new('spine.006') + bone.head[:] = 0.0000, -0.0247, 1.7813 + bone.tail[:] = 0.0000, -0.0247, 1.9796 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.005']] + bones['spine.006'] = bone.name + bone = arm.edit_bones.new('forearm.L') + bone.head[:] = 0.4424, 0.0885, 1.4491 + bone.tail[:] = 0.6594, 0.0492, 1.3061 + bone.roll = 2.1535 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['upper_arm.L']] + bones['forearm.L'] = bone.name + bone = arm.edit_bones.new('forearm.R') + bone.head[:] = -0.4424, 0.0885, 1.4491 + bone.tail[:] = -0.6594, 0.0492, 1.3061 + bone.roll = -2.1535 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['upper_arm.R']] + bones['forearm.R'] = bone.name + bone = arm.edit_bones.new('hand.L') + bone.head[:] = 0.6594, 0.0492, 1.3061 + bone.tail[:] = 0.7234, 0.0412, 1.2585 + bone.roll = 2.2103 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['forearm.L']] + bones['hand.L'] = bone.name + bone = arm.edit_bones.new('hand.R') + bone.head[:] = -0.6594, 0.0492, 1.3061 + bone.tail[:] = -0.7234, 0.0412, 1.2585 + bone.roll = -2.2103 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['forearm.R']] + bones['hand.R'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['spine']] + pbone.rigify_type = 'spines.super_spine' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.neck_pos = 5 + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['pelvis.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['pelvis.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['thigh.L']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "leg" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['thigh.R']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.limb_type = "leg" + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shin.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shin.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['foot.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['foot.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shoulder.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['shoulder.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['breast.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['breast.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['toe.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['heel.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['toe.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['heel.02.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.005']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['upper_arm.L']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['upper_arm.R']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.006']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forearm.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['forearm.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['hand.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['hand.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + + bpy.ops.object.mode_set(mode='EDIT') + for bone in arm.edit_bones: + bone.select = False + bone.select_head = False + bone.select_tail = False + for b in bones: + bone = arm.edit_bones[bones[b]] + bone.select = True + bone.select_head = True + bone.select_tail = True + arm.edit_bones.active = bone + + arm.layers = [(x in [3, 7, 10, 13, 16]) for x in range(32)] + +if __name__ == "__main__": + create(bpy.context.active_object)
\ No newline at end of file diff --git a/rigify/metarigs/Basic/basic_quadruped.py b/rigify/metarigs/Basic/basic_quadruped.py new file mode 100644 index 00000000..fe3449e1 --- /dev/null +++ b/rigify/metarigs/Basic/basic_quadruped.py @@ -0,0 +1,819 @@ +import bpy + + +from mathutils import Color + + +def create(obj): + # generated by rigify.utils.write_metarig + bpy.ops.object.mode_set(mode='EDIT') + arm = obj.data + + for i in range(6): + arm.rigify_colors.add() + + arm.rigify_colors[0].name = "Root" + arm.rigify_colors[0].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[0].normal = Color((0.4352940022945404, 0.18431399762630463, 0.4156860113143921)) + arm.rigify_colors[0].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[0].standard_colors_lock = True + arm.rigify_colors[1].name = "IK" + arm.rigify_colors[1].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[1].normal = Color((0.6039220094680786, 0.0, 0.0)) + arm.rigify_colors[1].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[1].standard_colors_lock = True + arm.rigify_colors[2].name = "Special" + arm.rigify_colors[2].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[2].normal = Color((0.9568629860877991, 0.7882350087165833, 0.04705899953842163)) + arm.rigify_colors[2].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[2].standard_colors_lock = True + arm.rigify_colors[3].name = "Tweak" + arm.rigify_colors[3].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[3].normal = Color((0.03921600058674812, 0.21176500618457794, 0.5803920030593872)) + arm.rigify_colors[3].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[3].standard_colors_lock = True + arm.rigify_colors[4].name = "FK" + arm.rigify_colors[4].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[4].normal = Color((0.11764699965715408, 0.5686269998550415, 0.035294000059366226)) + arm.rigify_colors[4].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[4].standard_colors_lock = True + arm.rigify_colors[5].name = "Extra" + arm.rigify_colors[5].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[5].normal = Color((0.9686279892921448, 0.2509799897670746, 0.09411799907684326)) + arm.rigify_colors[5].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[5].standard_colors_lock = True + + for i in range(29): + arm.rigify_layers.add() + + arm.rigify_layers[0].name = " " + arm.rigify_layers[0].row = 1 + arm.rigify_layers[0].set = False + arm.rigify_layers[0].group = 0 + arm.rigify_layers[1].name = " " + arm.rigify_layers[1].row = 2 + arm.rigify_layers[1].set = False + arm.rigify_layers[1].group = 0 + arm.rigify_layers[2].name = " " + arm.rigify_layers[2].row = 2 + arm.rigify_layers[2].set = False + arm.rigify_layers[2].group = 0 + arm.rigify_layers[3].name = "Spine" + arm.rigify_layers[3].row = 3 + arm.rigify_layers[3].set = False + arm.rigify_layers[3].group = 3 + arm.rigify_layers[4].name = "Spine (Tweak)" + arm.rigify_layers[4].row = 4 + arm.rigify_layers[4].set = False + arm.rigify_layers[4].group = 4 + arm.rigify_layers[5].name = " " + arm.rigify_layers[5].row = 5 + arm.rigify_layers[5].set = False + arm.rigify_layers[5].group = 0 + arm.rigify_layers[6].name = " " + arm.rigify_layers[6].row = 6 + arm.rigify_layers[6].set = False + arm.rigify_layers[6].group = 0 + arm.rigify_layers[7].name = "Arm.L (IK)" + arm.rigify_layers[7].row = 7 + arm.rigify_layers[7].set = False + arm.rigify_layers[7].group = 2 + arm.rigify_layers[8].name = "Arm.L (FK)" + arm.rigify_layers[8].row = 8 + arm.rigify_layers[8].set = False + arm.rigify_layers[8].group = 5 + arm.rigify_layers[9].name = "Arm.L (Tweak)" + arm.rigify_layers[9].row = 9 + arm.rigify_layers[9].set = False + arm.rigify_layers[9].group = 4 + arm.rigify_layers[10].name = "Arm.R (IK)" + arm.rigify_layers[10].row = 7 + arm.rigify_layers[10].set = False + arm.rigify_layers[10].group = 2 + arm.rigify_layers[11].name = "Arm.R (FK)" + arm.rigify_layers[11].row = 8 + arm.rigify_layers[11].set = False + arm.rigify_layers[11].group = 5 + arm.rigify_layers[12].name = "Arm.R (Tweak)" + arm.rigify_layers[12].row = 9 + arm.rigify_layers[12].set = False + arm.rigify_layers[12].group = 4 + arm.rigify_layers[13].name = "Leg.L (IK)" + arm.rigify_layers[13].row = 10 + arm.rigify_layers[13].set = False + arm.rigify_layers[13].group = 2 + arm.rigify_layers[14].name = "Leg.L (FK)" + arm.rigify_layers[14].row = 11 + arm.rigify_layers[14].set = False + arm.rigify_layers[14].group = 5 + arm.rigify_layers[15].name = "Leg.L (Tweak)" + arm.rigify_layers[15].row = 12 + arm.rigify_layers[15].set = False + arm.rigify_layers[15].group = 4 + arm.rigify_layers[16].name = "Leg.R (IK)" + arm.rigify_layers[16].row = 10 + arm.rigify_layers[16].set = False + arm.rigify_layers[16].group = 2 + arm.rigify_layers[17].name = "Leg.R (FK)" + arm.rigify_layers[17].row = 11 + arm.rigify_layers[17].set = False + arm.rigify_layers[17].group = 5 + arm.rigify_layers[18].name = "Leg.R (Tweak)" + arm.rigify_layers[18].row = 12 + arm.rigify_layers[18].set = False + arm.rigify_layers[18].group = 4 + arm.rigify_layers[19].name = "Tail" + arm.rigify_layers[19].row = 13 + arm.rigify_layers[19].set = False + arm.rigify_layers[19].group = 6 + arm.rigify_layers[20].name = "" + arm.rigify_layers[20].row = 1 + arm.rigify_layers[20].set = False + arm.rigify_layers[20].group = 0 + arm.rigify_layers[21].name = "" + arm.rigify_layers[21].row = 13 + arm.rigify_layers[21].set = False + arm.rigify_layers[21].group = 0 + arm.rigify_layers[22].name = "" + arm.rigify_layers[22].row = 13 + arm.rigify_layers[22].set = False + arm.rigify_layers[22].group = 0 + arm.rigify_layers[23].name = "" + arm.rigify_layers[23].row = 1 + arm.rigify_layers[23].set = False + arm.rigify_layers[23].group = 0 + arm.rigify_layers[24].name = "" + arm.rigify_layers[24].row = 1 + arm.rigify_layers[24].set = False + arm.rigify_layers[24].group = 0 + arm.rigify_layers[25].name = "" + arm.rigify_layers[25].row = 1 + arm.rigify_layers[25].set = False + arm.rigify_layers[25].group = 0 + arm.rigify_layers[26].name = "" + arm.rigify_layers[26].row = 1 + arm.rigify_layers[26].set = False + arm.rigify_layers[26].group = 0 + arm.rigify_layers[27].name = "" + arm.rigify_layers[27].row = 1 + arm.rigify_layers[27].set = False + arm.rigify_layers[27].group = 0 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 14 + arm.rigify_layers[28].set = False + arm.rigify_layers[28].group = 1 + + bones = {} + + bone = arm.edit_bones.new('spine') + bone.head[:] = 0.0000, 1.1044, 0.7633 + bone.tail[:] = 0.0000, 0.9624, 0.7412 + bone.roll = 0.0000 + bone.use_connect = False + bones['spine'] = bone.name + bone = arm.edit_bones.new('spine.001') + bone.head[:] = 0.0000, 0.9624, 0.7412 + bone.tail[:] = 0.0000, 0.7755, 0.7418 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine']] + bones['spine.001'] = bone.name + bone = arm.edit_bones.new('spine.002') + bone.head[:] = 0.0000, 0.7755, 0.7418 + bone.tail[:] = 0.0000, 0.5547, 0.7568 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.001']] + bones['spine.002'] = bone.name + bone = arm.edit_bones.new('spine.003') + bone.head[:] = 0.0000, 0.5547, 0.7568 + bone.tail[:] = 0.0000, 0.4418, 0.7954 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.002']] + bones['spine.003'] = bone.name + bone = arm.edit_bones.new('spine.004') + bone.head[:] = 0.0000, 0.4418, 0.7954 + bone.tail[:] = 0.0000, 0.3546, 0.8059 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.003']] + bones['spine.004'] = bone.name + bone = arm.edit_bones.new('spine.005') + bone.head[:] = 0.0000, 0.3546, 0.8059 + bone.tail[:] = 0.0000, 0.1803, 0.7782 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.004']] + bones['spine.005'] = bone.name + bone = arm.edit_bones.new('spine.006') + bone.head[:] = 0.0000, 0.1803, 0.7782 + bone.tail[:] = 0.0000, 0.0319, 0.7731 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.005']] + bones['spine.006'] = bone.name + bone = arm.edit_bones.new('pelvis.L') + bone.head[:] = 0.0000, 0.3757, 0.6043 + bone.tail[:] = 0.0751, 0.2755, 0.8544 + bone.roll = -1.5841 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['pelvis.L'] = bone.name + bone = arm.edit_bones.new('pelvis.R') + bone.head[:] = -0.0000, 0.3757, 0.6043 + bone.tail[:] = -0.0751, 0.2755, 0.8544 + bone.roll = 1.5841 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['pelvis.R'] = bone.name + bone = arm.edit_bones.new('thigh.L') + bone.head[:] = 0.1249, 0.3419, 0.7379 + bone.tail[:] = 0.1249, 0.2712, 0.4731 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['thigh.L'] = bone.name + bone = arm.edit_bones.new('thigh.R') + bone.head[:] = -0.1249, 0.3419, 0.7379 + bone.tail[:] = -0.1249, 0.2712, 0.4731 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.005']] + bones['thigh.R'] = bone.name + bone = arm.edit_bones.new('spine.007') + bone.head[:] = 0.0000, 0.0319, 0.7731 + bone.tail[:] = 0.0000, -0.0980, 0.7945 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.006']] + bones['spine.007'] = bone.name + bone = arm.edit_bones.new('shin.L') + bone.head[:] = 0.1249, 0.2712, 0.4731 + bone.tail[:] = 0.1114, 0.4766, 0.2473 + bone.roll = 0.0195 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.L']] + bones['shin.L'] = bone.name + bone = arm.edit_bones.new('shin.R') + bone.head[:] = -0.1249, 0.2712, 0.4731 + bone.tail[:] = -0.1114, 0.4766, 0.2473 + bone.roll = -0.0195 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.R']] + bones['shin.R'] = bone.name + bone = arm.edit_bones.new('spine.008') + bone.head[:] = 0.0000, -0.0980, 0.7945 + bone.tail[:] = 0.0000, -0.3618, 0.8375 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.007']] + bones['spine.008'] = bone.name + bone = arm.edit_bones.new('foot.L') + bone.head[:] = 0.1114, 0.4766, 0.2473 + bone.tail[:] = 0.1088, 0.4138, 0.0411 + bone.roll = 0.0165 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.L']] + bones['foot.L'] = bone.name + bone = arm.edit_bones.new('foot.R') + bone.head[:] = -0.1114, 0.4766, 0.2473 + bone.tail[:] = -0.1088, 0.4138, 0.0411 + bone.roll = -0.0165 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.R']] + bones['foot.R'] = bone.name + bone = arm.edit_bones.new('spine.009') + bone.head[:] = 0.0000, -0.3618, 0.8375 + bone.tail[:] = 0.0000, -0.4253, 0.8585 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.008']] + bones['spine.009'] = bone.name + bone = arm.edit_bones.new('shoulder.L') + bone.head[:] = 0.0596, -0.2578, 0.8876 + bone.tail[:] = 0.1249, -0.3418, 0.7153 + bone.roll = -0.3526 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.008']] + bones['shoulder.L'] = bone.name + bone = arm.edit_bones.new('shoulder.R') + bone.head[:] = -0.0596, -0.2578, 0.8876 + bone.tail[:] = -0.1249, -0.3418, 0.7153 + bone.roll = 0.3526 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.008']] + bones['shoulder.R'] = bone.name + bone = arm.edit_bones.new('breast.L') + bone.head[:] = 0.0340, -0.1694, 0.6676 + bone.tail[:] = 0.0340, -0.3139, 0.5296 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.008']] + bones['breast.L'] = bone.name + bone = arm.edit_bones.new('breast.R') + bone.head[:] = -0.0340, -0.1694, 0.6676 + bone.tail[:] = -0.0340, -0.3139, 0.5296 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.008']] + bones['breast.R'] = bone.name + bone = arm.edit_bones.new('toe.L') + bone.head[:] = 0.1088, 0.4138, 0.0411 + bone.tail[:] = 0.1088, 0.2808, 0.0000 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.L']] + bones['toe.L'] = bone.name + bone = arm.edit_bones.new('toe.R') + bone.head[:] = -0.1088, 0.4138, 0.0411 + bone.tail[:] = -0.1088, 0.2808, 0.0000 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.R']] + bones['toe.R'] = bone.name + bone = arm.edit_bones.new('spine.010') + bone.head[:] = 0.0000, -0.4253, 0.8585 + bone.tail[:] = 0.0000, -0.4888, 0.8796 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.009']] + bones['spine.010'] = bone.name + bone = arm.edit_bones.new('front_thigh.L') + bone.head[:] = 0.1249, -0.3161, 0.6902 + bone.tail[:] = 0.1249, -0.2245, 0.4418 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.L']] + bones['front_thigh.L'] = bone.name + bone = arm.edit_bones.new('front_thigh.R') + bone.head[:] = -0.1249, -0.3161, 0.6902 + bone.tail[:] = -0.1249, -0.2245, 0.4418 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.R']] + bones['front_thigh.R'] = bone.name + bone = arm.edit_bones.new('spine.011') + bone.head[:] = 0.0000, -0.4888, 0.8796 + bone.tail[:] = 0.0000, -0.6590, 0.9809 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.010']] + bones['spine.011'] = bone.name + bone = arm.edit_bones.new('front_shin.L') + bone.head[:] = 0.1249, -0.2245, 0.4418 + bone.tail[:] = 0.1114, -0.2147, 0.1698 + bone.roll = 0.0098 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_thigh.L']] + bones['front_shin.L'] = bone.name + bone = arm.edit_bones.new('front_shin.R') + bone.head[:] = -0.1249, -0.2245, 0.4418 + bone.tail[:] = -0.1114, -0.2147, 0.1698 + bone.roll = -0.0098 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_thigh.R']] + bones['front_shin.R'] = bone.name + bone = arm.edit_bones.new('front_foot.L') + bone.head[:] = 0.1114, -0.2147, 0.1698 + bone.tail[:] = 0.1088, -0.2462, 0.0411 + bone.roll = 0.0272 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_shin.L']] + bones['front_foot.L'] = bone.name + bone = arm.edit_bones.new('front_foot.R') + bone.head[:] = -0.1114, -0.2147, 0.1698 + bone.tail[:] = -0.1088, -0.2462, 0.0411 + bone.roll = -0.0272 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_shin.R']] + bones['front_foot.R'] = bone.name + bone = arm.edit_bones.new('front_toe.L') + bone.head[:] = 0.1088, -0.2462, 0.0411 + bone.tail[:] = 0.1088, -0.3707, 0.0000 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_foot.L']] + bones['front_toe.L'] = bone.name + bone = arm.edit_bones.new('front_toe.R') + bone.head[:] = -0.1088, -0.2462, 0.0411 + bone.tail[:] = -0.1088, -0.3707, 0.0000 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['front_foot.R']] + bones['front_toe.R'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['spine']] + pbone.rigify_type = 'spines.super_spine' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.use_tail = True + except AttributeError: + pass + try: + pbone.rigify_parameters.tail_pos = 4 + except AttributeError: + pass + try: + pbone.rigify_parameters.pivot_pos = 8 + except AttributeError: + pass + try: + pbone.rigify_parameters.neck_pos = 10 + except AttributeError: + pass + try: + pbone.rigify_parameters.copy_rotation_axes = [True, False, True] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.tweak_extra_layers = False + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.004']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.005']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.neck_pos = 5 + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.006']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['pelvis.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['pelvis.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['thigh.L']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['thigh.R']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.007']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shin.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shin.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.008']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['foot.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['foot.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.009']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shoulder.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['shoulder.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.make_widget = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['breast.L']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['breast.R']] + pbone.rigify_type = 'basic.super_copy' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['toe.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + pbone = obj.pose.bones[bones['toe.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.010']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['front_thigh.L']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['front_thigh.R']] + pbone.rigify_type = 'limbs.super_limb' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.011']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['front_shin.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['front_shin.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['front_foot.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['front_foot.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['front_toe.L']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + pbone = obj.pose.bones[bones['front_toe.R']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + try: + pbone.rigify_parameters.rotation_axis = "x" + except AttributeError: + pass + try: + pbone.rigify_parameters.limb_type = "paw" + except AttributeError: + pass + + bpy.ops.object.mode_set(mode='EDIT') + for bone in arm.edit_bones: + bone.select = False + bone.select_head = False + bone.select_tail = False + for b in bones: + bone = arm.edit_bones[bones[b]] + bone.select = True + bone.select_head = True + bone.select_tail = True + arm.edit_bones.active = bone + + arm.layers = [(x in [3, 4, 7, 10, 13, 16, 19]) for x in range(32)] + +if __name__ == "__main__": + create(bpy.context.active_object)
\ No newline at end of file diff --git a/rigify/metarigs/human.py b/rigify/metarigs/human.py index c641fdbf..cf301cd2 100644 --- a/rigify/metarigs/human.py +++ b/rigify/metarigs/human.py @@ -1,71 +1,167 @@ import bpy + +from mathutils import Color + + def create(obj): # generated by rigify.utils.write_metarig bpy.ops.object.mode_set(mode='EDIT') arm = obj.data + for i in range(6): + arm.rigify_colors.add() + + arm.rigify_colors[0].name = "Root" + arm.rigify_colors[0].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[0].normal = Color((0.4352940022945404, 0.18431399762630463, 0.4156860113143921)) + arm.rigify_colors[0].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[0].standard_colors_lock = True + arm.rigify_colors[1].name = "IK" + arm.rigify_colors[1].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[1].normal = Color((0.6039220094680786, 0.0, 0.0)) + arm.rigify_colors[1].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[1].standard_colors_lock = True + arm.rigify_colors[2].name = "Special" + arm.rigify_colors[2].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[2].normal = Color((0.9568629860877991, 0.7882350087165833, 0.04705899953842163)) + arm.rigify_colors[2].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[2].standard_colors_lock = True + arm.rigify_colors[3].name = "Tweak" + arm.rigify_colors[3].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[3].normal = Color((0.03921600058674812, 0.21176500618457794, 0.5803920030593872)) + arm.rigify_colors[3].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[3].standard_colors_lock = True + arm.rigify_colors[4].name = "FK" + arm.rigify_colors[4].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[4].normal = Color((0.11764699965715408, 0.5686269998550415, 0.035294000059366226)) + arm.rigify_colors[4].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[4].standard_colors_lock = True + arm.rigify_colors[5].name = "Extra" + arm.rigify_colors[5].active = Color((0.5490196347236633, 1.0, 1.0)) + arm.rigify_colors[5].normal = Color((0.9686279892921448, 0.2509799897670746, 0.09411799907684326)) + arm.rigify_colors[5].select = Color((0.31372547149658203, 0.7843138575553894, 1.0)) + arm.rigify_colors[5].standard_colors_lock = True + for i in range(29): arm.rigify_layers.add() arm.rigify_layers[0].name = "Face" arm.rigify_layers[0].row = 1 + arm.rigify_layers[0].set = False + arm.rigify_layers[0].group = 5 arm.rigify_layers[1].name = "Face (Primary)" arm.rigify_layers[1].row = 2 + arm.rigify_layers[1].set = False + arm.rigify_layers[1].group = 2 arm.rigify_layers[2].name = "Face (Secondary)" arm.rigify_layers[2].row = 2 + arm.rigify_layers[2].set = False + arm.rigify_layers[2].group = 3 arm.rigify_layers[3].name = "Torso" arm.rigify_layers[3].row = 3 + arm.rigify_layers[3].set = False + arm.rigify_layers[3].group = 3 arm.rigify_layers[4].name = "Torso (Tweak)" arm.rigify_layers[4].row = 4 + arm.rigify_layers[4].set = False + arm.rigify_layers[4].group = 4 arm.rigify_layers[5].name = "Fingers" arm.rigify_layers[5].row = 5 + arm.rigify_layers[5].set = False + arm.rigify_layers[5].group = 6 arm.rigify_layers[6].name = "Fingers (Tweak)" arm.rigify_layers[6].row = 6 + arm.rigify_layers[6].set = False + arm.rigify_layers[6].group = 4 arm.rigify_layers[7].name = "Arm.L (IK)" arm.rigify_layers[7].row = 7 + arm.rigify_layers[7].set = False + arm.rigify_layers[7].group = 2 arm.rigify_layers[8].name = "Arm.L (FK)" arm.rigify_layers[8].row = 8 + arm.rigify_layers[8].set = False + arm.rigify_layers[8].group = 5 arm.rigify_layers[9].name = "Arm.L (Tweak)" arm.rigify_layers[9].row = 9 + arm.rigify_layers[9].set = False + arm.rigify_layers[9].group = 4 arm.rigify_layers[10].name = "Arm.R (IK)" arm.rigify_layers[10].row = 7 + arm.rigify_layers[10].set = False + arm.rigify_layers[10].group = 2 arm.rigify_layers[11].name = "Arm.R (FK)" arm.rigify_layers[11].row = 8 + arm.rigify_layers[11].set = False + arm.rigify_layers[11].group = 5 arm.rigify_layers[12].name = "Arm.R (Tweak)" arm.rigify_layers[12].row = 9 + arm.rigify_layers[12].set = False + arm.rigify_layers[12].group = 4 arm.rigify_layers[13].name = "Leg.L (IK)" arm.rigify_layers[13].row = 10 + arm.rigify_layers[13].set = False + arm.rigify_layers[13].group = 2 arm.rigify_layers[14].name = "Leg.L (FK)" arm.rigify_layers[14].row = 11 + arm.rigify_layers[14].set = False + arm.rigify_layers[14].group = 5 arm.rigify_layers[15].name = "Leg.L (Tweak)" arm.rigify_layers[15].row = 12 + arm.rigify_layers[15].set = False + arm.rigify_layers[15].group = 4 arm.rigify_layers[16].name = "Leg.R (IK)" arm.rigify_layers[16].row = 10 + arm.rigify_layers[16].set = False + arm.rigify_layers[16].group = 2 arm.rigify_layers[17].name = "Leg.R (FK)" arm.rigify_layers[17].row = 11 + arm.rigify_layers[17].set = False + arm.rigify_layers[17].group = 5 arm.rigify_layers[18].name = "Leg.R (Tweak)" arm.rigify_layers[18].row = 12 + arm.rigify_layers[18].set = False + arm.rigify_layers[18].group = 4 arm.rigify_layers[19].name = "" arm.rigify_layers[19].row = 1 + arm.rigify_layers[19].set = False + arm.rigify_layers[19].group = 0 arm.rigify_layers[20].name = "" arm.rigify_layers[20].row = 1 + arm.rigify_layers[20].set = False + arm.rigify_layers[20].group = 0 arm.rigify_layers[21].name = "" arm.rigify_layers[21].row = 1 + arm.rigify_layers[21].set = False + arm.rigify_layers[21].group = 0 arm.rigify_layers[22].name = "" arm.rigify_layers[22].row = 1 + arm.rigify_layers[22].set = False + arm.rigify_layers[22].group = 0 arm.rigify_layers[23].name = "" arm.rigify_layers[23].row = 1 + arm.rigify_layers[23].set = False + arm.rigify_layers[23].group = 0 arm.rigify_layers[24].name = "" arm.rigify_layers[24].row = 1 + arm.rigify_layers[24].set = False + arm.rigify_layers[24].group = 0 arm.rigify_layers[25].name = "" arm.rigify_layers[25].row = 1 + arm.rigify_layers[25].set = False + arm.rigify_layers[25].group = 0 arm.rigify_layers[26].name = "" arm.rigify_layers[26].row = 1 + arm.rigify_layers[26].set = False + arm.rigify_layers[26].group = 0 arm.rigify_layers[27].name = "" arm.rigify_layers[27].row = 1 + arm.rigify_layers[27].set = False + arm.rigify_layers[27].group = 0 arm.rigify_layers[28].name = "Root" arm.rigify_layers[28].row = 14 + arm.rigify_layers[28].set = False + arm.rigify_layers[28].group = 1 bones = {} @@ -154,7 +250,7 @@ def create(obj): bones['foot.R'] = bone.name bone = arm.edit_bones.new('spine.004') bone.head[:] = 0.0000, 0.0114, 1.6582 - bone.tail[:] = 0.0000, -0.013, 1.7197 + bone.tail[:] = 0.0000, -0.0130, 1.7197 bone.roll = 0.0000 bone.use_connect = True bone.parent = arm.edit_bones[bones['spine.003']] @@ -216,7 +312,7 @@ def create(obj): bone.parent = arm.edit_bones[bones['foot.R']] bones['heel.02.R'] = bone.name bone = arm.edit_bones.new('spine.005') - bone.head[:] = 0.0000, -0.013, 1.7197 + bone.head[:] = 0.0000, -0.0130, 1.7197 bone.tail[:] = 0.0000, -0.0247, 1.7813 bone.roll = 0.0000 bone.use_connect = True @@ -386,7 +482,7 @@ def create(obj): bone = arm.edit_bones.new('eye.R') bone.head[:] = -0.0516, -0.1209, 1.8941 bone.tail[:] = -0.0516, -0.1451, 1.8941 - bone.roll = -0.0000 + bone.roll = 0.0000 bone.use_connect = False bone.parent = arm.edit_bones[bones['face']] bones['eye.R'] = bone.name @@ -1191,7 +1287,6 @@ def create(obj): pbone.lock_scale = (False, False, False) pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - try: pbone.rigify_parameters.neck_pos = 5 except AttributeError: @@ -1241,22 +1336,6 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_ik_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.ik_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - except AttributeError: - pass - try: - pbone.rigify_parameters.separate_hose_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.hose_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - except AttributeError: - pass - try: pbone.rigify_parameters.limb_type = "leg" except AttributeError: pass @@ -1277,22 +1356,6 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_ik_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.ik_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - except AttributeError: - pass - try: - pbone.rigify_parameters.separate_hose_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.hose_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False] - except AttributeError: - pass - try: pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass @@ -1449,22 +1512,6 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_ik_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.ik_layers = [False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - except AttributeError: - pass - try: - pbone.rigify_parameters.separate_hose_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.hose_layers = [False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - except AttributeError: - pass - try: pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass @@ -1481,22 +1528,6 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_ik_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.ik_layers = [False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - except AttributeError: - pass - try: - pbone.rigify_parameters.separate_hose_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.hose_layers = [False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - except AttributeError: - pass - try: pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass @@ -1933,15 +1964,11 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_extra_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.tweak_extra_layers = True except AttributeError: pass try: - pbone.rigify_parameters.tweak_extra_layers = False + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['thumb.01.L']] @@ -1953,15 +1980,11 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.tweak_extra_layers = True except AttributeError: pass try: - pbone.rigify_parameters.separate_extra_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.tweak_extra_layers = False + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['f_middle.01.L']] @@ -1973,15 +1996,11 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_extra_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.tweak_extra_layers = True except AttributeError: pass try: - pbone.rigify_parameters.tweak_extra_layers = False + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['f_ring.01.L']] @@ -1993,15 +2012,11 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_extra_layers = True + pbone.rigify_parameters.tweak_extra_layers = True except AttributeError: pass try: - pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - except AttributeError: - pass - try: - pbone.rigify_parameters.tweak_extra_layers = False + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['f_pinky.01.L']] @@ -2013,15 +2028,11 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_extra_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.tweak_extra_layers = True except AttributeError: pass try: - pbone.rigify_parameters.tweak_extra_layers = False + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['f_index.01.R']] @@ -2033,15 +2044,11 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.tweak_extra_layers = True except AttributeError: pass try: - pbone.rigify_parameters.separate_extra_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.tweak_extra_layers = False + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['thumb.01.R']] @@ -2053,15 +2060,11 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_extra_layers = True + pbone.rigify_parameters.tweak_extra_layers = True except AttributeError: pass try: - pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - except AttributeError: - pass - try: - pbone.rigify_parameters.tweak_extra_layers = False + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['f_middle.01.R']] @@ -2073,15 +2076,11 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_extra_layers = True + pbone.rigify_parameters.tweak_extra_layers = True except AttributeError: pass try: - pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - except AttributeError: - pass - try: - pbone.rigify_parameters.tweak_extra_layers = False + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['f_ring.01.R']] @@ -2093,15 +2092,11 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_extra_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.tweak_extra_layers = True except AttributeError: pass try: - pbone.rigify_parameters.tweak_extra_layers = False + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['f_pinky.01.R']] @@ -2113,15 +2108,11 @@ def create(obj): pbone.rotation_mode = 'QUATERNION' pbone.bone.layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] try: - pbone.rigify_parameters.separate_extra_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.tweak_extra_layers = True except AttributeError: pass try: - pbone.rigify_parameters.tweak_extra_layers = False + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass pbone = obj.pose.bones[bones['nose.002']] diff --git a/rigify/rigs/faces/super_face.py b/rigify/rigs/faces/super_face.py index ae12ecf6..129ddb87 100644 --- a/rigify/rigs/faces/super_face.py +++ b/rigify/rigs/faces/super_face.py @@ -57,6 +57,15 @@ class Rig: else: self.secondary_layers = None + def orient_org_bones(self): + + bpy.ops.object.mode_set(mode='EDIT') + eb = self.obj.data.edit_bones + + # Adjust eye bones roll + eb['ORG-eye.L'].roll = 0.0 + eb['ORG-eye.R'].roll = 0.0 + def symmetrical_split(self, bones): # RE pattern match right or left parts @@ -254,6 +263,16 @@ class Rig: eb[ tweak_name ].use_connect = False eb[ tweak_name ].parent = None + if bone in uniques: + if bone.split('.')[-1] == 'L': + simmetrical_bone = bone[:-1] + 'R' + elif bone.split('.')[-1] == 'R': + simmetrical_bone = bone[:-1] + 'L' + middle_position = (eb[bone].head + eb[simmetrical_bone].head)/2 + eb[tweak_name].head = middle_position + eb[tweak_name].tail[0] = middle_position[0] + eb[tweak_name].tail[1] = middle_position[1] + tweaks.append( tweak_name ) eb[ tweak_name ].tail[:] = \ @@ -979,7 +998,8 @@ class Rig: }, tweak_unique def generate(self): - + + self.orient_org_bones() all_bones, tweak_unique = self.create_bones() self.parent_bones(all_bones, tweak_unique) self.constraints(all_bones) @@ -1184,7 +1204,7 @@ def create_sample(obj): bone = arm.edit_bones.new('eye.R') bone.head[:] = -0.0360, -0.0686, 0.1107 bone.tail[:] = -0.0360, -0.0848, 0.1107 - bone.roll = -0.0000 + bone.roll = 0.0000 bone.use_connect = False bone.parent = arm.edit_bones[bones['face']] bones['eye.R'] = bone.name diff --git a/rigify/rigs/limbs/arm.py b/rigify/rigs/limbs/arm.py index e7e08c41..b5c07569 100644 --- a/rigify/rigs/limbs/arm.py +++ b/rigify/rigs/limbs/arm.py @@ -1140,22 +1140,6 @@ def create_sample(obj): bones = {} - for _ in range(29): - arm.rigify_layers.add() - - arm.rigify_layers[5].name = 'Fingers' - arm.rigify_layers[5].row = 5 - arm.rigify_layers[6].name = 'Fingers (Tweak)' - arm.rigify_layers[6].row = 6 - arm.rigify_layers[7].name = 'Arm.L (IK)' - arm.rigify_layers[7].row = 7 - arm.rigify_layers[8].name = 'Arm.L (FK)' - arm.rigify_layers[8].row = 8 - arm.rigify_layers[9].name = 'Arm.L (Tweak)' - arm.rigify_layers[9].row = 9 - arm.rigify_layers[28].name = "Root" - arm.rigify_layers[28].row = 14 - bone = arm.edit_bones.new('upper_arm.L') bone.head[:] = 0.1953, 0.0267, 1.5846 bone.tail[:] = 0.4424, 0.0885, 1.4491 diff --git a/rigify/rigs/limbs/leg.py b/rigify/rigs/limbs/leg.py index c1cd1f06..021f641b 100644 --- a/rigify/rigs/limbs/leg.py +++ b/rigify/rigs/limbs/leg.py @@ -1449,18 +1449,6 @@ def create_sample(obj): bones = {} - for _ in range(29): - arm.rigify_layers.add() - - arm.rigify_layers[13].name = 'Leg.L (IK)' - arm.rigify_layers[13].row = 10 - arm.rigify_layers[14].name = 'Leg.L (FK)' - arm.rigify_layers[14].row = 11 - arm.rigify_layers[15].name = 'Leg.L (Tweak)' - arm.rigify_layers[15].row = 12 - arm.rigify_layers[28].name = "Root" - arm.rigify_layers[28].row = 14 - bone = arm.edit_bones.new('thigh.L') bone.head[:] = 0.0980, 0.0124, 1.0720 bone.tail[:] = 0.0980, -0.0286, 0.5372 diff --git a/rigify/rigs/limbs/paw.py b/rigify/rigs/limbs/paw.py index 720dea1c..8c9dab20 100644 --- a/rigify/rigs/limbs/paw.py +++ b/rigify/rigs/limbs/paw.py @@ -1277,22 +1277,6 @@ def create_sample(obj): bones = {} - for _ in range(29): - arm.rigify_layers.add() - - arm.rigify_layers[5].name = 'Paws' - arm.rigify_layers[5].row = 5 - arm.rigify_layers[6].name = 'Paws (Tweak)' - arm.rigify_layers[6].row = 6 - arm.rigify_layers[7].name = 'Arm.L (IK)' - arm.rigify_layers[7].row = 7 - arm.rigify_layers[8].name = 'Arm.L (FK)' - arm.rigify_layers[8].row = 8 - arm.rigify_layers[9].name = 'Arm.L (Tweak)' - arm.rigify_layers[9].row = 9 - arm.rigify_layers[28].name = "Root" - arm.rigify_layers[28].row = 14 - bone = arm.edit_bones.new('upper_arm.L') bone.head[:] = 0.0313, -0.1149, 0.2257 bone.tail[:] = 0.0313, -0.0878, 0.1235 diff --git a/rigify/rigs/limbs/rear_paw.py b/rigify/rigs/limbs/rear_paw.py index 015ede83..74974bb6 100644 --- a/rigify/rigs/limbs/rear_paw.py +++ b/rigify/rigs/limbs/rear_paw.py @@ -21,22 +21,6 @@ def create_sample(obj): bones = {} - for _ in range(29): - arm.rigify_layers.add() - - arm.rigify_layers[5].name = 'Paws' - arm.rigify_layers[5].row = 5 - arm.rigify_layers[6].name = 'Paws (Tweak)' - arm.rigify_layers[6].row = 6 - arm.rigify_layers[13].name = 'Leg.L (IK)' - arm.rigify_layers[13].row = 7 - arm.rigify_layers[14].name = 'Leg.L (FK)' - arm.rigify_layers[14].row = 8 - arm.rigify_layers[15].name = 'Leg.L (Tweak)' - arm.rigify_layers[15].row = 9 - arm.rigify_layers[28].name = "Root" - arm.rigify_layers[28].row = 14 - bone = arm.edit_bones.new('thigh.L') bone.head[:] = 0.0291, 0.1181, 0.2460 bone.tail[:] = 0.0293, 0.1107, 0.1682 diff --git a/rigify/ui.py b/rigify/ui.py index 4c9e6e78..b35bda77 100644 --- a/rigify/ui.py +++ b/rigify/ui.py @@ -20,6 +20,7 @@ import bpy from bpy.props import StringProperty +from mathutils import Color from .utils import get_rig_type, MetarigError from .utils import write_metarig, write_widget @@ -34,7 +35,6 @@ class DATA_PT_rigify_buttons(bpy.types.Panel): bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "data" - #bl_options = {'DEFAULT_OPEN'} @classmethod def poll(cls, context): @@ -69,7 +69,60 @@ class DATA_PT_rigify_buttons(bpy.types.Panel): if show_warning: layout.label(text=WARNING, icon='ERROR') - layout.operator("pose.rigify_generate", text="Generate Rig") + layout.operator("pose.rigify_generate", text="Generate Rig", icon='POSE_HLT') + if id_store.rigify_advanced_generation: + icon = 'UNLOCKED' + else: + icon = 'LOCKED' + layout.prop(id_store, "rigify_advanced_generation", toggle=True, icon=icon) + + if id_store.rigify_advanced_generation: + + row = layout.row(align=True) + row.prop(id_store, "rigify_generate_mode", expand=True) + + main_row = layout.row(align=True).split(percentage=0.3) + col1 = main_row.column() + col2 = main_row.column() + col1.label(text="Rig Name") + row = col1.row() + row.label(text="Target Rig") + row.enabled = (id_store.rigify_generate_mode == "overwrite") + row = col1.row() + row.label(text="Target UI") + row.enabled = (id_store.rigify_generate_mode == "overwrite") + + row = col2.row(align=True) + row.prop(id_store, "rigify_rig_basename", text="", icon="SORTALPHA") + + row = col2.row(align=True) + for i in range(0, len(id_store.rigify_target_rigs)): + id_store.rigify_target_rigs.remove(0) + + for ob in context.scene.objects: + if type(ob.data) == bpy.types.Armature and "rig_id" in ob.data: + id_store.rigify_target_rigs.add() + id_store.rigify_target_rigs[-1].name = ob.name + + row.prop_search(id_store, "rigify_target_rig", id_store, "rigify_target_rigs", text="", + icon='OUTLINER_OB_ARMATURE') + row.enabled = (id_store.rigify_generate_mode == "overwrite") + + for i in range(0, len(id_store.rigify_rig_uis)): + id_store.rigify_rig_uis.remove(0) + + for t in bpy.data.texts: + id_store.rigify_rig_uis.add() + id_store.rigify_rig_uis[-1].name = t.name + + row = col2.row() + row.prop_search(id_store, "rigify_rig_ui", id_store, "rigify_rig_uis", text="", icon='TEXT') + row.enabled = (id_store.rigify_generate_mode == "overwrite") + + row = layout.row() + row.prop(id_store, "rigify_force_widget_update") + if id_store.rigify_generate_mode == 'new': + row.enabled = False if show_update_metarig: layout.label(text="Some bones have old legacy rigify_type. Click to upgrade", icon='ERROR') @@ -84,7 +137,7 @@ class DATA_PT_rigify_buttons(bpy.types.Panel): id_store.rigify_types.remove(0) for r in rig_lists.rig_list: - # collection = r.split('.')[0] # UNUSED + if collection_name == "All": a = id_store.rigify_types.add() a.name = r @@ -95,10 +148,6 @@ class DATA_PT_rigify_buttons(bpy.types.Panel): a = id_store.rigify_types.add() a.name = r - ## Rig collection field - #row = layout.row() - #row.prop(id_store, 'rigify_collection', text="Category") - # Rig type list row = layout.row() row.template_list("UI_UL_list", "rigify_types", id_store, "rigify_types", id_store, 'rigify_active_type') @@ -129,21 +178,30 @@ class DATA_PT_rigify_layer_names(bpy.types.Panel): arm.rigify_layers.add() else: # Can't add while drawing, just use button - if len(arm.rigify_layers) < 28: + if len(arm.rigify_layers) < 29: layout.operator("pose.rigify_layer_init") return # UI + main_row = layout.row(align=True).split(0.05) + col1 = main_row.column() + col2 = main_row.column() + col1.label() + for i in range(32): + if i == 16 or i == 29: + col1.label() + col1.label(str(i+1) + '.') + for i, rigify_layer in enumerate(arm.rigify_layers): # note: rigify_layer == arm.rigify_layers[i] if (i % 16) == 0: - col = layout.column() + col = col2.column() if i == 0: col.label(text="Top Row:") else: col.label(text="Bottom Row:") if (i % 8) == 0: - col = layout.column() + col = col2.column() if i != 28: row = col.row(align=True) icon = 'RESTRICT_VIEW_OFF' if arm.layers[i] else 'RESTRICT_VIEW_ON' @@ -172,7 +230,7 @@ class DATA_PT_rigify_layer_names(bpy.types.Panel): else: row.label(text=arm.rigify_colors[rigify_layer.group-1].name) - col = layout.column() + col = col2.column() col.label(text="Reserved:") # reserved_names = {28: 'Root', 29: 'DEF', 30: 'MCH', 31: 'ORG'} reserved_names = {29: 'DEF', 30: 'MCH', 31: 'ORG'} @@ -198,20 +256,31 @@ class DATA_OT_rigify_add_bone_groups(bpy.types.Operator): if not hasattr(armature, 'rigify_colors'): return {'FINISHED'} - groups = ['Face', 'Face Primary', 'Face Secondary', 'FK', 'IK', 'Tweaks', 'Torso', 'Upper Body', 'Upper Spine'] - themes = {'Face': 'THEME11', 'Face Primary': 'THEME01', 'Face Secondary': 'THEME09', - 'FK': 'THEME04', 'IK': 'THEME01', 'Tweaks': 'THEME14', - 'Torso': 'THEME03', 'Upper Body': 'THEME09', 'Upper Spine': 'THEME02'} + groups = ['Root', 'IK', 'Special', 'Tweak', 'FK', 'Extra'] for g in groups: if g in armature.rigify_colors.keys(): continue + armature.rigify_colors.add() armature.rigify_colors[-1].name = g - id = int(themes[g][-2:]) - 1 - armature.rigify_colors[-1].normal = bpy.context.user_preferences.themes[0].bone_color_sets[id].normal - armature.rigify_colors[-1].select = bpy.context.user_preferences.themes[0].bone_color_sets[id].select - armature.rigify_colors[-1].active = bpy.context.user_preferences.themes[0].bone_color_sets[id].active + + armature.rigify_colors[g].select = Color((0.3140000104904175, 0.7839999794960022, 1.0)) + armature.rigify_colors[g].active = Color((0.5490000247955322, 1.0, 1.0)) + armature.rigify_colors[g].standard_colors_lock = True + + if g == "Root": + armature.rigify_colors[g].normal = Color((0.43529415130615234, 0.18431372940540314, 0.41568630933761597)) + if g == "IK": + armature.rigify_colors[g].normal = Color((0.6039215922355652, 0.0, 0.0)) + if g== "Special": + armature.rigify_colors[g].normal = Color((0.9568628072738647, 0.7882353663444519, 0.0470588281750679)) + if g== "Tweak": + armature.rigify_colors[g].normal = Color((0.03921568766236305, 0.21176472306251526, 0.5803921818733215)) + if g== "FK": + armature.rigify_colors[g].normal = Color((0.11764706671237946, 0.5686274766921997, 0.03529411926865578)) + if g== "Extra": + armature.rigify_colors[g].normal = Color((0.9686275124549866, 0.250980406999588, 0.0941176563501358)) return {'FINISHED'} @@ -553,20 +622,6 @@ class VIEW3D_PT_tools_rigify_dev(bpy.types.Panel): r = self.layout.row() r.operator("mesh.rigify_encode_mesh_widget", text="Encode Mesh Widget to Python") -#~ class INFO_MT_armature_metarig_add(bpy.types.Menu): - #~ bl_idname = "INFO_MT_armature_metarig_add" - #~ bl_label = "Meta-Rig" - - #~ def draw(self, context): - #~ import rigify - - #~ layout = self.layout - #~ layout.operator_context = 'INVOKE_REGION_WIN' - - #~ for submodule_type in rigify.get_submodule_types(): - #~ text = bpy.path.display_name(submodule_type) - #~ layout.operator("pose.metarig_sample_add", text=text, icon='OUTLINER_OB_ARMATURE').metarig_type = submodule_type - def rigify_report_exception(operator, exception): import traceback @@ -600,8 +655,10 @@ class LayerInit(bpy.types.Operator): def execute(self, context): obj = context.object arm = obj.data - for i in range(1 + len(arm.rigify_layers), 29): + for i in range(1 + len(arm.rigify_layers), 30): arm.rigify_layers.add() + arm.rigify_layers[28].name = 'Root' + arm.rigify_layers[28].row = 14 return {'FINISHED'} @@ -696,7 +753,7 @@ class EncodeMetarig(bpy.types.Operator): else: text_block = bpy.data.texts.new(name) - text = write_metarig(context.active_object, layers=True, func_name="create") + text = write_metarig(context.active_object, layers=True, func_name="create", groups=True) text_block.write(text) bpy.ops.object.mode_set(mode='EDIT') diff --git a/rigify/utils.py b/rigify/utils.py index 32f845b8..a1a1dbec 100644 --- a/rigify/utils.py +++ b/rigify/utils.py @@ -26,7 +26,7 @@ import random import time import re import os -from mathutils import Vector, Matrix +from mathutils import Vector, Matrix, Color from rna_prop_ui import rna_idprop_ui_prop_get RIG_DIR = "rigs" # Name of the directory where rig types are kept @@ -51,6 +51,7 @@ outdated_types = {"pitchipoy.limbs.super_limb": "limbs.super_limb", "pitchipoy.simple_tentacle": "limbs.simple_tentacle", "pitchipoy.super_face": "faces.super_face", "pitchipoy.super_palm": "limbs.super_palm", + "pitchipoy.super_copy": "basic.super_copy", "palm": "limbs.super_palm", "basic.copy": "basic.super_copy"} @@ -411,8 +412,9 @@ def create_widget(rig, bone_name, bone_transform_name=None): if bone_transform_name is None: bone_transform_name = bone_name - obj_name = WGT_PREFIX + bone_name + obj_name = WGT_PREFIX + rig.name + '_' + bone_name scene = bpy.context.scene + id_store = bpy.context.window_manager # Check if it already exists in the scene if obj_name in scene.objects: @@ -436,8 +438,9 @@ def create_widget(rig, bone_name, bone_transform_name=None): # Move object to bone position and set layers obj_to_bone(obj, rig, bone_transform_name) - if 'WGTS' in bpy.data.objects.keys(): - obj.parent = bpy.data.objects['WGTS'] + wgts_group_name = 'WGTS_' + rig.name + if wgts_group_name in bpy.data.objects.keys(): + obj.parent = bpy.data.objects[wgts_group_name] obj.layers = WGT_LAYERS return obj @@ -954,7 +957,7 @@ def get_layers(layers): return [x in layers for x in range(0, 32)] -def write_metarig(obj, layers=False, func_name="create"): +def write_metarig(obj, layers=False, func_name="create", groups=False): """ Write a metarig as a python script, this rig is to have all info needed for generating the real rig with rigify. @@ -962,6 +965,7 @@ def write_metarig(obj, layers=False, func_name="create"): code = [] code.append("import bpy\n\n") + code.append("from mathutils import Color\n\n") code.append("def %s(obj):" % func_name) code.append(" # generated by rigify.utils.write_metarig") @@ -971,6 +975,23 @@ def write_metarig(obj, layers=False, func_name="create"): arm = obj.data + # Rigify bone group colors info + if groups and len(arm.rigify_colors) > 0: + code.append("\n for i in range(" + str(len(arm.rigify_colors)) + "):") + code.append(" arm.rigify_colors.add()\n") + + for i in range(len(arm.rigify_colors)): + name = arm.rigify_colors[i].name + active = arm.rigify_colors[i].active + normal = arm.rigify_colors[i].normal + select = arm.rigify_colors[i].select + standard_colors_lock = arm.rigify_colors[i].standard_colors_lock + code.append(' arm.rigify_colors[' + str(i) + '].name = "' + name + '"') + code.append(' arm.rigify_colors[' + str(i) + '].active = Color(' + str(active[:]) + ')') + code.append(' arm.rigify_colors[' + str(i) + '].normal = Color(' + str(normal[:]) + ')') + code.append(' arm.rigify_colors[' + str(i) + '].select = Color(' + str(select[:]) + ')') + code.append(' arm.rigify_colors[' + str(i) + '].standard_colors_lock = ' + str(standard_colors_lock)) + # Rigify layer layout info if layers and len(arm.rigify_layers) > 0: code.append("\n for i in range(" + str(len(arm.rigify_layers)) + "):") @@ -979,8 +1000,12 @@ def write_metarig(obj, layers=False, func_name="create"): for i in range(len(arm.rigify_layers)): name = arm.rigify_layers[i].name row = arm.rigify_layers[i].row + set = arm.rigify_layers[i].set + group = arm.rigify_layers[i].group code.append(' arm.rigify_layers[' + str(i) + '].name = "' + name + '"') code.append(' arm.rigify_layers[' + str(i) + '].row = ' + str(row)) + code.append(' arm.rigify_layers[' + str(i) + '].set = ' + str(set)) + code.append(' arm.rigify_layers[' + str(i) + '].group = ' + str(group)) # write parents first bones = [(len(bone.parent_recursive), bone.name) for bone in arm.edit_bones] @@ -1118,3 +1143,31 @@ def random_id(length=8): text += random.choice(chars) text += str(hex(int(time.time())))[2:][-tlength:].rjust(tlength, '0')[::-1] return text + + +#============================================= +# Color correction functions +#============================================= + +def linsrgb_to_srgb (linsrgb): + """Convert physically linear RGB values into sRGB ones. The transform is + uniform in the components, so *linsrgb* can be of any shape. + + *linsrgb* values should range between 0 and 1, inclusively. + + """ + # From Wikipedia, but easy analogue to the above. + gamma = 1.055 * linsrgb**(1./2.4) - 0.055 + scale = linsrgb * 12.92 + # return np.where (linsrgb > 0.0031308, gamma, scale) + if linsrgb > 0.0031308: + return gamma + return scale + + +def gamma_correct(color): + + corrected_color = Color() + for i, component in enumerate(color): + corrected_color[i] = linsrgb_to_srgb(color[i]) + return corrected_color diff --git a/space_clip_editor_autotracker.py b/space_clip_editor_autotracker.py index cd00f2e7..9dea7e54 100644 --- a/space_clip_editor_autotracker.py +++ b/space_clip_editor_autotracker.py @@ -19,7 +19,7 @@ bl_info = { "name": "Autotrack", "author": "Miika Puustinen, Matti Kaihola, Stephen Leger", - "version": (0, 0, 99), + "version": (0, 1, 0), "blender": (2, 78, 0), "location": "Movie clip Editor > Tools Panel > Autotrack", "description": "Motion Tracking with automatic feature detection.", @@ -579,7 +579,7 @@ class AutotrackerSettings(PropertyGroup): ] placement_list = EnumProperty( - name="", + name="Placement", description="Feature Placement", items=list_items ) @@ -604,43 +604,39 @@ class AutotrackerPanel(Panel): def draw(self, context): layout = self.layout wm = context.window_manager - row = layout.row(align=True) + + row = layout.row() row.scale_y = 1.5 - props = row.operator("tracking.auto_track", text="Autotrack! ", icon='PLAY') - row = layout.row(align=True) + row = layout.row() row.prop(wm.autotracker_props, "track_backwards") - row = layout.row(align=True) # make next row - row.prop(wm.autotracker_props, "delete_threshold") - - row = layout.row(align=True) # make next row - row.prop(wm.autotracker_props, "small_tracks") - - row = layout.row(align=True) - row.prop(wm.autotracker_props, "frame_separation", text="Frame Separation") + row = layout.row() + col = layout.column(align=True) + col.prop(wm.autotracker_props, "delete_threshold") + sub = col.row(align=True) + sub.prop(wm.autotracker_props, "small_tracks") + sub = col.row(align=True) + sub.prop(wm.autotracker_props, "frame_separation", text="Frame Separation") + sub = col.row(align=True) + sub.prop(wm.autotracker_props, "jump_cut", text="Jump Threshold") - row = layout.row(align=True) - row.prop(wm.autotracker_props, "jump_cut", text="Jump Threshold") - - row = layout.row(align=True) + row = layout.row() row.label(text="Detect Features Settings:") + col = layout.column(align=True) + col.prop(wm.autotracker_props, "df_margin", text="Margin:") + sub = col.row(align=True) + sub.prop(wm.autotracker_props, "df_distance", text="Distance:") + sub = col.row(align=True) + sub.prop(wm.autotracker_props, "df_threshold", text="Threshold:") - row = layout.row(align=True) - row.prop(wm.autotracker_props, "df_margin", text="Margin:") - - row = layout.row(align=True) - row.prop(wm.autotracker_props, "df_threshold", text="Threshold:") - - row = layout.row(align=True) - row.prop(wm.autotracker_props, "df_distance", text="Distance:") - - row = layout.row(align=True) + row = layout.row() row.label(text="Feature Placement:") + col = layout.column(align=True) + col.prop(wm.autotracker_props, "placement_list", text="") - row = layout.row(align=True) - row.prop(wm.autotracker_props, "placement_list") + layout.separator() def register(): bpy.utils.register_class(AutotrackerSettings) diff --git a/space_view3d_display_tools/__init__.py b/space_view3d_display_tools/__init__.py index 950f9f09..d76ca8e2 100644 --- a/space_view3d_display_tools/__init__.py +++ b/space_view3d_display_tools/__init__.py @@ -402,6 +402,8 @@ class DisplayToolsPanel(Panel): if obj: if obj.mode == 'OBJECT': layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...") + layout.operator_menu_enum("object.hide_by_type", "type", text="Hide By Type") + layout.operator_menu_enum("object.show_by_type", "type", text="Show By Type") col = layout.column(align=True) col.operator("opr.select_all", icon="MOD_MESHDEFORM") col.operator("opr.inverse_selection", icon="MOD_REMESH") @@ -608,10 +610,20 @@ class DisplayToolsPreferences(AddonPreferences): col.prop(self, "category", text="") +def DRAW_hide_by_type_MENU(self, context): + self.layout.operator_menu_enum( + "object.hide_by_type", + "type", text="Hide By Type" + ) + self.layout.operator_menu_enum( + "object.show_by_type", + "type", text="Show By Type" + ) + # register the classes and props def register(): bpy.utils.register_module(__name__) - + bpy.types.VIEW3D_MT_object_showhide.append(DRAW_hide_by_type_MENU) # Register Scene Properties bpy.types.Scene.display_tools = PointerProperty( type=display_tools_scene_props @@ -623,6 +635,7 @@ def register(): def unregister(): del bpy.types.Scene.display_tools selection_restrictor.unregister() + bpy.types.VIEW3D_MT_object_showhide.remove(DRAW_hide_by_type_MENU) bpy.utils.unregister_module(__name__) diff --git a/space_view3d_display_tools/select_tools.py b/space_view3d_display_tools/select_tools.py index ca429384..5327ba7f 100644 --- a/space_view3d_display_tools/select_tools.py +++ b/space_view3d_display_tools/select_tools.py @@ -210,6 +210,108 @@ class HideRenderAllSelected(Operator): return {'FINISHED'} +class OBJECT_OT_HideShowByTypeTemplate(): + + bl_options = {'UNDO','REGISTER'} + + type = bpy.props.EnumProperty(items=( + ('MESH', 'Mesh', ''), + ('CURVE', 'Curve', ''), + ('SURFACE', 'Surface', ''), + ('META', 'Meta', ''), + ('FONT', 'Font', ''), + ('ARMATURE', 'Armature', ''), + ('LATTICE', 'Lattice', ''), + ('EMPTY', 'Empty', ''), + ('CAMERA', 'Camera', ''), + ('LAMP', 'Lamp', ''), + ('ALL', 'All', '')), + name='Type', + description='Type', + default='LAMP', + options={'ANIMATABLE'}) + + def execute(self, context): + + scene = bpy.context.scene + objects = [] + eligible_objects = [] + + # Only Selected? + if self.hide_selected: + objects = bpy.context.selected_objects + else: + objects = scene.objects + + # Only Specific Types? + Filter layers + for obj in objects: + for i in range(0,20): + if obj.layers[i] & scene.layers[i]: + if self.type == 'ALL' or obj.type == self.type: + if obj not in eligible_objects: + eligible_objects.append(obj) + objects = eligible_objects + eligible_objects = [] + + + # Only Render Restricted? + if self.hide_render_restricted: + for obj in objects: + if obj.hide_render == self.hide_or_show: + eligible_objects.append(obj) + objects = eligible_objects + eligible_objects = [] + + # Perform Hiding / Showing + for obj in objects: + obj.hide = self.hide_or_show + + return {'FINISHED'} + + def invoke(self, context, event): + return self.execute(context) + + +## show hide by type ## by Felix Schlitter +class OBJECT_OT_HideByType(OBJECT_OT_HideShowByTypeTemplate, Operator): + bl_idname = 'object.hide_by_type' + bl_label = 'Hide By Type' + hide_or_show = bpy.props.BoolProperty( + name="Hide", + description="Inverse effect", + options={'HIDDEN'}, + default=1 + ) + hide_selected = bpy.props.BoolProperty( + name="Selected", + description="Hide only selected objects", + default=0 + ) + hide_render_restricted = bpy.props.BoolProperty( + name="Only Render-Restricted", + description="Hide only render restricted objects", + default=0 + ) + +class OBJECT_OT_ShowByType(OBJECT_OT_HideShowByTypeTemplate, Operator): + bl_idname = 'object.show_by_type' + bl_label = 'Show By Type' + hide_or_show = bpy.props.BoolProperty( + name="Hide", + description="Inverse effect", + options={'HIDDEN'}, + default=0 + ) + hide_selected = bpy.props.BoolProperty( + name="Selected", + options={'HIDDEN'}, + default=0 + ) + hide_render_restricted = bpy.props.BoolProperty( + name="Only Renderable", + description="Show only non render restricted objects", + default=0 + ) # Register def register(): diff --git a/space_view3d_pie_menus/__init__.py b/space_view3d_pie_menus/__init__.py index 101d7426..5a08426f 100644 --- a/space_view3d_pie_menus/__init__.py +++ b/space_view3d_pie_menus/__init__.py @@ -21,14 +21,13 @@ bl_info = { "name": "3D Viewport Pie Menus", "author": "meta-androcto, pitiwazou, chromoly, italic", - "version": (1, 1, 3), + "version": (1, 1, 4), "blender": (2, 7, 7), "description": "Individual Pie Menu Activation List", "location": "Addons Preferences", "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" "Scripts/3D_interaction/viewport_pies", - "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/", "category": "Pie Menu" } diff --git a/space_view3d_pie_menus/pie_editor_switch_menu.py b/space_view3d_pie_menus/pie_editor_switch_menu.py index 710c8fe1..788b053d 100644 --- a/space_view3d_pie_menus/pie_editor_switch_menu.py +++ b/space_view3d_pie_menus/pie_editor_switch_menu.py @@ -56,7 +56,8 @@ class AreaTypePieOperator(Operator): bl_options = {'REGISTER', 'UNDO'} def execute(self, context): - bpy.ops.wm.call_menu_pie(name=AreaTypeEditor.bl_idname) + bpy.ops.wm.call_menu_pie(name=AreaPieEditor.bl_idname) + return {'FINISHED'} @@ -99,7 +100,8 @@ class AreaTypePieOther(Menu): self.layout.operator(SetAreaType.bl_idname, text="Python Console", icon="CONSOLE").type = "CONSOLE" # 8 - TOP # 7 - TOP - LEFT - self.layout.operator(SetAreaType.bl_idname, text="User Setting", icon="PREFERENCES").type = "USER_PREFERENCES" + self.layout.operator(SetAreaType.bl_idname, text="User Setting", + icon="PREFERENCES").type = "USER_PREFERENCES" # 9 - TOP - RIGHT self.layout.operator(SetAreaType.bl_idname, text="Info", icon="INFO").type = "INFO" # 1 - BOTTOM - LEFT @@ -134,13 +136,16 @@ class AreaTypePieAnim(Menu): # 8 - TOP self.layout.operator(SetAreaType.bl_idname, text="Timeline", icon="TIME").type = "TIMELINE" # 7 - TOP - LEFT - self.layout.operator(SetAreaType.bl_idname, text="Video Sequence Editor", icon="SEQUENCE").type = "SEQUENCE_EDITOR" + self.layout.operator(SetAreaType.bl_idname, + text="Video Sequence Editor", icon="SEQUENCE").type = "SEQUENCE_EDITOR" # 9 - TOP - RIGHT - self.layout.operator(SetAreaType.bl_idname, text="Video Clip Editor", icon="RENDER_ANIMATION").type = "CLIP_EDITOR" + self.layout.operator(SetAreaType.bl_idname, + text="Video Clip Editor", icon="RENDER_ANIMATION").type = "CLIP_EDITOR" # 1 - BOTTOM - LEFT - self.layout.operator("wm.call_menu_pie", text="Back", icon="BACK").name = PieEditor.bl_idname + self.layout.operator("wm.call_menu_pie", text="Back", icon="BACK").name = AreaPieEditor.bl_idname # 3 - BOTTOM - RIGHT + classes = ( AreaPieMenu, AreaTypePieOperator, @@ -180,5 +185,6 @@ def unregister(): if kmi.properties.name == "wm.area_type_pie_operator": km.keymap_items.remove(kmi) + if __name__ == "__main__": register() diff --git a/ui_layer_manager.py b/ui_layer_manager.py index 1bae9770..8742df8a 100644 --- a/ui_layer_manager.py +++ b/ui_layer_manager.py @@ -411,7 +411,6 @@ class SCENE_PT_namedlayer_layers(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'TOOLS' bl_label = "Layer Management" - bl_options = {'DEFAULT_CLOSED'} bl_category = "Layers" bl_context = "objectmode" diff --git a/uv_magic_uv/__init__.py b/uv_magic_uv/__init__.py index dd236667..01d3582a 100644 --- a/uv_magic_uv/__init__.py +++ b/uv_magic_uv/__init__.py @@ -20,43 +20,45 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" +__version__ = "4.3.1" +__date__ = "6 June 2017" bl_info = { "name": "Magic UV", - "author": "Nutti, Mifth, Jace Priester, kgeogeo, mem, Keith (Wahooney) Boshoff, McBuff, MaxRobinot", - "version": (4, 3), + "author": "Nutti, Mifth, Jace Priester, kgeogeo, mem, " + "Keith (Wahooney) Boshoff, McBuff, MaxRobinot", + "version": (4, 3, 1), "blender": (2, 77, 0), "location": "See Add-ons Preferences", "description": "UV Manipulator Tools. See Add-ons Preferences for details", "warning": "", "support": "COMMUNITY", - "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/UV/Magic_UV", + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/" + "Py/Scripts/UV/Magic_UV", "tracker_url": "https://github.com/nutti/Magic-UV", "category": "UV" } if "bpy" in locals(): - import imp - imp.reload(muv_preferences) - imp.reload(muv_menu) - imp.reload(muv_common) - imp.reload(muv_props) - imp.reload(muv_cpuv_ops) - imp.reload(muv_cpuv_selseq_ops) - imp.reload(muv_fliprot_ops) - imp.reload(muv_transuv_ops) - imp.reload(muv_uvbb_ops) - imp.reload(muv_mvuv_ops) - imp.reload(muv_texproj_ops) - imp.reload(muv_packuv_ops) - imp.reload(muv_texlock_ops) - imp.reload(muv_mirroruv_ops) - imp.reload(muv_wsuv_ops) - imp.reload(muv_unwrapconst_ops) - imp.reload(muv_preserve_uv_aspect) + import importlib + importlib.reload(muv_preferences) + importlib.reload(muv_menu) + importlib.reload(muv_common) + importlib.reload(muv_props) + importlib.reload(muv_cpuv_ops) + importlib.reload(muv_cpuv_selseq_ops) + importlib.reload(muv_fliprot_ops) + importlib.reload(muv_transuv_ops) + importlib.reload(muv_uvbb_ops) + importlib.reload(muv_mvuv_ops) + importlib.reload(muv_texproj_ops) + importlib.reload(muv_packuv_ops) + importlib.reload(muv_texlock_ops) + importlib.reload(muv_mirroruv_ops) + importlib.reload(muv_wsuv_ops) + importlib.reload(muv_unwrapconst_ops) + importlib.reload(muv_preserve_uv_aspect) else: from . import muv_preferences from . import muv_menu diff --git a/uv_magic_uv/muv_common.py b/uv_magic_uv/muv_common.py index 66f2a54b..121915e8 100644 --- a/uv_magic_uv/muv_common.py +++ b/uv_magic_uv/muv_common.py @@ -20,9 +20,8 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" import bpy from . import muv_props diff --git a/uv_magic_uv/muv_cpuv_ops.py b/uv_magic_uv/muv_cpuv_ops.py index fbf1764f..3ef1a9de 100644 --- a/uv_magic_uv/muv_cpuv_ops.py +++ b/uv_magic_uv/muv_cpuv_ops.py @@ -20,13 +20,17 @@ __author__ = "Nutti <nutti.metro@gmail.com>, Jace Priester" __status__ = "production" -__version__ = "4.3" +__version__ = "4.3.1" __date__ = "1 Apr 2017" - import bpy import bmesh -from bpy.props import StringProperty, BoolProperty, IntProperty, EnumProperty +from bpy.props import ( + StringProperty, + BoolProperty, + IntProperty, + EnumProperty, + ) from . import muv_common @@ -399,8 +403,8 @@ class MUV_CPUVObjPasteUV(bpy.types.Operator): if len(props.src_uvs) != len(dest_uvs): self.report( {'WARNING'}, - "Number of faces is different from copied " - + "(src:%d, dest:%d)" + "Number of faces is different from copied " + + "(src:%d, dest:%d)" % (len(props.src_uvs), len(dest_uvs)) ) return {'CANCELLED'} diff --git a/uv_magic_uv/muv_cpuv_selseq_ops.py b/uv_magic_uv/muv_cpuv_selseq_ops.py index 37e9f8de..bbb9de5a 100644 --- a/uv_magic_uv/muv_cpuv_selseq_ops.py +++ b/uv_magic_uv/muv_cpuv_selseq_ops.py @@ -20,13 +20,17 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" import bpy import bmesh -from bpy.props import StringProperty, BoolProperty, IntProperty, EnumProperty +from bpy.props import ( + StringProperty, + BoolProperty, + IntProperty, + EnumProperty, + ) from . import muv_common @@ -180,8 +184,8 @@ class MUV_CPUVSelSeqPasteUV(bpy.types.Operator): if self.strategy == 'N_N' and len(props.src_uvs) != len(dest_uvs): self.report( {'WARNING'}, - "Number of selected faces is different from copied faces " - + "(src:%d, dest:%d)" + "Number of selected faces is different from copied faces " + + "(src:%d, dest:%d)" % (len(props.src_uvs), len(dest_uvs))) return {'CANCELLED'} diff --git a/uv_magic_uv/muv_fliprot_ops.py b/uv_magic_uv/muv_fliprot_ops.py index 597ee2a6..2c72d643 100644 --- a/uv_magic_uv/muv_fliprot_ops.py +++ b/uv_magic_uv/muv_fliprot_ops.py @@ -20,13 +20,15 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" import bpy import bmesh -from bpy.props import BoolProperty, IntProperty +from bpy.props import ( + BoolProperty, + IntProperty, + ) from . import muv_common diff --git a/uv_magic_uv/muv_menu.py b/uv_magic_uv/muv_menu.py index fd4ef205..b177e9c8 100644 --- a/uv_magic_uv/muv_menu.py +++ b/uv_magic_uv/muv_menu.py @@ -20,9 +20,8 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" import bpy from . import muv_cpuv_ops diff --git a/uv_magic_uv/muv_mirroruv_ops.py b/uv_magic_uv/muv_mirroruv_ops.py index d0a98b87..5fc2ac4c 100644 --- a/uv_magic_uv/muv_mirroruv_ops.py +++ b/uv_magic_uv/muv_mirroruv_ops.py @@ -20,12 +20,14 @@ __author__ = "Keith (Wahooney) Boshoff, Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" import bpy -from bpy.props import EnumProperty, FloatProperty +from bpy.props import ( + EnumProperty, + FloatProperty, + ) import bmesh from mathutils import Vector from . import muv_common diff --git a/uv_magic_uv/muv_mvuv_ops.py b/uv_magic_uv/muv_mvuv_ops.py index 2eb0991f..192d7f21 100644 --- a/uv_magic_uv/muv_mvuv_ops.py +++ b/uv_magic_uv/muv_mvuv_ops.py @@ -20,9 +20,8 @@ __author__ = "kgeogeo, mem, Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" import bpy import bmesh diff --git a/uv_magic_uv/muv_packuv_ops.py b/uv_magic_uv/muv_packuv_ops.py index 06e79e7a..829bf605 100644 --- a/uv_magic_uv/muv_packuv_ops.py +++ b/uv_magic_uv/muv_packuv_ops.py @@ -20,9 +20,8 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" from math import fabs from collections import defaultdict @@ -30,7 +29,11 @@ from collections import defaultdict import bpy import bmesh import mathutils -from bpy.props import FloatProperty, FloatVectorProperty, BoolProperty +from bpy.props import ( + FloatProperty, + FloatVectorProperty, + BoolProperty, + ) from mathutils import Vector from . import muv_common diff --git a/uv_magic_uv/muv_preferences.py b/uv_magic_uv/muv_preferences.py index 7e13c6ea..f80ad28e 100644 --- a/uv_magic_uv/muv_preferences.py +++ b/uv_magic_uv/muv_preferences.py @@ -20,11 +20,14 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - - -from bpy.props import BoolProperty, FloatProperty, FloatVectorProperty +__version__ = "4.3.1" +__date__ = "6 June 2017" + +from bpy.props import ( + BoolProperty, + FloatProperty, + FloatVectorProperty, + ) from bpy.types import AddonPreferences @@ -44,7 +47,7 @@ class MUV_Preferences(AddonPreferences): # for Texture Projection texproj_canvas_padding = FloatVectorProperty( name="Canvas Padding", - description="Canvas Padding.", + description="Canvas Padding", size=2, max=50.0, min=0.0, diff --git a/uv_magic_uv/muv_preserve_uv_aspect.py b/uv_magic_uv/muv_preserve_uv_aspect.py index 0fbb820d..bc9ce3eb 100644 --- a/uv_magic_uv/muv_preserve_uv_aspect.py +++ b/uv_magic_uv/muv_preserve_uv_aspect.py @@ -20,9 +20,8 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" import bpy import bmesh @@ -38,6 +37,7 @@ class MUV_PreserveUVAspect(bpy.types.Operator): bl_idname = "uv.muv_preserve_uv_aspect" bl_label = "Preserve UV Aspect" + bl_description = "Choose Image" bl_options = {'REGISTER', 'UNDO'} dest_img_name = StringProperty(options={'HIDDEN'}) @@ -48,6 +48,9 @@ class MUV_PreserveUVAspect(bpy.types.Operator): return obj and obj.type == 'MESH' def execute(self, context): + # Note: the current system only works if the + # f[tex_layer].image doesn't return None + # which will happen in certain cases obj = context.active_object bm = bmesh.from_edit_mesh(obj.data) @@ -57,6 +60,7 @@ class MUV_PreserveUVAspect(bpy.types.Operator): if not bm.loops.layers.uv: self.report({'WARNING'}, "Object must have more than one UV map") return {'CANCELLED'} + uv_layer = bm.loops.layers.uv.verify() tex_layer = bm.faces.layers.tex.verify() @@ -72,6 +76,9 @@ class MUV_PreserveUVAspect(bpy.types.Operator): info[f[tex_layer].image]['faces'].append(f) for img in info: + if img is None: + continue + src_img = img ratio = Vector(( dest_img.size[0] / src_img.size[0], @@ -86,6 +93,9 @@ class MUV_PreserveUVAspect(bpy.types.Operator): info[img]['origin'] = origin for img in info: + if img is None: + continue + for f in info[img]['faces']: f[tex_layer].image = dest_img for l in f.loops: @@ -112,6 +122,7 @@ class MUV_PreserveUVAspectMenu(bpy.types.Menu): def draw(self, _): layout = self.layout + # create sub menu for key in bpy.data.images.keys(): layout.operator( diff --git a/uv_magic_uv/muv_props.py b/uv_magic_uv/muv_props.py index 10e14614..3fdbdf00 100644 --- a/uv_magic_uv/muv_props.py +++ b/uv_magic_uv/muv_props.py @@ -20,12 +20,15 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" import bpy -from bpy.props import FloatProperty, EnumProperty, BoolProperty +from bpy.props import ( + FloatProperty, + EnumProperty, + BoolProperty, + ) DEBUG = False @@ -109,13 +112,13 @@ def init_props(scene): default=False) scene.muv_texproj_tex_magnitude = FloatProperty( name="Magnitude", - description="Texture Magnitude.", + description="Texture Magnitude", default=0.5, min=0.0, max=100.0) scene.muv_texproj_tex_image = EnumProperty( name="Image", - description="Texture Image.", + description="Texture Image", items=get_loaded_texture_name) scene.muv_texproj_tex_transparency = FloatProperty( name="Transparency", @@ -125,11 +128,11 @@ def init_props(scene): max=1.0) scene.muv_texproj_adjust_window = BoolProperty( name="Adjust Window", - description="Size of renderered texture is fitted to window.", + description="Size of renderered texture is fitted to window", default=True) scene.muv_texproj_apply_tex_aspect = BoolProperty( name="Texture Aspect Ratio", - description="Apply Texture Aspect ratio to displayed texture.", + description="Apply Texture Aspect ratio to displayed texture", default=True) diff --git a/uv_magic_uv/muv_texlock_ops.py b/uv_magic_uv/muv_texlock_ops.py index a3ddda2b..f3ff499e 100644 --- a/uv_magic_uv/muv_texlock_ops.py +++ b/uv_magic_uv/muv_texlock_ops.py @@ -20,11 +20,14 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" +__version__ = "4.3.1" +__date__ = "6 June 2017" import math -from math import atan2, cos, sqrt, sin, fabs +from math import ( + atan2, cos, + sqrt, sin, fabs, + ) import bpy import bmesh diff --git a/uv_magic_uv/muv_texproj_ops.py b/uv_magic_uv/muv_texproj_ops.py index 08b1d919..7b796e81 100644 --- a/uv_magic_uv/muv_texproj_ops.py +++ b/uv_magic_uv/muv_texproj_ops.py @@ -20,8 +20,8 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" +__version__ = "4.3.1" +__date__ = "6 June 2017" from collections import namedtuple @@ -229,12 +229,22 @@ class MUV_TexProjProject(bpy.types.Operator): bl_description = "Project Texture" bl_options = {'REGISTER', 'UNDO'} + @classmethod + def poll(cls, context): + obj = context.active_object + return obj is not None and obj.type == "MESH" + def execute(self, context): sc = context.scene + if context.mode != "EDIT_MESH": + self.report({'WARNING'}, "Mesh must be in Edit mode") + return {'CANCELLED'} + if sc.muv_texproj_tex_image == "None": self.report({'WARNING'}, "No textures are selected") return {'CANCELLED'} + _, region, space = muv_common.get_space( 'VIEW_3D', 'WINDOW', 'VIEW_3D') @@ -249,6 +259,7 @@ class MUV_TexProjProject(bpy.types.Operator): if not bm.loops.layers.uv: self.report({'WARNING'}, "Object must have more than one UV map") return {'CANCELLED'} + uv_layer = bm.loops.layers.uv.verify() tex_layer = bm.faces.layers.tex.verify() diff --git a/uv_magic_uv/muv_transuv_ops.py b/uv_magic_uv/muv_transuv_ops.py index e1083edc..095fa99b 100644 --- a/uv_magic_uv/muv_transuv_ops.py +++ b/uv_magic_uv/muv_transuv_ops.py @@ -20,8 +20,8 @@ __author__ = "Nutti <nutti.metro@gmail.com>, Mifth, MaxRobinot" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" +__version__ = "4.3.1" +__date__ = "6 June 2017" from collections import OrderedDict diff --git a/uv_magic_uv/muv_unwrapconst_ops.py b/uv_magic_uv/muv_unwrapconst_ops.py index d18634cd..86686090 100644 --- a/uv_magic_uv/muv_unwrapconst_ops.py +++ b/uv_magic_uv/muv_unwrapconst_ops.py @@ -18,13 +18,16 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" import bpy import bmesh -from bpy.props import BoolProperty, EnumProperty, FloatProperty +from bpy.props import ( + BoolProperty, + EnumProperty, + FloatProperty, + ) from . import muv_common diff --git a/uv_magic_uv/muv_uvbb_ops.py b/uv_magic_uv/muv_uvbb_ops.py index c596b1d1..3e773b7a 100644 --- a/uv_magic_uv/muv_uvbb_ops.py +++ b/uv_magic_uv/muv_uvbb_ops.py @@ -20,9 +20,8 @@ __author__ = "Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" from enum import IntEnum import math @@ -415,8 +414,8 @@ class MUV_UVBBStateNone(MUV_UVBBStateBase): arr = [1, 3, 6, 8] if i in arr: return ( - MUV_UVBBState.UNIFORM_SCALING_1 - + arr.index(i) + MUV_UVBBState.UNIFORM_SCALING_1 + + arr.index(i) ) else: return MUV_UVBBState.TRANSLATING + i @@ -552,8 +551,8 @@ class MUV_UVBBStateMgr(): obj = MUV_UVBBStateRotating(self.__cmd_exec, ctrl_points) elif next_state == MUV_UVBBState.NONE: obj = MUV_UVBBStateNone(self.__cmd_exec) - elif (MUV_UVBBState.UNIFORM_SCALING_1 <= next_state - <= MUV_UVBBState.UNIFORM_SCALING_4): + elif (MUV_UVBBState.UNIFORM_SCALING_1 <= next_state <= + MUV_UVBBState.UNIFORM_SCALING_4): obj = MUV_UVBBStateUniformScaling( self.__cmd_exec, next_state, ctrl_points) diff --git a/uv_magic_uv/muv_wsuv_ops.py b/uv_magic_uv/muv_wsuv_ops.py index dce56447..debc666c 100644 --- a/uv_magic_uv/muv_wsuv_ops.py +++ b/uv_magic_uv/muv_wsuv_ops.py @@ -20,9 +20,8 @@ __author__ = "McBuff, Nutti <nutti.metro@gmail.com>" __status__ = "production" -__version__ = "4.3" -__date__ = "1 Apr 2017" - +__version__ = "4.3.1" +__date__ = "6 June 2017" import bpy import bmesh |