Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2017-06-16 16:56:26 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2017-06-16 16:56:26 +0300
commitdc480baa613a0ef4184eec00d12c67aa5514ebd3 (patch)
tree043ec1e7a13ea25865a76e2c5d34835e9721f287
parent0a03ed937b62c55404a4abaf89fbc11c19862bd7 (diff)
parent856c1b92841d552cd763b678d75f74c214bdb963 (diff)
Merge branch 'master' into fbx_experiments
-rw-r--r--add_advanced_objects/delaunay_voronoi/__init__.py51
-rw-r--r--add_advanced_objects_menu/__init__.py (renamed from add_advanced_objects/__init__.py)222
-rw-r--r--add_advanced_objects_menu/add_light_template.py (renamed from add_advanced_objects/add_light_template.py)0
-rw-r--r--add_advanced_objects_menu/add_mesh_aggregate.py (renamed from add_advanced_objects/add_mesh_aggregate.py)0
-rw-r--r--add_advanced_objects_menu/arrange_on_curve.py (renamed from add_advanced_objects/arrange_on_curve.py)0
-rw-r--r--add_advanced_objects_menu/circle_array.py (renamed from add_advanced_objects/circle_array.py)0
-rw-r--r--add_advanced_objects_menu/copy2.py (renamed from add_advanced_objects/copy2.py)0
-rw-r--r--add_advanced_objects_menu/cubester.py (renamed from add_advanced_objects/cubester.py)0
-rw-r--r--add_advanced_objects_menu/make_struts.py (renamed from add_advanced_objects/make_struts.py)0
-rw-r--r--add_advanced_objects_menu/mesh_easylattice.py (renamed from add_advanced_objects/mesh_easylattice.py)0
-rw-r--r--add_advanced_objects_menu/object_add_chain.py (renamed from add_advanced_objects/object_add_chain.py)0
-rw-r--r--add_advanced_objects_menu/oscurart_chain_maker.py (renamed from add_advanced_objects/oscurart_chain_maker.py)0
-rw-r--r--add_advanced_objects_menu/pixelate_3d.py (renamed from add_advanced_objects/pixelate_3d.py)0
-rw-r--r--add_advanced_objects_menu/random_box_structure.py (renamed from add_advanced_objects/random_box_structure.py)0
-rw-r--r--add_advanced_objects_menu/rope_alpha.py (renamed from add_advanced_objects/rope_alpha.py)0
-rw-r--r--add_advanced_objects_menu/scene_objects_bi.py (renamed from add_advanced_objects/scene_objects_bi.py)0
-rw-r--r--add_advanced_objects_menu/scene_objects_cycles.py (renamed from add_advanced_objects/scene_objects_cycles.py)0
-rw-r--r--add_advanced_objects_menu/scene_texture_render.py (renamed from add_advanced_objects/scene_texture_render.py)0
-rw-r--r--add_advanced_objects_menu/trilighting.py (renamed from add_advanced_objects/trilighting.py)0
-rw-r--r--add_advanced_objects_panels/DelaunayVoronoi.py (renamed from add_advanced_objects/delaunay_voronoi/DelaunayVoronoi.py)0
-rw-r--r--add_advanced_objects_panels/__init__.py467
-rw-r--r--add_advanced_objects_panels/delaunay_voronoi.py (renamed from add_advanced_objects/delaunay_voronoi/delaunayVoronoiBlender.py)58
-rw-r--r--add_advanced_objects_panels/drop_to_ground.py (renamed from add_advanced_objects/drop_to_ground.py)3
-rw-r--r--add_advanced_objects_panels/object_laplace_lightning.py (renamed from add_advanced_objects/object_laplace_lightning.py)14
-rw-r--r--add_advanced_objects_panels/object_mangle_tools.py (renamed from add_advanced_objects/object_mangle_tools.py)9
-rw-r--r--add_advanced_objects_panels/oscurart_constellation.py (renamed from add_advanced_objects/delaunay_voronoi/oscurart_constellation.py)28
-rw-r--r--add_advanced_objects_panels/unfold_transition.py (renamed from add_advanced_objects/unfold_transition.py)26
-rw-r--r--add_curve_ivygen.py270
-rw-r--r--add_mesh_ant_landscape.py1422
-rw-r--r--add_mesh_extra_objects/Blocks.py279
-rw-r--r--add_mesh_extra_objects/Wallfactory.py1026
-rw-r--r--add_mesh_extra_objects/__init__.py168
-rw-r--r--add_mesh_extra_objects/add_mesh_beam_builder.py230
-rw-r--r--add_mesh_extra_objects/add_mesh_gears.py238
-rw-r--r--add_mesh_extra_objects/add_mesh_gemstones.py125
-rw-r--r--add_mesh_extra_objects/add_mesh_honeycomb.py74
-rw-r--r--add_mesh_extra_objects/add_mesh_menger_sponge.py48
-rw-r--r--add_mesh_extra_objects/add_mesh_pyramid.py152
-rw-r--r--add_mesh_extra_objects/add_mesh_round_brilliant.py150
-rw-r--r--add_mesh_extra_objects/add_mesh_round_cube.py53
-rw-r--r--add_mesh_extra_objects/add_mesh_star.py5
-rw-r--r--add_mesh_extra_objects/add_mesh_teapot.py19
-rw-r--r--add_mesh_extra_objects/add_mesh_triangles.py356
-rw-r--r--ant_landscape/__init__.py757
-rw-r--r--ant_landscape/add_mesh_ant_landscape.py668
-rw-r--r--ant_landscape/ant_functions.py930
-rw-r--r--ant_landscape/ant_landscape_refresh.py243
-rw-r--r--ant_landscape/mesh_ant_displace.py562
-rw-r--r--blender_id/CHANGELOG.md16
-rw-r--r--blender_id/__init__.py106
-rw-r--r--blender_id/communication.py65
-rw-r--r--blender_id/profiles.py40
-rw-r--r--camera_dolly_crane_rigs.py184
-rw-r--r--camera_turnaround.py2
-rw-r--r--development_edit_operator.py162
-rw-r--r--io_blend_utils/README.md17
-rw-r--r--io_blend_utils/__init__.py8
-rw-r--r--io_blend_utils/blender_bam-1.1.7-py3-none-any.whlbin49953 -> 0 bytes
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/__init__.py8
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/__main__.py8
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/blend/__init__.py0
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile.py956
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_copy.py114
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_pack.py676
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_pack_restore.py143
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_path_remap.py280
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/blend/blendfile_path_walker.py953
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/cli.py2018
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/pack.py10
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/utils/__init__.py0
-rw-r--r--io_blend_utils/blender_bam-unpacked.whl/bam/utils/system.py143
-rwxr-xr-xio_blend_utils/install_whl.py129
-rw-r--r--io_convert_image_to_mesh_img/__init__.py140
-rw-r--r--io_convert_image_to_mesh_img/import_img.py713
-rw-r--r--io_convert_image_to_mesh_img/mesh/__init__.py25
-rw-r--r--io_convert_image_to_mesh_img/mesh/dtm.py219
-rw-r--r--io_convert_image_to_mesh_img/mesh/terrain.py245
-rw-r--r--io_convert_image_to_mesh_img/mesh/triangulate.py186
-rw-r--r--io_convert_image_to_mesh_img/pvl/__init__.py27
-rw-r--r--io_convert_image_to_mesh_img/pvl/label.py24
-rw-r--r--io_convert_image_to_mesh_img/pvl/parse.py147
-rw-r--r--io_convert_image_to_mesh_img/pvl/patterns.py59
-rw-r--r--io_convert_image_to_mesh_img/ui/__init__.py25
-rw-r--r--io_convert_image_to_mesh_img/ui/importer.py177
-rw-r--r--io_convert_image_to_mesh_img/ui/terrainpanel.py133
-rw-r--r--io_scene_obj/__init__.py4
-rw-r--r--io_scene_obj/export_obj.py3
-rw-r--r--io_scene_obj/import_obj.py6
-rw-r--r--lighting_dynamic_sky.py405
-rw-r--r--measureit/measureit_main.py2
-rw-r--r--mesh_extra_tools/__init__.py2
-rw-r--r--mesh_extra_tools/mesh_edge_roundifier.py41
-rw-r--r--mesh_tissue/__init__.py8
-rw-r--r--mesh_tissue/colors_groups_exchanger.py87
-rw-r--r--mesh_tissue/dual_mesh.py86
-rw-r--r--mesh_tissue/lattice.py432
-rw-r--r--mesh_tissue/tessellate_numpy.py96
-rw-r--r--node_wrangler.py6
-rw-r--r--object_skinify.py195
-rw-r--r--presets/operator/mesh.landscape_add/abstract.py39
-rw-r--r--presets/operator/mesh.landscape_add/canion.py37
-rw-r--r--presets/operator/mesh.landscape_add/cauliflower_hills.py43
-rw-r--r--presets/operator/mesh.landscape_add/cristaline.py39
-rw-r--r--presets/operator/mesh.landscape_add/default.py39
-rw-r--r--presets/operator/mesh.landscape_add/default_large.py37
-rw-r--r--presets/operator/mesh.landscape_add/flatstone.py37
-rw-r--r--presets/operator/mesh.landscape_add/land_and_water.py54
-rw-r--r--presets/operator/mesh.landscape_add/mountain.py43
-rw-r--r--presets/operator/mesh.landscape_add/planet_noise.py39
-rw-r--r--presets/operator/mesh.landscape_add/plateau.py61
-rw-r--r--presets/operator/mesh.landscape_add/slick_rock.py59
-rw-r--r--presets/operator/mesh.landscape_add/smooth_terrain.py37
-rw-r--r--presets/operator/mesh.landscape_add/techno_grid.py41
-rw-r--r--presets/operator/mesh.landscape_add/terrain_large.py41
-rw-r--r--presets/operator/mesh.landscape_add/vlnoise_turbulence.py59
-rw-r--r--presets/operator/mesh.landscape_add/voronoi_hills.py45
-rw-r--r--presets/operator/mesh.landscape_add/vulcano.py39
-rw-r--r--render_povray/__init__.py2
-rw-r--r--render_povray/templates_pov/abyss.pov834
-rw-r--r--render_povray/templates_pov/biscuit.pov370
-rw-r--r--render_povray/templates_pov/bsp_Tango.pov61
-rw-r--r--render_povray/templates_pov/chess2.pov727
-rw-r--r--render_povray/templates_pov/cornell.pov130
-rw-r--r--render_povray/templates_pov/diffract.pov195
-rw-r--r--render_povray/templates_pov/diffuse_back.pov251
-rw-r--r--render_povray/templates_pov/float5.pov81
-rw-r--r--render_povray/templates_pov/gamma_showcase.pov189
-rw-r--r--render_povray/templates_pov/grenadine.pov375
-rw-r--r--render_povray/templates_pov/isocacti.pov242
-rw-r--r--render_povray/templates_pov/mediasky.pov147
-rw-r--r--render_povray/templates_pov/patio-radio.pov292
-rw-r--r--render_povray/templates_pov/subsurface.pov176
-rw-r--r--render_povray/templates_pov/wallstucco.pov186
-rw-r--r--render_povray/ui.py22
-rw-r--r--rigify/CREDITS32
-rw-r--r--rigify/README250
-rw-r--r--rigify/__init__.py40
-rw-r--r--rigify/generate.py96
-rw-r--r--rigify/legacy/utils.py2
-rw-r--r--rigify/metarig_menu.py35
-rw-r--r--rigify/metarigs/Animals/__init__.py0
-rw-r--r--rigify/metarigs/Animals/bird.py1494
-rw-r--r--rigify/metarigs/Animals/cat.py2979
-rw-r--r--rigify/metarigs/Animals/horse.py1372
-rw-r--r--rigify/metarigs/Animals/shark.py794
-rw-r--r--rigify/metarigs/Animals/wolf.py3227
-rw-r--r--rigify/metarigs/Basic/basic_human.py684
-rw-r--r--rigify/metarigs/Basic/basic_quadruped.py819
-rw-r--r--rigify/metarigs/human.py247
-rw-r--r--rigify/rigs/faces/super_face.py24
-rw-r--r--rigify/rigs/limbs/arm.py16
-rw-r--r--rigify/rigs/limbs/leg.py12
-rw-r--r--rigify/rigs/limbs/paw.py16
-rw-r--r--rigify/rigs/limbs/rear_paw.py16
-rw-r--r--rigify/ui.py127
-rw-r--r--rigify/utils.py63
-rw-r--r--space_clip_editor_autotracker.py54
-rw-r--r--space_view3d_display_tools/__init__.py15
-rw-r--r--space_view3d_display_tools/select_tools.py102
-rw-r--r--space_view3d_pie_menus/__init__.py5
-rw-r--r--space_view3d_pie_menus/pie_editor_switch_menu.py16
-rw-r--r--ui_layer_manager.py1
-rw-r--r--uv_magic_uv/__init__.py48
-rw-r--r--uv_magic_uv/muv_common.py5
-rw-r--r--uv_magic_uv/muv_cpuv_ops.py14
-rw-r--r--uv_magic_uv/muv_cpuv_selseq_ops.py16
-rw-r--r--uv_magic_uv/muv_fliprot_ops.py10
-rw-r--r--uv_magic_uv/muv_menu.py5
-rw-r--r--uv_magic_uv/muv_mirroruv_ops.py10
-rw-r--r--uv_magic_uv/muv_mvuv_ops.py5
-rw-r--r--uv_magic_uv/muv_packuv_ops.py11
-rw-r--r--uv_magic_uv/muv_preferences.py15
-rw-r--r--uv_magic_uv/muv_preserve_uv_aspect.py17
-rw-r--r--uv_magic_uv/muv_props.py19
-rw-r--r--uv_magic_uv/muv_texlock_ops.py9
-rw-r--r--uv_magic_uv/muv_texproj_ops.py15
-rw-r--r--uv_magic_uv/muv_transuv_ops.py4
-rw-r--r--uv_magic_uv/muv_unwrapconst_ops.py11
-rw-r--r--uv_magic_uv/muv_uvbb_ops.py13
-rw-r--r--uv_magic_uv/muv_wsuv_ops.py5
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
deleted file mode 100644
index 72fad694..00000000
--- a/io_blend_utils/blender_bam-1.1.7-py3-none-any.whl
+++ /dev/null
Binary files differ
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