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:
-rw-r--r--.gitignore3
-rw-r--r--add_advanced_objects_menu/__init__.py40
-rw-r--r--add_advanced_objects_menu/add_light_template.py10
-rw-r--r--add_advanced_objects_menu/copy2.py2
-rw-r--r--add_advanced_objects_menu/mesh_easylattice.py2
-rw-r--r--add_advanced_objects_menu/rope_alpha.py2
-rw-r--r--add_advanced_objects_menu/scene_objects_bi.py6
-rw-r--r--add_advanced_objects_menu/scene_objects_cycles.py6
-rw-r--r--add_advanced_objects_menu/scene_texture_render.py2
-rw-r--r--add_advanced_objects_menu/trilighting.py6
-rw-r--r--add_advanced_objects_panels/object_laplace_lightning.py2
-rw-r--r--add_advanced_objects_panels/unfold_transition.py4
-rw-r--r--add_curve_extra_objects/__init__.py14
-rw-r--r--add_curve_extra_objects/add_curve_curly.py4
-rw-r--r--add_curve_extra_objects/add_curve_simple.py14
-rw-r--r--add_curve_extra_objects/add_curve_spirofit_bouncespline.py2
-rw-r--r--add_curve_sapling/__init__.py4
-rw-r--r--add_curve_sapling/utils.py6
-rw-r--r--add_mesh_BoltFactory/__init__.py4
-rw-r--r--add_mesh_extra_objects/__init__.py52
-rw-r--r--add_mesh_extra_objects/add_empty_as_parent.py2
-rw-r--r--ant_landscape/__init__.py4
-rw-r--r--archimesh/__init__.py24
-rw-r--r--archimesh/achm_door_maker.py4
-rw-r--r--archimesh/achm_lamp_maker.py26
-rw-r--r--archimesh/achm_main_panel.py4
-rw-r--r--archimesh/achm_window_maker.py2
-rw-r--r--archimesh/achm_window_panel.py2
-rw-r--r--archipack/__init__.py4
-rw-r--r--archipack/archipack_autoboolean.py2
-rw-r--r--archipack/archipack_floor.py2
-rw-r--r--archipack/archipack_gl.py3
-rw-r--r--archipack/archipack_roof.py2
-rw-r--r--archipack/archipack_thumbs.py6
-rw-r--r--archipack/archipack_wall2.py2
-rw-r--r--archipack/archipack_window.py12
-rw-r--r--archipack/bmesh_utils.py4
-rw-r--r--blender_id/CHANGELOG.md12
-rw-r--r--blender_id/README.md3
-rw-r--r--blender_id/__init__.py52
-rw-r--r--bone_selection_sets.py160
-rw-r--r--camera_dolly_crane_rigs.py16
-rw-r--r--camera_turnaround.py2
-rw-r--r--curve_simplify.py78
-rw-r--r--depsgraph_debug.py29
-rw-r--r--development_api_navigator.py2
-rw-r--r--development_icon_get.py142
-rw-r--r--game_engine_publishing.py576
-rw-r--r--game_engine_save_as_runtime.py258
-rw-r--r--io_anim_acclaim/__init__.py14
-rw-r--r--io_anim_bvh/__init__.py73
-rw-r--r--io_anim_bvh/export_bvh.py8
-rw-r--r--io_anim_bvh/import_bvh.py24
-rw-r--r--io_anim_c3d/__init__.py8
-rw-r--r--io_anim_camera.py26
-rw-r--r--io_anim_nuke_chan/__init__.py8
-rw-r--r--io_blend_utils/__init__.py4
-rw-r--r--io_coat3D/__init__.py1395
-rw-r--r--io_coat3D/coat.py626
-rw-r--r--io_coat3D/tex.py533
-rw-r--r--io_convert_image_to_mesh_img/__init__.py4
-rw-r--r--io_curve_svg/__init__.py16
-rw-r--r--io_curve_svg/import_svg.py75
-rw-r--r--io_export_after_effects.py6
-rw-r--r--io_export_dxf/__init__.py4
-rw-r--r--io_export_dxf/export_dxf.py6
-rw-r--r--io_export_dxf/operator.py10
-rw-r--r--io_export_dxf/primitive_exporters/lamp_exporter.py2
-rw-r--r--io_export_paper_model.py8
-rw-r--r--io_export_pc2.py130
-rw-r--r--io_export_unreal_psk_psa.py16
-rw-r--r--io_import_dxf/__init__.py4
-rw-r--r--io_import_dxf/dxfimport/do.py4
-rw-r--r--io_import_gimp_image_to_scene.py6
-rw-r--r--io_import_images_as_planes.py160
-rw-r--r--io_import_scene_lwo.py4
-rw-r--r--io_import_scene_unreal_psa_psk.py4
-rw-r--r--io_mesh_pdb/__init__.py14
-rw-r--r--io_mesh_pdb/import_pdb.py28
-rw-r--r--io_mesh_ply/__init__.py38
-rw-r--r--io_mesh_ply/export_ply.py40
-rw-r--r--io_mesh_ply/import_ply.py80
-rw-r--r--io_mesh_raw/__init__.py8
-rw-r--r--io_mesh_stl/__init__.py63
-rw-r--r--io_mesh_stl/blender_utils.py35
-rw-r--r--io_mesh_uv_layout/__init__.py299
-rw-r--r--io_mesh_uv_layout/export_uv_eps.py118
-rw-r--r--io_mesh_uv_layout/export_uv_png.py238
-rw-r--r--io_mesh_uv_layout/export_uv_svg.py74
-rw-r--r--io_online_sketchfab/__init__.py4
-rw-r--r--io_online_sketchfab/pack_for_export.py4
-rw-r--r--io_scene_3ds/__init__.py19
-rw-r--r--io_scene_3ds/import_3ds.py52
-rw-r--r--io_scene_fbx/__init__.py130
-rw-r--r--io_scene_fbx/export_fbx_bin.py1144
-rw-r--r--io_scene_fbx/fbx_utils.py149
-rw-r--r--io_scene_fbx/import_fbx.py482
-rw-r--r--io_scene_ms3d/__init__.py12
-rw-r--r--io_scene_ms3d/ms3d_import.py4
-rw-r--r--io_scene_ms3d/ms3d_ui.py2
-rw-r--r--io_scene_obj/__init__.py88
-rw-r--r--io_scene_obj/export_obj.py225
-rw-r--r--io_scene_obj/import_obj.py355
-rw-r--r--io_scene_vrml2/__init__.py12
-rw-r--r--io_scene_vrml2/export_vrml2.py2
-rw-r--r--io_scene_x/__init__.py4
-rw-r--r--io_scene_x3d/__init__.py19
-rw-r--r--io_scene_x3d/export_x3d.py128
-rw-r--r--io_scene_x3d/import_x3d.py14
-rw-r--r--io_shape_mdd/__init__.py37
-rw-r--r--io_shape_mdd/export_mdd.py12
-rw-r--r--light_field_tools/light_field_tools.py4
-rw-r--r--materials_utils/__init__.py2
-rw-r--r--measureit/measureit_main.py6
-rw-r--r--mesh_carver.py50
-rw-r--r--mesh_custom_normals_tools.py90
-rw-r--r--mesh_extra_tools/mesh_extrude_and_reshape.py4
-rw-r--r--mesh_extra_tools/mesh_filletplus.py2
-rw-r--r--mesh_extra_tools/mesh_vertex_chamfer.py2
-rw-r--r--mesh_looptools.py296
-rw-r--r--mesh_snap_utilities_line.py10
-rw-r--r--modules/rna_manual_reference.py49
-rw-r--r--modules/snap_context/mesh_drawing.py21
-rw-r--r--netrender/ui.py4
-rw-r--r--node_wrangler.py258
-rw-r--r--object_boolean_tools.py52
-rw-r--r--object_cloud_gen.py16
-rw-r--r--object_collections.py309
-rw-r--r--object_fracture/__init__.py10
-rw-r--r--object_fracture_cell/__init__.py6
-rw-r--r--object_grease_scatter.py4
-rw-r--r--object_print3d_utils/__init__.py160
-rw-r--r--object_print3d_utils/export.py16
-rw-r--r--object_print3d_utils/mesh_helpers.py54
-rw-r--r--object_print3d_utils/operators.py76
-rw-r--r--object_print3d_utils/ui.py16
-rw-r--r--oscurart_tools/oscurart_meshes.py5
-rw-r--r--paint_palette.py6
-rw-r--r--pie_menus_official/__init__.py38
-rw-r--r--pie_menus_official/pie_manipulator_of.py12
-rw-r--r--pie_menus_official/pie_pivot_of.py4
-rw-r--r--pie_menus_official/pie_view_of.py2
-rw-r--r--render_povray/__init__.py12
-rw-r--r--render_povray/nodes.py14
-rw-r--r--render_povray/primitives.py2
-rw-r--r--render_povray/render.py383
-rw-r--r--render_povray/ui.py121
-rw-r--r--rigify/__init__.py299
-rw-r--r--rigify/generate.py117
-rw-r--r--rigify/legacy/__init__.py8
-rw-r--r--rigify/legacy/generate.py46
-rw-r--r--rigify/legacy/metarig_menu.py4
-rw-r--r--rigify/legacy/rigs/basic/copy.py4
-rw-r--r--rigify/legacy/rigs/basic/copy_chain.py4
-rw-r--r--rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py4
-rw-r--r--rigify/legacy/rigs/pitchipoy/super_copy.py2
-rw-r--r--rigify/legacy/rigs/pitchipoy/super_face.py16
-rw-r--r--rigify/legacy/rigs/pitchipoy/super_torso_turbo.py4
-rw-r--r--rigify/legacy/rigs/pitchipoy/super_widgets.py1
-rw-r--r--rigify/legacy/ui.py24
-rw-r--r--rigify/legacy/utils.py50
-rw-r--r--rigify/metarig_menu.py22
-rw-r--r--rigify/metarigs/Animals/bird.py58
-rw-r--r--rigify/metarigs/Animals/cat.py58
-rw-r--r--rigify/metarigs/Animals/horse.py58
-rw-r--r--rigify/metarigs/Animals/shark.py58
-rw-r--r--rigify/metarigs/Animals/wolf.py58
-rw-r--r--rigify/metarigs/Basic/basic_human.py58
-rw-r--r--rigify/metarigs/Basic/basic_quadruped.py58
-rw-r--r--rigify/metarigs/human.py58
-rw-r--r--rigify/rig_ui_template.py141
-rw-r--r--rigify/rigs/experimental/super_chain.py4
-rw-r--r--rigify/rigs/limbs/limb_utils.py4
-rw-r--r--rigify/rigs/spines/super_spine.py4
-rw-r--r--rigify/rigs/widgets.py1
-rw-r--r--rigify/rot_mode.py77
-rw-r--r--rigify/ui.py239
-rw-r--r--rigify/utils.py52
-rw-r--r--space_clip_editor_refine_solution.py30
-rw-r--r--space_view3d_3d_navigation.py6
-rw-r--r--space_view3d_copy_attributes.py310
-rw-r--r--space_view3d_display_tools/__init__.py10
-rw-r--r--space_view3d_display_tools/display.py12
-rw-r--r--space_view3d_display_tools/fast_navigate.py16
-rw-r--r--space_view3d_display_tools/select_tools.py10
-rw-r--r--space_view3d_display_tools/selection_restrictor.py22
-rw-r--r--space_view3d_display_tools/useless_tools.py4
-rw-r--r--space_view3d_pie_menus/__init__.py88
-rw-r--r--space_view3d_pie_menus/pie_align_menu.py8
-rw-r--r--space_view3d_pie_menus/pie_apply_transform_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_cursor.py2
-rw-r--r--space_view3d_pie_menus/pie_editor_switch_menu.py10
-rw-r--r--space_view3d_pie_menus/pie_manipulator_menu.py126
-rw-r--r--space_view3d_pie_menus/pie_modes_menu.py4
-rw-r--r--space_view3d_pie_menus/pie_orientation_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_save_open_menu.py4
-rw-r--r--space_view3d_pie_menus/pie_select_menu.py4
-rw-r--r--space_view3d_pie_menus/pie_snap_menu.py3
-rw-r--r--space_view3d_spacebar_menu.py167
-rw-r--r--system_blend_info.py8
-rw-r--r--system_demo_mode/__init__.py169
-rw-r--r--system_demo_mode/demo_mode.py16
-rw-r--r--system_property_chart.py4
-rw-r--r--ui_layer_manager.py8
-rw-r--r--uv_texture_atlas.py10
205 files changed, 6393 insertions, 7100 deletions
diff --git a/.gitignore b/.gitignore
index 80fb6e48..665a0414 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,6 @@ __pycache__/
Thumbs.db
ehthumbs.db
Desktop.ini
+
+# external addons
+cycles/
diff --git a/add_advanced_objects_menu/__init__.py b/add_advanced_objects_menu/__init__.py
index 42a33445..32bbbd7f 100644
--- a/add_advanced_objects_menu/__init__.py
+++ b/add_advanced_objects_menu/__init__.py
@@ -92,8 +92,8 @@ from bpy.props import (
# Define the "Scenes" menu
-class INFO_MT_scene_elements_add(Menu):
- bl_idname = "INFO_MT_scene_elements"
+class VIEW3D_MT_scene_elements_add(Menu):
+ bl_idname = "VIEW3D_MT_scene_elements"
bl_label = "Test Scenes"
def draw(self, context):
@@ -108,8 +108,8 @@ class INFO_MT_scene_elements_add(Menu):
# Define the "Lights" menu
-class INFO_MT_mesh_lamps_add(Menu):
- bl_idname = "INFO_MT_scene_lamps"
+class VIEW3D_MT_mesh_lights_add(Menu):
+ bl_idname = "VIEW3D_MT_scene_lights"
bl_label = "Lighting Sets"
def draw(self, context):
@@ -122,8 +122,8 @@ class INFO_MT_mesh_lamps_add(Menu):
# Define the "Chains" menu
-class INFO_MT_mesh_chain_add(Menu):
- bl_idname = "INFO_MT_mesh_chain"
+class VIEW3D_MT_mesh_chain_add(Menu):
+ bl_idname = "VIEW3D_MT_mesh_chain"
bl_label = "Chains"
def draw(self, context):
@@ -134,15 +134,15 @@ class INFO_MT_mesh_chain_add(Menu):
# Define the "Array" Menu
-class INFO_MT_array_mods_add(Menu):
- bl_idname = "INFO_MT_array_mods"
+class VIEW3D_MT_array_mods_add(Menu):
+ bl_idname = "VIEW3D_MT_array_mods"
bl_label = "Array Mods"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.menu("INFO_MT_mesh_chain", icon="LINKED")
+ layout.menu("VIEW3D_MT_mesh_chain", icon="LINKED")
layout.operator("objects.circle_array_operator",
text="Circle Array", icon="MOD_ARRAY")
@@ -153,8 +153,8 @@ class INFO_MT_array_mods_add(Menu):
# Define the "Blocks" Menu
-class INFO_MT_quick_blocks_add(Menu):
- bl_idname = "INFO_MT_quick_tools"
+class VIEW3D_MT_quick_blocks_add(Menu):
+ bl_idname = "VIEW3D_MT_quick_tools"
bl_label = "Block Tools"
def draw(self, context):
@@ -171,8 +171,8 @@ class INFO_MT_quick_blocks_add(Menu):
# Define the "Phsysics Tools" Menu
-class INFO_MT_Physics_tools_add(Menu):
- bl_idname = "INFO_MT_physics_tools"
+class VIEW3D_MT_Physics_tools_add(Menu):
+ bl_idname = "VIEW3D_MT_physics_tools"
bl_label = "Physics Tools"
def draw(self, context):
@@ -190,12 +190,12 @@ def menu(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
self.layout.separator()
- self.layout.menu("INFO_MT_scene_elements", icon="SCENE_DATA")
- self.layout.menu("INFO_MT_scene_lamps", icon="LAMP_SPOT")
+ self.layout.menu("VIEW3D_MT_scene_elements", icon="SCENE_DATA")
+ self.layout.menu("VIEW3D_MT_scene_lights", icon="LIGHT_SPOT")
self.layout.separator()
- self.layout.menu("INFO_MT_array_mods", icon="MOD_ARRAY")
- self.layout.menu("INFO_MT_quick_tools", icon="MOD_BUILD")
- self.layout.menu("INFO_MT_physics_tools", icon="PHYSICS")
+ self.layout.menu("VIEW3D_MT_array_mods", icon="MOD_ARRAY")
+ self.layout.menu("VIEW3D_MT_quick_tools", icon="MOD_BUILD")
+ self.layout.menu("VIEW3D_MT_physics_tools", icon="PHYSICS")
# Addons Preferences
@@ -524,7 +524,7 @@ def register():
)
# Add "Extras" menu to the "Add" menu
- bpy.types.INFO_MT_add.append(menu)
+ bpy.types.VIEW3D_MT_add.append(menu)
try:
bpy.types.VIEW3D_MT_AddMenu.append(menu)
except:
@@ -533,7 +533,7 @@ def register():
def unregister():
# Remove "Extras" menu from the "Add" menu.
- bpy.types.INFO_MT_add.remove(menu)
+ bpy.types.VIEW3D_MT_add.remove(menu)
try:
bpy.types.VIEW3D_MT_AddMenu.remove(menu)
except:
diff --git a/add_advanced_objects_menu/add_light_template.py b/add_advanced_objects_menu/add_light_template.py
index 9e2c139f..5b4fbc86 100644
--- a/add_advanced_objects_menu/add_light_template.py
+++ b/add_advanced_objects_menu/add_light_template.py
@@ -5,10 +5,10 @@ from bpy.types import Operator
from bpy.props import BoolProperty
-def add_lamps(self, context):
+def add_lights(self, context):
if self.bKeyLight:
- keyLight = bpy.data.lamps.new(name="Key_Light", type="SPOT")
+ keyLight = bpy.data.lights.new(name="Key_Light", type="SPOT")
ob = bpy.data.objects.new("Key_Light", keyLight)
constraint = ob.constraints.new(type='COPY_LOCATION')
constraint.use_offset = True
@@ -23,7 +23,7 @@ def add_lamps(self, context):
ob.rotation_euler[2] = -0.785398
if self.bFillLight:
- fillLight = bpy.data.lamps.new(name="Fill_Light", type="SPOT")
+ fillLight = bpy.data.lights.new(name="Fill_Light", type="SPOT")
ob = bpy.data.objects.new("Fill_Light", fillLight)
constraint = ob.constraints.new(type='COPY_LOCATION')
constraint.use_offset = True
@@ -39,7 +39,7 @@ def add_lamps(self, context):
ob.data.energy = 0.3
if self.bBackLight:
- backLight = bpy.data.lamps.new(name="Back_Light", type="SPOT")
+ backLight = bpy.data.lights.new(name="Back_Light", type="SPOT")
ob = bpy.data.objects.new("Back_Light", backLight)
constraint = ob.constraints.new(type='COPY_LOCATION')
constraint.use_offset = True
@@ -121,7 +121,7 @@ class OBJECT_OT_add_light_template(Operator):
self.target = context.active_object
self.camera = context.scene.camera
- add_lamps(self, context)
+ add_lights(self, context)
except Exception as e:
self.report({'WARNING'},
diff --git a/add_advanced_objects_menu/copy2.py b/add_advanced_objects_menu/copy2.py
index 489f6dee..9a94ac1d 100644
--- a/add_advanced_objects_menu/copy2.py
+++ b/add_advanced_objects_menu/copy2.py
@@ -168,7 +168,7 @@ def copy_to_from(scene, to_obj, from_obj, copymode, axes, edgescale, scale):
if copymode == 'E':
# don't pass edgescalling to object types that cannot be scaled
- if from_obj.type in ["CAMERA", "LAMP", "EMPTY", "ARMATURE", "SPEAKER", "META"]:
+ if from_obj.type in ["CAMERA", "LIGHT", "EMPTY", "ARMATURE", "SPEAKER", "META"]:
edgescale = False
edge_copy(scene, to_obj, from_obj, axes, edgescale, scale)
diff --git a/add_advanced_objects_menu/mesh_easylattice.py b/add_advanced_objects_menu/mesh_easylattice.py
index cdb165bd..3eb483e2 100644
--- a/add_advanced_objects_menu/mesh_easylattice.py
+++ b/add_advanced_objects_menu/mesh_easylattice.py
@@ -63,7 +63,7 @@ def createLattice(context, obj, props):
# the rotation comes from the combined obj world
# matrix which was converted to euler pairs
ob.rotation_euler = buildRot_World(obj)
- ob.show_x_ray = True
+ ob.show_in_front = True
# Link object to scene
scn = context.scene
diff --git a/add_advanced_objects_menu/rope_alpha.py b/add_advanced_objects_menu/rope_alpha.py
index 2815c7c6..f0bd5dd7 100644
--- a/add_advanced_objects_menu/rope_alpha.py
+++ b/add_advanced_objects_menu/rope_alpha.py
@@ -622,7 +622,7 @@ class BallRope(Operator):
bpy.ops.rigidbody.objects_add(type='ACTIVE')
bpy.context.object.name = "CubeLink"
if n != 0:
- bpy.context.object.draw_type = 'WIRE'
+ bpy.context.object.display_type = 'WIRE'
bpy.context.object.hide_render = True
n += 1
bpy.context.object.scale.z = (longitud * 2) / (segmentos * 2) - separation
diff --git a/add_advanced_objects_menu/scene_objects_bi.py b/add_advanced_objects_menu/scene_objects_bi.py
index f189bb11..94bda4bc 100644
--- a/add_advanced_objects_menu/scene_objects_bi.py
+++ b/add_advanced_objects_menu/scene_objects_bi.py
@@ -43,11 +43,11 @@ class add_BI_scene(Operator):
)
cam = bpy.context.active_object.data
cam.lens = 35
- cam.draw_size = 0.1
+ cam.display_size = 0.1
bpy.ops.view3d.viewnumpad(type='CAMERA')
# add point lamp
- bpy.ops.object.lamp_add(
+ bpy.ops.object.light_add(
type="POINT", location=(4.07625, 1.00545, 5.90386),
rotation=(0.650328, 0.055217, 1.866391)
)
@@ -59,7 +59,7 @@ class add_BI_scene(Operator):
lamp1.use_sphere = True
# add point lamp2
- bpy.ops.object.lamp_add(
+ bpy.ops.object.light_add(
type="POINT", location=(-0.57101, -4.24586, 5.53674),
rotation=(1.571, 0, 0.785)
)
diff --git a/add_advanced_objects_menu/scene_objects_cycles.py b/add_advanced_objects_menu/scene_objects_cycles.py
index 85e85867..7158b02f 100644
--- a/add_advanced_objects_menu/scene_objects_cycles.py
+++ b/add_advanced_objects_menu/scene_objects_cycles.py
@@ -43,11 +43,11 @@ class add_cycles_scene(Operator):
)
cam = bpy.context.active_object.data
cam.lens = 35
- cam.draw_size = 0.1
+ cam.display_size = 0.1
bpy.ops.view3d.viewnumpad(type='CAMERA')
# add point lamp
- bpy.ops.object.lamp_add(
+ bpy.ops.object.light_add(
type="POINT", location=(4.07625, 1.00545, 5.90386),
rotation=(0.650328, 0.055217, 1.866391)
)
@@ -59,7 +59,7 @@ class add_cycles_scene(Operator):
lamp1.use_sphere = True
# add point lamp2
- bpy.ops.object.lamp_add(
+ bpy.ops.object.light_add(
type="POINT", location=(-0.57101, -4.24586, 5.53674),
rotation=(1.571, 0, 0.785)
)
diff --git a/add_advanced_objects_menu/scene_texture_render.py b/add_advanced_objects_menu/scene_texture_render.py
index 02d6490b..0f9ccc2b 100644
--- a/add_advanced_objects_menu/scene_texture_render.py
+++ b/add_advanced_objects_menu/scene_texture_render.py
@@ -43,7 +43,7 @@ class add_texture_scene(Operator):
)
cam = bpy.context.active_object.data
cam.lens = 35
- cam.draw_size = 0.1
+ cam.display_size = 0.1
# add plane
bpy.ops.mesh.primitive_plane_add(enter_editmode=True, location=(0, 0, 0))
diff --git a/add_advanced_objects_menu/trilighting.py b/add_advanced_objects_menu/trilighting.py
index e0068e66..c163a894 100644
--- a/add_advanced_objects_menu/trilighting.py
+++ b/add_advanced_objects_menu/trilighting.py
@@ -173,7 +173,7 @@ class TriLighting(Operator):
backx = obj_position.x + self.distance * singleback_vector.x
backy = obj_position.y + self.distance * singleback_vector.y
- backData = bpy.data.lamps.new(name="TriLamp-Back", type=self.secondarytype)
+ backData = bpy.data.lights.new(name="TriLamp-Back", type=self.secondarytype)
backData.energy = backEnergy
backLamp = bpy.data.objects.new(name="TriLamp-Back", object_data=backData)
@@ -196,7 +196,7 @@ class TriLighting(Operator):
rightx = obj_position.x + self.distance * singleright_vector.x
righty = obj_position.y + self.distance * singleright_vector.y
- rightData = bpy.data.lamps.new(name="TriLamp-Fill", type=self.secondarytype)
+ rightData = bpy.data.lights.new(name="TriLamp-Fill", type=self.secondarytype)
rightData.energy = fillEnergy
rightLamp = bpy.data.objects.new(name="TriLamp-Fill", object_data=rightData)
scene.objects.link(rightLamp)
@@ -215,7 +215,7 @@ class TriLighting(Operator):
leftx = obj_position.x + self.distance * singleleft_vector.x
lefty = obj_position.y + self.distance * singleleft_vector.y
- leftData = bpy.data.lamps.new(name="TriLamp-Key", type=self.primarytype)
+ leftData = bpy.data.lights.new(name="TriLamp-Key", type=self.primarytype)
leftData.energy = keyEnergy
leftLamp = bpy.data.objects.new(name="TriLamp-Key", object_data=leftData)
diff --git a/add_advanced_objects_panels/object_laplace_lightning.py b/add_advanced_objects_panels/object_laplace_lightning.py
index fa50afd3..15e6730f 100644
--- a/add_advanced_objects_panels/object_laplace_lightning.py
+++ b/add_advanced_objects_panels/object_laplace_lightning.py
@@ -1087,7 +1087,7 @@ def setupObjects():
bpy.context.scene.objects.link(oOB)
gOB = bpy.data.objects.new('ELground', None)
- gOB.empty_draw_type = 'ARROWS'
+ gOB.empty_display_type = 'ARROWS'
bpy.context.scene.objects.link(gOB)
cME = makeMeshCube(1)
diff --git a/add_advanced_objects_panels/unfold_transition.py b/add_advanced_objects_panels/unfold_transition.py
index 42d8c3ba..44051bf0 100644
--- a/add_advanced_objects_panels/unfold_transition.py
+++ b/add_advanced_objects_panels/unfold_transition.py
@@ -129,8 +129,8 @@ class Set_Up_Fold(Operator):
scn.objects.link(rig)
scn.objects.active = rig
bpy.ops.object.mode_set(mode="EDIT")
- arm.draw_type = "WIRE"
- rig.show_x_ray = True
+ arm.display_type = "WIRE"
+ rig.show_in_front = True
mod = obj.modifiers.new("UnFold", "ARMATURE")
mod.show_in_editmode = True
mod.object = rig
diff --git a/add_curve_extra_objects/__init__.py b/add_curve_extra_objects/__init__.py
index 42ae2d44..5c093af4 100644
--- a/add_curve_extra_objects/__init__.py
+++ b/add_curve_extra_objects/__init__.py
@@ -225,9 +225,9 @@ class CurveExtraObjectsAddonPreferences(AddonPreferences):
icon="LAYER_USED")
-class INFO_MT_curve_knots_add(Menu):
+class VIEW3D_MT_curve_knots_add(Menu):
# Define the "Extras" menu
- bl_idname = "INFO_MT_curve_knots_add"
+ bl_idname = "VIEW3D_MT_curve_knots_add"
bl_label = "Plants"
def draw(self, context):
@@ -253,7 +253,7 @@ def menu_func(self, context):
icon='CURVE_DATA')
layout.separator()
- layout.menu(INFO_MT_curve_knots_add.bl_idname, text="Knots", icon='CURVE_DATA')
+ layout.menu(VIEW3D_MT_curve_knots_add.bl_idname, text="Knots", icon='CURVE_DATA')
layout.separator()
layout.operator("curve.curlycurve", text="Curly Curve",
icon='CURVE_DATA')
@@ -282,17 +282,17 @@ def register():
bpy.utils.register_module(__name__)
# Add "Extras" menu to the "Add Curve" menu
- bpy.types.INFO_MT_curve_add.append(menu_func)
+ bpy.types.VIEW3D_MT_curve_add.append(menu_func)
# Add "Extras" menu to the "Add Surface" menu
- bpy.types.INFO_MT_surface_add.append(menu_surface)
+ bpy.types.VIEW3D_MT_surface_add.append(menu_surface)
def unregister():
add_curve_simple.unregister()
# Remove "Extras" menu from the "Add Curve" menu.
- bpy.types.INFO_MT_curve_add.remove(menu_func)
+ bpy.types.VIEW3D_MT_curve_add.remove(menu_func)
# Remove "Extras" menu from the "Add Surface" menu.
- bpy.types.INFO_MT_surface_add.remove(menu_surface)
+ bpy.types.VIEW3D_MT_surface_add.remove(menu_surface)
bpy.utils.unregister_module(__name__)
diff --git a/add_curve_extra_objects/add_curve_curly.py b/add_curve_extra_objects/add_curve_curly.py
index 779689a9..d3950787 100644
--- a/add_curve_extra_objects/add_curve_curly.py
+++ b/add_curve_extra_objects/add_curve_curly.py
@@ -479,12 +479,12 @@ def add_curlycurve_button(self, context):
def register():
bpy.utils.register_class(add_curlycurve)
- bpy.types.INFO_MT_curve_add.append(add_curlycurve_button)
+ bpy.types.VIEW3D_MT_curve_add.append(add_curlycurve_button)
def unregister():
bpy.utils.unregister_class(add_curlycurve)
- bpy.types.INFO_MT_curve_add.remove(add_curlycurve_button)
+ bpy.types.VIEW3D_MT_curve_add.remove(add_curlycurve_button)
if __name__ == "__main__":
diff --git a/add_curve_extra_objects/add_curve_simple.py b/add_curve_extra_objects/add_curve_simple.py
index d8ff9ad7..a1ed873e 100644
--- a/add_curve_extra_objects/add_curve_simple.py
+++ b/add_curve_extra_objects/add_curve_simple.py
@@ -1645,8 +1645,8 @@ class SimpleVariables(PropertyGroup):
)
-class INFO_MT_simple_menu(Menu):
- bl_idname = "INFO_MT_simple_menu"
+class VIEW3D_MT_simple_menu(Menu):
+ bl_idname = "VIEW3D_MT_simple_menu"
bl_label = "2D Objects"
def draw(self, context):
@@ -1714,7 +1714,7 @@ class INFO_MT_simple_menu(Menu):
def Simple_button(self, context):
layout = self.layout
layout.separator()
- self.layout.menu("INFO_MT_simple_menu", icon="MOD_CURVE")
+ self.layout.menu("VIEW3D_MT_simple_menu", icon="MOD_CURVE")
def register():
@@ -1723,10 +1723,10 @@ def register():
bpy.utils.register_class(BezierDivide)
bpy.utils.register_class(SimplePanel)
bpy.utils.register_class(SimpleEdit)
- bpy.utils.register_class(INFO_MT_simple_menu)
+ bpy.utils.register_class(VIEW3D_MT_simple_menu)
bpy.utils.register_class(SimpleVariables)
- bpy.types.INFO_MT_curve_add.append(Simple_button)
+ bpy.types.VIEW3D_MT_curve_add.append(Simple_button)
bpy.types.Object.s_curve = PointerProperty(type=SimpleVariables)
@@ -1737,10 +1737,10 @@ def unregister():
bpy.utils.unregister_class(BezierDivide)
bpy.utils.unregister_class(SimplePanel)
bpy.utils.unregister_class(SimpleEdit)
- bpy.utils.unregister_class(INFO_MT_simple_menu)
+ bpy.utils.unregister_class(VIEW3D_MT_simple_menu)
bpy.utils.unregister_class(SimpleVariables)
- bpy.types.INFO_MT_curve_add.remove(Simple_button)
+ bpy.types.VIEW3D_MT_curve_add.remove(Simple_button)
del bpy.types.Object.s_curve
diff --git a/add_curve_extra_objects/add_curve_spirofit_bouncespline.py b/add_curve_extra_objects/add_curve_spirofit_bouncespline.py
index 382b2d6b..e80c6ee1 100644
--- a/add_curve_extra_objects/add_curve_spirofit_bouncespline.py
+++ b/add_curve_extra_objects/add_curve_spirofit_bouncespline.py
@@ -933,7 +933,7 @@ def add_curve_object(
bpy.context.scene.objects.active = cur
cur.select = True
if x_ray is True:
- cur.show_x_ray = x_ray
+ cur.show_in_front = x_ray
return
diff --git a/add_curve_sapling/__init__.py b/add_curve_sapling/__init__.py
index f49823b5..a63e55c1 100644
--- a/add_curve_sapling/__init__.py
+++ b/add_curve_sapling/__init__.py
@@ -1126,13 +1126,13 @@ def menu_func(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_curve_add.append(menu_func)
+ bpy.types.VIEW3D_MT_curve_add.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_curve_add.remove(menu_func)
+ bpy.types.VIEW3D_MT_curve_add.remove(menu_func)
if __name__ == "__main__":
diff --git a/add_curve_sapling/utils.py b/add_curve_sapling/utils.py
index 87ae57fe..7f6a45b7 100644
--- a/add_curve_sapling/utils.py
+++ b/add_curve_sapling/utils.py
@@ -735,13 +735,13 @@ def create_armature(armAnim, leafP, cu, frameRate, leafMesh, leafObj, leafVertSi
newAction = bpy.data.actions.new(name='windAction')
armOb.animation_data_create()
armOb.animation_data.action = newAction
- arm.draw_type = 'STICK'
+ arm.display_type = 'STICK'
arm.use_deform_delay = True
# Add the armature modifier to the curve
armMod = treeOb.modifiers.new('windSway', 'ARMATURE')
if previewArm:
armMod.show_viewport = False
- arm.draw_type = 'WIRE'
+ arm.display_type = 'WIRE'
treeOb.hide = True
armMod.use_apply_on_spline = True
armMod.object = armOb
@@ -1996,7 +1996,7 @@ def addTree(props):
armMod = treeObj.modifiers.new('windSway', 'ARMATURE')
if previewArm:
bpy.data.objects['treeArm'].hide = True
- bpy.data.armatures['tree'].draw_type = 'STICK'
+ bpy.data.armatures['tree'].display_type = 'STICK'
armMod.object = bpy.data.objects['treeArm']
armMod.use_bone_envelopes = False
armMod.use_vertex_groups = True
diff --git a/add_mesh_BoltFactory/__init__.py b/add_mesh_BoltFactory/__init__.py
index 46d250de..d441a0e8 100644
--- a/add_mesh_BoltFactory/__init__.py
+++ b/add_mesh_BoltFactory/__init__.py
@@ -49,14 +49,14 @@ def add_mesh_bolt_button(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_mesh_add.append(add_mesh_bolt_button)
+ bpy.types.VIEW3D_MT_mesh_add.append(add_mesh_bolt_button)
# bpy.types.VIEW3D_PT_tools_objectmode.prepend(add_mesh_bolt_button) # just for testing
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_mesh_add.remove(add_mesh_bolt_button)
+ bpy.types.VIEW3D_MT_mesh_add.remove(add_mesh_bolt_button)
# bpy.types.VIEW3D_PT_tools_objectmode.remove(add_mesh_bolt_button) # just for testing
diff --git a/add_mesh_extra_objects/__init__.py b/add_mesh_extra_objects/__init__.py
index ecc023df..1197738c 100644
--- a/add_mesh_extra_objects/__init__.py
+++ b/add_mesh_extra_objects/__init__.py
@@ -107,9 +107,9 @@ from bpy.props import (
)
-class INFO_MT_mesh_vert_add(Menu):
+class VIEW3D_MT_mesh_vert_add(Menu):
# Define the "Single Vert" menu
- bl_idname = "INFO_MT_mesh_vert_add"
+ bl_idname = "VIEW3D_MT_mesh_vert_add"
bl_label = "Single Vert"
def draw(self, context):
@@ -126,9 +126,9 @@ class INFO_MT_mesh_vert_add(Menu):
text="Object Origin Mirrored")
-class INFO_MT_mesh_gears_add(Menu):
+class VIEW3D_MT_mesh_gears_add(Menu):
# Define the "Gears" menu
- bl_idname = "INFO_MT_mesh_gears_add"
+ bl_idname = "VIEW3D_MT_mesh_gears_add"
bl_label = "Gears"
def draw(self, context):
@@ -140,9 +140,9 @@ class INFO_MT_mesh_gears_add(Menu):
text="Worm")
-class INFO_MT_mesh_diamonds_add(Menu):
+class VIEW3D_MT_mesh_diamonds_add(Menu):
# Define the "Diamonds" menu
- bl_idname = "INFO_MT_mesh_diamonds_add"
+ bl_idname = "VIEW3D_MT_mesh_diamonds_add"
bl_label = "Diamonds"
def draw(self, context):
@@ -156,9 +156,9 @@ class INFO_MT_mesh_diamonds_add(Menu):
text="Gem")
-class INFO_MT_mesh_math_add(Menu):
+class VIEW3D_MT_mesh_math_add(Menu):
# Define the "Math Function" menu
- bl_idname = "INFO_MT_mesh_math_add"
+ bl_idname = "VIEW3D_MT_mesh_math_add"
bl_label = "Math Functions"
def draw(self, context):
@@ -172,29 +172,29 @@ class INFO_MT_mesh_math_add(Menu):
self.layout.operator("mesh.make_triangle", icon="MESH_DATA")
-class INFO_MT_mesh_mech(Menu):
+class VIEW3D_MT_mesh_mech(Menu):
# Define the "Math Function" menu
- bl_idname = "INFO_MT_mesh_mech_add"
+ bl_idname = "VIEW3D_MT_mesh_mech_add"
bl_label = "Mechanical"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.menu("INFO_MT_mesh_pipe_joints_add",
+ layout.menu("VIEW3D_MT_mesh_pipe_joints_add",
text="Pipe Joints", icon="SNAP_PEEL_OBJECT")
- layout.menu("INFO_MT_mesh_gears_add",
+ layout.menu("VIEW3D_MT_mesh_gears_add",
text="Gears", icon="SCRIPTWIN")
-class INFO_MT_mesh_extras_add(Menu):
+class VIEW3D_MT_mesh_extras_add(Menu):
# Define the "Extra Objects" menu
- bl_idname = "INFO_MT_mesh_extras_add"
+ bl_idname = "VIEW3D_MT_mesh_extras_add"
bl_label = "Extras"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.menu("INFO_MT_mesh_diamonds_add", text="Diamonds",
+ layout.menu("VIEW3D_MT_mesh_diamonds_add", text="Diamonds",
icon="PMARKER_SEL")
layout.separator()
layout.operator("mesh.add_beam",
@@ -214,9 +214,9 @@ class INFO_MT_mesh_extras_add(Menu):
text="Menger Sponge")
-class INFO_MT_mesh_torus_add(Menu):
+class VIEW3D_MT_mesh_torus_add(Menu):
# Define the "Torus Objects" menu
- bl_idname = "INFO_MT_mesh_torus_add"
+ bl_idname = "VIEW3D_MT_mesh_torus_add"
bl_label = "Torus Objects"
def draw(self, context):
@@ -230,9 +230,9 @@ class INFO_MT_mesh_torus_add(Menu):
text="Torus Knot")
-class INFO_MT_mesh_pipe_joints_add(Menu):
+class VIEW3D_MT_mesh_pipe_joints_add(Menu):
# Define the "Pipe Joints" menu
- bl_idname = "INFO_MT_mesh_pipe_joints_add"
+ bl_idname = "VIEW3D_MT_mesh_pipe_joints_add"
bl_label = "Pipe Joints"
def draw(self, context):
@@ -355,15 +355,15 @@ def menu_func(self, context):
lay_out.operator_context = 'INVOKE_REGION_WIN'
lay_out.separator()
- lay_out.menu("INFO_MT_mesh_vert_add",
+ lay_out.menu("VIEW3D_MT_mesh_vert_add",
text="Single Vert", icon="LAYER_ACTIVE")
lay_out.operator("mesh.primitive_round_cube_add",
text="Round Cube", icon="MOD_SUBSURF")
- lay_out.menu("INFO_MT_mesh_math_add",
+ lay_out.menu("VIEW3D_MT_mesh_math_add",
text="Math Function", icon="PACKAGE")
- lay_out.menu("INFO_MT_mesh_mech_add",
+ lay_out.menu("VIEW3D_MT_mesh_mech_add",
text="Mechanical", icon="SCRIPTWIN")
- lay_out.menu("INFO_MT_mesh_torus_add",
+ lay_out.menu("VIEW3D_MT_mesh_torus_add",
text="Torus Objects", icon="MESH_TORUS")
lay_out.separator()
lay_out.operator("mesh.generate_geodesic_dome",
@@ -371,7 +371,7 @@ def menu_func(self, context):
lay_out.operator("discombobulate.ops",
text="Discombobulator", icon="RETOPO")
lay_out.separator()
- lay_out.menu("INFO_MT_mesh_extras_add",
+ lay_out.menu("VIEW3D_MT_mesh_extras_add",
text="Extras", icon="MESH_DATA")
lay_out.separator()
lay_out.operator("object.parent_to_empty",
@@ -402,12 +402,12 @@ def register():
)
# Add "Extras" menu to the "Add Mesh" menu
- bpy.types.INFO_MT_mesh_add.append(menu_func)
+ bpy.types.VIEW3D_MT_mesh_add.append(menu_func)
def unregister():
# Remove "Extras" menu from the "Add Mesh" menu.
- bpy.types.INFO_MT_mesh_add.remove(menu_func)
+ bpy.types.VIEW3D_MT_mesh_add.remove(menu_func)
del bpy.types.Scene.discomb
del bpy.types.Scene.error_message
diff --git a/add_mesh_extra_objects/add_empty_as_parent.py b/add_mesh_extra_objects/add_empty_as_parent.py
index bcaecf64..32d0d167 100644
--- a/add_mesh_extra_objects/add_empty_as_parent.py
+++ b/add_mesh_extra_objects/add_empty_as_parent.py
@@ -78,7 +78,7 @@ class P2E(Operator):
bpy.ops.object.add(type='EMPTY', location=loc)
context.object.name = self.nombre
context.object.show_name = True
- context.object.show_x_ray = True
+ context.object.show_in_front = True
if self.grupo:
bpy.ops.group.create(name=self.nombre)
diff --git a/ant_landscape/__init__.py b/ant_landscape/__init__.py
index 68dd2342..fd758e33 100644
--- a/ant_landscape/__init__.py
+++ b/ant_landscape/__init__.py
@@ -938,14 +938,14 @@ class AntLandscapePropertiesGroup(bpy.types.PropertyGroup):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_mesh_add.append(menu_func_landscape)
+ bpy.types.VIEW3D_MT_mesh_add.append(menu_func_landscape)
bpy.types.Object.ant_landscape = PointerProperty(type=AntLandscapePropertiesGroup, name="ANT_Landscape", description="Landscape properties")
bpy.types.VIEW3D_MT_paint_weight.append(menu_func_eroder)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_mesh_add.remove(menu_func_landscape)
+ bpy.types.VIEW3D_MT_mesh_add.remove(menu_func_landscape)
bpy.types.VIEW3D_MT_paint_weight.remove(menu_func_eroder)
diff --git a/archimesh/__init__.py b/archimesh/__init__.py
index cb22e157..07049ff2 100644
--- a/archimesh/__init__.py
+++ b/archimesh/__init__.py
@@ -53,7 +53,7 @@ if "bpy" in locals():
importlib.reload(achm_kitchen_maker)
importlib.reload(achm_shelves_maker)
importlib.reload(achm_books_maker)
- importlib.reload(achm_lamp_maker)
+ importlib.reload(achm_light_maker)
importlib.reload(achm_curtain_maker)
importlib.reload(achm_venetian_maker)
importlib.reload(achm_main_panel)
@@ -66,7 +66,7 @@ else:
from . import achm_venetian_maker
from . import achm_door_maker
from . import achm_kitchen_maker
- from . import achm_lamp_maker
+ from . import achm_light_maker
from . import achm_main_panel
from . import achm_roof_maker
from . import achm_room_maker
@@ -92,7 +92,7 @@ from bpy.types import (
AddonPreferences,
Menu,
Scene,
- INFO_MT_mesh_add,
+ VIEW3D_MT_mesh_add,
WindowManager,
)
@@ -102,13 +102,13 @@ from bpy.types import (
class AchmInfoMtMeshDecorationAdd(Menu):
- bl_idname = "INFO_MT_mesh_decoration_add"
+ bl_idname = "VIEW3D_MT_mesh_decoration_add"
bl_label = "Decoration assets"
# noinspection PyUnusedLocal
def draw(self, context):
self.layout.operator("mesh.archimesh_books", text="Add Books")
- self.layout.operator("mesh.archimesh_lamp", text="Add Lamp")
+ self.layout.operator("mesh.archimesh_light", text="Add Lamp")
self.layout.operator("mesh.archimesh_roller", text="Add Roller curtains")
self.layout.operator("mesh.archimesh_venetian", text="Add Venetian blind")
self.layout.operator("mesh.archimesh_japan", text="Add Japanese curtains")
@@ -119,7 +119,7 @@ class AchmInfoMtMeshDecorationAdd(Menu):
class AchmInfoMtMeshCustomMenuAdd(Menu):
- bl_idname = "INFO_MT_mesh_custom_menu_add"
+ bl_idname = "VIEW3D_MT_mesh_custom_menu_add"
bl_label = "Archimesh"
# noinspection PyUnusedLocal
@@ -134,7 +134,7 @@ class AchmInfoMtMeshCustomMenuAdd(Menu):
self.layout.operator("mesh.archimesh_column", text="Add Column")
self.layout.operator("mesh.archimesh_stairs", text="Add Stairs")
self.layout.operator("mesh.archimesh_roof", text="Add Roof")
- self.layout.menu("INFO_MT_mesh_decoration_add", text="Decoration props", icon="GROUP")
+ self.layout.menu("VIEW3D_MT_mesh_decoration_add", text="Decoration props", icon="GROUP")
# --------------------------------------------------------------
# Register all operators and panels
@@ -189,7 +189,7 @@ class Archi_Pref(AddonPreferences):
# Define menu
# noinspection PyUnusedLocal
def AchmMenu_func(self, context):
- self.layout.menu("INFO_MT_mesh_custom_menu_add", icon="GROUP")
+ self.layout.menu("VIEW3D_MT_mesh_custom_menu_add", icon="GROUP")
def register():
@@ -210,7 +210,7 @@ def register():
bpy.utils.register_class(achm_kitchen_maker.AchmExportInventory)
bpy.utils.register_class(achm_shelves_maker.AchmShelves)
bpy.utils.register_class(achm_books_maker.AchmBooks)
- bpy.utils.register_class(achm_lamp_maker.AchmLamp)
+ bpy.utils.register_class(achm_light_maker.AchmLamp)
bpy.utils.register_class(achm_curtain_maker.AchmRoller)
bpy.utils.register_class(achm_curtain_maker.AchmJapan)
bpy.utils.register_class(achm_venetian_maker.AchmVenetian)
@@ -222,7 +222,7 @@ def register():
bpy.utils.register_class(achm_window_panel.AchmWinPanel)
bpy.utils.register_class(achm_window_panel.AchmWindowEditPanel)
bpy.utils.register_class(Archi_Pref)
- INFO_MT_mesh_add.append(AchmMenu_func)
+ VIEW3D_MT_mesh_add.append(AchmMenu_func)
update_panel(None, bpy.context)
# Define properties
Scene.archimesh_select_only = BoolProperty(
@@ -321,7 +321,7 @@ def unregister():
bpy.utils.unregister_class(achm_kitchen_maker.AchmExportInventory)
bpy.utils.unregister_class(achm_shelves_maker.AchmShelves)
bpy.utils.unregister_class(achm_books_maker.AchmBooks)
- bpy.utils.unregister_class(achm_lamp_maker.AchmLamp)
+ bpy.utils.unregister_class(achm_light_maker.AchmLamp)
bpy.utils.unregister_class(achm_curtain_maker.AchmRoller)
bpy.utils.unregister_class(achm_curtain_maker.AchmJapan)
bpy.utils.unregister_class(achm_venetian_maker.AchmVenetian)
@@ -333,7 +333,7 @@ def unregister():
bpy.utils.unregister_class(achm_window_panel.AchmWinPanel)
bpy.utils.unregister_class(achm_window_panel.AchmWindowEditPanel)
bpy.utils.unregister_class(Archi_Pref)
- INFO_MT_mesh_add.remove(AchmMenu_func)
+ VIEW3D_MT_mesh_add.remove(AchmMenu_func)
# Remove properties
del Scene.archimesh_select_only
diff --git a/archimesh/achm_door_maker.py b/archimesh/achm_door_maker.py
index 6d048bfd..4ef99373 100644
--- a/archimesh/achm_door_maker.py
+++ b/archimesh/achm_door_maker.py
@@ -233,7 +233,7 @@ def shape_children(mainobject, update=False):
myctrl.location.x = 0
myctrl.location.y = -((mp.frame_thick * 3) / 2)
myctrl.location.z = -gap
- myctrl.draw_type = 'BOUNDS'
+ myctrl.display_type = 'BOUNDS'
myctrl.hide = False
myctrl.hide_render = True
if bpy.context.scene.render.engine == 'CYCLES':
@@ -256,7 +256,7 @@ def shape_children(mainobject, update=False):
myctrlbase.location.x = 0
myctrlbase.location.y = -0.15 - (mp.frame_thick / 3)
myctrlbase.location.z = -0.10
- myctrlbase.draw_type = 'BOUNDS'
+ myctrlbase.display_type = 'BOUNDS'
myctrlbase.hide = False
myctrlbase.hide_render = True
if bpy.context.scene.render.engine == 'CYCLES':
diff --git a/archimesh/achm_lamp_maker.py b/archimesh/achm_lamp_maker.py
index a6b15435..67fbfc1e 100644
--- a/archimesh/achm_lamp_maker.py
+++ b/archimesh/achm_lamp_maker.py
@@ -130,7 +130,7 @@ def set_preset(self):
# Lamps
# ------------------------------------------------------------------
class AchmLamp(Operator):
- bl_idname = "mesh.archimesh_lamp"
+ bl_idname = "mesh.archimesh_light"
bl_label = "Lamp"
bl_description = "Lamp Generator"
bl_category = 'Archimesh'
@@ -375,7 +375,7 @@ class AchmLamp(Operator):
self.oldpreset = self.preset
# Create lamp
- create_lamp_mesh(self)
+ create_light_mesh(self)
return {'FINISHED'}
else:
self.report({'WARNING'}, "Archimesh: Option only valid in Object mode")
@@ -386,13 +386,13 @@ class AchmLamp(Operator):
# Generate mesh data
# All custom values are passed using self container (self.myvariable)
# ------------------------------------------------------------------------------
-def create_lamp_mesh(self):
+def create_light_mesh(self):
# deactivate others
for o in bpy.data.objects:
if o.select is True:
o.select = False
bpy.ops.object.select_all(False)
- generate_lamp(self)
+ generate_light(self)
return
@@ -401,13 +401,13 @@ def create_lamp_mesh(self):
# Generate lamps
# All custom values are passed using self container (self.myvariable)
# ------------------------------------------------------------------------------
-def generate_lamp(self):
+def generate_light(self):
location = bpy.context.scene.cursor_location
myloc = copy(location) # copy location to keep 3D cursor position
# ---------------------
# Lamp base
# ---------------------
- mydata = create_lamp_base("Lamp_base", self.base_height,
+ mydata = create_light_base("Lamp_base", self.base_height,
myloc.x, myloc.y, myloc.z,
self.base_segments, self.base_rings,
[self.br01, self.br02, self.br03, self.br04, self.br05, self.br06,
@@ -429,7 +429,7 @@ def generate_lamp(self):
# ---------------------
# Lampholder
# ---------------------
- myholder = create_lampholder("Lampholder", self.holder,
+ myholder = create_lightholder("Lampholder", self.holder,
myloc.x, myloc.y, myloc.z,
self.crt_mat)
# refine
@@ -444,7 +444,7 @@ def generate_lamp(self):
# ---------------------
# Lamp strings
# ---------------------
- mystrings = create_lampholder_strings("Lampstrings", self.holder,
+ mystrings = create_lightholder_strings("Lampstrings", self.holder,
myloc.x, myloc.y, myloc.z,
self.tr02,
self.top_height,
@@ -460,7 +460,7 @@ def generate_lamp(self):
# ---------------------
# Lampshade
# ---------------------
- mytop = create_lampshade("Lampshade", self.top_height,
+ mytop = create_lightshade("Lampshade", self.top_height,
myloc.x, myloc.y, myloc.z,
self.top_segments,
self.tr01, self.tr02,
@@ -517,7 +517,7 @@ def generate_lamp(self):
# mat: Flag for creating materials
# objcol: Color
# ------------------------------------------------------------------------------
-def create_lamp_base(objname, height, px, py, pz, segments, rings, radios, ratios, subdivide, mat, objcol):
+def create_light_base(objname, height, px, py, pz, segments, rings, radios, ratios, subdivide, mat, objcol):
# Calculate heights
h = height / (rings - 1)
listheight = []
@@ -562,7 +562,7 @@ def create_lamp_base(objname, height, px, py, pz, segments, rings, radios, ratio
# pZ: position Z axis
# mat: Flag for creating materials
# ------------------------------------------------------------------------------
-def create_lampholder(objname, height, px, py, pz, mat):
+def create_lightholder(objname, height, px, py, pz, mat):
mydata = create_cylinder_data(16, [0, height, height + 0.005, height + 0.008, height + 0.05],
[0.005, 0.005, 0.010, 0.018, 0.018],
False, False, False, 0, False)
@@ -600,7 +600,7 @@ def create_lampholder(objname, height, px, py, pz, mat):
# shadeh: height of lampshader
# mat: Flag for creating materials
# ------------------------------------------------------------------------------
-def create_lampholder_strings(objname, height, px, py, pz, radio, shadeh, mat):
+def create_lightholder_strings(objname, height, px, py, pz, radio, shadeh, mat):
mydata = create_cylinder_data(32, [height + 0.005, height + 0.005, height + 0.006, height + 0.006],
[0.018, 0.025, 0.025, 0.018],
False, False, False, 0, False)
@@ -652,7 +652,7 @@ def create_lampholder_strings(objname, height, px, py, pz, radio, shadeh, mat):
# opacity: opacity factor
# mat: Flag for creating materials
# ------------------------------------------------------------------------------
-def create_lampshade(objname, height, px, py, pz, segments, radio1, radio2, pleats, pleatsize, opacity, mat):
+def create_lightshade(objname, height, px, py, pz, segments, radio1, radio2, pleats, pleatsize, opacity, mat):
gap = 0.002
radios = [radio1 - gap, radio1 - gap, radio1, radio2, radio2 - gap, radio2 - gap]
heights = [gap * 2, 0, 0, height, height, height - (gap * 2)]
diff --git a/archimesh/achm_main_panel.py b/archimesh/achm_main_panel.py
index 70312ac3..eb3d7748 100644
--- a/archimesh/achm_main_panel.py
+++ b/archimesh/achm_main_panel.py
@@ -462,10 +462,10 @@ class ArchimeshMainPanel(Panel):
# Prop Buttons
# ------------------------------
box = layout.box()
- box.label("Props", icon='LAMP_DATA')
+ box.label("Props", icon='LIGHT_DATA')
row = box.row()
row.operator("mesh.archimesh_books")
- row.operator("mesh.archimesh_lamp")
+ row.operator("mesh.archimesh_light")
row = box.row()
row.operator("mesh.archimesh_venetian")
row.operator("mesh.archimesh_roller")
diff --git a/archimesh/achm_window_maker.py b/archimesh/achm_window_maker.py
index b7eb8235..1e43c792 100644
--- a/archimesh/achm_window_maker.py
+++ b/archimesh/achm_window_maker.py
@@ -216,7 +216,7 @@ def shape_mesh_and_create_children(mainobject, tmp_mesh, update=False):
myctrl.location.x = 0
myctrl.location.y = -mp.depth * 3 / 2
myctrl.location.z = 0
- myctrl.draw_type = 'BOUNDS'
+ myctrl.display_type = 'BOUNDS'
myctrl.hide = False
myctrl.hide_render = True
if bpy.context.scene.render.engine == 'CYCLES':
diff --git a/archimesh/achm_window_panel.py b/archimesh/achm_window_panel.py
index dbeed892..16c9209b 100644
--- a/archimesh/achm_window_panel.py
+++ b/archimesh/achm_window_panel.py
@@ -394,7 +394,7 @@ def do_ctrl_box(myobject):
myctrl.location.x = 0
myctrl.location.y = 0
myctrl.location.z = 0
- myctrl.draw_type = 'WIRE'
+ myctrl.display_type = 'WIRE'
myctrl.hide = False
myctrl.hide_render = True
if bpy.context.scene.render.engine == 'CYCLES':
diff --git a/archipack/__init__.py b/archipack/__init__.py
index 0f5d3a86..8b87585b 100644
--- a/archipack/__init__.py
+++ b/archipack/__init__.py
@@ -504,12 +504,12 @@ def register():
bpy.utils.register_class(Archipack_Pref)
update_panel(None, bpy.context)
bpy.utils.register_class(ARCHIPACK_MT_create)
- bpy.types.INFO_MT_mesh_add.append(menu_func)
+ bpy.types.VIEW3D_MT_mesh_add.append(menu_func)
def unregister():
global icons_collection
- bpy.types.INFO_MT_mesh_add.remove(menu_func)
+ bpy.types.VIEW3D_MT_mesh_add.remove(menu_func)
bpy.utils.unregister_class(ARCHIPACK_MT_create)
bpy.utils.unregister_class(TOOLS_PT_Archipack_Tools)
diff --git a/archipack/archipack_autoboolean.py b/archipack/archipack_autoboolean.py
index c7e60305..10b8c5ce 100644
--- a/archipack/archipack_autoboolean.py
+++ b/archipack/archipack_autoboolean.py
@@ -105,7 +105,7 @@ class ArchipackBoolManager():
hole.lock_location = (True, True, True)
hole.lock_rotation = (True, True, True)
hole.lock_scale = (True, True, True)
- hole.draw_type = 'WIRE'
+ hole.display_type = 'WIRE'
hole.hide_render = True
hole.hide_select = True
hole.select = True
diff --git a/archipack/archipack_floor.py b/archipack/archipack_floor.py
index ed52fd8f..25d4db2f 100644
--- a/archipack/archipack_floor.py
+++ b/archipack/archipack_floor.py
@@ -337,7 +337,7 @@ class FloorGenerator(CutAblePolygon, CutAbleGenerator):
segments=1, # d.bevel_res
profile=0.5,
vertex_only=False,
- clamp_overlap=False,
+ clight_overlap=False,
material=-1)
bm.to_mesh(o.data)
diff --git a/archipack/archipack_gl.py b/archipack/archipack_gl.py
index a85a3080..8c475617 100644
--- a/archipack/archipack_gl.py
+++ b/archipack/archipack_gl.py
@@ -849,8 +849,7 @@ class Screen():
y_max = h - self.margin
x_min = self.margin
x_max = w - self.margin
- if (system.use_region_overlap and
- system.window_draw_method in {'TRIPLE_BUFFER', 'AUTOMATIC'}):
+ if system.use_region_overlap:
area = context.area
for r in area.regions:
diff --git a/archipack/archipack_roof.py b/archipack/archipack_roof.py
index 024dccb7..7d396d36 100644
--- a/archipack/archipack_roof.py
+++ b/archipack/archipack_roof.py
@@ -1868,7 +1868,7 @@ class RoofGenerator(CutAbleGenerator):
segments=d.tile_bevel_segs,
profile=0.5,
vertex_only=False,
- clamp_overlap=True,
+ clight_overlap=True,
material=-1)
if d.tile_solidify:
diff --git a/archipack/archipack_thumbs.py b/archipack/archipack_thumbs.py
index 8f652ab2..bfc9d55e 100644
--- a/archipack/archipack_thumbs.py
+++ b/archipack/archipack_thumbs.py
@@ -111,7 +111,7 @@ def generateThumb(context, cls, preset):
p.data.materials.append(m)
# add 3 lights
- bpy.ops.object.lamp_add(
+ bpy.ops.object.light_add(
type='POINT',
radius=1,
view_align=False,
@@ -123,7 +123,7 @@ def generateThumb(context, cls, preset):
emit = nodes["Emission"]
emit.inputs[1].default_value = 2000.0
- bpy.ops.object.lamp_add(
+ bpy.ops.object.light_add(
type='POINT',
radius=1,
view_align=False,
@@ -137,7 +137,7 @@ def generateThumb(context, cls, preset):
falloff.inputs[0].default_value = 5
tree.links.new(falloff.outputs[2], emit.inputs[1])
- bpy.ops.object.lamp_add(
+ bpy.ops.object.light_add(
type='POINT',
radius=1,
view_align=False,
diff --git a/archipack/archipack_wall2.py b/archipack/archipack_wall2.py
index 5f464a02..1506e171 100644
--- a/archipack/archipack_wall2.py
+++ b/archipack/archipack_wall2.py
@@ -1672,7 +1672,7 @@ class ARCHIPACK_OT_wall2_throttle_update(Operator):
m = o.modifiers.get("AutoBoolean")
if m is not None:
o.hide = False
- # o.draw_type = 'TEXTURED'
+ # o.display_type = 'TEXTURED'
# m.show_viewport = True
return self.cancel(context)
diff --git a/archipack/archipack_window.py b/archipack/archipack_window.py
index 54d057e7..1bf349db 100644
--- a/archipack/archipack_window.py
+++ b/archipack/archipack_window.py
@@ -993,7 +993,7 @@ class archipack_window(ArchipackObject, Manipulable, PropertyGroup):
def find_portal(self, o):
for child in o.children:
- if child.type == 'LAMP':
+ if child.type == 'LIGHT':
return child
return None
@@ -1002,7 +1002,7 @@ class archipack_window(ArchipackObject, Manipulable, PropertyGroup):
lamp = self.find_portal(o)
if self.portal:
if lamp is None:
- bpy.ops.object.lamp_add(type='AREA')
+ bpy.ops.object.light_add(type='AREA')
lamp = context.active_object
lamp.name = "Portal"
lamp.parent = o
@@ -1025,7 +1025,7 @@ class archipack_window(ArchipackObject, Manipulable, PropertyGroup):
d = lamp.data
context.scene.objects.unlink(lamp)
bpy.data.objects.remove(lamp)
- bpy.data.lamps.remove(d)
+ bpy.data.lights.remove(d)
context.scene.objects.active = o
@@ -1658,7 +1658,7 @@ class ARCHIPACK_PT_window(Panel):
box.prop(prop, 'hole_inside_mat')
box.prop(prop, 'hole_outside_mat')
- layout.prop(prop, 'portal', icon="LAMP_AREA")
+ layout.prop(prop, 'portal', icon="LIGHT_AREA")
class ARCHIPACK_PT_window_panel(Panel):
@@ -1751,11 +1751,11 @@ class ARCHIPACK_OT_window(ArchipackCreateTool, Operator):
if archipack_window.filter(o):
bpy.ops.archipack.disable_manipulate()
for child in o.children:
- if child.type == 'LAMP':
+ if child.type == 'LIGHT':
d = child.data
context.scene.objects.unlink(child)
bpy.data.objects.remove(child)
- bpy.data.lamps.remove(d)
+ bpy.data.lights.remove(d)
elif 'archipack_hole' in child:
context.scene.objects.unlink(child)
bpy.data.objects.remove(child, do_unlink=True)
diff --git a/archipack/bmesh_utils.py b/archipack/bmesh_utils.py
index 3f402d1d..1157d9a3 100644
--- a/archipack/bmesh_utils.py
+++ b/archipack/bmesh_utils.py
@@ -216,7 +216,7 @@ class BmeshEdit():
segments=1,
profile=0.5,
vertex_only=False,
- clamp_overlap=True,
+ clight_overlap=True,
material=-1,
use_selection=True):
"""
@@ -245,7 +245,7 @@ class BmeshEdit():
segments=segments,
profile=profile,
vertex_only=vertex_only,
- clamp_overlap=clamp_overlap,
+ clight_overlap=clight_overlap,
material=material)
bm.to_mesh(o.data)
diff --git a/blender_id/CHANGELOG.md b/blender_id/CHANGELOG.md
index cf62a6e1..94b21376 100644
--- a/blender_id/CHANGELOG.md
+++ b/blender_id/CHANGELOG.md
@@ -1,5 +1,17 @@
# Blender ID Add-on Changelog
+# Version 2.0 (in development)
+
+- Require Blender 2.80+.
+- API change: `blender_id.get_subclient_user_id()` now returns `''` instead of `None` when the user
+ is not logged in.
+
+
+# Version 1.5 (released 2018-07-03)
+
+- Support Blender 2.80.
+
+
## Version 1.4.1 (released 2017-12-15)
- Improved error reporting when validating a token fails due to
diff --git a/blender_id/README.md b/blender_id/README.md
index 936e6e3e..8f73fbc7 100644
--- a/blender_id/README.md
+++ b/blender_id/README.md
@@ -13,6 +13,9 @@ Blender ID add-on version 1.2.0 removed some workarounds necessary for
Blender 2.77a. As such, versions 1.1.x are the last versions compatible with
Blender 2.77a, and 1.2.0 and newer require at least Blender 2.78.
+Blender ID add-on version 2.0 is the first to support and require Blender 2.80+.
+
+
Building & Bundling
-------------------
diff --git a/blender_id/__init__.py b/blender_id/__init__.py
index 73371945..e5d94715 100644
--- a/blender_id/__init__.py
+++ b/blender_id/__init__.py
@@ -14,15 +14,17 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
+# Copyright (C) 2014-2018 Blender Foundation
+#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
bl_info = {
'name': 'Blender ID authentication',
- 'author': 'Francesco Siddi, Inês Almeida and Sybren A. Stüvel',
- 'version': (1, 4, 1),
- 'blender': (2, 77, 0),
+ 'author': 'Sybren A. Stüvel, Francesco Siddi, and Inês Almeida',
+ 'version': (1, 9, 9),
+ 'blender': (2, 80, 0),
'location': 'Add-on preferences',
'description':
'Stores your Blender ID credentials for usage with other add-ons',
@@ -117,11 +119,11 @@ def get_subclient_user_id(subclient_id: str) -> str:
Requires that the user has been authenticated at the subclient using
a call to create_subclient_token(...)
- :returns: the subclient-local user ID, or None if not logged in.
+ :returns: the subclient-local user ID, or the empty string if not logged in.
"""
if not BlenderIdProfile.user_id:
- return None
+ return ''
return BlenderIdProfile.subclients[subclient_id]['subclient_user_id']
@@ -159,9 +161,9 @@ def token_expires() -> typing.Optional[datetime.datetime]:
# 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:%SZ', # ISO 8601 with Z-suffix
- '%Y-%m-%dT%H:%M:%S.%fZ', # ISO 8601 with fractional seconds and Z-suffix
- '%a, %d %b %Y %H:%M:%S GMT', # RFC 1123, used by old Blender ID
+ '%Y-%m-%dT%H:%M:%SZ', # ISO 8601 with Z-suffix
+ '%Y-%m-%dT%H:%M:%S.%fZ', # ISO 8601 with fractional seconds and Z-suffix
+ '%a, %d %b %Y %H:%M:%S GMT', # RFC 1123, used by old Blender ID
]
for fmt in formats:
try:
@@ -177,22 +179,22 @@ def token_expires() -> typing.Optional[datetime.datetime]:
class BlenderIdPreferences(AddonPreferences):
bl_idname = __name__
- error_message = StringProperty(
+ error_message: StringProperty(
name='Error Message',
default='',
options={'HIDDEN', 'SKIP_SAVE'}
)
- ok_message = StringProperty(
+ ok_message: StringProperty(
name='Message',
default='',
options={'HIDDEN', 'SKIP_SAVE'}
)
- blender_id_username = StringProperty(
+ blender_id_username: StringProperty(
name='E-mail address',
default='',
options={'HIDDEN', 'SKIP_SAVE'}
)
- blender_id_password = StringProperty(
+ blender_id_password: StringProperty(
name='Password',
default='',
options={'HIDDEN', 'SKIP_SAVE'},
@@ -209,10 +211,10 @@ class BlenderIdPreferences(AddonPreferences):
if self.error_message:
sub = layout.row()
sub.alert = True # labels don't display in red :(
- sub.label(self.error_message, icon='ERROR')
+ sub.label(text=self.error_message, icon='ERROR')
if self.ok_message:
sub = layout.row()
- sub.label(self.ok_message, icon='FILE_TICK')
+ sub.label(text=self.ok_message, icon='FILE_TICK')
active_profile = get_active_profile()
if active_profile:
@@ -238,15 +240,17 @@ class BlenderIdPreferences(AddonPreferences):
exp_str = 'within seconds'
if time_left.days < 14:
- layout.label('You are logged in as %s.' % active_profile.username,
+ layout.label(text='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')
+ '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')
+ layout.label(
+ text='You are logged in as %s. Your authentication token expires %s.'
+ % (active_profile.username, exp_str),
+ icon='WORLD_DATA')
- row = layout.row().split(0.8)
+ row = layout.row().split(factor=0.8)
row.operator('blender_id.logout')
row.operator('blender_id.validate')
else:
@@ -343,14 +347,20 @@ def register():
profiles.register()
BlenderIdProfile.read_json()
- bpy.utils.register_module(__name__)
+ bpy.utils.register_class(BlenderIdLogin)
+ bpy.utils.register_class(BlenderIdLogout)
+ bpy.utils.register_class(BlenderIdPreferences)
+ bpy.utils.register_class(BlenderIdValidate)
preferences = bpy.context.user_preferences.addons[__name__].preferences
preferences.reset_messages()
def unregister():
- bpy.utils.unregister_module(__name__)
+ bpy.utils.unregister_class(BlenderIdLogin)
+ bpy.utils.unregister_class(BlenderIdLogout)
+ bpy.utils.unregister_class(BlenderIdPreferences)
+ bpy.utils.unregister_class(BlenderIdValidate)
if __name__ == '__main__':
diff --git a/bone_selection_sets.py b/bone_selection_sets.py
index 686eb808..e91d5557 100644
--- a/bone_selection_sets.py
+++ b/bone_selection_sets.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Bone Selection Sets",
"author": "Inês Almeida, Sybren A. Stüvel, Antony Riakiotakis, Dan Eicher",
"version": (2, 1, 1),
- "blender": (2, 75, 0),
+ "blender": (2, 80, 0),
"location": "Properties > Object Data (Armature) > Selection Sets",
"description": "List of Bone sets for easy selection while animating",
"warning": "",
@@ -41,6 +41,7 @@ from bpy.props import (
StringProperty,
IntProperty,
EnumProperty,
+ BoolProperty,
CollectionProperty,
)
@@ -48,14 +49,15 @@ from bpy.props import (
# Data Structure ##############################################################
# Note: bones are stored by name, this means that if the bone is renamed,
-# there can be problems. However, bone renaming is unlikely during animation
+# there can be problems. However, bone renaming is unlikely during animation.
class SelectionEntry(PropertyGroup):
- name = StringProperty(name="Bone Name")
+ name: StringProperty(name="Bone Name")
class SelectionSet(PropertyGroup):
- name = StringProperty(name="Set Name")
- bone_ids = CollectionProperty(type=SelectionEntry)
+ name: StringProperty(name="Set Name")
+ bone_ids: CollectionProperty(type=SelectionEntry)
+ is_selected: BoolProperty(name="Is Selected")
# UI Panel w/ UIList ##########################################################
@@ -103,8 +105,8 @@ class POSE_PT_selection_sets(Panel):
# add/remove/specials UI list Menu
col = row.column(align=True)
- col.operator("pose.selection_set_add", icon='ZOOMIN', text="")
- col.operator("pose.selection_set_remove", icon='ZOOMOUT', text="")
+ col.operator("pose.selection_set_add", icon='ADD', text="")
+ col.operator("pose.selection_set_remove", icon='REMOVE', text="")
col.menu("POSE_MT_selection_sets_specials", icon='DOWNARROW_HLT', text="")
# move up/down arrows
@@ -126,8 +128,11 @@ class POSE_PT_selection_sets(Panel):
class POSE_UL_selection_set(UIList):
- def draw_item(self, context, layout, data, set, icon, active_data, active_propname, index):
- layout.prop(set, "name", text="", icon='GROUP_BONE', emboss=False)
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ sel_set = item
+ layout.prop(item, "name", text="", icon='GROUP_BONE', emboss=False)
+ if self.layout_type in ('DEFAULT', 'COMPACT'):
+ layout.prop(item, "is_selected", text="")
class POSE_MT_selection_set_create(Menu):
@@ -139,7 +144,7 @@ class POSE_MT_selection_set_create(Menu):
text="New Selection Set")
-class POSE_MT_selection_sets(Menu):
+class POSE_MT_selection_sets_select(Menu):
bl_label = 'Select Selection Set'
@classmethod
@@ -157,6 +162,7 @@ class POSE_MT_selection_sets(Menu):
# Operators ###################################################################
class PluginOperator(Operator):
+ """Operator only available for objects of type armature in pose mode."""
@classmethod
def poll(cls, context):
return (context.object and
@@ -165,6 +171,7 @@ class PluginOperator(Operator):
class NeedSelSetPluginOperator(PluginOperator):
+ """Operator only available if the armature has a selected selection set."""
@classmethod
def poll(cls, context):
if not super().poll(context):
@@ -187,8 +194,8 @@ class POSE_OT_selection_set_delete_all(PluginOperator):
class POSE_OT_selection_set_remove_bones(PluginOperator):
bl_idname = "pose.selection_set_remove_bones"
- bl_label = "Remove Bones from Sets"
- bl_description = "Removes the Active Bones from All Sets"
+ bl_label = "Remove Selected Bones from All Sets"
+ bl_description = "Removes the Selected Bones from All Sets"
bl_options = {'UNDO', 'REGISTER'}
def execute(self, context):
@@ -210,14 +217,15 @@ class POSE_OT_selection_set_move(NeedSelSetPluginOperator):
bl_description = "Move the active Selection Set up/down the list of sets"
bl_options = {'UNDO', 'REGISTER'}
- direction = EnumProperty(
+ direction: EnumProperty(
name="Move Direction",
description="Direction to move the active Selection Set: UP (default) or DOWN",
items=[
('UP', "Up", "", -1),
('DOWN', "Down", "", 1),
],
- default='UP'
+ default='UP',
+ options={'HIDDEN'},
)
@classmethod
@@ -334,10 +342,12 @@ class POSE_OT_selection_set_select(NeedSelSetPluginOperator):
bl_description = "Add Selection Set bones to current selection"
bl_options = {'UNDO', 'REGISTER'}
- selection_set_index = IntProperty(
+ selection_set_index: IntProperty(
name='Selection Set Index',
default=-1,
- description='Which Selection Set to select; -1 uses the active Selection Set')
+ description='Which Selection Set to select; -1 uses the active Selection Set',
+ options={'HIDDEN'},
+ )
def execute(self, context):
arm = context.object
@@ -386,20 +396,20 @@ class POSE_OT_selection_set_add_and_assign(PluginOperator):
class POSE_OT_selection_set_copy(NeedSelSetPluginOperator):
bl_idname = "pose.selection_set_copy"
- bl_label = "Copy Selection Set to Clipboard"
- bl_description = "Converts the Selection Set to JSON and places it on the clipboard"
+ bl_label = "Copy Selection Set(s)"
+ bl_description = "Copies the selected Selection Set(s) to the clipboard"
bl_options = {'UNDO', 'REGISTER'}
def execute(self, context):
context.window_manager.clipboard = to_json(context)
- self.report({'INFO'}, 'Copied Selection Set to Clipboard')
+ self.report({'INFO'}, 'Copied Selection Set(s) to Clipboard')
return {'FINISHED'}
class POSE_OT_selection_set_paste(PluginOperator):
bl_idname = "pose.selection_set_paste"
- bl_label = "Paste Selection Set from Clipboard"
- bl_description = "Adds a new Selection Set from copied JSON on the clipboard"
+ bl_label = "Paste Selection Set(s)"
+ bl_description = "Adds new Selection Set(s) from the Clipboard"
bl_options = {'UNDO', 'REGISTER'}
def execute(self, context):
@@ -416,67 +426,51 @@ class POSE_OT_selection_set_paste(PluginOperator):
return {'FINISHED'}
-# Registry ####################################################################
-
-classes = (
- POSE_MT_selection_set_create,
- POSE_MT_selection_sets_specials,
- POSE_MT_selection_sets,
- POSE_PT_selection_sets,
- POSE_UL_selection_set,
- SelectionEntry,
- SelectionSet,
- POSE_OT_selection_set_delete_all,
- POSE_OT_selection_set_remove_bones,
- POSE_OT_selection_set_move,
- POSE_OT_selection_set_add,
- POSE_OT_selection_set_remove,
- POSE_OT_selection_set_assign,
- POSE_OT_selection_set_unassign,
- POSE_OT_selection_set_select,
- POSE_OT_selection_set_deselect,
- POSE_OT_selection_set_add_and_assign,
- POSE_OT_selection_set_copy,
- POSE_OT_selection_set_paste,
-)
-
+# Helper Functions ############################################################
-def add_sss_button(self, context):
- self.layout.menu('POSE_MT_selection_sets')
+def menu_func_select_selection_set(self, context):
+ self.layout.menu('POSE_MT_selection_sets_select', text="Bone Selection Set")
def to_json(context) -> str:
- """Convert the active bone selection set of the current rig to JSON."""
+ """Convert the selected Selection Sets of the current rig to JSON.
+
+ Selected Sets are the active_selection_set determined by the UIList
+ plus any with the is_selected checkbox on."""
import json
arm = context.object
active_idx = arm.active_selection_set
- sel_set = arm.selection_sets[active_idx]
- return json.dumps({
- 'name': sel_set.name,
- 'bones': [bone_id.name for bone_id in sel_set.bone_ids]
- })
+ json_obj = {}
+ for idx, sel_set in enumerate(context.object.selection_sets):
+ if idx == active_idx or sel_set.is_selected:
+ bones = [bone_id.name for bone_id in sel_set.bone_ids]
+ json_obj[sel_set.name] = bones
+
+ return json.dumps(json_obj)
def from_json(context, as_json: str):
- """Add the single bone selection set from JSON to the current rig."""
+ """Add the selection sets (one or more) from JSON to the current rig."""
import json
- sel_set = json.loads(as_json)
-
- sel_sets = context.object.selection_sets
- new_sel_set = sel_sets.add()
- new_sel_set.name = uniqify(sel_set['name'], sel_sets.keys())
+ json_obj = json.loads(as_json)
+ arm_sel_sets = context.object.selection_sets
- for bone_name in sel_set['bones']:
- bone_id = new_sel_set.bone_ids.add()
- bone_id.name = bone_name
+ for name, bones in json_obj.items():
+ new_sel_set = arm_sel_sets.add()
+ new_sel_set.name = uniqify(name, arm_sel_sets.keys())
+ for bone_name in bones:
+ bone_id = new_sel_set.bone_ids.add()
+ bone_id.name = bone_name
def uniqify(name: str, other_names: list) -> str:
"""Return a unique name with .xxx suffix if necessary.
+ Example usage:
+
>>> uniqify('hey', ['there'])
'hey'
>>> uniqify('hey', ['hey.001', 'hey.005'])
@@ -514,7 +508,32 @@ def uniqify(name: str, other_names: list) -> str:
return "{}.{:03d}".format(name, min_index)
-# store keymaps here to access after registration
+# Registry ####################################################################
+
+classes = (
+ POSE_MT_selection_set_create,
+ POSE_MT_selection_sets_specials,
+ POSE_MT_selection_sets_select,
+ POSE_PT_selection_sets,
+ POSE_UL_selection_set,
+ SelectionEntry,
+ SelectionSet,
+ POSE_OT_selection_set_delete_all,
+ POSE_OT_selection_set_remove_bones,
+ POSE_OT_selection_set_move,
+ POSE_OT_selection_set_add,
+ POSE_OT_selection_set_remove,
+ POSE_OT_selection_set_assign,
+ POSE_OT_selection_set_unassign,
+ POSE_OT_selection_set_select,
+ POSE_OT_selection_set_deselect,
+ POSE_OT_selection_set_add_and_assign,
+ POSE_OT_selection_set_copy,
+ POSE_OT_selection_set_paste,
+)
+
+
+# Store keymaps here to access after registration.
addon_keymaps = []
@@ -522,6 +541,7 @@ def register():
for cls in classes:
bpy.utils.register_class(cls)
+ # Add properties.
bpy.types.Object.selection_sets = CollectionProperty(
type=SelectionSet,
name="Selection Sets",
@@ -533,28 +553,34 @@ def register():
default=0
)
+ # Add shortcuts to the keymap.
wm = bpy.context.window_manager
km = wm.keyconfigs.addon.keymaps.new(name='Pose')
-
kmi = km.keymap_items.new('wm.call_menu', 'W', 'PRESS', alt=True, shift=True)
- kmi.properties.name = 'POSE_MT_selection_sets'
+ kmi.properties.name = 'POSE_MT_selection_sets_select'
addon_keymaps.append((km, kmi))
- bpy.types.VIEW3D_MT_select_pose.append(add_sss_button)
+ # Add entries to menus.
+ bpy.types.VIEW3D_MT_select_pose.append(menu_func_select_selection_set)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
+ # Clear properties.
del bpy.types.Object.selection_sets
del bpy.types.Object.active_selection_set
- # handle the keymap
+ # Clear shortcuts from the keymap.
for km, kmi in addon_keymaps:
km.keymap_items.remove(kmi)
addon_keymaps.clear()
+ # Clear entries from menus.
+ bpy.types.VIEW3D_MT_select_pose.remove(menu_func_select_selection_set)
+
+
if __name__ == "__main__":
import doctest
diff --git a/camera_dolly_crane_rigs.py b/camera_dolly_crane_rigs.py
index c55b19e8..bd4b88bc 100644
--- a/camera_dolly_crane_rigs.py
+++ b/camera_dolly_crane_rigs.py
@@ -533,7 +533,7 @@ def build_dolly_rig(context):
cam.data.name = "Dolly_Camera.000"
cam_data_name = bpy.context.object.data.name
- bpy.data.cameras[cam_data_name].draw_size = 1.0
+ bpy.data.cameras[cam_data_name].display_size = 1.0
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 position
cam.parent = rig
@@ -631,9 +631,9 @@ def build_crane_rig(context):
ctrlAimChild.parent = ctrlAim
# change display to BBone: it just looks nicer
- bpy.context.object.data.draw_type = 'BBONE'
+ bpy.context.object.data.display_type = 'BBONE'
# change display to wire for object
- bpy.context.object.draw_type = 'WIRE'
+ bpy.context.object.display_type = 'WIRE'
# jump into pose mode and change bones to euler
bpy.ops.object.mode_set(mode='POSE')
@@ -718,7 +718,7 @@ def build_crane_rig(context):
cam.data.name = "Crane_Camera.000"
cam_data_name = bpy.context.object.data.name
- bpy.data.cameras[cam_data_name].draw_size = 1.0
+ bpy.data.cameras[cam_data_name].display_size = 1.0
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 position
cam.parent = rig
@@ -801,7 +801,7 @@ class DollyCameraUI(Panel):
text="Make Active Camera", icon='CAMERA_DATA')
col.prop(context.active_object,
- 'show_x_ray', toggle=False, text='X Ray')
+ 'show_in_front', toggle=False, text='X Ray')
col.prop(cam, "show_limits")
col.prop(cam, "show_safe_areas")
col.prop(cam, "show_passepartout")
@@ -865,7 +865,7 @@ class CraneCameraUI(Panel):
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')
+ context.active_object, 'show_in_front', toggle=False, text='X Ray')
col.prop(cam, "show_limits")
col.prop(cam, "show_safe_areas")
col.prop(cam, "show_passepartout")
@@ -966,7 +966,7 @@ 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_crane_buttons)
+ bpy.types.VIEW3D_MT_camera_add.append(add_dolly_crane_buttons)
def unregister():
@@ -977,7 +977,7 @@ 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_crane_buttons)
+ bpy.types.VIEW3D_MT_camera_add.remove(add_dolly_crane_buttons)
if __name__ == "__main__":
diff --git a/camera_turnaround.py b/camera_turnaround.py
index 6a6e710f..547c2834 100644
--- a/camera_turnaround.py
+++ b/camera_turnaround.py
@@ -96,7 +96,7 @@ class RunAction(Operator):
context.user_preferences.edit.keyframe_new_interpolation_type = 'LINEAR'
# create first frame
myempty.rotation_euler = (0, 0, 0)
- myempty.empty_draw_size = 0.1
+ myempty.empty_display_size = 0.1
context.scene.frame_set(scene.frame_start)
myempty.keyframe_insert(data_path='rotation_euler', frame=scene.frame_start)
diff --git a/curve_simplify.py b/curve_simplify.py
index b053a4b9..e14b2857 100644
--- a/curve_simplify.py
+++ b/curve_simplify.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Simplify Curves",
"author": "testscreenings",
"version": (1, 0, 3),
- "blender": (2, 75, 0),
+ "blender": (2, 80, 0),
"location": "View3D > Add > Curve > Simplify Curves",
"description": "Simplifies 3D Curve objects and animation F-Curves",
"warning": "",
@@ -35,16 +35,16 @@ This script simplifies Curve objects and animation F-Curves.
import bpy
from bpy.props import (
- BoolProperty,
- EnumProperty,
- FloatProperty,
- IntProperty,
- )
+ BoolProperty,
+ EnumProperty,
+ FloatProperty,
+ IntProperty,
+)
from mathutils import Vector
from math import (
- sin,
- pow,
- )
+ sin,
+ pow,
+)
from bpy.types import Operator
@@ -307,10 +307,11 @@ def main(context, obj, options, curve_dimension):
# create new object and put into scene
newCurve = bpy.data.objects.new("Simple_" + obj.name, curve)
- scene.objects.link(newCurve)
- newCurve.select = True
+ coll = context.view_layer.collections.active.collection
+ coll.objects.link(newCurve)
+ newCurve.select_set('SELECT')
- scene.objects.active = newCurve
+ context.view_layer.objects.active = newCurve
newCurve.matrix_world = obj.matrix_world
# set bezierhandles to auto
@@ -325,7 +326,7 @@ def getFcurveData(obj):
for fc in obj.animation_data.action.fcurves:
if fc.select:
fcVerts = [vcVert.co.to_3d()
- for vcVert in fc.keyframe_points.values()]
+ for vcVert in fc.keyframe_points.values()]
fcurves.append(fcVerts)
return fcurves
@@ -396,38 +397,38 @@ class GRAPH_OT_simplify(Operator):
opModes = [
('DISTANCE', 'Distance', 'Distance-based simplification (Poly)'),
('CURVATURE', 'Curvature', 'Curvature-based simplification (RDP)')]
- mode = EnumProperty(
+ mode: EnumProperty(
name="Mode",
description="Choose algorithm to use",
items=opModes
)
- k_thresh = FloatProperty(
+ k_thresh: FloatProperty(
name="k",
min=0, soft_min=0,
default=0, precision=3,
description="Threshold"
)
- pointsNr = IntProperty(
+ pointsNr: IntProperty(
name="n",
min=5, soft_min=5,
max=16, soft_max=9,
default=5,
description="Degree of curve to get averaged curvatures"
)
- error = FloatProperty(
+ error: FloatProperty(
name="Error",
description="Maximum allowed distance error",
min=0.0, soft_min=0.0,
default=0, precision=3
)
- degreeOut = IntProperty(
+ degreeOut: IntProperty(
name="Degree",
min=3, soft_min=3,
max=7, soft_max=7,
default=5,
description="Degree of new curve"
)
- dis_error = FloatProperty(
+ dis_error: FloatProperty(
name="Distance error",
description="Maximum allowed distance error in Blender Units",
min=0, soft_min=0,
@@ -490,7 +491,7 @@ class CURVE_OT_simplify(Operator):
('DISTANCE', 'Distance', 'Distance-based simplification (Poly)'),
('CURVATURE', 'Curvature', 'Curvature-based simplification (RDP)')
]
- mode = EnumProperty(
+ mode: EnumProperty(
name="Mode",
description="Choose algorithm to use",
items=opModes
@@ -501,42 +502,44 @@ class CURVE_OT_simplify(Operator):
('BEZIER', 'Bezier', 'BEZIER'),
('POLY', 'Poly', 'POLY')
]
- output = EnumProperty(
+ output: EnumProperty(
name="Output splines",
description="Type of splines to output",
items=SplineTypes
)
- k_thresh = FloatProperty(
+ k_thresh: FloatProperty(
name="k",
min=0, soft_min=0,
default=0, precision=3,
description="Threshold"
)
- pointsNr = IntProperty(name="n",
+ pointsNr: IntProperty(
+ name="n",
min=5, soft_min=5,
max=9, soft_max=9,
default=5,
description="Degree of curve to get averaged curvatures"
)
- error = FloatProperty(
+ error: FloatProperty(
name="Error",
description="Maximum allowed distance error in Blender Units",
min=0, soft_min=0,
default=0.0, precision=3
)
- degreeOut = IntProperty(name="Degree",
+ degreeOut: IntProperty(
+ name="Degree",
min=3, soft_min=3,
max=7, soft_max=7,
default=5,
description="Degree of new curve"
)
- dis_error = FloatProperty(
+ dis_error: FloatProperty(
name="Distance error",
description="Maximum allowed distance error in Blender Units",
min=0, soft_min=0,
default=0.0
)
- keepShort = BoolProperty(
+ keepShort: BoolProperty(
name="Keep short splines",
description="Keep short splines (less than 7 points)",
default=True
@@ -546,7 +549,7 @@ class CURVE_OT_simplify(Operator):
layout = self.layout
col = layout.column()
- col.label("Distance Error:")
+ col.label(text="Distance Error:")
col.prop(self, "error", expand=True)
col.prop(self, "output", text="Output", icon="OUTLINER_OB_CURVE")
if self.output == "NURBS":
@@ -591,21 +594,30 @@ class CURVE_OT_simplify(Operator):
# Register
+classes = [
+ GRAPH_OT_simplify,
+ CURVE_OT_simplify,
+]
+
def register():
- bpy.utils.register_module(__name__)
+ from bpy.utils import register_class
+ for cls in classes:
+ register_class(cls)
bpy.types.GRAPH_MT_channel.append(menu_func)
bpy.types.DOPESHEET_MT_channel.append(menu_func)
- bpy.types.INFO_MT_curve_add.append(menu)
+ bpy.types.VIEW3D_MT_curve_add.append(menu)
def unregister():
+ from bpy.utils import unregister_class
+ for cls in reversed(classes):
+ unregister_class(cls)
+
bpy.types.GRAPH_MT_channel.remove(menu_func)
bpy.types.DOPESHEET_MT_channel.remove(menu_func)
- bpy.types.INFO_MT_curve_add.remove(menu)
-
- bpy.utils.unregister_module(__name__)
+ bpy.types.VIEW3D_MT_curve_add.remove(menu)
if __name__ == "__main__":
diff --git a/depsgraph_debug.py b/depsgraph_debug.py
index 438d4885..76f25290 100644
--- a/depsgraph_debug.py
+++ b/depsgraph_debug.py
@@ -27,7 +27,7 @@ bl_info = {
"name": "Dependency Graph Debug",
"author": "Sergey Sharybin",
"version": (0, 1),
- "blender": (2, 79, 0),
+ "blender": (2, 80, 0),
"description": "Various dependency graph debugging tools",
"warning": "",
"wiki_url": "",
@@ -48,12 +48,12 @@ def _get_depsgraph(context):
# Save data from depsgraph to a specified file.
class SCENE_OT_depsgraph_save_common:
- filepath = StringProperty(
- name="File Path",
- description="Filepath used for saving the file",
- maxlen=1024,
- subtype='FILE_PATH',
- )
+ filepath: StringProperty(
+ name="File Path",
+ description="Filepath used for saving the file",
+ maxlen=1024,
+ subtype='FILE_PATH',
+ )
def _getExtension(self, context):
return ""
@@ -86,8 +86,10 @@ class SCENE_OT_depsgraph_save_common:
pass
-class SCENE_OT_depsgraph_relations_graphviz(Operator,
- SCENE_OT_depsgraph_save_common):
+class SCENE_OT_depsgraph_relations_graphviz(
+ Operator,
+ SCENE_OT_depsgraph_save_common,
+):
bl_idname = "scene.depsgraph_relations_graphviz"
bl_label = "Save Depsgraph"
bl_description = "Save current scene's dependency graph to a graphviz file"
@@ -96,13 +98,16 @@ class SCENE_OT_depsgraph_relations_graphviz(Operator,
return ".dot"
def performSave(self, context, depsgraph):
+ import os
basename, extension = os.path.splitext(self.filepath)
- depsgraph.debug_relations_graphviz(self.filepath, absename + ".png")
+ depsgraph.debug_relations_graphviz(os.path.join(self.filepath, basename + ".dot"))
return True
-class SCENE_OT_depsgraph_stats_gnuplot(Operator,
- SCENE_OT_depsgraph_save_common):
+class SCENE_OT_depsgraph_stats_gnuplot(
+ Operator,
+ SCENE_OT_depsgraph_save_common,
+):
bl_idname = "scene.depsgraph_stats_gnuplot"
bl_label = "Save Depsgraph Stats"
bl_description = "Save current scene's evaluaiton stats to gnuplot file"
diff --git a/development_api_navigator.py b/development_api_navigator.py
index 5e0276cb..deae8443 100644
--- a/development_api_navigator.py
+++ b/development_api_navigator.py
@@ -514,7 +514,7 @@ class OBJECT_PT_api_navigator(ApiNavigator, Panel):
elif iterable == 'b':
box = self.layout.box()
row = box.row()
- row.label(text="Item Values", icon="OOPS")
+ row.label(text="Item Values", icon='OUTLINER')
box = box.box()
col = box.column(align=True)
collection = list(current_module)
diff --git a/development_icon_get.py b/development_icon_get.py
index a7740c31..c8360e88 100644
--- a/development_icon_get.py
+++ b/development_icon_get.py
@@ -23,9 +23,9 @@ bl_info = {
"name": "Icon Viewer",
"description": "Click an icon to copy its name to the clipboard",
"author": "roaoao",
- "version": (1, 3, 2),
- "blender": (2, 75, 0),
- "location": "Spacebar > Icon Viewer, Text Editor > Properties",
+ "version": (1, 4, 0),
+ "blender": (2, 80, 0),
+ "location": "Search Menu > Icon Viewer, Text Editor > Properties",
"wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6"
"/Py/Scripts/Development/Display_All_Icons",
"category": "Development"
@@ -33,6 +33,10 @@ bl_info = {
import bpy
import math
+from bpy.props import (
+ BoolProperty,
+ StringProperty,
+)
DPI = 72
POPUP_PADDING = 10
@@ -88,6 +92,9 @@ class Icons:
not pr.show_brush_icons and "BRUSH_" in icon and \
icon != 'BRUSH_DATA' or \
not pr.show_matcap_icons and "MATCAP_" in icon or \
+ not pr.show_event_icons and (
+ "EVENT_" in icon or "MOUSE_" in icon
+ ) or \
not pr.show_colorset_icons and "COLORSET_" in icon:
continue
self._filtered_icons.append(icon)
@@ -109,8 +116,8 @@ class Icons:
else:
filtered_icons = self.filtered_icons
- column = layout.column(True)
- row = column.row(True)
+ column = layout.column(align=True)
+ row = column.row(align=True)
row.alignment = 'CENTER'
selected_icon = self.selected_icon if self.is_popup else \
@@ -118,7 +125,7 @@ class Icons:
col_idx = 0
for i, icon in enumerate(filtered_icons):
p = row.operator(
- IV_OT_icon_select.bl_idname, "",
+ IV_OT_icon_select.bl_idname, text="",
icon=icon, emboss=icon == selected_icon)
p.icon = icon
p.force_copy_on_select = not self.is_popup
@@ -129,16 +136,15 @@ class Icons:
break
col_idx = 0
if i < len(filtered_icons) - 1:
- row = column.row(True)
+ row = column.row(align=True)
row.alignment = 'CENTER'
if col_idx != 0 and not icons and i >= num_cols:
- sub = row.row(True)
- sub.scale_x = num_cols - col_idx
- sub.label("", icon='BLANK1')
+ for _ in range(num_cols - col_idx):
+ row.label(text="", icon='BLANK1')
if not filtered_icons:
- row.label("No icons were found")
+ row.label(text="No icons were found")
class IV_Preferences(bpy.types.AddonPreferences):
@@ -154,47 +160,51 @@ class IV_Preferences(bpy.types.AddonPreferences):
def set_panel_filter(self, value):
self.panel_icons.filter = value
- panel_filter = bpy.props.StringProperty(
+ panel_filter: StringProperty(
description="Filter",
default="",
get=lambda s: s.panel_icons.filter,
set=set_panel_filter,
options={'TEXTEDIT_UPDATE'})
- show_panel_icons = bpy.props.BoolProperty(
+ show_panel_icons: BoolProperty(
name="Show Icons",
description="Show icons", default=True)
- show_history = bpy.props.BoolProperty(
+ show_history: BoolProperty(
name="Show History",
description="Show history", default=True)
- show_brush_icons = bpy.props.BoolProperty(
+ show_brush_icons: BoolProperty(
name="Show Brush Icons",
description="Show brush icons", default=True,
update=update_icons)
- show_matcap_icons = bpy.props.BoolProperty(
+ show_matcap_icons: BoolProperty(
name="Show Matcap Icons",
description="Show matcap icons", default=True,
update=update_icons)
- show_colorset_icons = bpy.props.BoolProperty(
+ show_event_icons: BoolProperty(
+ name="Show Event Icons",
+ description="Show event icons", default=True,
+ update=update_icons)
+ show_colorset_icons: BoolProperty(
name="Show Colorset Icons",
description="Show colorset icons", default=True,
update=update_icons)
- copy_on_select = bpy.props.BoolProperty(
+ copy_on_select: BoolProperty(
name="Copy Icon On Click",
description="Copy icon on click", default=True)
- close_on_select = bpy.props.BoolProperty(
+ close_on_select: BoolProperty(
name="Close Popup On Click",
description=(
"Close the popup on click.\n"
"Not supported by some windows (User Preferences, Render)"
- ),
+ ),
default=False)
- auto_focus_filter = bpy.props.BoolProperty(
+ auto_focus_filter: BoolProperty(
name="Auto Focus Input Field",
description="Auto focus input field", default=True)
- show_panel = bpy.props.BoolProperty(
+ show_panel: BoolProperty(
name="Show Panel",
description="Show the panel in the Text Editor", default=True)
- show_header = bpy.props.BoolProperty(
+ show_header: BoolProperty(
name="Show Header",
description="Show the header in the Python Console",
default=True)
@@ -207,29 +217,30 @@ class IV_Preferences(bpy.types.AddonPreferences):
row = layout.row()
- col = row.column(True)
- col.label("Icons:")
+ col = row.column(align=True)
+ col.label(text="Icons:")
col.prop(self, "show_matcap_icons")
col.prop(self, "show_brush_icons")
col.prop(self, "show_colorset_icons")
+ col.prop(self, "show_event_icons")
col.separator()
col.prop(self, "show_history")
- col = row.column(True)
- col.label("Popup:")
+ col = row.column(align=True)
+ col.label(text="Popup:")
col.prop(self, "auto_focus_filter")
col.prop(self, "copy_on_select")
if self.copy_on_select:
col.prop(self, "close_on_select")
- col = row.column(True)
- col.label("Panel:")
+ col = row.column(align=True)
+ col.label(text="Panel:")
col.prop(self, "show_panel")
if self.show_panel:
col.prop(self, "show_panel_icons")
col.separator()
- col.label("Header:")
+ col.label(text="Header:")
col.prop(self, "show_header")
@@ -253,12 +264,13 @@ class IV_PT_icons(bpy.types.Panel):
def draw(self, context):
pr = prefs()
- row = self.layout.row(True)
+ row = self.layout.row(align=True)
if pr.show_panel_icons:
- row.prop(pr, "panel_filter", "", icon='VIEWZOOM')
+ row.prop(pr, "panel_filter", text="", icon='VIEWZOOM')
else:
row.operator(IV_OT_icons_show.bl_idname)
- row.operator(IV_OT_panel_menu_call.bl_idname, "", icon='COLLAPSEMENU')
+ row.operator(
+ IV_OT_panel_menu_call.bl_idname, text="", icon='COLLAPSEMENU')
_, y0 = context.region.view2d.region_to_view(0, 0)
_, y1 = context.region.view2d.region_to_view(0, 10)
@@ -271,11 +283,11 @@ class IV_PT_icons(bpy.types.Panel):
col = None
if HISTORY and pr.show_history:
- col = self.layout.column(True)
+ col = self.layout.column(align=True)
pr.panel_icons.draw(col.box(), num_cols, HISTORY)
if pr.show_panel_icons:
- col = col or self.layout.column(True)
+ col = col or self.layout.column(align=True)
pr.panel_icons.draw(col.box(), num_cols)
@classmethod
@@ -313,9 +325,10 @@ class IV_OT_panel_menu_call(bpy.types.Operator):
layout.prop(pr, "show_matcap_icons")
layout.prop(pr, "show_brush_icons")
layout.prop(pr, "show_colorset_icons")
+ layout.prop(pr, "show_event_icons")
def execute(self, context):
- context.window_manager.popup_menu(self.menu, "Icon Viewer")
+ context.window_manager.popup_menu(self.menu, title="Icon Viewer")
return {'FINISHED'}
@@ -325,8 +338,8 @@ class IV_OT_icon_select(bpy.types.Operator):
bl_description = "Select the icon"
bl_options = {'INTERNAL'}
- icon = bpy.props.StringProperty()
- force_copy_on_select = bpy.props.BoolProperty()
+ icon: StringProperty()
+ force_copy_on_select: BoolProperty()
def execute(self, context):
pr = prefs()
@@ -362,17 +375,17 @@ class IV_OT_icons_show(bpy.types.Operator):
if IV_OT_icons_show.instance:
IV_OT_icons_show.instance.auto_focusable = False
- filter_auto_focus = bpy.props.StringProperty(
+ filter_auto_focus: StringProperty(
description="Filter",
get=lambda s: prefs().popup_icons.filter,
set=set_filter,
options={'TEXTEDIT_UPDATE', 'SKIP_SAVE'})
- filter = bpy.props.StringProperty(
+ filter: StringProperty(
description="Filter",
get=lambda s: prefs().popup_icons.filter,
set=set_filter,
options={'TEXTEDIT_UPDATE'})
- selected_icon = bpy.props.StringProperty(
+ selected_icon: StringProperty(
description="Selected Icon",
get=lambda s: prefs().popup_icons.selected_icon,
set=set_selected_icon)
@@ -383,36 +396,38 @@ class IV_OT_icons_show(bpy.types.Operator):
def draw_header(self, layout):
pr = prefs()
header = layout.box()
- header = header.split(0.75) if self.selected_icon else header.row()
- row = header.row(True)
- row.prop(pr, "show_matcap_icons", "", icon='SMOOTH')
- row.prop(pr, "show_brush_icons", "", icon='BRUSH_DATA')
- row.prop(pr, "show_colorset_icons", "", icon='COLOR')
+ header = header.split(factor=0.75) if self.selected_icon else \
+ header.row()
+ row = header.row(align=True)
+ row.prop(pr, "show_matcap_icons", text="", icon='SHADING_RENDERED')
+ row.prop(pr, "show_brush_icons", text="", icon='BRUSH_DATA')
+ row.prop(pr, "show_colorset_icons", text="", icon='COLOR')
+ row.prop(pr, "show_event_icons", text="", icon='HAND')
row.separator()
row.prop(
- pr, "copy_on_select", "",
+ pr, "copy_on_select", text="",
icon='BORDER_RECT', toggle=True)
if pr.copy_on_select:
- sub = row.row(True)
+ sub = row.row(align=True)
if bpy.context.window.screen.name == "temp":
sub.alert = True
sub.prop(
- pr, "close_on_select", "",
+ pr, "close_on_select", text="",
icon='RESTRICT_SELECT_OFF', toggle=True)
row.prop(
- pr, "auto_focus_filter", "",
+ pr, "auto_focus_filter", text="",
icon='OUTLINER_DATA_FONT', toggle=True)
row.separator()
if self.auto_focusable and pr.auto_focus_filter:
- row.prop(self, "filter_auto_focus", "", icon='VIEWZOOM')
+ row.prop(self, "filter_auto_focus", text="", icon='VIEWZOOM')
else:
- row.prop(self, "filter", "", icon='VIEWZOOM')
+ row.prop(self, "filter", text="", icon='VIEWZOOM')
if self.selected_icon:
row = header.row()
- row.prop(self, "selected_icon", "", icon=self.selected_icon)
+ row.prop(self, "selected_icon", text="", icon=self.selected_icon)
def draw(self, context):
pr = prefs()
@@ -425,7 +440,7 @@ class IV_OT_icons_show(bpy.types.Operator):
self.get_num_cols(len(pr.popup_icons.filtered_icons)),
history_num_cols)
- subcol = col.column(True)
+ subcol = col.column(align=True)
if HISTORY and pr.show_history:
pr.popup_icons.draw(subcol.box(), history_num_cols, HISTORY)
@@ -468,18 +483,31 @@ class IV_OT_icons_show(bpy.types.Operator):
ui_scale() * (num_cols * ICON_SIZE + POPUP_PADDING),
context.window.width - WIN_PADDING)
- return context.window_manager.invoke_props_dialog(self, self.width)
+ return context.window_manager.invoke_props_dialog(
+ self, width=self.width)
+
+
+classes = (
+ IV_PT_icons,
+ IV_HT_icons,
+ IV_OT_panel_menu_call,
+ IV_OT_icon_select,
+ IV_OT_icons_show,
+ IV_Preferences,
+)
def register():
if bpy.app.background:
return
- bpy.utils.register_module(__name__)
+ for cls in classes:
+ bpy.utils.register_class(cls)
def unregister():
if bpy.app.background:
return
- bpy.utils.unregister_module(__name__)
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
diff --git a/game_engine_publishing.py b/game_engine_publishing.py
deleted file mode 100644
index 495b0123..00000000
--- a/game_engine_publishing.py
+++ /dev/null
@@ -1,576 +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 #####
-
-import bpy
-import os
-import tempfile
-import shutil
-import tarfile
-import time
-import stat
-
-
-bl_info = {
- "name": "Game Engine Publishing",
- "author": "Mitchell Stokes (Moguri), Oren Titane (Genome36)",
- "version": (0, 1, 0),
- "blender": (2, 75, 0),
- "location": "Render Properties > Publishing Info",
- "description": "Publish .blend file as game engine runtime, manage versions and platforms",
- "warning": "",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Game_Engine/Publishing",
- "category": "Game Engine",
-}
-
-
-def WriteRuntime(player_path, output_path, asset_paths, copy_python, overwrite_lib, copy_dlls, make_archive, report=print):
- import struct
-
- player_path = bpy.path.abspath(player_path)
- ext = os.path.splitext(player_path)[-1].lower()
- output_path = bpy.path.abspath(output_path)
- output_dir = os.path.dirname(output_path)
- if not os.path.exists(output_dir):
- os.makedirs(output_dir)
-
- python_dir = os.path.join(os.path.dirname(player_path),
- bpy.app.version_string.split()[0],
- "python",
- "lib")
-
- # Check the paths
- if not os.path.isfile(player_path) and not(os.path.exists(player_path) and player_path.endswith('.app')):
- report({'ERROR'}, "The player could not be found! Runtime not saved")
- return
-
- # Check if we're bundling a .app
- if player_path.lower().endswith('.app'):
- # Python doesn't need to be copied for OS X since it's already inside blenderplayer.app
- copy_python = False
-
- output_path = bpy.path.ensure_ext(output_path, '.app')
-
- if os.path.exists(output_path):
- shutil.rmtree(output_path)
-
- shutil.copytree(player_path, output_path)
- bpy.ops.wm.save_as_mainfile(filepath=os.path.join(output_path, 'Contents', 'Resources', 'game.blend'),
- relative_remap=False,
- compress=False,
- copy=True,
- )
- else:
- # Enforce "exe" extension on Windows
- if player_path.lower().endswith('.exe'):
- output_path = bpy.path.ensure_ext(output_path, '.exe')
-
- # Get the player's binary and the offset for the blend
- with open(player_path, "rb") as file:
- player_d = file.read()
- offset = file.tell()
-
- # Create a tmp blend file (Blenderplayer doesn't like compressed blends)
- tempdir = tempfile.mkdtemp()
- blend_path = os.path.join(tempdir, bpy.path.clean_name(output_path))
- bpy.ops.wm.save_as_mainfile(filepath=blend_path,
- relative_remap=False,
- compress=False,
- copy=True,
- )
-
- # Get the blend data
- with open(blend_path, "rb") as blend_file:
- blend_d = blend_file.read()
-
- # Get rid of the tmp blend, we're done with it
- os.remove(blend_path)
- os.rmdir(tempdir)
-
- # Create a new file for the bundled runtime
- with open(output_path, "wb") as output:
- # Write the player and blend data to the new runtime
- print("Writing runtime...", end=" ", flush=True)
- output.write(player_d)
- output.write(blend_d)
-
- # Store the offset (an int is 4 bytes, so we split it up into 4 bytes and save it)
- output.write(struct.pack('BBBB', (offset >> 24) & 0xFF,
- (offset >> 16) & 0xFF,
- (offset >> 8) & 0xFF,
- (offset >> 0) & 0xFF))
-
- # Stuff for the runtime
- output.write(b'BRUNTIME')
-
- print("done", flush=True)
-
- # Make sure the runtime is executable
- os.chmod(output_path, 0o755)
-
- # Copy bundled Python
- blender_dir = os.path.dirname(player_path)
-
- if copy_python:
- print("Copying Python files...", end=" ", flush=True)
- py_folder = os.path.join(bpy.app.version_string.split()[0], "python", "lib")
- dst = os.path.join(output_dir, py_folder)
- src = python_dir
-
- if os.path.exists(dst) and overwrite_lib:
- shutil.rmtree(dst)
-
- if not os.path.exists(dst):
- shutil.copytree(src, dst, ignore=lambda dir, contents: [i for i in contents if i == '__pycache__'])
- print("done", flush=True)
- else:
- print("used existing Python folder", flush=True)
-
- # And DLLs if we're doing a Windows runtime)
- if copy_dlls and ext == ".exe":
- print("Copying DLLs...", end=" ", flush=True)
- for file in [i for i in os.listdir(blender_dir) if i.lower().endswith('.dll')]:
- src = os.path.join(blender_dir, file)
- dst = os.path.join(output_dir, file)
- shutil.copy2(src, dst)
-
- print("done", flush=True)
-
- # Copy assets
- for ap in asset_paths:
- src = bpy.path.abspath(ap.name)
- dst = os.path.join(output_dir, ap.name[2:] if ap.name.startswith('//') else ap.name)
-
- if os.path.exists(src):
- if os.path.isdir(src):
- if ap.overwrite and os.path.exists(dst):
- shutil.rmtree(dst)
- elif not os.path.exists(dst):
- shutil.copytree(src, dst)
- else:
- if ap.overwrite or not os.path.exists(dst):
- shutil.copy2(src, dst)
- else:
- report({'ERROR'}, "Could not find asset path: '%s'" % src)
-
- # Make archive
- if make_archive:
- print("Making archive...", end=" ", flush=True)
-
- arctype = ''
- if player_path.lower().endswith('.exe'):
- arctype = 'zip'
- elif player_path.lower().endswith('.app'):
- arctype = 'zip'
- else: # Linux
- arctype = 'gztar'
-
- basedir = os.path.normpath(os.path.join(os.path.dirname(output_path), '..'))
- afilename = os.path.join(basedir, os.path.basename(output_dir))
-
- if arctype == 'gztar':
- # Create the tarball ourselves instead of using shutil.make_archive
- # so we can handle permission bits.
-
- # The runtimename needs to use forward slashes as a path separator
- # since this is what tarinfo.name is using.
- runtimename = os.path.relpath(output_path, basedir).replace('\\', '/')
-
- def _set_ex_perm(tarinfo):
- if tarinfo.name == runtimename:
- tarinfo.mode = 0o755
- return tarinfo
-
- with tarfile.open(afilename + '.tar.gz', 'w:gz') as tf:
- tf.add(output_dir, os.path.relpath(output_dir, basedir), filter=_set_ex_perm)
- elif arctype == 'zip':
- shutil.make_archive(afilename, 'zip', output_dir)
- else:
- report({'ERROR'}, "Unknown archive type %s for runtime %s\n" % (arctype, player_path))
-
- print("done", flush=True)
-
-
-class PublishAllPlatforms(bpy.types.Operator):
- bl_idname = "wm.publish_platforms"
- bl_label = "Exports a runtime for each listed platform"
-
- def execute(self, context):
- ps = context.scene.ge_publish_settings
-
- if ps.publish_default_platform:
- print("Publishing default platform")
- blender_bin_path = bpy.app.binary_path
- blender_bin_dir = os.path.dirname(blender_bin_path)
- ext = os.path.splitext(blender_bin_path)[-1].lower()
- WriteRuntime(os.path.join(blender_bin_dir, 'blenderplayer' + ext),
- os.path.join(ps.output_path, 'default', ps.runtime_name),
- ps.asset_paths,
- True,
- True,
- True,
- ps.make_archive,
- self.report
- )
- else:
- print("Skipping default platform")
-
- for platform in ps.platforms:
- if platform.publish:
- print("Publishing", platform.name)
- WriteRuntime(platform.player_path,
- os.path.join(ps.output_path, platform.name, ps.runtime_name),
- ps.asset_paths,
- True,
- True,
- True,
- ps.make_archive,
- self.report
- )
- else:
- print("Skipping", platform.name)
-
- return {'FINISHED'}
-
-
-class RENDER_UL_assets(bpy.types.UIList):
- bl_label = "Asset Paths Listing"
-
- def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
- layout.prop(item, "name", text="", emboss=False)
-
-
-class RENDER_UL_platforms(bpy.types.UIList):
- bl_label = "Platforms Listing"
-
- def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
- row = layout.row()
- row.label(item.name)
- row.prop(item, "publish", text="")
-
-
-class RENDER_PT_publish(bpy.types.Panel):
- bl_label = "Publishing Info"
- bl_space_type = "PROPERTIES"
- bl_region_type = "WINDOW"
- bl_context = "render"
-
- @classmethod
- def poll(cls, context):
- scene = context.scene
- return scene and (scene.render.engine == "BLENDER_GAME")
-
- def draw(self, context):
- ps = context.scene.ge_publish_settings
- layout = self.layout
-
- # config
- layout.prop(ps, 'output_path')
- layout.prop(ps, 'runtime_name')
- layout.prop(ps, 'lib_path')
- layout.prop(ps, 'make_archive')
-
- layout.separator()
-
- # assets list
- layout.label("Asset Paths")
-
- # UI_UL_list
- row = layout.row()
- row.template_list("RENDER_UL_assets", "assets_list", ps, 'asset_paths', ps, 'asset_paths_active')
-
- # operators
- col = row.column(align=True)
- col.operator(PublishAddAssetPath.bl_idname, icon='ZOOMIN', text="")
- col.operator(PublishRemoveAssetPath.bl_idname, icon='ZOOMOUT', text="")
-
- # indexing
- if len(ps.asset_paths) > ps.asset_paths_active >= 0:
- ap = ps.asset_paths[ps.asset_paths_active]
- row = layout.row()
- row.prop(ap, 'overwrite')
-
- layout.separator()
-
- # publishing list
- row = layout.row(align=True)
- row.label("Platforms")
- row.prop(ps, 'publish_default_platform')
-
- # UI_UL_list
- row = layout.row()
- row.template_list("RENDER_UL_platforms", "platforms_list", ps, 'platforms', ps, 'platforms_active')
-
- # operators
- col = row.column(align=True)
- col.operator(PublishAddPlatform.bl_idname, icon='ZOOMIN', text="")
- col.operator(PublishRemovePlatform.bl_idname, icon='ZOOMOUT', text="")
- col.menu("PUBLISH_MT_platform_specials", icon='DOWNARROW_HLT', text="")
-
- # indexing
- if len(ps.platforms) > ps.platforms_active >= 0:
- platform = ps.platforms[ps.platforms_active]
- layout.prop(platform, 'name')
- layout.prop(platform, 'player_path')
-
- layout.operator(PublishAllPlatforms.bl_idname, 'Publish Platforms')
-
-
-class PublishAutoPlatforms(bpy.types.Operator):
- bl_idname = "scene.publish_auto_platforms"
- bl_label = "Auto Add Platforms"
-
- def execute(self, context):
- ps = context.scene.ge_publish_settings
-
- # verify lib folder
- lib_path = bpy.path.abspath(ps.lib_path)
- if not os.path.exists(lib_path):
- self.report({'ERROR'}, "Could not add platforms, lib folder (%s) does not exist" % lib_path)
- return {'CANCELLED'}
-
- for lib in [i for i in os.listdir(lib_path) if os.path.isdir(os.path.join(lib_path, i))]:
- print("Found folder:", lib)
- player_found = False
- for root, dirs, files in os.walk(os.path.join(lib_path, lib)):
- if "__MACOSX" in root:
- continue
-
- for f in dirs + files:
- if f.startswith("blenderplayer.app") or f.startswith("blenderplayer"):
- a = ps.platforms.add()
- if lib.startswith('blender-'):
- # Clean up names for packages from blender.org
- # example: blender-2.71-RC2-OSX_10.6-x86_64.zip => OSX_10.6-x86_64.zip
- # We're pretty consistent on naming, so this should hold up.
- a.name = '-'.join(lib.split('-')[3 if 'rc' in lib.lower() else 2:])
- else:
- a.name = lib
- a.player_path = bpy.path.relpath(os.path.join(root, f))
- player_found = True
- break
-
- if player_found:
- break
-
- return {'FINISHED'}
-
-# TODO This operator takes a long time to run, which is bad for UX. Could this instead be done as some sort of
-# modal dialog? This could also allow users to select which platforms to download and give a better progress
-# indicator.
-class PublishDownloadPlatforms(bpy.types.Operator):
- bl_idname = "scene.publish_download_platforms"
- bl_label = "Download Platforms"
-
- def execute(self, context):
- import html.parser
- import urllib.request
-
- remote_platforms = []
-
- ps = context.scene.ge_publish_settings
-
- # create lib folder if not already available
- lib_path = bpy.path.abspath(ps.lib_path)
- if not os.path.exists(lib_path):
- os.makedirs(lib_path)
-
- print("Retrieving list of platforms from blender.org...", end=" ", flush=True)
-
- class AnchorParser(html.parser.HTMLParser):
- def handle_starttag(self, tag, attrs):
- if tag == 'a':
- for key, value in attrs:
- if key == 'href' and value.startswith('blender'):
- remote_platforms.append(value)
-
- url = 'http://download.blender.org/release/Blender' + bpy.app.version_string.split()[0]
- parser = AnchorParser()
- data = urllib.request.urlopen(url).read()
- parser.feed(str(data))
-
- print("done", flush=True)
-
- print("Downloading files (this will take a while depending on your internet connection speed).", flush=True)
- for i in remote_platforms:
- src = '/'.join((url, i))
- dst = os.path.join(lib_path, i)
-
- dst_dir = '.'.join([i for i in dst.split('.') if i not in {'zip', 'tar', 'bz2'}])
- if not os.path.exists(dst) and not os.path.exists(dst.split('.')[0]):
- print("Downloading " + src + "...", end=" ", flush=True)
- urllib.request.urlretrieve(src, dst)
- print("done", flush=True)
- else:
- print("Reusing existing file: " + dst, flush=True)
-
- print("Unpacking " + dst + "...", end=" ", flush=True)
- if os.path.exists(dst_dir):
- shutil.rmtree(dst_dir)
- shutil.unpack_archive(dst, dst_dir)
- print("done", flush=True)
-
- print("Creating platform from libs...", flush=True)
- bpy.ops.scene.publish_auto_platforms()
- return {'FINISHED'}
-
-
-class PublishAddPlatform(bpy.types.Operator):
- bl_idname = "scene.publish_add_platform"
- bl_label = "Add Publish Platform"
-
- def execute(self, context):
- a = context.scene.ge_publish_settings.platforms.add()
- a.name = a.name
- return {'FINISHED'}
-
-
-class PublishRemovePlatform(bpy.types.Operator):
- bl_idname = "scene.publish_remove_platform"
- bl_label = "Remove Publish Platform"
-
- def execute(self, context):
- ps = context.scene.ge_publish_settings
- if ps.platforms_active < len(ps.platforms):
- ps.platforms.remove(ps.platforms_active)
- return {'FINISHED'}
- return {'CANCELLED'}
-
-
-# TODO maybe this should display a file browser?
-class PublishAddAssetPath(bpy.types.Operator):
- bl_idname = "scene.publish_add_assetpath"
- bl_label = "Add Asset Path"
-
- def execute(self, context):
- a = context.scene.ge_publish_settings.asset_paths.add()
- a.name = a.name
- return {'FINISHED'}
-
-
-class PublishRemoveAssetPath(bpy.types.Operator):
- bl_idname = "scene.publish_remove_assetpath"
- bl_label = "Remove Asset Path"
-
- def execute(self, context):
- ps = context.scene.ge_publish_settings
- if ps.asset_paths_active < len(ps.asset_paths):
- ps.asset_paths.remove(ps.asset_paths_active)
- return {'FINISHED'}
- return {'CANCELLED'}
-
-
-class PUBLISH_MT_platform_specials(bpy.types.Menu):
- bl_label = "Platform Specials"
-
- def draw(self, context):
- layout = self.layout
- layout.operator(PublishAutoPlatforms.bl_idname)
- layout.operator(PublishDownloadPlatforms.bl_idname)
-
-
-class PlatformSettings(bpy.types.PropertyGroup):
- name = bpy.props.StringProperty(
- name = "Platform Name",
- description = "The name of the platform",
- default = "Platform",
- )
-
- player_path = bpy.props.StringProperty(
- name = "Player Path",
- description = "The path to the Blenderplayer to use for this platform",
- default = "//lib/platform/blenderplayer",
- subtype = 'FILE_PATH',
- )
-
- publish = bpy.props.BoolProperty(
- name = "Publish",
- description = "Whether or not to publish to this platform",
- default = True,
- )
-
-
-class AssetPath(bpy.types.PropertyGroup):
- # TODO This needs a way to be a FILE_PATH or a DIR_PATH
- name = bpy.props.StringProperty(
- name = "Asset Path",
- description = "Path to the asset to be copied",
- default = "//src",
- subtype = 'FILE_PATH',
- )
-
- overwrite = bpy.props.BoolProperty(
- name = "Overwrite Asset",
- description = "Overwrite the asset if it already exists in the destination folder",
- default = True,
- )
-
-
-class PublishSettings(bpy.types.PropertyGroup):
- output_path = bpy.props.StringProperty(
- name = "Publish Output",
- description = "Where to publish the game",
- default = "//bin/",
- subtype = 'DIR_PATH',
- )
-
- runtime_name = bpy.props.StringProperty(
- name = "Runtime name",
- description = "The filename for the created runtime",
- default = "game",
- )
-
- lib_path = bpy.props.StringProperty(
- name = "Library Path",
- description = "Directory to search for platforms",
- default = "//lib/",
- subtype = 'DIR_PATH',
- )
-
- publish_default_platform = bpy.props.BoolProperty(
- name = "Publish Default Platform",
- description = "Whether or not to publish the default platform (the Blender install running this addon) when publishing platforms",
- default = True,
- )
-
-
- platforms = bpy.props.CollectionProperty(type=PlatformSettings, name="Platforms")
- platforms_active = bpy.props.IntProperty()
-
- asset_paths = bpy.props.CollectionProperty(type=AssetPath, name="Asset Paths")
- asset_paths_active = bpy.props.IntProperty()
-
- make_archive = bpy.props.BoolProperty(
- name = "Make Archive",
- description = "Create a zip archive of the published game",
- default = True,
- )
-
-
-def register():
- bpy.utils.register_module(__name__)
-
- bpy.types.Scene.ge_publish_settings = bpy.props.PointerProperty(type=PublishSettings)
-
-
-def unregister():
- bpy.utils.unregister_module(__name__)
- del bpy.types.Scene.ge_publish_settings
-
-
-if __name__ == "__main__":
- register()
diff --git a/game_engine_save_as_runtime.py b/game_engine_save_as_runtime.py
deleted file mode 100644
index 25e47d94..00000000
--- a/game_engine_save_as_runtime.py
+++ /dev/null
@@ -1,258 +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": "Save As Game Engine Runtime",
- "author": "Mitchell Stokes (Moguri)",
- "version": (0, 3, 1),
- "blender": (2, 61, 0),
- "location": "File > Export",
- "description": "Bundle a .blend file with the Blenderplayer",
- "warning": "",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
- "Scripts/Game_Engine/Save_As_Runtime",
- "category": "Game Engine",
-}
-
-import bpy
-import os
-import sys
-import shutil
-import tempfile
-
-
-def CopyPythonLibs(dst, overwrite_lib, report=print):
- import platform
-
- # use python module to find pytohn's libpath
- src = os.path.dirname(platform.__file__)
-
- # dst points to lib/, but src points to current python's library path, eg:
- # '/usr/lib/python3.2' vs '/usr/lib'
- # append python's library dir name to destination, so only python's
- # libraries would be copied
- if os.name == 'posix':
- dst = os.path.join(dst, os.path.basename(src))
-
- if os.path.exists(src):
- write = False
- if os.path.exists(dst):
- if overwrite_lib:
- shutil.rmtree(dst)
- write = True
- else:
- write = True
- if write:
- shutil.copytree(src, dst, ignore=lambda dir, contents: [i for i in contents if i == '__pycache__'])
- else:
- report({'WARNING'}, "Python not found in %r, skipping pythn copy" % src)
-
-
-def WriteAppleRuntime(player_path, output_path, copy_python, overwrite_lib):
- # Enforce the extension
- if not output_path.endswith('.app'):
- output_path += '.app'
-
- # Use the system's cp command to preserve some meta-data
- os.system('cp -R "%s" "%s"' % (player_path, output_path))
-
- bpy.ops.wm.save_as_mainfile(filepath=os.path.join(output_path, "Contents/Resources/game.blend"),
- relative_remap=False,
- compress=False,
- copy=True,
- )
-
- # Python doesn't need to be copied for OS X since it's already inside blenderplayer.app
-
-
-def WriteRuntime(player_path, output_path, copy_python, overwrite_lib, copy_dlls, report=print):
- import struct
-
- # Check the paths
- if not os.path.isfile(player_path) and not(os.path.exists(player_path) and player_path.endswith('.app')):
- report({'ERROR'}, "The player could not be found! Runtime not saved")
- return
-
- # Check if we're bundling a .app
- if player_path.endswith('.app'):
- WriteAppleRuntime(player_path, output_path, copy_python, overwrite_lib)
- return
-
- # Enforce "exe" extension on Windows
- if player_path.endswith('.exe') and not output_path.endswith('.exe'):
- output_path += '.exe'
-
- # Get the player's binary and the offset for the blend
- file = open(player_path, 'rb')
- player_d = file.read()
- offset = file.tell()
- file.close()
-
- # Create a tmp blend file (Blenderplayer doesn't like compressed blends)
- tempdir = tempfile.mkdtemp()
- blend_path = os.path.join(tempdir, bpy.path.clean_name(output_path))
- bpy.ops.wm.save_as_mainfile(filepath=blend_path,
- relative_remap=False,
- compress=False,
- copy=True,
- )
-
- # Get the blend data
- blend_file = open(blend_path, 'rb')
- blend_d = blend_file.read()
- blend_file.close()
-
- # Get rid of the tmp blend, we're done with it
- os.remove(blend_path)
- os.rmdir(tempdir)
-
- # Create a new file for the bundled runtime
- output = open(output_path, 'wb')
-
- # Write the player and blend data to the new runtime
- print("Writing runtime...", end=" ")
- output.write(player_d)
- output.write(blend_d)
-
- # Store the offset (an int is 4 bytes, so we split it up into 4 bytes and save it)
- output.write(struct.pack('B', (offset>>24)&0xFF))
- output.write(struct.pack('B', (offset>>16)&0xFF))
- output.write(struct.pack('B', (offset>>8)&0xFF))
- output.write(struct.pack('B', (offset>>0)&0xFF))
-
- # Stuff for the runtime
- output.write(b'BRUNTIME')
- output.close()
-
- print("done")
-
- # Make the runtime executable on Linux
- if os.name == 'posix':
- os.chmod(output_path, 0o755)
-
- # Copy bundled Python
- blender_dir = os.path.dirname(bpy.app.binary_path)
- runtime_dir = os.path.dirname(output_path)
-
- if copy_python:
- print("Copying Python files...", end=" ")
- py_folder = os.path.join(bpy.app.version_string.split()[0], "python", "lib")
- dst = os.path.join(runtime_dir, py_folder)
- CopyPythonLibs(dst, overwrite_lib, report)
- print("done")
-
- # And DLLs
- if copy_dlls:
- print("Copying DLLs...", end=" ")
- for file in [i for i in os.listdir(blender_dir) if i.lower().endswith('.dll')]:
- src = os.path.join(blender_dir, file)
- dst = os.path.join(runtime_dir, file)
- shutil.copy2(src, dst)
-
- print("done")
-
-from bpy.props import *
-
-
-class SaveAsRuntime(bpy.types.Operator):
- bl_idname = "wm.save_as_runtime"
- bl_label = "Save As Game Engine Runtime"
- bl_options = {'REGISTER'}
-
- if sys.platform == 'darwin':
- # XXX, this line looks suspicious, could be done better?
- blender_bin_dir = '/' + os.path.join(*bpy.app.binary_path.split('/')[0:-4])
- ext = '.app'
- else:
- blender_bin_path = bpy.app.binary_path
- blender_bin_dir = os.path.dirname(blender_bin_path)
- ext = os.path.splitext(blender_bin_path)[-1].lower()
-
- default_player_path = os.path.join(blender_bin_dir, 'blenderplayer' + ext)
- player_path = StringProperty(
- name="Player Path",
- description="The path to the player to use",
- default=default_player_path,
- subtype='FILE_PATH',
- )
- filepath = StringProperty(
- subtype='FILE_PATH',
- )
- copy_python = BoolProperty(
- name="Copy Python",
- description="Copy bundle Python with the runtime",
- default=True,
- )
- overwrite_lib = BoolProperty(
- name="Overwrite 'lib' folder",
- description="Overwrites the lib folder (if one exists) with the bundled Python lib folder",
- default=False,
- )
-
- # Only Windows has dlls to copy
- if ext == '.exe':
- copy_dlls = BoolProperty(
- name="Copy DLLs",
- description="Copy all needed DLLs with the runtime",
- default=True,
- )
- else:
- copy_dlls = False
-
- def execute(self, context):
- import time
- start_time = time.clock()
- print("Saving runtime to %r" % self.filepath)
- WriteRuntime(self.player_path,
- self.filepath,
- self.copy_python,
- self.overwrite_lib,
- self.copy_dlls,
- self.report,
- )
- print("Finished in %.4fs" % (time.clock()-start_time))
- return {'FINISHED'}
-
- def invoke(self, context, event):
- if not self.filepath:
- ext = '.app' if sys.platform == 'darwin' else os.path.splitext(bpy.app.binary_path)[-1]
- self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ext)
-
- wm = context.window_manager
- wm.fileselect_add(self)
- return {'RUNNING_MODAL'}
-
-
-def menu_func(self, context):
- self.layout.operator(SaveAsRuntime.bl_idname)
-
-
-def register():
- bpy.utils.register_module(__name__)
-
- bpy.types.INFO_MT_file_export.append(menu_func)
-
-
-def unregister():
- bpy.utils.unregister_module(__name__)
-
- bpy.types.INFO_MT_file_export.remove(menu_func)
-
-
-if __name__ == "__main__":
- register()
diff --git a/io_anim_acclaim/__init__.py b/io_anim_acclaim/__init__.py
index 620c1fc4..7cada817 100644
--- a/io_anim_acclaim/__init__.py
+++ b/io_anim_acclaim/__init__.py
@@ -189,7 +189,7 @@ class StructureBuilder(DataStructure):
self.armature = self.object.data
self.object.name = self.name
self.armature.name = self.name
- self.armature.draw_type = 'STICK'
+ self.armature.display_type = 'STICK'
self.object['source_file_path'] = self.file_path
self.object['source_scale'] = self.user_def_scale
self.object['MhxArmature'] = 'Daz'
@@ -530,16 +530,16 @@ def menu_func_me(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_import.append(menu_func_s)
- bpy.types.INFO_MT_file_import.append(menu_func_mi)
- bpy.types.INFO_MT_file_export.append(menu_func_me)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_s)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_mi)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_me)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_import.remove(menu_func_s)
- bpy.types.INFO_MT_file_import.remove(menu_func_mi)
- bpy.types.INFO_MT_file_export.remove(menu_func_me)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_s)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_mi)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_me)
if __name__ == "__main__":
diff --git a/io_anim_bvh/__init__.py b/io_anim_bvh/__init__.py
index 4a4983ff..dd9c2037 100644
--- a/io_anim_bvh/__init__.py
+++ b/io_anim_bvh/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "BioVision Motion Capture (BVH) format",
"author": "Campbell Barton",
"version": (1, 0, 0),
- "blender": (2, 74, 0),
+ "blender": (2, 80, 0),
"location": "File > Import-Export",
"description": "Import-Export BVH from armature objects",
"warning": "",
@@ -52,24 +52,22 @@ from bpy.props import (
from bpy_extras.io_utils import (
ImportHelper,
ExportHelper,
- orientation_helper_factory,
+ orientation_helper,
axis_conversion,
)
-ImportBVHOrientationHelper = orientation_helper_factory("ImportBVHOrientationHelper", axis_forward='-Z', axis_up='Y')
-
-
-class ImportBVH(bpy.types.Operator, ImportHelper, ImportBVHOrientationHelper):
+@orientation_helper(axis_forward='-Z', axis_up='Y')
+class ImportBVH(bpy.types.Operator, ImportHelper):
"""Load a BVH motion capture file"""
bl_idname = "import_anim.bvh"
bl_label = "Import BVH"
bl_options = {'REGISTER', 'UNDO'}
filename_ext = ".bvh"
- filter_glob = StringProperty(default="*.bvh", options={'HIDDEN'})
+ filter_glob: StringProperty(default="*.bvh", options={'HIDDEN'})
- target = EnumProperty(
+ target: EnumProperty(
items=(
('ARMATURE', "Armature", ""),
('OBJECT', "Object", ""),
@@ -78,20 +76,19 @@ class ImportBVH(bpy.types.Operator, ImportHelper, ImportBVHOrientationHelper):
description="Import target type",
default='ARMATURE',
)
-
- global_scale = FloatProperty(
+ global_scale: FloatProperty(
name="Scale",
description="Scale the BVH by this value",
min=0.0001, max=1000000.0,
soft_min=0.001, soft_max=100.0,
default=1.0,
)
- frame_start = IntProperty(
+ frame_start: IntProperty(
name="Start Frame",
description="Starting frame for the animation",
default=1,
)
- use_fps_scale = BoolProperty(
+ use_fps_scale: BoolProperty(
name="Scale FPS",
description=(
"Scale the framerate from the BVH to the current scenes, "
@@ -99,25 +96,25 @@ class ImportBVH(bpy.types.Operator, ImportHelper, ImportBVHOrientationHelper):
),
default=False,
)
- update_scene_fps = BoolProperty(
+ update_scene_fps: BoolProperty(
name="Update Scene FPS",
description=(
"Set the scene framerate to that of the BVH file (note that this "
"nullifies the 'Scale FPS' option, as the scale will be 1:1)"
),
- default=False
+ default=False,
)
- update_scene_duration = BoolProperty(
+ update_scene_duration: BoolProperty(
name="Update Scene Duration",
description="Extend the scene's duration to the BVH duration (never shortens the scene)",
default=False,
)
- use_cyclic = BoolProperty(
+ use_cyclic: BoolProperty(
name="Loop",
description="Loop the animation playback",
default=False,
)
- rotate_mode = EnumProperty(
+ rotate_mode: EnumProperty(
name="Rotation",
description="Rotation conversion",
items=(
@@ -143,7 +140,6 @@ class ImportBVH(bpy.types.Operator, ImportHelper, ImportBVHOrientationHelper):
"filter_glob",
)
)
-
global_matrix = axis_conversion(
from_forward=self.axis_forward,
from_up=self.axis_up,
@@ -161,29 +157,29 @@ class ExportBVH(bpy.types.Operator, ExportHelper):
bl_label = "Export BVH"
filename_ext = ".bvh"
- filter_glob = StringProperty(
+ filter_glob: StringProperty(
default="*.bvh",
options={'HIDDEN'},
)
- global_scale = FloatProperty(
+ global_scale: FloatProperty(
name="Scale",
description="Scale the BVH by this value",
min=0.0001, max=1000000.0,
soft_min=0.001, soft_max=100.0,
default=1.0,
)
- frame_start = IntProperty(
+ frame_start: IntProperty(
name="Start Frame",
description="Starting frame to export",
default=0,
)
- frame_end = IntProperty(
+ frame_end: IntProperty(
name="End Frame",
description="End frame to export",
default=0,
)
- rotate_mode = EnumProperty(
+ rotate_mode: EnumProperty(
name="Rotation",
description="Rotation conversion",
items=(
@@ -198,7 +194,7 @@ class ExportBVH(bpy.types.Operator, ExportHelper):
),
default='NATIVE',
)
- root_transform_only = BoolProperty(
+ root_transform_only: BoolProperty(
name="Root Translation Only",
description="Only write out translation channels for the root bone",
default=False,
@@ -220,7 +216,14 @@ class ExportBVH(bpy.types.Operator, ExportHelper):
self.frame_start = context.scene.frame_start
self.frame_end = context.scene.frame_end
- keywords = self.as_keywords(ignore=("check_existing", "filter_glob"))
+ keywords = self.as_keywords(
+ ignore=(
+ "axis_forward",
+ "axis_up",
+ "check_existing",
+ "filter_glob",
+ )
+ )
from . import export_bvh
return export_bvh.save(context, **keywords)
@@ -234,19 +237,25 @@ def menu_func_export(self, context):
self.layout.operator(ExportBVH.bl_idname, text="Motion Capture (.bvh)")
+classes = (
+ ImportBVH,
+ ExportBVH
+)
+
def register():
- bpy.utils.register_module(__name__)
+ for cls in classes:
+ bpy.utils.register_class(cls)
- bpy.types.INFO_MT_file_import.append(menu_func_import)
- bpy.types.INFO_MT_file_export.append(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
- bpy.utils.unregister_module(__name__)
-
- bpy.types.INFO_MT_file_import.remove(menu_func_import)
- bpy.types.INFO_MT_file_export.remove(menu_func_export)
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
diff --git a/io_anim_bvh/export_bvh.py b/io_anim_bvh/export_bvh.py
index 6a0c210f..a8b589df 100644
--- a/io_anim_bvh/export_bvh.py
+++ b/io_anim_bvh/export_bvh.py
@@ -255,12 +255,12 @@ def write_armature(
itrans = Matrix.Translation(-dbone.rest_bone.head_local)
if dbone.parent:
- mat_final = dbone.parent.rest_arm_mat * dbone.parent.pose_imat * dbone.pose_mat * dbone.rest_arm_imat
- mat_final = itrans * mat_final * trans
+ mat_final = dbone.parent.rest_arm_mat @ dbone.parent.pose_imat @ dbone.pose_mat @ dbone.rest_arm_imat
+ mat_final = itrans @ mat_final @ trans
loc = mat_final.to_translation() + (dbone.rest_bone.head_local - dbone.parent.rest_bone.head_local)
else:
- mat_final = dbone.pose_mat * dbone.rest_arm_imat
- mat_final = itrans * mat_final * trans
+ mat_final = dbone.pose_mat @ dbone.rest_arm_imat
+ mat_final = itrans @ mat_final @ trans
loc = mat_final.to_translation() + dbone.rest_bone.head
# keep eulers compatible, no jumping on interpolation.
diff --git a/io_anim_bvh/import_bvh.py b/io_anim_bvh/import_bvh.py
index 1f3c93fe..0a9e4b30 100644
--- a/io_anim_bvh/import_bvh.py
+++ b/io_anim_bvh/import_bvh.py
@@ -348,19 +348,19 @@ def bvh_node_dict2objects(context, bvh_name, bvh_nodes, rotate_mode='NATIVE', fr
scene = context.scene
for obj in scene.objects:
- obj.select = False
+ obj.select_set("DESELECT")
objects = []
def add_ob(name):
obj = bpy.data.objects.new(name, None)
- scene.objects.link(obj)
+ context.collection.objects.link(obj)
objects.append(obj)
- obj.select = True
+ obj.select_set("SELECT")
# nicer drawing.
- obj.empty_draw_type = 'CUBE'
- obj.empty_draw_size = 0.1
+ obj.empty_display_type = 'CUBE'
+ obj.empty_display_size = 0.1
return obj
@@ -422,15 +422,15 @@ def bvh_node_dict2armature(
# Add the new armature,
scene = context.scene
for obj in scene.objects:
- obj.select = False
+ obj.select_set("DESELECT")
arm_data = bpy.data.armatures.new(bvh_name)
arm_ob = bpy.data.objects.new(bvh_name, arm_data)
- scene.objects.link(arm_ob)
+ context.collection.objects.link(arm_ob)
- arm_ob.select = True
- scene.objects.active = arm_ob
+ arm_ob.select_set("SELECT")
+ context.view_layer.objects.active = arm_ob
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
@@ -580,7 +580,7 @@ def bvh_node_dict2armature(
bone_translate_matrix = Matrix.Translation(
Vector(bvh_loc) - bvh_node.rest_head_local)
- location[frame_i] = (bone_rest_matrix_inv *
+ location[frame_i] = (bone_rest_matrix_inv @
bone_translate_matrix).to_translation()
# For each location x, y, z.
@@ -617,8 +617,8 @@ def bvh_node_dict2armature(
euler = Euler(bvh_rot, bvh_node.rot_order_str[::-1])
bone_rotation_matrix = euler.to_matrix().to_4x4()
bone_rotation_matrix = (
- bone_rest_matrix_inv *
- bone_rotation_matrix *
+ bone_rest_matrix_inv @
+ bone_rotation_matrix @
bone_rest_matrix
)
diff --git a/io_anim_c3d/__init__.py b/io_anim_c3d/__init__.py
index 2c9cd0d6..e14fcaec 100644
--- a/io_anim_c3d/__init__.py
+++ b/io_anim_c3d/__init__.py
@@ -272,7 +272,7 @@ class C3DImporter(bpy.types.Operator):
unames[name] = o.name
bpy.ops.transform.resize(value=empty_size)
o.show_name = self.properties.show_names
- o.show_x_ray = self.properties.x_ray
+ o.show_in_front = self.properties.x_ray
for name in unames.values():
bpy.context.scene.objects[name].select = True
return unames
@@ -291,7 +291,7 @@ class C3DImporter(bpy.types.Operator):
arm = bpy.context.active_object
arm.name = os.path.basename(self.properties.filepath)
arm.data.show_names = self.properties.show_names
- arm.show_x_ray = self.properties.x_ray
+ arm.show_in_front = self.properties.x_ray
for idx, ml in enumerate(ms.markerLabels):
name = self.properties.prefix + ml
bpy.ops.armature.select_all(action='DESELECT')
@@ -354,12 +354,12 @@ def menu_func(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_import.append(menu_func)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_import.remove(menu_func)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func)
if __name__ == "__main__":
diff --git a/io_anim_camera.py b/io_anim_camera.py
index 20cb5395..b382a32d 100644
--- a/io_anim_camera.py
+++ b/io_anim_camera.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Export Camera Animation",
"author": "Campbell Barton",
"version": (0, 1),
- "blender": (2, 57, 0),
+ "blender": (2, 80, 0),
"location": "File > Export > Cameras & Markers (.py)",
"description": "Export Cameras & Markers (.py)",
"warning": "",
@@ -45,7 +45,7 @@ def write_cameras(context, filepath, frame_start, frame_end, only_selected=False
'dof_distance',
'clip_start',
'clip_end',
- 'draw_size',
+ 'display_size',
)
obj_attrs = (
@@ -59,7 +59,7 @@ def write_cameras(context, filepath, frame_start, frame_end, only_selected=False
cameras = []
for obj in scene.objects:
- if only_selected and not obj.select:
+ if only_selected and not obj.select_get():
continue
if obj.type != 'CAMERA':
continue
@@ -84,7 +84,7 @@ def write_cameras(context, filepath, frame_start, frame_end, only_selected=False
for attr in obj_attrs:
fw("obj.%s = %s\n" % (attr, repr(getattr(obj, attr))))
- fw("scene.objects.link(obj)\n")
+ fw("bpy.context.collection.objects.link(obj)\n")
fw("cameras[%r] = obj\n" % obj.name)
fw("\n")
@@ -134,15 +134,15 @@ class CameraExporter(bpy.types.Operator, ExportHelper):
bl_label = "Export Camera & Markers"
filename_ext = ".py"
- filter_glob = StringProperty(default="*.py", options={'HIDDEN'})
+ filter_glob: StringProperty(default="*.py", options={'HIDDEN'})
- frame_start = IntProperty(name="Start Frame",
+ frame_start: IntProperty(name="Start Frame",
description="Start frame for export",
default=1, min=1, max=300000)
- frame_end = IntProperty(name="End Frame",
+ frame_end: IntProperty(name="End Frame",
description="End frame for export",
default=250, min=1, max=300000)
- only_selected = BoolProperty(name="Only Selected",
+ only_selected: BoolProperty(name="Only Selected",
default=True)
def execute(self, context):
@@ -165,15 +165,13 @@ def menu_export(self, context):
def register():
- bpy.utils.register_module(__name__)
-
- bpy.types.INFO_MT_file_export.append(menu_export)
+ bpy.utils.register_class(CameraExporter)
+ bpy.types.TOPBAR_MT_file_export.append(menu_export)
def unregister():
- bpy.utils.unregister_module(__name__)
-
- bpy.types.INFO_MT_file_export.remove(menu_export)
+ bpy.utils.unregister_class(CameraExporter)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_export)
if __name__ == "__main__":
diff --git a/io_anim_nuke_chan/__init__.py b/io_anim_nuke_chan/__init__.py
index b3102329..9266c439 100644
--- a/io_anim_nuke_chan/__init__.py
+++ b/io_anim_nuke_chan/__init__.py
@@ -143,15 +143,15 @@ def menu_func_export(self, context):
def register():
bpy.utils.register_class(ImportChan)
bpy.utils.register_class(ExportChan)
- bpy.types.INFO_MT_file_import.append(menu_func_import)
- bpy.types.INFO_MT_file_export.append(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_class(ImportChan)
bpy.utils.unregister_class(ExportChan)
- bpy.types.INFO_MT_file_import.remove(menu_func_import)
- bpy.types.INFO_MT_file_export.remove(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
diff --git a/io_blend_utils/__init__.py b/io_blend_utils/__init__.py
index d44d4754..9d102102 100644
--- a/io_blend_utils/__init__.py
+++ b/io_blend_utils/__init__.py
@@ -135,14 +135,14 @@ def register():
for cls in classes:
bpy.utils.register_class(cls)
- bpy.types.INFO_MT_file_external_data.append(menu_func)
+ bpy.types.TOPBAR_MT_file_external_data.append(menu_func)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
- bpy.types.INFO_MT_file_external_data.remove(menu_func)
+ bpy.types.TOPBAR_MT_file_external_data.remove(menu_func)
if __name__ == "__main__":
diff --git a/io_coat3D/__init__.py b/io_coat3D/__init__.py
index b5539ede..751e56f7 100644
--- a/io_coat3D/__init__.py
+++ b/io_coat3D/__init__.py
@@ -19,8 +19,8 @@
bl_info = {
"name": "3D-Coat Applink",
"author": "Kalle-Samuli Riihikoski (haikalle)",
- "version": (3, 5, 22),
- "blender": (2, 59, 0),
+ "version": (5, 0, 00),
+ "blender": (2, 80, 0),
"location": "Scene > 3D-Coat Applink",
"description": "Transfer data between 3D-Coat/Blender",
"warning": "",
@@ -35,10 +35,16 @@ if "bpy" in locals():
importlib.reload(coat)
importlib.reload(tex)
else:
- from . import coat
from . import tex
+from io_coat3D import tex
+import os
+import ntpath
+import re
+
+import time
import bpy
+import subprocess
from bpy.types import PropertyGroup
from bpy.props import (
BoolProperty,
@@ -49,244 +55,1175 @@ from bpy.props import (
)
+bpy.coat3D = dict()
+bpy.coat3D['active_coat'] = ''
+bpy.coat3D['status'] = 0
+
+def folder_size(path):
+
+ tosi = True
+ while tosi:
+ list_of_files = []
+ for file in os.listdir(path):
+ list_of_files.append(path + os.sep + file)
+
+ if len(list_of_files) >= 400:
+ oldest_file = min(list_of_files, key=os.path.getctime)
+ os.remove(os.path.abspath(oldest_file))
+ else:
+ tosi = False
+
+def set_exchange_folder():
+ platform = os.sys.platform
+ coat3D = bpy.context.scene.coat3D
+ Blender_export = ""
+
+ if(platform == 'win32'):
+ exchange = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3D-CoatV4' + os.sep +'Exchange'
+ if not(os.path.isdir(exchange)):
+ exchange = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3D-CoatV3' + os.sep +'Exchange'
+ else:
+ exchange = os.path.expanduser("~") + os.sep + '3D-CoatV4' + os.sep + 'Exchange'
+ if not(os.path.isdir(exchange)):
+ exchange = os.path.expanduser("~") + os.sep + '3D-CoatV3' + os.sep + 'Exchange'
+ if(not(os.path.isdir(exchange))):
+ exchange = coat3D.exchangedir
+
+ if(os.path.isdir(exchange)):
+ bpy.coat3D['status'] = 1
+ if(platform == 'win32'):
+ exchange_path = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt'
+ applink_folder = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender'
+ if(not(os.path.isdir(applink_folder))):
+ os.makedirs(applink_folder)
+ else:
+ exchange_path = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt'
+ applink_folder = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender'
+ if(not(os.path.isdir(applink_folder))):
+ os.makedirs(applink_folder)
+ file = open(exchange_path, "w")
+ file.write("%s"%(coat3D.exchangedir))
+ file.close()
+
+ else:
+ if(platform == 'win32'):
+ exchange_path = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt'
+ else:
+ exchange_path = os.path.expanduser("~") + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt'
+ if(os.path.isfile(exchange_path)):
+ ex_path =''
+
+ ex_pathh = open(exchange_path)
+ for line in ex_pathh:
+ ex_path = line
+ break
+ ex_pathh.close()
+
+ if(os.path.isdir(ex_path) and ex_path.rfind('Exchange') >= 0):
+ exchange = ex_path
+ bpy.coat3D['status'] = 1
+ else:
+ bpy.coat3D['status'] = 0
+ else:
+ bpy.coat3D['status'] = 0
+ if(bpy.coat3D['status'] == 1):
+ Blender_folder = ("%s%sBlender"%(exchange,os.sep))
+ Blender_export = Blender_folder
+ path3b_now = exchange
+ path3b_now += ('last_saved_3b_file.txt')
+ Blender_export += ('%sexport.txt'%(os.sep))
+
+ if(not(os.path.isdir(Blender_folder))):
+ os.makedirs(Blender_folder)
+ Blender_folder = os.path.join(Blender_folder,"run.txt")
+ file = open(Blender_folder, "w")
+ file.close()
+ return exchange
+
+def set_working_folders():
+ platform = os.sys.platform
+ coat3D = bpy.context.scene.coat3D
+ if(platform == 'win32'):
+ folder_objects = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'ApplinkObjects'
+ if(not(os.path.isdir(folder_objects))):
+ os.makedirs(folder_objects)
+ else:
+ folder_objects = os.path.expanduser("~") + os.sep + '3DC2Blender' + os.sep + 'ApplinkObjects'
+ if(not(os.path.isdir(folder_objects))):
+ os.makedirs(folder_objects)
+
+ return folder_objects
+
+def make_texture_list(texturefolder):
+ texturefolder += ('%stextures.txt'%(os.sep))
+ texturelist = []
+
+ if (os.path.isfile(texturefolder)):
+ texturefile = open(texturefolder)
+ index = 0
+ for line in texturefile:
+ if line != '' and index == 0:
+ line = line.rstrip('\n')
+ objekti = line
+ index += 1
+ elif index == 1:
+ line = line.rstrip('\n')
+ material = line
+ index += 1
+ elif index == 2:
+ line = line.rstrip('\n')
+ type = line
+ index += 1
+ elif index == 3:
+ line = line.rstrip('\n')
+ address = line
+ texturelist.append([objekti,material,type,address])
+ index = 0
+ texturefile.close()
+ return texturelist
+
+
+'''
+#Updating objects MESH part ( Mesh, Vertex Groups, Vertex Colors )
+'''
+
+def updatemesh(objekti, proxy):
+
+
+ #TO DO VERTEX GROUPS, gives an error with this code.
+
+ if(objekti.vertex_groups.keys() != []):
+ bpy.ops.object.select_all(action='DESELECT')
+ proxy.select_set('SELECT')
+ objekti.select_set('SELECT')
+ bpy.ops.object.vertex_group_copy_to_selected()
+ bpy.ops.object.select_all(action='DESELECT')
+
+ # UV Set Copy
+
+ proxy.select_set('SELECT')
+ objekti.select_set('SELECT')
+
+ if len(objekti.data.uv_layers) > 1:
+ obj_uv_index = objekti.data.uv_layers.active_index
+ index = 0
+ for uv_layer in objekti.data.uv_layers:
+ if (uv_layer != objekti.data.uv_layers[0]):
+ proxy.data.uv_layers.new(uv_layer.name)
+ proxy.data.uv_layers.active_index = index
+ objekti.data.uv_layers.active_index = index
+ bpy.ops.object.join_uvs()
+ index += 1
+ proxy.data.uv_layers.active_index = obj_uv_index
+
+ bpy.ops.object.select_all(action='DESELECT')
+
+ #Mesh Copy
+
+ proxy.select_set('SELECT')
+ obj_data = objekti.data.id_data
+ objekti.data = proxy.data.id_data
+ objekti.data.id_data.name = obj_data.name
+ if (bpy.data.meshes[obj_data.name].users == 0):
+ bpy.data.meshes.remove(obj_data)
+
+
+
+class SCENE_PT_Main(bpy.types.Panel):
+ bl_label = "3D-Coat Applink"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOLS"
+ bl_context = "objectmode"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ coat = bpy.coat3D
+ coat3D = bpy.context.scene.coat3D
+ if(bpy.context.active_object):
+ coa = bpy.context.active_object.coat3D
+
+ if(coat['status'] == 0):
+ row = layout.row()
+ row.label(text="Applink didn't find your 3d-Coat/Excahnge folder.")
+ row = layout.row()
+ row.label("Please select it before using Applink.")
+ row = layout.row()
+ row.prop(coat3D,"exchangedir",text="")
+ row = layout.row()
+ row.operator("update_exchange_folder.pilgway_3d_coat", text="Apply folder")
+
+ else:
+ #Here you add your GUI
+ row = layout.row()
+ row.prop(coat3D,"type",text = "")
+ row = layout.row()
+ colL = row.column()
+ colR = row.column()
+
+ colR.operator("export_applink.pilgway_3d_coat", text="Transfer")
+ colL.operator("import_applink.pilgway_3d_coat", text="Update")
+
+
+def running():
+ n=0# number of instances of the program running
+ prog=[line.split() for line in subprocess.check_output("tasklist").splitlines()]
+ [prog.pop(e) for e in [0,1,2]] #useless
+ for task in prog:
+ if str(task[0]) == "b'3D-CoatDX64C.exe'" or str(task[0]) == "b'3D-CoatGL64C.exe'":
+ n+=1
+ break
+ if n>0:
+ return True
+ else:
+ return False
+
+class SCENE_OT_folder(bpy.types.Operator):
+ bl_idname = "update_exchange_folder.pilgway_3d_coat"
+ bl_label = "Export your custom property"
+ bl_description = "Export your custom property"
+ bl_options = {'UNDO'}
+
+ def invoke(self, context, event):
+ coat3D = bpy.context.scene.coat3D
+
+ if(os.path.isdir(coat3D.exchangedir)):
+ coat3D.exchange_found = True
+ else:
+ coat3D.exchange_found = False
+
+ return {'FINISHED'}
+
+class SCENE_OT_opencoat(bpy.types.Operator):
+ bl_idname = "open_3dcoat.pilgway_3d_coat"
+ bl_label = "Export your custom property"
+ bl_description = "Export your custom property"
+ bl_options = {'UNDO'}
+
+ def invoke(self, context, event):
+ coat3D = bpy.context.selected_objects[0].coat3D.applink_3b_path
+ platform = os.sys.platform
+ prog_path = os.environ['PROGRAMFILES']
+ if (platform == 'win32'):
+ index = 0
+ for file in os.listdir(prog_path):
+ if index == 0:
+ if file.startswith('3D-Coat-V4'):
+ modi = os.path.getmtime(prog_path + os.sep + file)
+ active_3dcoat = prog_path + os.sep + file
+ index += 1
+ else:
+ if file.startswith('3D-Coat-V4'):
+ if(os.path.getmtime(prog_path + os.sep + file) > modi):
+ modi = os.path.getmtime(prog_path + os.sep + file)
+ active_3dcoat = prog_path + os.sep + file
+
+ if running() == False:
+
+ os.popen('"' + active_3dcoat + os.sep + '3D-CoatDX64C.exe' '" ' + coat3D)
+ else:
+ importfile = bpy.context.scene.coat3D.exchangedir
+ importfile += ('%simport.txt' % (os.sep))
+ file = open(importfile, "w")
+ file.write("%s" % (coat3D))
+ file.write("\n%s" % (coat3D))
+ file.write("\n[3B]")
+ file.close()
+
+ '''
+ If not Windows Os it will only write import.txt. Auto run 3d-coat.exe is disabled.
+ '''
+
+ else:
+ importfile = bpy.context.scene.coat3D.exchangedir
+ importfile += ('%simport.txt' % (os.sep))
+ file = open(importfile, "w")
+ file.write("%s" % (coat3D))
+ file.write("\n%s" % (coat3D))
+ file.write("\n[3B]")
+ file.close()
+
+
+
+ return {'FINISHED'}
+
+class SCENE_OT_export(bpy.types.Operator):
+ bl_idname = "export_applink.pilgway_3d_coat"
+ bl_label = "Export your custom property"
+ bl_description = "Export your custom property"
+ bl_options = {'UNDO'}
+
+ def invoke(self, context, event):
+
+ for mesh in bpy.data.meshes:
+ if (mesh.users == 0 and mesh.coat3D.name == '3DC'):
+ bpy.data.meshes.remove(mesh)
+
+ for material in bpy.data.materials:
+ if (material.users == 1 and material.coat3D.name == '3DC'):
+ bpy.data.materials.remove(material)
+
+ export_ok = False
+ coat3D = bpy.context.scene.coat3D
+
+ if (bpy.context.selected_objects == []):
+ return {'FINISHED'}
+ else:
+ for objec in bpy.context.selected_objects:
+ if objec.type == 'MESH':
+ export_ok = True
+ if (export_ok == False):
+ return {'FINISHED'}
+
+ activeobj = bpy.context.active_object.name
+ checkname = ''
+ coa = bpy.context.active_object.coat3D
+ coat3D.exchangedir = set_exchange_folder()
+
+ if (not os.path.isdir(coat3D.exchangedir)):
+ coat3D.exchange_found = False
+ return {'FINISHED'}
+
+
+ folder_objects = set_working_folders()
+ folder_size(folder_objects)
+
+ importfile = coat3D.exchangedir
+ texturefile = coat3D.exchangedir
+ importfile += ('%simport.txt'%(os.sep))
+ texturefile += ('%stextures.txt'%(os.sep))
+
+ looking = True
+ object_index = 0
+
+ while(looking == True):
+ checkname = folder_objects + os.sep + activeobj
+ checkname = ("%s%.2d.fbx"%(checkname,object_index))
+ if(os.path.isfile(checkname)):
+ object_index += 1
+ else:
+ looking = False
+ coa.applink_name = ("%s%.2d"%(activeobj,object_index))
+ coa.applink_address = checkname
+
+ matindex = 0
+ for objekti in bpy.context.selected_objects:
+ if(objekti.material_slots.keys() == []):
+ newmat = bpy.data.materials.new('Material')
+ newmat.use_nodes = True
+ objekti.data.materials.append(newmat)
+ matindex += 1
+
+ for objekti in bpy.context.selected_objects:
+ objekti.coat3D.applink_scale = objekti.scale
+
+ bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
+ #bpy.ops.object.transforms_to_deltas(mode='SCALE')
+
+ if(coat3D.type == 'ppp' or coat3D.type == 'mv' or coat3D.type == 'ptex'):
+ bpy.ops.export_scene.fbx(filepath=coa.applink_address, use_selection=True, use_mesh_modifiers=False, axis_forward='X', axis_up='Y')
+ else:
+ bpy.ops.export_scene.fbx(filepath=coa.applink_address, use_selection=True, use_mesh_modifiers=False, axis_up='Z', axis_forward='Y')
+
+
+ file = open(importfile, "w")
+ file.write("%s"%(checkname))
+ file.write("\n%s"%(checkname))
+ file.write("\n[%s]"%(coat3D.type))
+ file.close()
+ group_index = -1.0
+
+ for objekti in bpy.context.selected_objects:
+ nimi = ''
+ for koko in bpy.context.selected_objects:
+ nimi += koko.data.name + ':::'
+ objekti.coat3D.applink_group = nimi
+ objekti.coat3D.applink_address = coa.applink_address
+ objekti.coat3D.obj_mat = ''
+ objekti.coat3D.applink_name = coa.applink_name
+ objekti.coat3D.applink_firsttime = True
+ objekti.coat3D.objecttime = str(os.path.getmtime(objekti.coat3D.applink_address))
+ objekti.data.coat3D.name = '3DC'
+
+ if(objekti.material_slots.keys() != []):
+ for material in objekti.material_slots:
+ if material.material.use_nodes == True:
+ for node in material.material.node_tree.nodes:
+ if(node.name.startswith('3DC_') == True):
+ material.material.node_tree.nodes.remove(node)
+
+ return {'FINISHED'}
+
+class SCENE_OT_import(bpy.types.Operator):
+ bl_idname = "import_applink.pilgway_3d_coat"
+ bl_label = "import your custom property"
+ bl_description = "import your custom property"
+ bl_options = {'UNDO'}
+
+ def invoke(self, context, event):
+
+ for mesh in bpy.data.meshes:
+ if(mesh.users == 0 and mesh.coat3D.name == '3DC'):
+ bpy.data.meshes.remove(mesh)
+
+ for material in bpy.data.materials:
+ img_list = []
+ if (material.users == 1 and material.coat3D.name == '3DC'):
+ if material.use_nodes == True:
+ for node in material.node_tree.nodes:
+ if node.type == 'TEX_IMAGE' and node.name.startswith('3DC'):
+ img_list.append(node.image)
+ if img_list != []:
+ for del_img in img_list:
+ bpy.data.images.remove(del_img)
+
+ bpy.data.materials.remove(material)
+
+ coat3D = bpy.context.scene.coat3D
+ coat = bpy.coat3D
+ coat3D.exchangedir = set_exchange_folder()
+
+
+ texturelist = make_texture_list(coat3D.exchangedir)
+ for texturepath in texturelist:
+ for image in bpy.data.images:
+ if(image.filepath == texturepath[3] and image.users == 0):
+ bpy.data.images.remove(image)
+
+ Blender_folder = ("%s%sBlender"%(coat3D.exchangedir,os.sep))
+ Blender_export = Blender_folder
+ path3b_now = coat3D.exchangedir
+ path3b_now += ('last_saved_3b_file.txt')
+ Blender_export += ('%sexport.txt'%(os.sep))
+ new_applink_address = 'False'
+ new_object = False
+ if(os.path.isfile(Blender_export)):
+ obj_pathh = open(Blender_export)
+ new_object = True
+ for line in obj_pathh:
+ new_applink_address = line
+ break
+ obj_pathh.close()
+
+ for scene_objects in bpy.context.collection.objects:
+ if(scene_objects.type == 'MESH'):
+ if(scene_objects.coat3D.applink_address == new_applink_address):
+ new_object = False
+
+ exportfile = coat3D.exchangedir
+ exportfile += ('%sBlender' % (os.sep))
+ exportfile += ('%sexport.txt' % (os.sep))
+ if (os.path.isfile(exportfile)):
+ os.remove(exportfile)
+
+ if(new_object == False):
+
+ '''
+ #Blender -> 3DC -> Blender workflow
+ #First check if objects needs to be imported, if imported it will then delete extra mat and objs.
+ '''
+
+ old_materials = bpy.data.materials.keys()
+ old_objects = bpy.data.objects.keys()
+ old_images = bpy.data.images.keys()
+ image_list = []
+ object_list = []
+ import_list = []
+ mesh_del_list = []
+ for objekti in bpy.context.scene.collection.all_objects:
+ if (objekti.type == 'MESH'):
+ object_list.append(objekti.name)
+ obj_coat = objekti.coat3D
+ if(obj_coat.applink_address != ''):
+ if (obj_coat.objecttime != str(os.path.getmtime(obj_coat.applink_address))):
+ obj_coat.dime = objekti.dimensions
+ obj_coat.import_mesh = True
+ obj_coat.objecttime = str(os.path.getmtime(obj_coat.applink_address))
+ if(obj_coat.applink_address not in import_list):
+ import_list.append(obj_coat.applink_address)
+ print('image:', bpy.data.images)
+ if(import_list):
+ for list in import_list:
+ bpy.ops.import_scene.fbx(filepath=list, global_scale = 1,axis_forward='X')
+
+ bpy.ops.object.select_all(action='DESELECT')
+
+ new_materials = bpy.data.materials.keys()
+ new_objects = bpy.data.objects.keys()
+ new_images = bpy.data.images.keys()
+
+
+ diff_mat = [i for i in new_materials if i not in old_materials]
+ diff_objects = [i for i in new_objects if i not in old_objects]
+
+ for mark_mesh in diff_objects:
+ bpy.data.objects[mark_mesh].data.coat3D.name = '3DC'
+ for c_index in diff_mat:
+ bpy.data.materials.remove(bpy.data.materials[c_index])
+ '''The main Applink Object Loop'''
+
+ for oname in object_list:
+ objekti = bpy.data.objects[oname]
+ if(objekti.coat3D.import_mesh and coat3D.importmesh == True):
+ objekti.coat3D.import_mesh = False
+ objekti.select_set('SELECT')
+
+ new_name = objekti.data.name
+ name_boxs = new_name.split('.')
+ if len(name_boxs) > 1:
+ if len(name_boxs[-1]) == 3:
+ luku = int(name_boxs[-1])
+ luku +=1
+ uusi_nimi = ("%s.%.3d" % (new_name[:-4], luku))
+ find_name = uusi_nimi
+ else:
+ find_name = objekti.data.name
+ tosi = True
+ luku = 1
+ find_name = ("%s.%.3d" % (objekti.data.name, luku))
+ loyty = False
+ while tosi:
+ for obj in bpy.data.meshes:
+ if (obj.name == find_name):
+ loyty = True
+ break
+ if(loyty == True):
+ luku += 1
+ find_name = ("%s.%.3d" % (objekti.data.name, luku))
+ loyty = False
+ else:
+ find_name = ("%s.%.3d" % (objekti.data.name, luku-1))
+ tosi = False
+
+ for proxy_objects in diff_objects:
+ if (bpy.data.objects[proxy_objects].data.name == find_name):
+ obj_proxy = bpy.data.objects[proxy_objects]
+ break
+
+ exportfile = coat3D.exchangedir
+ path3b_n = coat3D.exchangedir
+ path3b_n += ('last_saved_3b_file.txt')
+ exportfile += ('%sBlender' % (os.sep))
+ exportfile += ('%sexport.txt'%(os.sep))
+ if(os.path.isfile(exportfile)):
+ export_file = open(exportfile)
+ for line in export_file:
+ if line.rfind('.3b'):
+ coat['active_coat'] = line
+ export_file.close()
+ os.remove(exportfile)
+
+ obj_names = objekti.coat3D.applink_group
+ obj_list = obj_names.split(':::')
+ applinks = []
+ mat_list = []
+ obj_list.pop()
+
+ use_smooth = objekti.data.polygons[0].use_smooth
+
+ if(objekti.material_slots):
+ act_mat = objekti.active_material
+ for obj_mat in objekti.material_slots:
+ mat_list.append(obj_mat.material)
+
+ bpy.ops.object.select_all(action='DESELECT')
+ obj_proxy.select_set('SELECT')
+
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ if objekti.coat3D.applink_firsttime == True:
+ objekti.scale = (objekti.scale[0]/objekti.coat3D.applink_scale[0],objekti.scale[1]/objekti.coat3D.applink_scale[1],objekti.scale[2]/objekti.coat3D.applink_scale[2])
+ bpy.ops.object.transforms_to_deltas(mode='SCALE')
+ objekti.rotation_euler = (0,0,0)
+ objekti.scale = (0.01,0.01,0.01)
+ objekti.coat3D.applink_firsttime = False
+
+ if(coat3D.importlevel):
+ obj_proxy.select = True
+ obj_proxy.modifiers.new(name='temp',type='MULTIRES')
+ objekti.select = True
+ bpy.ops.object.multires_reshape(modifier=multires_name)
+ bpy.ops.object.select_all(action='TOGGLE')
+ multires_on = False
+ else:
+ updatemesh(objekti,obj_proxy)
+
+ #tärkee että saadaan oikein käännettyä objekt
+
+ objekti.select_set('SELECT')
+ bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN')
+
+ objekti.data.materials.pop()
+ for mat in mat_list:
+ objekti.data.materials.append(mat)
+
+ if (use_smooth):
+ for data_mesh in objekti.data.polygons:
+ data_mesh.use_smooth = True
+
+ bpy.ops.object.select_all(action='DESELECT')
+
+ if(os.path.isfile(path3b_n)):
+ path3b_fil = open(path3b_n)
+ for lin in path3b_fil:
+ objekti.coat3D.applink_3b_path = lin
+ head, tail = os.path.split(objekti.coat3D.applink_3b_path)
+ objekti.coat3D.applink_3b_just_name = tail
+ path3b_fil.close()
+ os.remove(path3b_n)
+
+ if(coat3D.importmesh and not(os.path.isfile(objekti.coat3D.applink_address))):
+ coat3D.importmesh = False
+
+ objekti.select_set('SELECT')
+ if(coat3D.importtextures):
+ is_new = False
+ print('matlist: ', mat_list)
+ print('objekti: ', objekti)
+ print('is_new: ', is_new)
+ tex.matlab(objekti,mat_list,texturelist,is_new)
+ objekti.select_set('DESELECT')
+ else:
+ mat_list = []
+
+ if (objekti.material_slots):
+ for obj_mat in objekti.material_slots:
+ mat_list.append(obj_mat.material)
+
+ if (coat3D.importtextures):
+ is_new = False
+ print('matlist: ',mat_list)
+ print('objekti: ', objekti)
+ print('is_new: ', is_new)
+ tex.matlab(objekti,mat_list,texturelist, is_new)
+ objekti.select_set('DESELECT')
+
+
+ bpy.ops.object.select_all(action='DESELECT')
+ if(import_list):
+ for del_obj in diff_objects:
+ bpy.context.collection.all_objects[del_obj].select_set('SELECT')
+ bpy.ops.object.delete()
+
+
+
+ else:
+
+ '''
+ 3DC -> Blender workflow
+ '''
+
+ for old_obj in bpy.context.collection.objects:
+ old_obj.coat3D.applink_old = True
+
+ coat3D = bpy.context.scene.coat3D
+ scene = context.scene
+ Blender_folder = ("%s%sBlender"%(coat3D.exchangedir,os.sep))
+ Blender_export = Blender_folder
+ path3b_now = coat3D.exchangedir + os.sep
+ path3b_now += ('last_saved_3b_file.txt')
+ Blender_export += ('%sexport.txt'%(os.sep))
+ mat_list = []
+ nimi = ''
+ osoite_3b = ''
+ if (os.path.isfile(path3b_now)):
+ path3b_fil = open(path3b_now)
+ for lin in path3b_fil:
+ osoite_3b = lin
+ path3b_fil.close()
+ head, tail = os.path.split(osoite_3b)
+ just_3b_name = tail
+ os.remove(path3b_now)
+
+ old_materials = bpy.data.materials.keys()
+ old_objects = bpy.data.objects.keys()
+
+ bpy.ops.import_scene.fbx(filepath=new_applink_address)
+
+ new_materials = bpy.data.materials.keys()
+ new_objects = bpy.data.objects.keys()
+
+ diff_mat = [i for i in new_materials if i not in old_materials]
+ diff_objects = [i for i in new_objects if i not in old_objects]
+
+ for mark_mesh in diff_mat:
+ bpy.data.materials[mark_mesh].coat3D.name = '3DC'
+ bpy.data.materials[mark_mesh].use_fake_user = True
+ laskuri = 0
+ for c_index in diff_objects:
+ bpy.data.objects[c_index].data.coat3D.name = '3DC'
+ bpy.data.objects[c_index].material_slots[0].material = bpy.data.materials[diff_mat[laskuri]]
+ laskuri += 1
+
+ bpy.ops.object.select_all(action='DESELECT')
+ for new_obj in bpy.context.collection.objects:
+
+ if(new_obj.coat3D.applink_old == False):
+ nimi += new_obj.data.name + ':::'
+ new_obj.select_set('SELECT')
+ #bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN')
+ new_obj.rotation_euler = (0, 0, 0)
+ new_obj.scale = (1, 1, 1)
+ new_obj.coat3D.applink_firsttime = False
+ new_obj.select_set('DESELECT')
+ new_obj.coat3D.applink_address = new_applink_address
+ new_obj.coat3D.objecttime = str(os.path.getmtime(new_obj.coat3D.applink_address))
+ splittext = ntpath.basename(new_applink_address)
+ new_obj.coat3D.applink_name = splittext.split('.')[0]
+ new_obj.coat3D.applink_export = True
+ if(osoite_3b != ''):
+ new_obj.coat3D.applink_3b_path = osoite_3b
+ new_obj.coat3D.applink_3b_just_name = just_3b_name
+
+ mat_list.append(new_obj.material_slots[0].material)
+ is_new = True
+ tex.matlab(mat_list, new_obj, bpy.context.scene, is_new)
+
+ for new_obj in bpy.context.collection.objects:
+ if(new_obj.coat3D.applink_old == False):
+ new_obj.coat3D.applink_group = nimi
+ new_obj.coat3D.applink_old = True
+
+ bpy.ops.object.select_all(action='SELECT')
+ bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
+ bpy.ops.object.select_all(action='DESELECT')
+ if (os.path.isfile(Blender_export)):
+ os.remove(Blender_export)
+ for material in bpy.data.materials:
+ if material.use_nodes == True:
+ for node in material.node_tree.nodes:
+ if (node.name).startswith('3DC'):
+ node.location = node.location
+
+ return {'FINISHED'}
+
+from bpy import *
+from mathutils import Vector, Matrix
+
+class ObjectButtonsPanel():
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "object"
+
+class SCENE_PT_Settings(ObjectButtonsPanel,bpy.types.Panel):
+ bl_label = "3D-Coat Applink Settings"
+ bl_space_type = "PROPERTIES"
+ bl_region_type = "WINDOW"
+ bl_context = "scene"
+
+ def draw(self, context):
+ pass
+
+class SCENE_PT_Settings_Update(ObjectButtonsPanel, bpy.types.Panel):
+ bl_label = "Update"
+ bl_parent_id = "SCENE_PT_Settings"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = False
+ coat3D = bpy.context.scene.coat3D
+
+ rd = context.scene.render
+
+ layout.active = True
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True)
+
+ col = flow.column()
+ col.prop(coat3D, "importmesh", text="Update Mesh")
+ col = flow.column()
+ col.prop(coat3D, "createnodes", text="Create Extra Nodes")
+ col = flow.column()
+ col.prop(coat3D, "importtextures", text="Update Textures")
+ col = flow.column()
+ col.prop(coat3D, "creategroup", text="Group Nodes")
+
+class SCENE_PT_Settings_Folders(ObjectButtonsPanel, bpy.types.Panel):
+ bl_label = "Folders"
+ bl_parent_id = "SCENE_PT_Settings"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ coat3D = bpy.context.scene.coat3D
+
+ rd = context.scene.render
+
+ layout.active = True
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True)
+
+ col = flow.column()
+ col.prop(coat3D, "exchangedir", text="Exchange folder")
+
+ col = flow.column()
+ col.prop(coat3D, "coat3D_exe", text="3D-Coat.exe")
+
+# 3D-Coat Dynamic Menu
+class VIEW3D_MT_Coat_Dynamic_Menu(bpy.types.Menu):
+ bl_label = "3D-Coat Applink Menu"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator_context = 'INVOKE_REGION_WIN'
+
+ ob = context
+ if ob.mode == 'OBJECT':
+ if(len(context.selected_objects) > 0):
+ layout.operator("import_applink.pilgway_3d_coat", text="Update Scene")
+ layout.separator()
+
+ layout.operator("export_applink.pilgway_3d_coat", text="Copy selected object(s) into 3D-Coat")
+ layout.separator()
+ if(context.selected_objects[0].coat3D.applink_3b_path != ''):
+ layout.operator("open_3dcoat.pilgway_3d_coat", text="Open " +context.selected_objects[0].coat3D.applink_3b_just_name)
+ layout.separator()
+
+ else:
+ layout.operator("import_applink.pilgway_3d_coat", text="Update Scene")
+ layout.separator()
+
+class VIEW3D_MT_ImportMenu(bpy.types.Menu):
+ bl_label = "Import Settings"
+
+ def draw(self, context):
+ layout = self.layout
+ coat3D = bpy.context.scene.coat3D
+ settings = context.tool_settings
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.prop(coat3D,"importmesh")
+ layout.prop(coat3D,"importmod")
+ layout.prop(coat3D,"smooth_on")
+ layout.prop(coat3D,"importtextures")
+
+class VIEW3D_MT_ExportMenu(bpy.types.Menu):
+ bl_label = "Export Settings"
+
+ def draw(self, context):
+ layout = self.layout
+ coat3D = bpy.context.scene.coat3D
+ settings = context.tool_settings
+
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("view3d.copybuffer", icon="COPY_ID")
+
+ layout.prop(coat3D,"exportover")
+ if(coat3D.exportover):
+ layout.prop(coat3D,"exportmod")
+
+class VIEW3D_MT_ExtraMenu(bpy.types.Menu):
+ bl_label = "Extra"
+
+ def draw(self, context):
+ layout = self.layout
+ coat3D = bpy.context.scene.coat3D
+ settings = context.tool_settings
+ layout.operator_context = 'INVOKE_REGION_WIN'
+
+ layout.operator("import_applink.pilgway_3d_deltex",text="Delete all Textures")
+ layout.separator()
+
+class ObjectCoat3D(PropertyGroup):
+ objpath: StringProperty(
+ name="Object_Path"
+ )
+ obj_mat: StringProperty(
+ name="Object_Path",
+ default=''
+ )
+ applink_address: StringProperty(
+ name="Object_Applink_address"
+ )
+ applink_3b_path: StringProperty(
+ name="Object_3B_Path"
+ )
+ applink_name: StringProperty(
+ name="Applink object name"
+ )
+ applink_3b_just_name: StringProperty(
+ name="Applink object name"
+ )
+ applink_group: StringProperty(
+ name="Applink group"
+ )
+ applink_firsttime: BoolProperty(
+ name="FirstTime",
+ description="FirstTime",
+ default=True
+ )
+ import_mesh: BoolProperty(
+ name="ImportMesh",
+ description="ImportMesh",
+ default=False
+ )
+ applink_old: BoolProperty(
+ name="OldObject",
+ description="Old Object",
+ default=False
+ )
+ applink_export: BoolProperty(
+ name="FirstTime",
+ description="Object is from 3d-ocat",
+ default=False
+ )
+ objecttime: StringProperty(
+ name="ObjectTime",
+ subtype="FILE_PATH"
+ )
+ path3b: StringProperty(
+ name="3B Path",
+ subtype="FILE_PATH"
+ )
+ dime: FloatVectorProperty(
+ name="dime",
+ description="Dimension"
+ )
+ applink_scale: FloatVectorProperty(
+ name="Scale",
+ description="Scale"
+ )
+
+class SceneCoat3D(PropertyGroup):
+ defaultfolder: StringProperty(
+ name="FilePath",
+ subtype="DIR_PATH",
+ )
+ coat3D_exe: StringProperty(
+ name="FilePath",
+ subtype="DIR_PATH",
+ )
+ cursor_loc: FloatVectorProperty(
+ name="Cursor_loc",
+ description="location"
+ )
+ exchangedir: StringProperty(
+ name="FilePath",
+ subtype="DIR_PATH"
+ )
+ exchangefolder: StringProperty(
+ name="FilePath",
+ subtype="DIR_PATH"
+ )
+ wasactive: StringProperty(
+ name="Pass active object",
+ )
+ import_box: BoolProperty(
+ name="Import window",
+ description="Allows to skip import dialog",
+ default=True
+ )
+ exchange_found: BoolProperty(
+ name="Exchange Found",
+ description="Alert if Exchange folder is not found",
+ default=True
+ )
+ export_box: BoolProperty(
+ name="Export window",
+ description="Allows to skip export dialog",
+ default=True
+ )
+ export_color: BoolProperty(
+ name="Export color",
+ description="Export color texture",
+ default=True
+ )
+ export_spec: BoolProperty(
+ name="Export specular",
+ description="Export specular texture",
+ default=True
+ )
+ export_normal: BoolProperty(
+ name="Export Normal",
+ description="Export normal texture",
+ default=True
+ )
+ export_disp: BoolProperty(
+ name="Export Displacement",
+ description="Export displacement texture",
+ default=True
+ )
+ export_position: BoolProperty(
+ name="Export Source Position",
+ description="Export source position",
+ default=True
+ )
+ export_zero_layer: BoolProperty(
+ name="Export from Layer 0",
+ description="Export mesh from Layer 0",
+ default=True
+ )
+ export_coarse: BoolProperty(
+ name="Export Coarse",
+ description="Export Coarse",
+ default=True
+ )
+ exportfile: BoolProperty(
+ name="No Import File",
+ description="Add Modifiers and export",
+ default=False
+ )
+ importmod: BoolProperty(
+ name="Remove Modifiers",
+ description="Import and add modifiers",
+ default=False
+ )
+ exportmod: BoolProperty(
+ name="Modifiers",
+ description="Export modifiers",
+ default=False
+ )
+ export_pos: BoolProperty(
+ name="Remember Position",
+ description="Remember position",
+ default=True
+ )
+ importtextures: BoolProperty(
+ name="Bring Textures",
+ description="Import Textures",
+ default=True
+ )
+ createnodes: BoolProperty(
+ name="Bring Textures",
+ description="Import Textures",
+ default=True
+ )
+ creategroup: BoolProperty(
+ name="Bring Textures",
+ description="Import Textures",
+ default=True
+ )
+ importlevel: BoolProperty(
+ name="Multires. Level",
+ description="Bring Specific Multires Level",
+ default=False
+ )
+ exportover: BoolProperty(
+ name="Export Obj",
+ description="Import Textures",
+ default=False
+ )
+ importmesh: BoolProperty(
+ name="Mesh",
+ description="Import Mesh",
+ default=True
+ )
+
+ # copy location
+
+ loca: FloatVectorProperty(
+ name="location",
+ description="Location",
+ subtype="XYZ",
+ default=(0.0, 0.0, 0.0)
+ )
+ rota: FloatVectorProperty(
+ name="location",
+ description="Location",
+ subtype="EULER",
+ default=(0.0, 0.0, 0.0)
+ )
+ scal: FloatVectorProperty(
+ name="location",
+ description="Location",
+ subtype="XYZ",
+ default=(0.0, 0.0, 0.0)
+ )
+ dime: FloatVectorProperty(
+ name="dimension",
+ description="Dimension",
+ subtype="XYZ",
+ default=(0.0, 0.0, 0.0)
+ )
+ type: EnumProperty(
+ name="Export Type",
+ description="Different Export Types",
+ items=(("ppp", "Per-Pixel Painting", ""),
+ ("mv", "Microvertex Painting", ""),
+ ("ptex", "Ptex Painting", ""),
+ ("uv", "UV-Mapping", ""),
+ ("ref", "Reference Mesh", ""),
+ ("retopo", "Retopo mesh as new layer", ""),
+ ("vox", "Mesh As Voxel Object", ""),
+ ("alpha", "Mesh As New Pen Alpha", ""),
+ ("prim", "Mesh As Voxel Primitive", ""),
+ ("curv", "Mesh As a Curve Profile", ""),
+ ("autopo", "Mesh For Auto-retopology", ""),
+ ),
+ default="ppp"
+ )
+class MeshCoat3D(PropertyGroup):
+ applink_address: StringProperty(
+ name="ApplinkAddress",
+ subtype="APPLINK_ADDRESS",
+ )
+class MaterialCoat3D(PropertyGroup):
+ name: StringProperty(
+ name="ApplinkAddress",
+ subtype="APPLINK_ADDRESS",
+ )
+
+classes = (
+ #ObjectButtonsPanel,
+ SCENE_PT_Main,
+ SCENE_PT_Settings,
+ SCENE_PT_Settings_Update,
+ SCENE_PT_Settings_Folders,
+ SCENE_OT_folder,
+ SCENE_OT_opencoat,
+ SCENE_OT_export,
+ SCENE_OT_import,
+ VIEW3D_MT_Coat_Dynamic_Menu,
+ #VIEW3D_MT_ImportMenu,
+ #VIEW3D_MT_ExportMenu,
+ #VIEW3D_MT_ExtraMenu,
+ ObjectCoat3D,
+ SceneCoat3D,
+ MeshCoat3D,
+ MaterialCoat3D,
+ )
+
def register():
bpy.coat3D = dict()
bpy.coat3D['active_coat'] = ''
- bpy.coat3D['status'] = 0
+ bpy.coat3D['status'] = 1
bpy.coat3D['kuva'] = 1
- class ObjectCoat3D(PropertyGroup):
- objpath = StringProperty(
- name="Object_Path"
- )
- applink_name = StringProperty(
- name="Object_Applink_name"
- )
- coatpath = StringProperty(
- name="Coat_Path"
- )
- objectdir = StringProperty(
- name="ObjectPath",
- subtype="FILE_PATH"
- )
- objecttime = StringProperty(
- name="ObjectTime",
- subtype="FILE_PATH"
- )
- texturefolder = StringProperty(
- name="Texture folder:",
- subtype="DIR_PATH"
- )
- path3b = StringProperty(
- name="3B Path",
- subtype="FILE_PATH"
- )
- export_on = BoolProperty(
- name="Export_On",
- description="Add Modifiers and export",
- default=False
- )
- dime = FloatVectorProperty(
- name="dime",
- description="Dimension"
- )
- loc = FloatVectorProperty(
- name="Location",
- description="Location"
- )
- rot = FloatVectorProperty(
- name="Rotation",
- description="Rotation",
- subtype='EULER'
- )
- sca = FloatVectorProperty(
- name="Scale",
- description="Scale"
- )
-
- class SceneCoat3D(PropertyGroup):
- defaultfolder = StringProperty(
- name="FilePath",
- subtype="DIR_PATH",
- )
- cursor_loc = FloatVectorProperty(
- name="Cursor_loc",
- description="location"
- )
- exchangedir = StringProperty(
- name="FilePath",
- subtype="DIR_PATH"
- )
- exchangefolder = StringProperty(
- name="FilePath",
- subtype="DIR_PATH"
- )
- wasactive = StringProperty(
- name="Pass active object",
- )
- import_box = BoolProperty(
- name="Import window",
- description="Allows to skip import dialog",
- default=True
- )
- exchange_found = BoolProperty(
- name="Exchange Found",
- description="Alert if Exchange folder is not found",
- default=True
- )
- export_box = BoolProperty(
- name="Export window",
- description="Allows to skip export dialog",
- default=True
- )
- export_color = BoolProperty(
- name="Export color",
- description="Export color texture",
- default=True
- )
- export_spec = BoolProperty(
- name="Export specular",
- description="Export specular texture",
- default=True
- )
- export_normal = BoolProperty(
- name="Export Normal",
- description="Export normal texture",
- default=True
- )
- export_disp = BoolProperty(
- name="Export Displacement",
- description="Export displacement texture",
- default=True
- )
- export_position = BoolProperty(
- name="Export Source Position",
- description="Export source position",
- default=True
- )
- export_zero_layer = BoolProperty(
- name="Export from Layer 0",
- description="Export mesh from Layer 0",
- default=True
- )
- export_coarse = BoolProperty(
- name="Export Coarse",
- description="Export Coarse",
- default=True
- )
- exportfile = BoolProperty(
- name="No Import File",
- description="Add Modifiers and export",
- default=False
- )
- importmod = BoolProperty(
- name="Remove Modifiers",
- description="Import and add modifiers",
- default=False
- )
- exportmod = BoolProperty(
- name="Modifiers",
- description="Export modifiers",
- default=False
- )
- export_pos = BoolProperty(
- name="Remember Position",
- description="Remember position",
- default=True
- )
- importtextures = BoolProperty(
- name="Bring Textures",
- description="Import Textures",
- default=True
- )
- importlevel = BoolProperty(
- name="Multires. Level",
- description="Bring Specific Multires Level",
- default=False
- )
- exportover = BoolProperty(
- name="Export Obj",
- description="Import Textures",
- default=False
- )
- importmesh = BoolProperty(
- name="Mesh",
- description="Import Mesh",
- default=True
- )
-
- # copy location
- cursor = FloatVectorProperty(
- name="Cursor",
- description="Location",
- subtype="XYZ",
- default=(0.0, 0.0, 0.0)
- )
- loca = FloatVectorProperty(
- name="location",
- description="Location",
- subtype="XYZ",
- default=(0.0, 0.0, 0.0)
- )
- rota = FloatVectorProperty(
- name="location",
- description="Location",
- subtype="EULER",
- default=(0.0, 0.0, 0.0)
- )
- scal = FloatVectorProperty(
- name="location",
- description="Location",
- subtype="XYZ",
- default=(0.0, 0.0, 0.0)
- )
- dime = FloatVectorProperty(
- name="dimension",
- description="Dimension",
- subtype="XYZ",
- default=(0.0, 0.0, 0.0)
- )
- type = EnumProperty(
- name="Export Type",
- description="Different Export Types",
- items=(("ppp", "Per-Pixel Painting", ""),
- ("mv", "Microvertex Painting", ""),
- ("ptex", "Ptex Painting", ""),
- ("uv", "UV-Mapping", ""),
- ("ref", "Reference Mesh", ""),
- ("retopo", "Retopo mesh as new layer", ""),
- ("vox", "Mesh As Voxel Object", ""),
- ("alpha", "Mesh As New Pen Alpha", ""),
- ("prim", "Mesh As Voxel Primitive", ""),
- ("curv", "Mesh As a Curve Profile", ""),
- ("autopo", "Mesh For Auto-retopology", ""),
- ),
- default="ppp"
- )
-
- bpy.utils.register_module(__name__)
-
- bpy.types.Object.coat3D = PointerProperty(
- name="Applink Variables",
- type=ObjectCoat3D,
- description="Applink variables"
- )
- bpy.types.Scene.coat3D = PointerProperty(
- name="Applink Variables",
- type=SceneCoat3D,
- description="Applink variables"
- )
+ from bpy.utils import register_class
+ for cls in classes:
+ register_class(cls)
+
+ bpy.types.Object.coat3D = PointerProperty(type=ObjectCoat3D)
+ bpy.types.Scene.coat3D = PointerProperty(type=SceneCoat3D)
+ bpy.types.Mesh.coat3D = PointerProperty(type=MeshCoat3D)
+ bpy.types.Material.coat3D = PointerProperty(type=MaterialCoat3D)
+
+ kc = bpy.context.window_manager.keyconfigs.addon
+ if kc:
+ km = kc.keymaps.new(name="Object Mode")
+ kmi = km.keymap_items.new('wm.call_menu', 'Q', 'PRESS')
+ kmi.properties.name = "VIEW3D_MT_Coat_Dynamic_Menu"
def unregister():
+
import bpy
+ from bpy.utils import unregister_class
del bpy.types.Object.coat3D
del bpy.types.Scene.coat3D
+ del bpy.types.Mesh.coat3D
del bpy.coat3D
- bpy.utils.unregister_module(__name__)
-
+ kc = bpy.context.window_manager.keyconfigs.addon
+ if kc:
+ km = kc.keymaps.get('Object Mode')
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu':
+ if kmi.properties.name == "VIEW3D_MT_Coat_Dynamic_Menu":
+ km.keymap_items.remove(kmi)
-if __name__ == "__main__":
- register()
+ for cls in reversed(classes):
+ unregister_class(cls)
diff --git a/io_coat3D/coat.py b/io_coat3D/coat.py
deleted file mode 100644
index fc3cb747..00000000
--- a/io_coat3D/coat.py
+++ /dev/null
@@ -1,626 +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 LICENCE BLOCK *****
-
-import bpy
-from bpy.props import *
-from io_coat3D import tex
-import os
-
-
-bpy.coat3D = dict()
-bpy.coat3D['active_coat'] = ''
-bpy.coat3D['status'] = 0
-def set_exchange_folder():
- platform = os.sys.platform
- coat3D = bpy.context.scene.coat3D
- Blender_export = ""
-
- if(platform == 'win32'):
- exchange = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3D-CoatV4' + os.sep +'Exchange'
- if not(os.path.isdir(exchange)):
- exchange = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3D-CoatV3' + os.sep +'Exchange'
- else:
- exchange = os.path.expanduser("~") + os.sep + '3D-CoatV4' + os.sep + 'Exchange'
- if not(os.path.isdir(exchange)):
- exchange = os.path.expanduser("~") + os.sep + '3D-CoatV3' + os.sep + 'Exchange'
- if(not(os.path.isdir(exchange))):
- exchange = coat3D.exchangedir
-
- if(os.path.isdir(exchange)):
- bpy.coat3D['status'] = 1
- if(platform == 'win32'):
- exchange_path = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt'
- applink_folder = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender'
- if(not(os.path.isdir(applink_folder))):
- os.makedirs(applink_folder)
- else:
- exchange_path = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt'
- applink_folder = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender'
- if(not(os.path.isdir(applink_folder))):
- os.makedirs(applink_folder)
- file = open(exchange_path, "w")
- file.write("%s"%(coat3D.exchangedir))
- file.close()
-
- else:
- if(platform == 'win32'):
- exchange_path = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt'
- else:
- exchange_path = os.path.expanduser("~") + os.sep + '3DC2Blender' + os.sep + 'Exchange_folder.txt'
- if(os.path.isfile(exchange_path)):
- ex_path =''
-
- ex_pathh = open(exchange_path)
- for line in ex_pathh:
- ex_path = line
- break
- ex_pathh.close()
-
- if(os.path.isdir(ex_path) and ex_path.rfind('Exchange') >= 0):
- exchange = ex_path
- bpy.coat3D['status'] = 1
- else:
- bpy.coat3D['status'] = 0
- else:
- bpy.coat3D['status'] = 0
- if(bpy.coat3D['status'] == 1):
- Blender_folder = ("%s%sBlender"%(exchange,os.sep))
- Blender_export = Blender_folder
- path3b_now = exchange
- path3b_now += ('last_saved_3b_file.txt')
- Blender_export += ('%sexport.txt'%(os.sep))
-
- if(not(os.path.isdir(Blender_folder))):
- os.makedirs(Blender_folder)
- Blender_folder = os.path.join(Blender_folder,"run.txt")
- file = open(Blender_folder, "w")
- file.close()
- return exchange
-
-def set_working_folders():
- platform = os.sys.platform
- coat3D = bpy.context.scene.coat3D
- if(platform == 'win32'):
- folder_objects = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Objects'
- folder_textures = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Textures' + os.sep
- if(not(os.path.isdir(folder_objects))):
- os.makedirs(folder_objects)
- if(not(os.path.isdir(folder_textures))):
- os.makedirs(folder_textures)
- else:
- folder_objects = os.path.expanduser("~") + os.sep + '3DC2Blender' + os.sep + 'Objects'
- folder_textures = os.path.expanduser("~") + os.sep + '3DC2Blender' + os.sep + 'Textures' + os.sep
- if(not(os.path.isdir(folder_objects))):
- os.makedirs(folder_objects)
- if(not(os.path.isdir(folder_textures))):
- os.makedirs(folder_textures)
-
-
- return folder_objects,folder_textures
-
-class ObjectButtonsPanel():
- bl_space_type = 'PROPERTIES'
- bl_region_type = 'WINDOW'
- bl_context = "object"
-
-class SCENE_PT_Main(ObjectButtonsPanel,bpy.types.Panel):
- bl_label = "3D-Coat Applink"
- bl_space_type = "PROPERTIES"
- bl_region_type = "WINDOW"
- bl_context = "scene"
-
- def draw(self, context):
- layout = self.layout
- scene = context.scene
- me = context.scene.objects
- mat_list = []
- import_no = 0
- coat = bpy.coat3D
- coat3D = bpy.context.scene.coat3D
- if(bpy.context.scene.objects.active):
- coa = bpy.context.scene.objects.active.coat3D
-
-
- if(bpy.coat3D['status'] == 0 and not(os.path.isdir(coat3D.exchangedir))):
- bpy.coat3D['active_coat'] = set_exchange_folder()
- row = layout.row()
- row.label(text="Applink didn't find your 3d-Coat/Excahnge folder.")
- row = layout.row()
- row.label("Please select it before using Applink.")
- row = layout.row()
- row.prop(coat3D,"exchangedir",text="")
-
- else:
-
-
- #Here you add your GUI
- row = layout.row()
- row.prop(coat3D,"type",text = "")
- row = layout.row()
- colL = row.column()
- colR = row.column()
-
- colR.operator("export_applink.pilgway_3d_coat", text="Transfer")
-
- colL.operator("import_applink.pilgway_3d_coat", text="Update")
-
-
-
-
-
-
-
-
-
-
-class SCENE_OT_export(bpy.types.Operator):
- bl_idname = "export_applink.pilgway_3d_coat"
- bl_label = "Export your custom property"
- bl_description = "Export your custom property"
- bl_options = {'UNDO'}
-
- def invoke(self, context, event):
- checkname = ''
- coat3D = bpy.context.scene.coat3D
- scene = context.scene
- activeobj = bpy.context.active_object.name
- obj = scene.objects[activeobj]
- coa = bpy.context.scene.objects.active.coat3D
- coat3D.exchangedir = set_exchange_folder()
- export_ok = False
-
- folder_objects,folder_textures = set_working_folders()
-
- if(coat3D.exchange_found == False):
- return {'FINISHED'}
-
- if(bpy.context.selected_objects == []):
- return {'FINISHED'}
- else:
- for objec in bpy.context.selected_objects:
- if objec.type == 'MESH':
- export_ok = True
- if(export_ok == False):
- return {'FINISHED'}
-
- importfile = coat3D.exchangedir
- texturefile = coat3D.exchangedir
- importfile += ('%simport.txt'%(os.sep))
- texturefile += ('%stextures.txt'%(os.sep))
-
- looking = True
- object_index = 0
- if(coa.applink_name and os.path.isfile(coa.applink_name)):
- checkname = coa.applink_name
-
- else:
- while(looking == True):
- checkname = folder_objects + os.sep + activeobj
- checkname = ("%s%.2d.obj"%(checkname,object_index))
- if(os.path.isfile(checkname)):
- object_index += 1
- else:
- looking = False
- coa.applink_name = checkname
-
-
- coat3D.cursor_loc = obj.location
- coat3D.cursor_orginal = bpy.context.scene.cursor_location
-
-
-
- coa.loc = obj.location
- coa.rot = obj.rotation_euler
- coa.sca = obj.scale
- coa.dime = obj.dimensions
-
- obj.location = (0,0,0)
- obj.rotation_euler = (0,0,0)
- bpy.ops.object.transform_apply(scale=True)
-
- bpy.ops.export_scene.obj(filepath=coa.applink_name,use_selection=True,
- use_mesh_modifiers=False,use_blen_objects=True, use_materials = True,
- keep_vertex_order = True,axis_forward='-Z',axis_up='Y')
-
- obj.location = coa.loc
- obj.rotation_euler = coa.rot
-
-
- bpy.context.scene.cursor_location = coat3D.cursor_loc
- bpy.context.scene.cursor_location = coat3D.cursor_orginal
-
- file = open(importfile, "w")
- file.write("%s"%(checkname))
- file.write("\n%s"%(checkname))
- file.write("\n[%s]"%(coat3D.type))
- file.write("\n[TexOutput:%s]"%(folder_textures))
- file.close()
-
- coa.objecttime = str(os.path.getmtime(coa.applink_name))
-
-
-
- return {'FINISHED'}
-
-class SCENE_OT_import(bpy.types.Operator):
- bl_idname = "import_applink.pilgway_3d_coat"
- bl_label = "import your custom property"
- bl_description = "import your custom property"
- bl_options = {'UNDO'}
-
- def invoke(self, context, event):
- scene = context.scene
- coat3D = bpy.context.scene.coat3D
- coat = bpy.coat3D
- test = bpy.context.selected_objects
- act_first = bpy.context.scene.objects.active
- bpy.context.scene.game_settings.material_mode = 'GLSL'
- coat3D.exchangedir = set_exchange_folder()
-
- folder_objects,folder_textures = set_working_folders()
-
- Blender_folder = ("%s%sBlender"%(coat3D.exchangedir,os.sep))
- Blender_export = Blender_folder
- path3b_now = coat3D.exchangedir
- path3b_now += ('last_saved_3b_file.txt')
- Blender_export += ('%sexport.txt'%(os.sep))
- new_applink_name = 'False'
- new_object = False
- if(os.path.isfile(Blender_export)):
- obj_pathh = open(Blender_export)
- new_object = True
- for line in obj_pathh:
- new_applink_name = line
- break
- obj_pathh.close()
-
- for scene_objects in bpy.context.scene.objects:
- if(scene_objects.type == 'MESH'):
- if(scene_objects.coat3D.applink_name == new_applink_name):
- new_object = False
-
- for act_name in test:
- coa = act_name.coat3D
- path_object = coa.applink_name
- if act_name.type == 'MESH' and os.path.isfile(path_object):
- multires_on = False
- activeobj = act_name.name
- mat_list = []
- scene.objects[activeobj].select = True
- objekti = scene.objects[activeobj]
- coat3D.loca = objekti.location
- coat3D.rota = objekti.rotation_euler
- coat3D.dime = objekti.scale
-
-
-
- #See if there is multres modifier.
- for modifiers in objekti.modifiers:
- if modifiers.type == 'MULTIRES' and (modifiers.total_levels > 0):
- if(not(coat3D.importlevel)):
- bpy.ops.object.multires_external_pack()
- multires = coat3D.exchangedir
- multires += ('%stemp.btx'%(os.sep))
- bpy.ops.object.multires_external_save(filepath=multires)
- #bpy.ops.object.multires_external_pack()
- multires_on = True
- multires_name = modifiers.name
- break
-
- exportfile = coat3D.exchangedir
- path3b_n = coat3D.exchangedir
- path3b_n += ('last_saved_3b_file.txt')
- exportfile += ('%sexport.txt'%(os.sep))
- if(os.path.isfile(exportfile)):
- export_file = open(exportfile)
- for line in export_file:
- if line.rfind('.3b'):
- objekti.coat3D.coatpath = line
- coat['active_coat'] = line
- export_file.close()
- os.remove(exportfile)
-
- if(len(objekti.material_slots) == 0):
- delete_material = False
- else:
- delete_material = True
-
-
- if(not(objekti.active_material) and objekti.material_slots):
- act_mat_index = objekti.active_material_index
- materials_old = bpy.data.materials.keys()
- bpy.ops.material.new()
- materials_new = bpy.data.materials.keys()
- new_ma = list(set(materials_new).difference(set(materials_old)))
- new_mat = new_ma[0]
- ki = bpy.data.materials[new_mat]
- objekti.material_slots[act_mat_index].material = ki
-
-
-
- if(os.path.isfile(path_object) and (coa.objecttime != str(os.path.getmtime(path_object)))):
-
- if(objekti.material_slots):
- act_mat_index = objekti.active_material_index
- for obj_mat in objekti.material_slots:
- mat_list.append(obj_mat.material)
-
- coa.dime = objekti.dimensions
- coa.objecttime = str(os.path.getmtime(path_object))
- mtl = coa.applink_name
- mtl = mtl.replace('.obj','.mtl')
- if(os.path.isfile(mtl)):
- os.remove(mtl)
-
- bpy.ops.import_scene.obj(filepath=path_object,axis_forward='-Z',axis_up='Y',use_image_search=False)
- obj_proxy = scene.objects[0]
- bpy.ops.object.select_all(action='TOGGLE')
- obj_proxy.select = True
-
-
- bpy.ops.object.transform_apply(rotation=True)
- proxy_mat = obj_proxy.material_slots[0].material
- if(delete_material):
- while(list(obj_proxy.data.materials) != []):
- proxy_mat = obj_proxy.material_slots[0].material
- obj_proxy.data.materials.pop(0,1)
- proxy_mat.user_clear()
- bpy.data.materials.remove(proxy_mat)
- bpy.ops.object.select_all(action='TOGGLE')
-
- if(coat3D.importlevel):
- obj_proxy.select = True
- obj_proxy.modifiers.new(name='temp',type='MULTIRES')
- objekti.select = True
- bpy.ops.object.multires_reshape(modifier=multires_name)
- bpy.ops.object.select_all(action='TOGGLE')
- multires_on = False
- else:
-
- scene.objects.active = obj_proxy
-
- obj_data = objekti.data.id_data
- objekti.data = obj_proxy.data.id_data
- if(bpy.data.meshes[obj_data.name].users == 0):
- objekti.data.id_data.name = obj_data.name
- bpy.data.meshes.remove(obj_data)
-
-
- obj_proxy.select = True
- bpy.ops.object.delete()
- objekti.select = True
- objekti.scale = coat3D.dime
-
- bpy.context.scene.objects.active = objekti
-
- if(os.path.isfile(path3b_n)):
- path3b_fil = open(path3b_n)
- for lin in path3b_fil:
- objekti.coat3D.path3b = lin
- path3b_fil.close()
- os.remove(path3b_n)
-
- if(coat3D.importmesh and not(os.path.isfile(path_object))):
- coat3D.importmesh = False
-
- if(mat_list and coat3D.importmesh):
- for mat_one in mat_list:
- objekti.data.materials.append(mat_one)
- objekti.active_material_index = act_mat_index
-
- if(mat_list):
- for obj_mate in objekti.material_slots:
- if(hasattr(obj_mate.material,'texture_slots')):
- for tex_slot in obj_mate.material.texture_slots:
- if(hasattr(tex_slot,'texture')):
- if(tex_slot.texture.type == 'IMAGE'):
- if tex_slot.texture.image is not None:
- tex_slot.texture.image.reload()
-
-
- if(coat3D.importtextures):
- export = ''
- tex.gettex(mat_list,objekti,scene,export)
-
- if(multires_on):
- temp_file = coat3D.exchangedir
- temp_file += ('%stemp2.btx'%(os.sep))
- if(objekti.modifiers[multires_name].levels == 0):
- objekti.modifiers[multires_name].levels = 1
- bpy.ops.object.multires_external_save(filepath=temp_file)
- objekti.modifiers[multires_name].filepath = multires
- objekti.modifiers[multires_name].levels = 0
-
- else:
- bpy.ops.object.multires_external_save(filepath=temp_file)
- objekti.modifiers[multires_name].filepath = multires
- #bpy.ops.object.multires_external_pack()
- bpy.ops.object.shade_smooth()
-
-
- for act_name in test:
- act_name.select = True
- bpy.context.scene.objects.active = act_first
-
- if(new_object == True):
- coat3D = bpy.context.scene.coat3D
- scene = context.scene
-
- Blender_folder = ("%s%sBlender"%(coat3D.exchangedir,os.sep))
- Blender_export = Blender_folder
- path3b_now = coat3D.exchangedir
- path3b_now += ('last_saved_3b_file.txt')
- Blender_export += ('%sexport.txt'%(os.sep))
-
-
- mat_list = []
- obj_path =''
-
-
- export = new_applink_name
- mod_time = os.path.getmtime(new_applink_name)
- mtl_list = new_applink_name.replace('.obj','.mtl')
- if(os.path.isfile(mtl_list)):
- os.remove(mtl_list)
-
- bpy.ops.import_scene.obj(filepath=new_applink_name,axis_forward='-Z',axis_up='Y')
- bpy.ops.object.transform_apply(rotation=True)
- new_obj = scene.objects[0]
- new_obj.coat3D.applink_name = obj_path
- scene.objects[0].coat3D.applink_name = export #objectdir muutettava
-
- os.remove(Blender_export)
-
- bpy.context.scene.objects.active = new_obj
-
- bpy.ops.object.shade_smooth()
-
- Blender_tex = ("%s%stextures.txt"%(coat3D.exchangedir,os.sep))
- mat_list.append(new_obj.material_slots[0].material)
- tex.gettex(mat_list, new_obj, scene,export)
-
- return {'FINISHED'}
-
-
-
-from bpy import *
-from mathutils import Vector, Matrix
-
-# 3D-Coat Dynamic Menu
-class VIEW3D_MT_Coat_Dynamic_Menu(bpy.types.Menu):
- bl_label = "3D-Coat Applink Menu"
-
- def draw(self, context):
- layout = self.layout
- settings = context.tool_settings
- layout.operator_context = 'INVOKE_REGION_WIN'
- coat3D = bpy.context.scene.coat3D
- Blender_folder = ("%s%sBlender"%(coat3D.exchangedir,os.sep))
- Blender_export = Blender_folder
- Blender_export += ('%sexport.txt'%(os.sep))
-
- ob = context
- if ob.mode == 'OBJECT':
- if(bpy.context.selected_objects):
- for ind_obj in bpy.context.selected_objects:
- if(ind_obj.type == 'MESH'):
- layout.active = True
- break
- layout.active = False
-
- if(layout.active == True):
-
- layout.operator("import_applink.pilgway_3d_coat", text="Import")
- layout.separator()
-
- layout.operator("export_applink.pilgway_3d_coat", text="Export")
- layout.separator()
-
- layout.menu("VIEW3D_MT_ImportMenu")
- layout.separator()
-
- layout.menu("VIEW3D_MT_ExportMenu")
- layout.separator()
-
- layout.menu("VIEW3D_MT_ExtraMenu")
- layout.separator()
-
- if(len(bpy.context.selected_objects) == 1):
- if(os.path.isfile(bpy.context.selected_objects[0].coat3D.path3b)):
- layout.operator("import_applink.pilgway_3d_coat_3b", text="Load 3b")
- layout.separator()
-
- if(os.path.isfile(Blender_export)):
-
- layout.operator("import3b_applink.pilgway_3d_coat", text="Bring from 3D-Coat")
- layout.separator()
- else:
- if(os.path.isfile(Blender_export)):
- layout.active = True
-
- layout.operator("import3b_applink.pilgway_3d_coat", text="Bring from 3D-Coat")
- layout.separator()
- else:
- if(os.path.isfile(Blender_export)):
-
-
- layout.operator("import3b_applink.pilgway_3d_coat", text="Bring from 3D-Coat")
- layout.separator()
-
-class VIEW3D_MT_ImportMenu(bpy.types.Menu):
- bl_label = "Import Settings"
-
- def draw(self, context):
- layout = self.layout
- coat3D = bpy.context.scene.coat3D
- settings = context.tool_settings
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.prop(coat3D,"importmesh")
- layout.prop(coat3D,"importmod")
- layout.prop(coat3D,"smooth_on")
- layout.prop(coat3D,"importtextures")
-
-class VIEW3D_MT_ExportMenu(bpy.types.Menu):
- bl_label = "Export Settings"
-
- def draw(self, context):
- layout = self.layout
- coat3D = bpy.context.scene.coat3D
- settings = context.tool_settings
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.prop(coat3D,"exportover")
- if(coat3D.exportover):
- layout.prop(coat3D,"exportmod")
-
-class VIEW3D_MT_ExtraMenu(bpy.types.Menu):
- bl_label = "Extra"
-
- def draw(self, context):
- layout = self.layout
- coat3D = bpy.context.scene.coat3D
- settings = context.tool_settings
- layout.operator_context = 'INVOKE_REGION_WIN'
-
- layout.operator("import_applink.pilgway_3d_deltex",text="Delete all Textures")
- layout.separator()
-
-def register():
- bpy.utils.register_module(__name__)
-
- kc = bpy.context.window_manager.keyconfigs.addon
- if kc:
- km = kc.keymaps.new(name='3D View', space_type='VIEW_3D')
- kmi = km.keymap_items.new('wm.call_menu2', 'Q', 'PRESS')
- kmi.properties.name = "VIEW3D_MT_Coat_Dynamic_Menu"
-
-def unregister():
- bpy.utils.unregister_module(__name__)
-
- kc = bpy.context.window_manager.keyconfigs.addon
- if kc:
- km = kc.keymapskeymaps['3D View']
- for kmi in km.keymap_items:
- if kmi.idname == '':
- if kmi.properties.name == "VIEW3D_MT_Coat_Dynamic_Menu":
- km.keymap_items.remove(kmi)
- break
-
-
-if __name__ == "__main__":
- register()
diff --git a/io_coat3D/tex.py b/io_coat3D/tex.py
index f532177c..c9feec95 100644
--- a/io_coat3D/tex.py
+++ b/io_coat3D/tex.py
@@ -19,8 +19,9 @@
import bpy
import os
-
+import re
def find_index(objekti):
+
luku = 0
for tex in objekti.active_material.texture_slots:
if(not(hasattr(tex,'texture'))):
@@ -28,308 +29,256 @@ def find_index(objekti):
luku = luku +1
return luku
-def gettex(mat_list, objekti, scene,export):
-
- coat3D = bpy.context.scene.coat3D
- coa = objekti.coat3D
-
- if(bpy.context.scene.render.engine == 'VRAY_RENDER' or bpy.context.scene.render.engine == 'VRAY_RENDER_PREVIEW'):
- vray = True
- else:
- vray = False
+def RemoveFbxNodes(objekti):
+ Node_Tree = objekti.active_material.node_tree
+ for node in Node_Tree.nodes:
+ if node.type != 'OUTPUT_MATERIAL':
+ Node_Tree.nodes.remove(node)
+ else:
+ output = node
+ output.location = 340,400
+ Prin_mat = Node_Tree.nodes.new(type="ShaderNodeBsdfPrincipled")
+ Prin_mat.location = 13, 375
- take_color = 0
- take_spec = 0
- take_normal = 0
- take_disp = 0
+ Node_Tree.links.new(Prin_mat.outputs[0], output.inputs[0])
- bring_color = 1
- bring_spec = 1
- bring_normal = 1
- bring_disp = 1
+def readtexturefolder(mat_list,texturelist,is_new): #read textures from texture file
texcoat = {}
texcoat['color'] = []
- texcoat['specular'] = []
+ texcoat['metalness'] = []
+ texcoat['rough'] = []
texcoat['nmap'] = []
texcoat['disp'] = []
- texu = []
-
- if(export):
- objekti.coat3D.objpath = export
- nimi = os.path.split(export)[1]
- osoite = os.path.dirname(export) + os.sep #pitaa ehka muuttaa
- for mate in objekti.material_slots:
- for tex_slot in mate.material.texture_slots:
- if(hasattr(tex_slot,'texture')):
- if(tex_slot.texture.type == 'IMAGE'):
- if tex_slot.texture.image is not None:
- tex_slot.texture.image.reload()
- else:
- if(os.sys.platform == 'win32'):
- osoite = os.path.expanduser("~") + os.sep + 'Documents' + os.sep + '3DC2Blender' + os.sep + 'Textures' + os.sep
- else:
- osoite = os.path.expanduser("~") + os.sep + '3DC2Blender' + os.sep + 'Textures' + os.sep
- ki = os.path.split(coa.applink_name)[1]
- ko = os.path.splitext(ki)[0]
- just_nimi = ko + '_'
- just_nimi_len = len(just_nimi)
- print('terve:' + coa.applink_name)
-
- if(len(objekti.material_slots) != 0):
- for obj_tex in objekti.active_material.texture_slots:
- if(hasattr(obj_tex,'texture')):
- if(obj_tex.texture.type == 'IMAGE'):
- if(obj_tex.use_map_color_diffuse):
- bring_color = 0;
- if(obj_tex.use_map_specular):
- bring_spec = 0;
- if(obj_tex.use_map_normal):
- bring_normal = 0;
- if(obj_tex.use_map_displacement):
- bring_disp = 0;
-
- files = os.listdir(osoite)
- for i in files:
- tui = i[:just_nimi_len]
- if(tui == just_nimi):
- texu.append(i)
-
- for yy in texu:
- minimi = (yy.rfind('_'))+1
- maksimi = (yy.rfind('.'))
- tex_name = yy[minimi:maksimi]
- koko = ''
- koko += osoite
- koko += yy
- texcoat[tex_name].append(koko)
-
- if((texcoat['color'] or texcoat['nmap'] or texcoat['disp'] or texcoat['specular']) and (len(objekti.material_slots)) == 0):
- materials_old = bpy.data.materials.keys()
- bpy.ops.material.new()
- materials_new = bpy.data.materials.keys()
- new_ma = list(set(materials_new).difference(set(materials_old)))
- new_mat = new_ma[0]
- ki = bpy.data.materials[new_mat]
- objekti.data.materials.append(ki)
-
- if(bring_color == 1 and texcoat['color']):
- index = find_index(objekti)
- tex = bpy.ops.Texture
- objekti.active_material.texture_slots.create(index)
- total_mat = len(objekti.active_material.texture_slots.items())
- useold = ''
-
- for seekco in bpy.data.textures:
- if((seekco.name[:5] == 'Color') and (seekco.users_material == ())):
- useold = seekco
-
-
- if(useold == ''):
-
- textures_old = bpy.data.textures.keys()
- bpy.data.textures.new('Color',type='IMAGE')
- textures_new = bpy.data.textures.keys()
- name_te = list(set(textures_new).difference(set(textures_old)))
- name_tex = name_te[0]
-
- bpy.ops.image.new(name=name_tex)
- bpy.data.images[name_tex].filepath = texcoat['color'][0]
- bpy.data.images[name_tex].source = 'FILE'
-
- objekti.active_material.texture_slots[index].texture = bpy.data.textures[name_tex]
- objekti.active_material.texture_slots[index].texture.image = bpy.data.images[name_tex]
-
- if(objekti.data.uv_textures.active):
- objekti.active_material.texture_slots[index].texture_coords = 'UV'
- objekti.active_material.texture_slots[index].uv_layer = objekti.data.uv_textures.active.name
-
- objekti.active_material.texture_slots[index].texture.image.reload()
-
-
- elif(useold != ''):
-
- objekti.active_material.texture_slots[index].texture = useold
- objekti.active_material.texture_slots[index].texture.image = bpy.data.images[useold.name]
- objekti.active_material.texture_slots[index].texture.image.filepath = texcoat['color'][0]
- if(objekti.data.uv_textures.active):
- objekti.active_material.texture_slots[index].texture_coords = 'UV'
- objekti.active_material.texture_slots[index].uv_layer = objekti.data.uv_textures.active.name
-
-
- if(bring_normal == 1 and texcoat['nmap']):
- index = find_index(objekti)
- tex = bpy.ops.Texture
- objekti.active_material.texture_slots.create(index)
- total_mat = len(objekti.active_material.texture_slots.items())
- useold = ''
-
- for seekco in bpy.data.textures:
- if((seekco.name[:6] == 'Normal') and (seekco.users_material == ())):
- useold = seekco
-
- if(useold == ''):
-
- textures_old = bpy.data.textures.keys()
- bpy.data.textures.new('Normal',type='IMAGE')
- textures_new = bpy.data.textures.keys()
- name_te = list(set(textures_new).difference(set(textures_old)))
- name_tex = name_te[0]
-
- bpy.ops.image.new(name=name_tex)
- bpy.data.images[name_tex].filepath = texcoat['nmap'][0]
- bpy.data.images[name_tex].source = 'FILE'
-
- objekti.active_material.texture_slots[index].texture = bpy.data.textures[name_tex]
- objekti.active_material.texture_slots[index].texture.image = bpy.data.images[name_tex]
-
- if(objekti.data.uv_textures.active):
- objekti.active_material.texture_slots[index].texture_coords = 'UV'
- objekti.active_material.texture_slots[index].uv_layer = objekti.data.uv_textures.active.name
-
- objekti.active_material.texture_slots[index].use_map_color_diffuse = False
- objekti.active_material.texture_slots[index].use_map_normal = True
-
- objekti.active_material.texture_slots[index].texture.image.reload()
- if(vray):
- bpy.data.textures[name_tex].vray_slot.BRDFBump.map_type = 'TANGENT'
-
- else:
- bpy.data.textures[name_tex].use_normal_map = True
- objekti.active_material.texture_slots[index].normal_map_space = 'TANGENT'
- objekti.active_material.texture_slots[index].normal_factor = 1
-
+ texcoat['emissive'] = []
+
+
+ for texture_info in texturelist:
+ if texture_info[0] == mat_list[0].name:
+ if texture_info[2] == 'color' or texture_info[2] == 'diffuse':
+ texcoat['color'].append(texture_info[3])
+ if texture_info[2] == 'metalness' or texture_info[2] == 'reflection':
+ texcoat['metalness'].append(texture_info[3])
+ if texture_info[2] == 'rough' or texture_info[2] == 'roughness':
+ texcoat['rough'].append(texture_info[3])
+ if texture_info[2] == 'nmap' or texture_info[2] == 'normal_map':
+ texcoat['nmap'].append(texture_info[3])
+ if texture_info[2] == 'emissive':
+ texcoat['emissive'].append(texture_info[3])
+
+ createnodes(mat_list, texcoat)
+
+def checkmaterial(mat_list, objekti): #check how many materials object has
+ mat_list = []
+
+ for obj_mate in objekti.material_slots:
+ if(obj_mate.material.use_nodes == False):
+ obj_mate.material.use_nodes = True
+
+def createnodes(mat_list,texcoat): #luo nodes palikat ja linkittaa tekstuurit niihin
+ bring_color = True #naiden tarkoitus on tsekata onko tarvetta luoda uusi node vai riittaako paivitys
+ bring_metalness = True
+ bring_roughness = True
+ bring_normal = True
+ bring_disp = True
-
- elif(useold != ''):
-
- objekti.active_material.texture_slots[index].texture = useold
- objekti.active_material.texture_slots[index].texture.image = bpy.data.images[useold.name]
- objekti.active_material.texture_slots[index].texture.image.filepath = texcoat['nmap'][0]
- if(objekti.data.uv_textures.active):
- objekti.active_material.texture_slots[index].texture_coords = 'UV'
- objekti.active_material.texture_slots[index].uv_layer = objekti.data.uv_textures.active.name
- objekti.active_material.texture_slots[index].use_map_color_diffuse = False
- objekti.active_material.texture_slots[index].use_map_normal = True
- objekti.active_material.texture_slots[index].normal_factor = 1
-
-
- if(bring_spec == 1 and texcoat['specular']):
-
- index = find_index(objekti)
-
- objekti.active_material.texture_slots.create(index)
- useold = ''
-
- for seekco in bpy.data.textures:
- if((seekco.name[:8] == 'Specular') and (seekco.users_material == ())):
- useold = seekco
-
- if(useold == ''):
-
- textures_old = bpy.data.textures.keys()
- bpy.data.textures.new('Specular',type='IMAGE')
- textures_new = bpy.data.textures.keys()
- name_te = list(set(textures_new).difference(set(textures_old)))
- name_tex = name_te[0]
-
- bpy.ops.image.new(name=name_tex)
- bpy.data.images[name_tex].filepath = texcoat['specular'][0]
- bpy.data.images[name_tex].source = 'FILE'
-
- objekti.active_material.texture_slots[index].texture = bpy.data.textures[name_tex]
- objekti.active_material.texture_slots[index].texture.image = bpy.data.images[name_tex]
-
- if(objekti.data.uv_textures.active):
- objekti.active_material.texture_slots[index].texture_coords = 'UV'
- objekti.active_material.texture_slots[index].uv_layer = objekti.data.uv_textures.active.name
-
- objekti.active_material.texture_slots[index].use_map_color_diffuse = False
- objekti.active_material.texture_slots[index].use_map_specular = True
-
- objekti.active_material.texture_slots[index].texture.image.reload()
-
-
- elif(useold != ''):
-
- objekti.active_material.texture_slots[index].texture = useold
- objekti.active_material.texture_slots[index].texture.image = bpy.data.images[useold.name]
- objekti.active_material.texture_slots[index].texture.image.filepath = texcoat['specular'][0]
- if(objekti.data.uv_textures.active):
- objekti.active_material.texture_slots[index].texture_coords = 'UV'
- objekti.active_material.texture_slots[index].uv_layer = objekti.data.uv_textures.active.name
- objekti.active_material.texture_slots[index].use_map_color_diffuse = False
- objekti.active_material.texture_slots[index].use_map_specular = True
-
- if(bring_disp == 1 and texcoat['disp']):
-
- index = find_index(objekti)
-
-
- objekti.active_material.texture_slots.create(index)
- useold = ''
-
- for seekco in bpy.data.textures:
- if((seekco.name[:12] == 'Displacement') and (seekco.users_material == ())):
- useold = seekco
-
- if useold == "":
-
- textures_old = bpy.data.textures.keys()
- bpy.data.textures.new('Displacement',type='IMAGE')
- textures_new = bpy.data.textures.keys()
- name_te = list(set(textures_new).difference(set(textures_old)))
- name_tex = name_te[0]
-
- bpy.ops.image.new(name=name_tex)
- bpy.data.images[name_tex].filepath = texcoat['disp'][0]
- bpy.data.images[name_tex].source = 'FILE'
-
- objekti.active_material.texture_slots[index].texture = bpy.data.textures[name_tex]
- objekti.active_material.texture_slots[index].texture.image = bpy.data.images[name_tex]
-
- if(objekti.data.uv_textures.active):
- objekti.active_material.texture_slots[index].texture_coords = 'UV'
- objekti.active_material.texture_slots[index].uv_layer = objekti.data.uv_textures.active.name
-
- objekti.active_material.texture_slots[index].use_map_color_diffuse = False
- objekti.active_material.texture_slots[index].use_map_displacement = True
-
- objekti.active_material.texture_slots[index].texture.image.reload()
-
-
- elif(useold != ''):
-
- objekti.active_material.texture_slots[index].texture = useold
- objekti.active_material.texture_slots[index].texture.image = bpy.data.images[useold.name]
- objekti.active_material.texture_slots[index].texture.image.filepath = texcoat['disp'][0]
- if(objekti.data.uv_textures.active):
- objekti.active_material.texture_slots[index].texture_coords = 'UV'
- objekti.active_material.texture_slots[index].uv_layer = objekti.data.uv_textures.active.name
- objekti.active_material.texture_slots[index].use_map_color_diffuse = False
- objekti.active_material.texture_slots[index].use_map_displacement = True
-
- if(vray):
- objekti.active_material.texture_slots[index].texture.use_interpolation = False
- objekti.active_material.texture_slots[index].displacement_factor = 0.05
+ coat3D = bpy.context.scene.coat3D
+ coatMat = mat_list[0]
+
+ if(coatMat.use_nodes == False):
+ coatMat.use_nodes = True
+ act_material = coatMat.node_tree
+ main_material = coatMat.node_tree
+ applink_group_node = False
+
+ #ensimmaiseksi kaydaan kaikki image nodet lapi ja tarkistetaan onko nimi 3DC alkunen jos on niin reload
+ print('texcoat:',texcoat)
+ for node in act_material.nodes:
+ if(node.name == '3DC_Applink' and node.type == 'GROUP'):
+ applink_group_node = True
+ act_material = node.node_tree
+ break
+ for node in act_material.nodes:
+ if(node.type == 'TEX_IMAGE'):
+ if(node.name == '3DC_color'):
+ bring_color = False
+ node.image.reload()
+ elif(node.name == '3DC_metalness'):
+ bring_metalness = False
+ node.image.reload()
+ elif(node.name == '3DC_roughness'):
+ bring_roughness = False
+ node.image.reload()
+ elif(node.name == '3DC_normal'):
+ bring_normal = False
+ node.image.reload()
+
+ #seuraavaksi lahdemme rakentamaan node tree. Lahdetaan Material Outputista rakentaa
+ if(applink_group_node == False and coat3D.creategroup):
+ group_tree = bpy.data.node_groups.new('3DC_Applink', 'ShaderNodeTree')
+ applink_tree = act_material.nodes.new('ShaderNodeGroup')
+ applink_tree.name = '3DC_Applink'
+ applink_tree.node_tree = group_tree
+ applink_tree.location = -400, 300
+ act_material = group_tree
+ notegroup = act_material.nodes.new('NodeGroupOutput')
+
+ main_mat = main_material.nodes['Material Output']
+ if(main_mat.inputs['Surface'].is_linked == True):
+ glue_mat = main_mat.inputs['Surface'].links[0].from_node
+ if(glue_mat.inputs.find('Base Color') == -1):
+ input_color = glue_mat.inputs.find('Color')
else:
- disp_modi = ''
- for seek_modi in objekti.modifiers:
- if(seek_modi.type == 'DISPLACE'):
- disp_modi = seek_modi
- break
- if(disp_modi):
- disp_modi.texture = objekti.active_material.texture_slots[index].texture
- if(objekti.data.uv_textures.active):
- disp_modi.texture_coords = 'UV'
- disp_modi.uv_layer = objekti.data.uv_textures.active.name
+ input_color = glue_mat.inputs.find('Base Color')
+ input_index = 0
+ #Color
+ if(bring_color == True and texcoat['color'] != []):
+ print('image:', bpy.data.images)
+ node = act_material.nodes.new('ShaderNodeTexImage')
+ node.name = '3DC_color'
+ if (texcoat['color']):
+ sameimage = False
+ for image in bpy.data.images:
+ if(image.filepath == texcoat['color'][0]):
+ sameimage = True
+ imagename = image
+ break
+
+ if sameimage == True:
+ node.image = imagename
+ else:
+ node.image = bpy.data.images.load(texcoat['color'][0])
+ if(coat3D.createnodes):
+ curvenode = act_material.nodes.new('ShaderNodeRGBCurve')
+ curvenode.name = '3DC_RGBCurve'
+ huenode = act_material.nodes.new('ShaderNodeHueSaturation')
+ huenode.name = '3DC_HueSaturation'
+ act_material.links.new(huenode.outputs[0], glue_mat.inputs[input_color])
+ act_material.links.new(curvenode.outputs[0], huenode.inputs[4])
+ act_material.links.new(node.outputs[0], curvenode.inputs[1])
+ node.location = -990, 530
+ curvenode.location = -660, 480
+ huenode.location = -337, 335
+ if(coat3D.creategroup):
+ act_material.links.new(huenode.outputs[0], notegroup.inputs[input_index])
+ group_tree.outputs[input_index].name = 'Color'
+ main_material.links.new(applink_tree.outputs[input_index], glue_mat.inputs[input_color])
+ input_index += 1
+ else:
+ if (coat3D.creategroup):
+ node.location = -400, 400
+ act_material.links.new(node.outputs[0], notegroup.inputs[input_index])
+ if (input_color != -1):
+ main_material.links.new(applink_tree.outputs[input_index], glue_mat.inputs[input_color])
+ input_index += 1
+
+ else:
+ node.location = -400,400
+ if (input_color != -1):
+ act_material.links.new(node.outputs[0], glue_mat.inputs[input_color])
+ #Metalness
+ if(bring_metalness == True and texcoat['metalness'] != []):
+ node = act_material.nodes.new('ShaderNodeTexImage')
+ node.name='3DC_metalness'
+ input_color = glue_mat.inputs.find('Metallic')
+ if(texcoat['metalness']):
+ node.image = bpy.data.images.load(texcoat['metalness'][0])
+ node.color_space = 'NONE'
+ if (coat3D.createnodes):
+ curvenode = act_material.nodes.new('ShaderNodeRGBCurve')
+ curvenode.name = '3DC_RGBCurve'
+ huenode = act_material.nodes.new('ShaderNodeHueSaturation')
+ huenode.name = '3DC_HueSaturation'
+ act_material.links.new(huenode.outputs[0], glue_mat.inputs[input_color])
+ act_material.links.new(curvenode.outputs[0], huenode.inputs[4])
+ act_material.links.new(node.outputs[0], curvenode.inputs[1])
+ node.location = -994, 119
+ curvenode.location = -668, 113
+ huenode.location = -345, 118
+ if (coat3D.creategroup):
+ act_material.links.new(huenode.outputs[0], notegroup.inputs[input_index])
+ group_tree.outputs[input_index].name = 'Metalness'
+ main_material.links.new(applink_tree.outputs[input_index], glue_mat.inputs[input_color])
+ input_index += 1
+ else:
+ if (coat3D.creategroup):
+ node.location = -830, 160
+ act_material.links.new(node.outputs[0], notegroup.inputs[input_index])
+ if (input_color != -1):
+ main_material.links.new(applink_tree.outputs[input_index], glue_mat.inputs[input_color])
+ input_index += 1
+ else:
+ node.location = -830, 160
+ if (input_color != -1):
+ act_material.links.new(node.outputs[0], glue_mat.inputs[input_color])
+
+ #Roughness
+ if(bring_roughness == True and texcoat['rough'] != []):
+ node = act_material.nodes.new('ShaderNodeTexImage')
+ node.name='3DC_roughness'
+ input_color = glue_mat.inputs.find('Roughness')
+ if(texcoat['rough']):
+ node.image = bpy.data.images.load(texcoat['rough'][0])
+ node.color_space = 'NONE'
+ if (coat3D.createnodes):
+ curvenode = act_material.nodes.new('ShaderNodeRGBCurve')
+ curvenode.name = '3DC_RGBCurve'
+ huenode = act_material.nodes.new('ShaderNodeHueSaturation')
+ huenode.name = '3DC_HueSaturation'
+ act_material.links.new(huenode.outputs[0], glue_mat.inputs[input_color])
+ act_material.links.new(curvenode.outputs[0], huenode.inputs[4])
+ act_material.links.new(node.outputs[0], curvenode.inputs[1])
+ node.location = -1000, -276
+ curvenode.location = -670, -245
+ huenode.location = -340, -100
+ if (coat3D.creategroup):
+ act_material.links.new(huenode.outputs[0], notegroup.inputs[input_index])
+ group_tree.outputs[input_index].name = 'Roughness'
+ main_material.links.new(applink_tree.outputs[input_index], glue_mat.inputs[input_color])
+ input_index += 1
else:
- objekti.modifiers.new('Displace',type='DISPLACE')
- objekti.modifiers['Displace'].texture = objekti.active_material.texture_slots[index].texture
- if(objekti.data.uv_textures.active):
- objekti.modifiers['Displace'].texture_coords = 'UV'
- objekti.modifiers['Displace'].uv_layer = objekti.data.uv_textures.active.name
+ if (coat3D.creategroup):
+ node.location = -550, 0
+ act_material.links.new(node.outputs[0], notegroup.inputs[input_index])
+ if (input_color != -1):
+ main_material.links.new(applink_tree.outputs[input_index], glue_mat.inputs[input_color])
+ input_index += 1
+ else:
+ node.location = -550, 0
+ if (input_color != -1):
+ act_material.links.new(node.outputs[0], glue_mat.inputs[input_color])
+
+ #Normal map
+ if(bring_normal == True and texcoat['nmap'] != []):
+ node = act_material.nodes.new('ShaderNodeTexImage')
+ normal_node = act_material.nodes.new('ShaderNodeNormalMap')
+ node.location = -600,-670
+ normal_node.location = -300,-300
+ node.name='3DC_normal'
+ normal_node.name='3DC_normalnode'
+ if(texcoat['nmap']):
+ node.image = bpy.data.images.load(texcoat['nmap'][0])
+ node.color_space = 'NONE'
+ input_color = glue_mat.inputs.find('Normal')
+ act_material.links.new(node.outputs[0], normal_node.inputs[1])
+ act_material.links.new(normal_node.outputs[0], glue_mat.inputs[input_color])
+ if (coat3D.creategroup):
+ act_material.links.new(normal_node.outputs[0], notegroup.inputs[input_index])
+ main_material.links.new(applink_tree.outputs[input_index], glue_mat.inputs[input_color])
+ input_index += 1
+
+
+
+def matlab(objekti,mat_list,texturelist,is_new):
+
+ ''' FBX Materials: remove all nodes and create princibles node'''
+ if(is_new):
+ RemoveFbxNodes(objekti)
+
+ '''Main Loop for Texture Update'''
+ #checkmaterial(mat_list, objekti)
+ readtexturefolder(mat_list,texturelist,is_new)
return('FINISHED')
diff --git a/io_convert_image_to_mesh_img/__init__.py b/io_convert_image_to_mesh_img/__init__.py
index 1e5bdddf..a884fb90 100644
--- a/io_convert_image_to_mesh_img/__init__.py
+++ b/io_convert_image_to_mesh_img/__init__.py
@@ -51,12 +51,12 @@ def menu_import(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_import.append(menu_import)
+ bpy.types.TOPBAR_MT_file_import.append(menu_import)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_import.remove(menu_import)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_import)
if __name__ == '__main__':
diff --git a/io_curve_svg/__init__.py b/io_curve_svg/__init__.py
index 188e9189..c8a9988d 100644
--- a/io_curve_svg/__init__.py
+++ b/io_curve_svg/__init__.py
@@ -21,8 +21,7 @@
bl_info = {
"name": "Scalable Vector Graphics (SVG) 1.1 format",
"author": "JM Soler, Sergey Sharybin",
- "version": (1, 0, 0),
- "blender": (2, 57, 0),
+ "blender": (2, 80, 0),
"location": "File > Import > Scalable Vector Graphics (.svg)",
"description": "Import SVG as curves",
"warning": "",
@@ -53,13 +52,12 @@ class ImportSVG(bpy.types.Operator, ImportHelper):
bl_options = {'UNDO'}
filename_ext = ".svg"
- filter_glob = StringProperty(default="*.svg", options={'HIDDEN'})
+ filter_glob: StringProperty(default="*.svg", options={'HIDDEN'})
def execute(self, context):
from . import import_svg
- return import_svg.load(self, context,
- **self.as_keywords(ignore=("filter_glob",)))
+ return import_svg.load(self, context, filepath=self.filepath)
def menu_func_import(self, context):
@@ -68,15 +66,15 @@ def menu_func_import(self, context):
def register():
- bpy.utils.register_module(__name__)
+ bpy.utils.register_class(ImportSVG)
- bpy.types.INFO_MT_file_import.append(menu_func_import)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
def unregister():
- bpy.utils.unregister_module(__name__)
+ bpy.utils.unregister_class(ImportSVG)
- bpy.types.INFO_MT_file_import.remove(menu_func_import)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
# NOTES
# - blender version is hardcoded
diff --git a/io_curve_svg/import_svg.py b/io_curve_svg/import_svg.py
index 00c90dc6..1a8c2f65 100644
--- a/io_curve_svg/import_svg.py
+++ b/io_curve_svg/import_svg.py
@@ -118,14 +118,15 @@ def SVGParseFloat(s, i=0):
return token, i
-def SVGCreateCurve():
+def SVGCreateCurve(context):
"""
Create new curve object to hold splines in
"""
cu = bpy.data.curves.new("Curve", 'CURVE')
obj = bpy.data.objects.new("Curve", cu)
- bpy.context.scene.objects.link(obj)
+
+ context['collection'].objects.link(obj)
return obj
@@ -213,8 +214,8 @@ def SVGMatrixFromNode(node, context):
m = Matrix.Translation(Vector((x, y, 0.0)))
if has_user_coordinate:
if rect[0] != 0 and rect[1] != 0:
- m = m * Matrix.Scale(w / rect[0], 4, Vector((1.0, 0.0, 0.0)))
- m = m * Matrix.Scale(h / rect[1], 4, Vector((0.0, 1.0, 0.0)))
+ m = m @ Matrix.Scale(w / rect[0], 4, Vector((1.0, 0.0, 0.0)))
+ m = m @ Matrix.Scale(h / rect[1], 4, Vector((0.0, 1.0, 0.0)))
if node.getAttribute('viewBox'):
viewBox = node.getAttribute('viewBox').replace(',', ' ').split()
@@ -237,11 +238,11 @@ def SVGMatrixFromNode(node, context):
tx = (w - vw * scale) / 2
ty = (h - vh * scale) / 2
- m = m * Matrix.Translation(Vector((tx, ty, 0.0)))
+ m = m @ Matrix.Translation(Vector((tx, ty, 0.0)))
- m = m * Matrix.Translation(Vector((-vx, -vy, 0.0)))
- m = m * Matrix.Scale(scale, 4, Vector((1.0, 0.0, 0.0)))
- m = m * Matrix.Scale(scale, 4, Vector((0.0, 1.0, 0.0)))
+ m = m @ Matrix.Translation(Vector((-vx, -vy, 0.0)))
+ m = m @ Matrix.Scale(scale, 4, Vector((1.0, 0.0, 0.0)))
+ m = m @ Matrix.Scale(scale, 4, Vector((0.0, 1.0, 0.0)))
return m
@@ -263,7 +264,7 @@ def SVGParseTransform(transform):
if proc is None:
raise Exception('Unknown trasnform function: ' + func)
- m = m * proc(params)
+ m = m @ proc(params)
return m
@@ -304,7 +305,6 @@ def SVGGetMaterial(color, context):
mat = bpy.data.materials.new(name='SVGMat')
mat.diffuse_color = diffuse_color
- mat.diffuse_intensity = 1.0
materials[color] = mat
@@ -350,8 +350,8 @@ def SVGTransformScale(params):
m = Matrix()
- m = m * Matrix.Scale(sx, 4, Vector((1.0, 0.0, 0.0)))
- m = m * Matrix.Scale(sy, 4, Vector((0.0, 1.0, 0.0)))
+ m = m @ Matrix.Scale(sx, 4, Vector((1.0, 0.0, 0.0)))
+ m = m @ Matrix.Scale(sy, 4, Vector((0.0, 1.0, 0.0)))
return m
@@ -395,7 +395,7 @@ def SVGTransformRotate(params):
tm = Matrix.Translation(Vector((cx, cy, 0.0)))
rm = Matrix.Rotation(ang, 4, Vector((0.0, 0.0, 1.0)))
- return tm * rm * tm.inverted()
+ return tm @ rm @ tm.inverted()
SVGTransforms = {'translate': SVGTransformTranslate,
'scale': SVGTransformScale,
@@ -1030,7 +1030,7 @@ class SVGGeometry:
"""
self._context['transform'].append(matrix)
- self._context['matrix'] = self._context['matrix'] * matrix
+ self._context['matrix'] = self._context['matrix'] @ matrix
def _popMatrix(self):
"""
@@ -1038,7 +1038,7 @@ class SVGGeometry:
"""
matrix = self._context['transform'].pop()
- self._context['matrix'] = self._context['matrix'] * matrix.inverted()
+ self._context['matrix'] = self._context['matrix'] @ matrix.inverted()
def _pushStyle(self, style):
"""
@@ -1063,7 +1063,7 @@ class SVGGeometry:
v = Vector((point[0], point[1], 0.0))
- return self._context['matrix'] * v
+ return self._context['matrix'] @ v
def getNodeMatrix(self):
"""
@@ -1211,7 +1211,7 @@ class SVGGeometryPATH(SVGGeometry):
Create real geometries
"""
- ob = SVGCreateCurve()
+ ob = SVGCreateCurve(self._context)
cu = ob.data
if self._node.getAttribute('id'):
@@ -1234,7 +1234,7 @@ class SVGGeometryPATH(SVGGeometry):
act_spline = cu.splines[-1]
act_spline.use_cyclic_u = spline['closed']
else:
- act_spline.bezier_points.add()
+ act_spline.bezier_points.add(1)
bezt = act_spline.bezier_points[-1]
bezt.co = co
@@ -1378,7 +1378,7 @@ class SVGGeometryRECT(SVGGeometry):
co = self._transformCoord(coord)
if not firstTime:
- spline.bezier_points.add()
+ spline.bezier_points.add(1)
bezt = spline.bezier_points[-1]
bezt.co = co
@@ -1429,7 +1429,7 @@ class SVGGeometryRECT(SVGGeometry):
radius = (rx, ry)
# Geometry creation
- ob = SVGCreateCurve()
+ ob = SVGCreateCurve(self._context)
cu = ob.data
if self._styles['useFill']:
@@ -1539,7 +1539,7 @@ class SVGGeometryELLIPSE(SVGGeometry):
return
# Create circle
- ob = SVGCreateCurve()
+ ob = SVGCreateCurve(self._context)
cu = ob.data
if self._node.getAttribute('id'):
@@ -1578,7 +1578,7 @@ class SVGGeometryELLIPSE(SVGGeometry):
spline = cu.splines[-1]
spline.use_cyclic_u = True
else:
- spline.bezier_points.add()
+ spline.bezier_points.add(1)
bezt = spline.bezier_points[-1]
bezt.co = co
@@ -1656,7 +1656,7 @@ class SVGGeometryLINE(SVGGeometry):
y2 = SVGParseCoord(self._y2, crect[1])
# Create cline
- ob = SVGCreateCurve()
+ ob = SVGCreateCurve(self._context)
cu = ob.data
coords = [(x1, y1), (x2, y2)]
@@ -1670,7 +1670,7 @@ class SVGGeometryLINE(SVGGeometry):
spline = cu.splines[-1]
spline.use_cyclic_u = True
else:
- spline.bezier_points.add()
+ spline.bezier_points.add(1)
bezt = spline.bezier_points[-1]
bezt.co = co
@@ -1727,7 +1727,7 @@ class SVGGeometryPOLY(SVGGeometry):
Create real geometries
"""
- ob = SVGCreateCurve()
+ ob = SVGCreateCurve(self._context)
cu = ob.data
if self._closed and self._styles['useFill']:
@@ -1746,7 +1746,7 @@ class SVGGeometryPOLY(SVGGeometry):
spline = cu.splines[-1]
spline.use_cyclic_u = self._closed
else:
- spline.bezier_points.add()
+ spline.bezier_points.add(1)
bezt = spline.bezier_points[-1]
bezt.co = co
@@ -1798,7 +1798,7 @@ class SVGGeometrySVG(SVGGeometryContainer):
if self._node.getAttribute('inkscape:version'):
raw_height = self._node.getAttribute('height')
document_height = SVGParseCoord(raw_height, 1.0)
- matrix = matrix * Matrix.Translation([0.0, -document_height , 0.0])
+ matrix = matrix @ matrix.Translation([0.0, -document_height , 0.0])
self._pushMatrix(matrix)
self._pushRect(rect)
@@ -1824,16 +1824,22 @@ class SVGLoader(SVGGeometryContainer):
return None
- def __init__(self, filepath, do_colormanage):
+ def __init__(self, context, filepath, do_colormanage):
"""
Initialize SVG loader
"""
+ import os
+
+ svg_name = os.path.basename(filepath)
+ scene = context.scene
+ collection = bpy.data.collections.new(name=svg_name)
+ scene.collection.children.link(collection)
node = xml.dom.minidom.parse(filepath)
m = Matrix()
- m = m * Matrix.Scale(1.0 / 90.0 * 0.3048 / 12.0, 4, Vector((1.0, 0.0, 0.0)))
- m = m * Matrix.Scale(-1.0 / 90.0 * 0.3048 / 12.0, 4, Vector((0.0, 1.0, 0.0)))
+ m = m @ Matrix.Scale(1.0 / 90.0 * 0.3048 / 12.0, 4, Vector((1.0, 0.0, 0.0)))
+ m = m @ Matrix.Scale(-1.0 / 90.0 * 0.3048 / 12.0, 4, Vector((0.0, 1.0, 0.0)))
rect = (0, 0)
@@ -1845,7 +1851,8 @@ class SVGLoader(SVGGeometryContainer):
'materials': {},
'styles': [None],
'style': None,
- 'do_colormanage': do_colormanage}
+ 'do_colormanage': do_colormanage,
+ 'collection': collection}
super().__init__(node, self._context)
@@ -1882,7 +1889,7 @@ def parseAbstractNode(node, context):
return None
-def load_svg(filepath, do_colormanage):
+def load_svg(context, filepath, do_colormanage):
"""
Load specified SVG file
"""
@@ -1890,7 +1897,7 @@ def load_svg(filepath, do_colormanage):
if bpy.ops.object.mode_set.poll():
bpy.ops.object.mode_set(mode='OBJECT')
- loader = SVGLoader(filepath, do_colormanage)
+ loader = SVGLoader(context, filepath, do_colormanage)
loader.parse()
loader.createGeom(False)
@@ -1901,7 +1908,7 @@ def load(operator, context, filepath=""):
# non SVG files can give useful messages.
do_colormanage = context.scene.display_settings.display_device != 'NONE'
try:
- load_svg(filepath, do_colormanage)
+ load_svg(context, filepath, do_colormanage)
except (xml.parsers.expat.ExpatError, UnicodeEncodeError) as e:
import traceback
traceback.print_exc()
diff --git a/io_export_after_effects.py b/io_export_after_effects.py
index bb7ec73c..d682497d 100644
--- a/io_export_after_effects.py
+++ b/io_export_after_effects.py
@@ -110,7 +110,7 @@ def get_selected(context):
# not ready yet. is_plane(object) returns False in all cases. This is temporary
solids.append([ob, convert_name(ob.name)])
- elif ob.type == 'LAMP':
+ elif ob.type == 'LIGHT':
lights.append([ob, ob.data.type + convert_name(ob.name)]) # Type of lamp added to name
else:
@@ -768,12 +768,12 @@ def menu_func(self, context):
def register():
bpy.utils.register_class(ExportJsx)
- bpy.types.INFO_MT_file_export.append(menu_func)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func)
def unregister():
bpy.utils.unregister_class(ExportJsx)
- bpy.types.INFO_MT_file_export.remove(menu_func)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func)
if __name__ == "__main__":
register()
diff --git a/io_export_dxf/__init__.py b/io_export_dxf/__init__.py
index 254ffdae..41fd79e6 100644
--- a/io_export_dxf/__init__.py
+++ b/io_export_dxf/__init__.py
@@ -45,7 +45,7 @@ classes = (
)
def register():
- bpy.types.INFO_MT_file_export.append(menu_func)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func)
from bpy.utils import register_class
for cls in classes:
@@ -53,7 +53,7 @@ def register():
def unregister():
- bpy.types.INFO_MT_file_export.remove(menu_func)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func)
from bpy.utils import unregister_class
for cls in reversed(classes):
diff --git a/io_export_dxf/export_dxf.py b/io_export_dxf/export_dxf.py
index df0dcddc..934ae90e 100644
--- a/io_export_dxf/export_dxf.py
+++ b/io_export_dxf/export_dxf.py
@@ -27,7 +27,7 @@ if DEBUG:
from .model.migiusModel import MigiusDXFLibDrawing
-SUPPORTED_TYPES = ('MESH')#,'CURVE','EMPTY','TEXT','CAMERA','LAMP')
+SUPPORTED_TYPES = ('MESH')#,'CURVE','EMPTY','TEXT','CAMERA','LIGHT')
def exportDXF(context, filePath, settings):
"""
@@ -277,8 +277,8 @@ def _exportItem(ctx, o, mw, drawing, settings):
elif (o.type == 'CAMERA') and settings['camera_as']:
from .primitive_exporters.camera_exporter import CameraDXFExporter
e = CameraDXFExporter(settings)
- elif (o.type == 'LAMP') and settings['lamp_as']:
- from .primitive_exporters.lamp_exporter import LampDXFExporter
+ elif (o.type == 'LIGHT') and settings['light_as']:
+ from .primitive_exporters.light_exporter import LampDXFExporter
e = LampDXFExporter(settings)
return e.export(ctx, drawing, o, mx, mx_n, color=ecolor, layer=elayer, lineType=eltype)
diff --git a/io_export_dxf/operator.py b/io_export_dxf/operator.py
index e419608f..7e2dd7a7 100644
--- a/io_export_dxf/operator.py
+++ b/io_export_dxf/operator.py
@@ -160,10 +160,10 @@ class DXFExporter(bpy.types.Operator):
# ('VIEW', 'VIEW', ''),
# ('POINT', 'POINT', '')
# )
-# lamp_asItems = (
+# light_asItems = (
# ('NO', 'Do not export', ''),
# ('..BLOCK', '..BLOCK', ''),
-# ('..A_LAMP', '..A_LAMP', ''),
+# ('..A_LIGHT', '..A_LIGHT', ''),
# ('POINT', 'POINT', '')
# )
# --------- CONTROL PROPERTIES --------------------------------------------
@@ -207,9 +207,9 @@ class DXFExporter(bpy.types.Operator):
# camera_as = EnumProperty( name="Export camera As:", default='NO',
# description="Select representation of a camera",
# items=camera_asItems)
-# lamp_as = EnumProperty( name="Export lamp As:", default='NO',
+# light_as = EnumProperty( name="Export lamp As:", default='NO',
# description="Select representation of a lamp",
-# items=lamp_asItems)
+# items=light_asItems)
# ----------------------------------------------------------
entitylayer_from = EnumProperty(name="Entity Layer", default="obj.data.name",
description="Entity LAYER assigned to?",
@@ -265,7 +265,7 @@ class DXFExporter(bpy.types.Operator):
# 'group_as' : self._checkNO(self.group_as),
# 'proxy_as' : self._checkNO(self.proxy_as),
# 'camera_as' : self._checkNO(self.camera_as),
-# 'lamp_as' : self._checkNO(self.lamp_as),
+# 'light_as' : self._checkNO(self.light_as),
'entitylayer_from' : self.entitylayer_from,
'entitycolor_from' : self.entitycolor_from,
diff --git a/io_export_dxf/primitive_exporters/lamp_exporter.py b/io_export_dxf/primitive_exporters/lamp_exporter.py
index c67eb032..849f0984 100644
--- a/io_export_dxf/primitive_exporters/lamp_exporter.py
+++ b/io_export_dxf/primitive_exporters/lamp_exporter.py
@@ -13,7 +13,7 @@ def exportLamp(ob, mx, mw, **common):
[p] = toGlobalOrigin([p])
entities = []
- c = lamp_as_list[GUI_A['lamp_as'].val]
+ c = light_as_list[GUI_A['light_as'].val]
if c=="POINT": # export as POINT
dxfPOINT = DXF.Point(points=[p],**common)
entities.append(dxfPOINT)
diff --git a/io_export_paper_model.py b/io_export_paper_model.py
index 38444b37..0906eb33 100644
--- a/io_export_paper_model.py
+++ b/io_export_paper_model.py
@@ -2238,8 +2238,8 @@ class ExportPaperModel(bpy.types.Operator):
row = layout.row(align=True)
row.menu("VIEW3D_MT_paper_model_presets", text=bpy.types.VIEW3D_MT_paper_model_presets.bl_label)
- row.operator("export_mesh.paper_model_preset_add", text="", icon='ZOOMIN')
- row.operator("export_mesh.paper_model_preset_add", text="", icon='ZOOMOUT').remove_active = True
+ row.operator("export_mesh.paper_model_preset_add", text="", icon='ADD')
+ row.operator("export_mesh.paper_model_preset_add", text="", icon='REMOVE').remove_active = True
# a little hack: this prints out something like "Scale: 1: 72"
layout.prop(self.properties, "scale", text="Scale: 1")
@@ -2582,12 +2582,12 @@ def register():
bpy.types.Mesh.paper_island_index = bpy.props.IntProperty(
name="Island List Index",
default=-1, min=-1, max=100, options={'SKIP_SAVE'})
- bpy.types.INFO_MT_file_export.append(menu_func)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_export.remove(menu_func)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func)
if display_islands.handle:
bpy.types.SpaceView3D.draw_handler_remove(display_islands.handle, 'WINDOW')
display_islands.handle = None
diff --git a/io_export_pc2.py b/io_export_pc2.py
index 752df5c4..7384e21e 100644
--- a/io_export_pc2.py
+++ b/io_export_pc2.py
@@ -19,8 +19,8 @@
bl_info = {
"name": "Export Pointcache Format(.pc2)",
"author": "Florian Meyer (tstscr)",
- "version": (1, 1, 1),
- "blender": (2, 71, 0),
+ "version": (1, 1, 2),
+ "blender": (2, 80, 0),
"location": "File > Export > Pointcache (.pc2)",
"description": "Export mesh Pointcache data (.pc2)",
"warning": "",
@@ -50,9 +50,11 @@ import time
import math
import struct
+
def get_sampled_frames(start, end, sampling):
return [math.modf(start + x * sampling) for x in range(int((end - start) / sampling) + 1)]
+
def do_export(context, props, filepath):
mat_x90 = mathutils.Matrix.Rotation(-math.pi/2, 4, 'X')
ob = context.active_object
@@ -61,13 +63,13 @@ def do_export(context, props, filepath):
end = props.range_end
sampling = float(props.sampling)
apply_modifiers = props.apply_modifiers
- me = ob.to_mesh(sc, apply_modifiers, 'PREVIEW')
+ me = ob.to_mesh(context.depsgraph, apply_modifiers)
vertCount = len(me.vertices)
sampletimes = get_sampled_frames(start, end, sampling)
sampleCount = len(sampletimes)
# Create the header
- headerFormat='<12siiffi'
+ headerFormat = '<12siiffi'
headerStr = struct.pack(headerFormat, b'POINTCACHE2\0',
1, vertCount, start, sampling, sampleCount)
@@ -75,8 +77,9 @@ def do_export(context, props, filepath):
file.write(headerStr)
for frame in sampletimes:
- sc.frame_set(int(frame[1]), frame[0]) # stupid modf() gives decimal part first!
- me = ob.to_mesh(sc, apply_modifiers, 'PREVIEW')
+ # stupid modf() gives decimal part first!
+ sc.frame_set(int(frame[1]), subframe=frame[0])
+ me = ob.to_mesh(context.depsgraph, apply_modifiers)
if len(me.vertices) != vertCount:
bpy.data.meshes.remove(me, do_unlink=True)
@@ -97,19 +100,18 @@ def do_export(context, props, filepath):
for v in me.vertices:
thisVertex = struct.pack('<fff', float(v.co[0]),
- float(v.co[1]),
- float(v.co[2]))
+ float(v.co[1]),
+ float(v.co[2]))
file.write(thisVertex)
bpy.data.meshes.remove(me, do_unlink=True)
-
file.flush()
file.close()
return True
-###### EXPORT OPERATOR #######
+# EXPORT OPERATOR
class Export_pc2(bpy.types.Operator, ExportHelper):
"""Export the active Object as a .pc2 Pointcache file"""
bl_idname = "export_shape.pc2"
@@ -117,50 +119,51 @@ class Export_pc2(bpy.types.Operator, ExportHelper):
filename_ext = ".pc2"
- rot_x90 = BoolProperty(name="Convert to Y-up",
- description="Rotate 90 degrees around X to convert to y-up",
- default=True,
- )
- world_space = BoolProperty(name="Export into Worldspace",
- description="Transform the Vertexcoordinates into Worldspace",
- default=False,
- )
- apply_modifiers = BoolProperty(name="Apply Modifiers",
- description="Applies the Modifiers",
- default=True,
- )
- range_start = IntProperty(name='Start Frame',
- description='First frame to use for Export',
- default=1,
- )
- range_end = IntProperty(name='End Frame',
- description='Last frame to use for Export',
- default=250,
- )
- sampling = EnumProperty(name='Sampling',
- description='Sampling --> frames per sample (0.1 yields 10 samples per frame)',
- items=(('0.01', '0.01', ''),
- ('0.05', '0.05', ''),
- ('0.1', '0.1', ''),
- ('0.2', '0.2', ''),
- ('0.25', '0.25', ''),
- ('0.5', '0.5', ''),
- ('1', '1', ''),
- ('2', '2', ''),
- ('3', '3', ''),
- ('4', '4', ''),
- ('5', '5', ''),
- ('10', '10', ''),
- ),
- default='1',
- )
+ rot_x90: BoolProperty(
+ name="Convert to Y-up",
+ description="Rotate 90 degrees around X to convert to y-up",
+ default=True,)
+ world_space: BoolProperty(
+ name="Export into Worldspace",
+ description="Transform the Vertexcoordinates into Worldspace",
+ default=False,)
+ apply_modifiers: BoolProperty(
+ name="Apply Modifiers",
+ description="Applies the Modifiers",
+ default=True,)
+ range_start: IntProperty(
+ name='Start Frame',
+ description='First frame to use for Export',
+ default=1,)
+ range_end: IntProperty(
+ name='End Frame',
+ description='Last frame to use for Export',
+ default=250,)
+ sampling: EnumProperty(
+ name='Sampling',
+ description='Sampling --> frames per sample (0.1 yields 10 samples per frame)',
+ items=(('0.01', '0.01', ''),
+ ('0.05', '0.05', ''),
+ ('0.1', '0.1', ''),
+ ('0.2', '0.2', ''),
+ ('0.25', '0.25', ''),
+ ('0.5', '0.5', ''),
+ ('1', '1', ''),
+ ('2', '2', ''),
+ ('3', '3', ''),
+ ('4', '4', ''),
+ ('5', '5', ''),
+ ('10', '10', ''),
+ ),
+ default='1',
+ )
@classmethod
def poll(cls, context):
obj = context.active_object
return (
- obj is not None and
- obj.type in {'MESH', 'CURVE', 'SURFACE', 'FONT'}
+ obj is not None
+ and obj.type in {'MESH', 'CURVE', 'SURFACE', 'FONT'}
)
def execute(self, context):
@@ -173,7 +176,8 @@ class Export_pc2(bpy.types.Operator, ExportHelper):
exported = do_export(context, props, filepath)
if exported:
- print('finished export in %s seconds' %((time.time() - start_time)))
+ print('finished export in %s seconds' %
+ ((time.time() - start_time)))
print(filepath)
return {'FINISHED'}
@@ -183,7 +187,7 @@ class Export_pc2(bpy.types.Operator, ExportHelper):
if True:
# File selector
- wm.fileselect_add(self) # will run self.execute()
+ wm.fileselect_add(self) # will run self.execute()
return {'RUNNING_MODAL'}
elif True:
# search the enum
@@ -196,23 +200,29 @@ class Export_pc2(bpy.types.Operator, ExportHelper):
return self.execute(context)
-### REGISTER ###
-
-def menu_func(self, context):
+def menu_func_export_button(self, context):
self.layout.operator(Export_pc2.bl_idname, text="Pointcache (.pc2)")
+classes = [
+ Export_pc2,
+]
+
+
def register():
- bpy.utils.register_module(__name__)
+ for cls in classes:
+ bpy.utils.register_class(cls)
+
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_export_button)
+ #bpy.types.VIEW3D_PT_tools_objectmode.prepend(menu_func_export_button)
- bpy.types.INFO_MT_file_export.append(menu_func)
- #bpy.types.VIEW3D_PT_tools_objectmode.prepend(menu_func)
def unregister():
- bpy.utils.unregister_module(__name__)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_export_button)
+ #bpy.types.VIEW3D_PT_tools_objectmode.remove(menu_func_export_button)
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
- bpy.types.INFO_MT_file_export.remove(menu_func)
- #bpy.types.VIEW3D_PT_tools_objectmode.remove(menu_func)
if __name__ == "__main__":
register()
diff --git a/io_export_unreal_psk_psa.py b/io_export_unreal_psk_psa.py
index 6179470c..40840e90 100644
--- a/io_export_unreal_psk_psa.py
+++ b/io_export_unreal_psk_psa.py
@@ -1201,8 +1201,8 @@ def parse_mesh(mesh, psk):
# does with the mesh Y coordinates. this is otherwise known as MAGIC-2
uv[1] = 1.0 - uv[1]
- # clamp UV coords if udk_option_clamp_uv is True
- if bpy.context.scene.udk_option_clamp_uv:
+ # clamp UV coords if udk_option_clight_uv is True
+ if bpy.context.scene.udk_option_clight_uv:
if (uv[0] > 1):
uv[0] = 1
if (uv[0] < 0):
@@ -2422,7 +2422,7 @@ class Panel_UDKExport(Panel):
object_name = context.active_object.name
row10 = layout.row()
row10.prop(context.scene, "udk_option_smoothing_groups")
- row10.prop(context.scene, "udk_option_clamp_uv")
+ row10.prop(context.scene, "udk_option_clight_uv")
row10.prop(context.scene, "udk_option_verbose")
row = layout.row()
@@ -2792,7 +2792,7 @@ class ExportUDKAnimData(Operator):
scene = context.scene
layout.prop(scene, "udk_option_smoothing_groups")
- layout.prop(scene, "udk_option_clamp_uv")
+ layout.prop(scene, "udk_option_clight_uv")
layout.prop(scene, "udk_option_verbose")
layout.prop(scene, "udk_option_filename_src")
layout.prop(scene, "udk_option_export")
@@ -2865,7 +2865,7 @@ class PskAddonPreferences(AddonPreferences):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_export.append(menu_func)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func)
update_panel(None, bpy.context)
# Added by [MGVS]
@@ -2888,7 +2888,7 @@ def register():
description="Boolean for exporting psa format (Animation Data)",
default=True
)
- bpy.types.Scene.udk_option_clamp_uv = BoolProperty(
+ bpy.types.Scene.udk_option_clight_uv = BoolProperty(
name="Clamp UV",
description="True is to limit Clamp UV co-ordinates to [0-1]. False is unrestricted (x,y)",
default=False
@@ -2972,12 +2972,12 @@ def register():
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_export.remove(menu_func)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func)
del bpy.types.Scene.udk_option_filename_src
del bpy.types.Scene.udk_option_export_psk
del bpy.types.Scene.udk_option_export_psa
- del bpy.types.Scene.udk_option_clamp_uv
+ del bpy.types.Scene.udk_option_clight_uv
del bpy.types.Scene.udk_copy_merge
del bpy.types.Scene.udk_option_export
del bpy.types.Scene.udk_option_verbose
diff --git a/io_import_dxf/__init__.py b/io_import_dxf/__init__.py
index d768d624..46e84fd5 100644
--- a/io_import_dxf/__init__.py
+++ b/io_import_dxf/__init__.py
@@ -559,12 +559,12 @@ def menu_func(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_import.append(menu_func)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_import.remove(menu_func)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func)
if __name__ == "__main__":
diff --git a/io_import_dxf/dxfimport/do.py b/io_import_dxf/dxfimport/do.py
index 7ac4c392..be79908c 100644
--- a/io_import_dxf/dxfimport/do.py
+++ b/io_import_dxf/dxfimport/do.py
@@ -738,7 +738,7 @@ class Do:
if self.import_light:
type_map = ["NONE", "SUN", "POINT", "SPOT"]
layer = self.dwg.layers[en.layer]
- lamp = bpy.data.lamps.new(en.name, type_map[en.light_type])
+ lamp = bpy.data.lights.new(en.name, type_map[en.light_type])
if en.color != 256:
aci = en.color
else:
@@ -1005,7 +1005,7 @@ class Do:
bpy.context.screen.scene = scene
o = bbox.copy()
- # o.empty_draw_size = 0.3
+ # o.empty_display_size = 0.3
o.dupli_type = "GROUP"
o.dupli_group = block_group
group.objects.link(o)
diff --git a/io_import_gimp_image_to_scene.py b/io_import_gimp_image_to_scene.py
index 6ff1d66f..94d496e3 100644
--- a/io_import_gimp_image_to_scene.py
+++ b/io_import_gimp_image_to_scene.py
@@ -619,7 +619,7 @@ class GIMPImageToScene(bpy.types.Operator):
if self.OpacityMode == 'COMPO' and self.SetupCompo == False:
box.label('Tip: Enable Node Compositing', icon='INFO')
box.prop(self, 'AlphaMode', icon='IMAGE_RGB_ALPHA')
- box.prop(self, 'ShadelessMats', icon='SOLID')
+ box.prop(self, 'ShadelessMats', icon='SHADING_SOLID')
box.prop(self, 'LayerOffset')
box.prop(self, 'LayerScale')
@@ -680,13 +680,13 @@ def menu_func(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_import.append(menu_func)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_import.remove(menu_func)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func)
if __name__ == "__main__":
diff --git a/io_import_images_as_planes.py b/io_import_images_as_planes.py
index 1f32bc5f..e0c71426 100644
--- a/io_import_images_as_planes.py
+++ b/io_import_images_as_planes.py
@@ -21,8 +21,8 @@
bl_info = {
"name": "Import Images as Planes",
"author": "Florian Meyer (tstscr), mont29, matali, Ted Schundler (SpkyElctrc)",
- "version": (3, 1, 1),
- "blender": (2, 78, 0),
+ "version": (3, 2, 0),
+ "blender": (2, 80, 0),
"location": "File > Import > Images as Planes or Add > Mesh > Images as Planes",
"description": "Imports images and creates planes with the appropriate aspect ratio. "
"The images are mapped to the planes.",
@@ -179,7 +179,6 @@ def load_images(filenames, directory, force_reload=False, frame_start=1, find_se
frames = image.frame_duration
elif frames > 1: # Not movie, but multiple frames -> image sequence
- image.use_animation = True
image.source = 'SEQUENCE'
yield ImageSpec(image, size, frame_start, offset - 1, frames)
@@ -200,11 +199,10 @@ def offset_planes(planes, gap, axis):
prior = planes[0]
offset = Vector()
for current in planes[1:]:
-
- local_offset = abs((prior.dimensions + current.dimensions) * axis) / 2.0 + gap
+ local_offset = abs((prior.dimensions + current.dimensions).dot(axis)) / 2.0 + gap
offset += local_offset * axis
- current.location = current.matrix_world * offset
+ current.location = current.matrix_world @ offset
prior = current
@@ -242,7 +240,7 @@ def compute_camera_size(context, center, fill_mode, aspect):
def center_in_camera(scene, camera, obj, axis=(1, 1)):
- """Center object along specified axiis of the camera"""
+ """Center object along specified axis of the camera"""
camera_matrix_col = camera.matrix_world.col
location = obj.location
@@ -250,11 +248,11 @@ def center_in_camera(scene, camera, obj, axis=(1, 1)):
delta = camera_matrix_col[3].xyz - location
# How far off center we are along the camera's local X
- camera_x_mag = delta * camera_matrix_col[0].xyz * axis[0]
+ camera_x_mag = delta.dot(camera_matrix_col[0].xyz) * axis[0]
# How far off center we are along the camera's local Y
- camera_y_mag = delta * camera_matrix_col[1].xyz * axis[1]
+ camera_y_mag = delta.dot(camera_matrix_col[1].xyz) * axis[1]
- # Now offet only along camera local axiis
+ # Now offset only along camera local axis
offset = camera_matrix_col[0].xyz * camera_x_mag + \
camera_matrix_col[1].xyz * camera_y_mag
@@ -262,7 +260,7 @@ def center_in_camera(scene, camera, obj, axis=(1, 1)):
# -----------------------------------------------------------------------------
-# Cycles utils
+# Cycles/Eevee utils
def get_input_nodes(node, links):
"""Get nodes that are a inputs to the given node"""
@@ -327,7 +325,7 @@ def clean_node_tree(node_tree):
def get_shadeless_node(dest_node_tree):
- """Return a "shadless" cycles node, creating a node group if nonexistent"""
+ """Return a "shadless" cycles/eevee node, creating a node group if nonexistent"""
try:
node_tree = bpy.data.node_groups['IAP_SHADELESS']
@@ -474,7 +472,7 @@ def find_plane_corner(object_name, x, y, axis, camera=None, *args, **kwargs):
v = plane.dimensions.copy()
v.x *= x / scale.x
v.y *= y / scale.y
- v = plane.matrix_world * v
+ v = plane.matrix_world @ v
camera_vertex = world_to_camera_view(
bpy.context.scene, camera, v)
@@ -614,22 +612,22 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
# ----------------------
# File dialog properties
- files = CollectionProperty(type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'})
+ files: CollectionProperty(type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'})
- directory = StringProperty(maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'})
+ directory: StringProperty(maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'})
- filter_image = BoolProperty(default=True, options={'HIDDEN', 'SKIP_SAVE'})
- filter_movie = BoolProperty(default=True, options={'HIDDEN', 'SKIP_SAVE'})
- filter_folder = BoolProperty(default=True, options={'HIDDEN', 'SKIP_SAVE'})
+ filter_image: BoolProperty(default=True, options={'HIDDEN', 'SKIP_SAVE'})
+ filter_movie: BoolProperty(default=True, options={'HIDDEN', 'SKIP_SAVE'})
+ filter_folder: BoolProperty(default=True, options={'HIDDEN', 'SKIP_SAVE'})
# ----------------------
# Properties - Importing
- force_reload = BoolProperty(
+ force_reload: BoolProperty(
name="Force Reload", default=False,
description="Force reloading of the image if already opened elsewhere in Blender"
)
- image_sequence = BoolProperty(
+ image_sequence: BoolProperty(
name="Animate Image Sequences", default=False,
description="Import sequentially numbered images as an animated "
"image sequence instead of separate planes"
@@ -646,7 +644,7 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
'Z-': Vector(( 0, 0, -1)),
}
- offset = BoolProperty(name="Offset Planes", default=True, description="Offset Planes From Each Other")
+ offset: BoolProperty(name="Offset Planes", default=True, description="Offset Planes From Each Other")
OFFSET_MODES = (
('X+', "X+", "Side by Side to the Left"),
@@ -656,12 +654,12 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
('Y-', "Y-", "Side by Side, Upward"),
('Z-', "Z-", "Stacked Below"),
)
- offset_axis = EnumProperty(
+ offset_axis: EnumProperty(
name="Orientation", default='X+', items=OFFSET_MODES,
description="How planes are oriented relative to each others' local axis"
)
- offset_amount = FloatProperty(
+ offset_amount: FloatProperty(
name="Offset", soft_min=0, default=0.1, description="Space between planes",
subtype='DISTANCE', unit='LENGTH'
)
@@ -676,14 +674,14 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
('CAM', "Face Camera", "Facing Camera"),
('CAM_AX', "Main Axis", "Facing the Camera's dominant axis"),
)
- align_axis = EnumProperty(
+ align_axis: EnumProperty(
name="Align", default='CAM_AX', items=AXIS_MODES,
description="How to align the planes"
)
# prev_align_axis is used only by update_size_model
- prev_align_axis = EnumProperty(
+ prev_align_axis: EnumProperty(
items=AXIS_MODES + (('NONE', '', ''),), default='NONE', options={'HIDDEN', 'SKIP_SAVE'})
- align_track = BoolProperty(
+ align_track: BoolProperty(
name="Track Camera", default=False, description="Always face the camera"
)
@@ -707,7 +705,7 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
('DPI', "Dpi", "Use definition of the image as dots per inch"),
('DPBU', "Dots/BU", "Use definition of the image as dots per Blender Unit"),
)
- size_mode = EnumProperty(
+ size_mode: EnumProperty(
name="Size Mode", default='ABSOLUTE', items=SIZE_MODES,
update=update_size_mode,
description="How the size of the plane is computed")
@@ -716,13 +714,13 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
('FILL', "Fill", "Fill camera frame, spilling outside the frame"),
('FIT', "Fit", "Fit entire image within the camera frame"),
)
- fill_mode = EnumProperty(name="Scale", default='FILL', items=FILL_MODES,
+ fill_mode: EnumProperty(name="Scale", default='FILL', items=FILL_MODES,
description="How large in the camera frame is the plane")
- height = FloatProperty(name="Height", description="Height of the created plane",
+ height: FloatProperty(name="Height", description="Height of the created plane",
default=1.0, min=0.001, soft_min=0.001, subtype='DISTANCE', unit='LENGTH')
- factor = FloatProperty(name="Definition", min=1.0, default=600.0,
+ factor: FloatProperty(name="Definition", min=1.0, default=600.0,
description="Number of pixels per inch or Blender Unit")
# ------------------------------
@@ -732,40 +730,37 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
('SHADELESS', "Shadeless", "Only visible to camera and reflections."),
('EMISSION', "Emit", "Emission Shader"),
)
- shader = EnumProperty(name="Shader", items=SHADERS, default='DIFFUSE', description="Node shader to use")
+ shader: EnumProperty(name="Shader", items=SHADERS, default='DIFFUSE', description="Node shader to use")
- emit_strength = FloatProperty(
+ emit_strength: FloatProperty(
name="Strength", min=0.0, default=1.0, soft_max=10.0,
step=100, description="Brightness of Emission Texture")
- overwrite_material = BoolProperty(
+ overwrite_material: BoolProperty(
name="Overwrite Material", default=True,
description="Overwrite existing Material (based on material name)")
- compositing_nodes = BoolProperty(
+ compositing_nodes: BoolProperty(
name="Setup Corner Pin", default=False,
description="Build Compositor Nodes to reference this image "
"without re-rendering")
# ------------------
# Properties - Image
- use_transparency = BoolProperty(
+ use_transparency: BoolProperty(
name="Use Alpha", default=True,
description="Use alphachannel for transparency")
t = bpy.types.Image.bl_rna.properties["alpha_mode"]
alpha_mode_items = tuple((e.identifier, e.name, e.description) for e in t.enum_items)
- alpha_mode = EnumProperty(
+ alpha_mode: EnumProperty(
name=t.name, items=alpha_mode_items, default=t.default,
description=t.description)
- t = bpy.types.Image.bl_rna.properties["use_fields"]
- use_fields = BoolProperty(name=t.name, default=False, description=t.description)
-
t = bpy.types.ImageUser.bl_rna.properties["use_auto_refresh"]
- use_auto_refresh = BoolProperty(name=t.name, default=True, description=t.description)
+ use_auto_refresh: BoolProperty(name=t.name, default=True, description=t.description)
- relative = BoolProperty(name="Relative Paths", default=True, description="Use relative file paths")
+ relative: BoolProperty(name="Relative Paths", default=True, description="Use relative file paths")
# -------
# Draw UI
@@ -798,7 +793,7 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
box.prop(self, "emit_strength")
engine = context.scene.render.engine
- if engine not in ('CYCLES', 'BLENDER_RENDER'):
+ if engine not in ('CYCLES', 'BLENDER_EEVEE', 'BLENDER_OPENGL'):
box.label(text="%s is not supported" % engine, icon='ERROR')
box.prop(self, "overwrite_material")
@@ -809,7 +804,6 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
sub = row.row()
sub.active = self.use_transparency
sub.prop(self, "alpha_mode", text="")
- box.prop(self, "use_fields")
box.prop(self, "use_auto_refresh")
def draw_spatial_config(self, context):
@@ -857,9 +851,13 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
# Core functionality
def invoke(self, context, event):
engine = context.scene.render.engine
- if engine not in ('CYCLES', 'BLENDER_RENDER', 'BLENDER_GAME'):
- # Use default blender texture, but acknowledge things may not work
- self.report({'WARNING'}, "Cannot generate materials for unknown %s render engine" % engine)
+ if engine not in {'CYCLES', 'BLENDER_EEVEE'}:
+ if engine not in {'BLENDER_OPENGL'}:
+ self.report({'ERROR'}, "Cannot generate materials for unknown %s render engine" % engine)
+ return {'CANCELLED'}
+ else:
+ self.report({'WARNING'},
+ "Generating Cycles/EEVEE compatible material, but won't be visible with %s engine" % engine)
# Open file browser
context.window_manager.fileselect_add(self)
@@ -910,7 +908,7 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
# setup new selection
for plane in planes:
- plane.select = True
+ plane.select_set('SELECT')
# all done!
self.report({'INFO'}, "Added {} Image Plane(s)".format(len(planes)))
@@ -923,22 +921,14 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
# Configure material
engine = context.scene.render.engine
- if engine == 'CYCLES':
+ if engine in {'CYCLES', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}:
material = self.create_cycles_material(context, img_spec)
- else:
- tex = self.create_image_textures(context, img_spec)
- material = self.create_material_for_texture(tex)
-
- # Game Engine Material Settings
- material.game_settings.use_backface_culling = False
- material.game_settings.alpha_blend = 'ALPHA'
# Create and position plane object
plane = self.create_image_plane(context, material.name, img_spec)
# Assign Material
plane.data.materials.append(material)
- plane.data.uv_textures[0].data[0].image = img_spec.image
# If applicable, setup Corner Pin node
if self.compositing_nodes:
@@ -949,7 +939,6 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
def apply_image_options(self, image):
image.use_alpha = self.use_transparency
image.alpha_mode = self.alpha_mode
- image.use_fields = self.use_fields
if self.relative:
try: # can't always find the relative path (between drive letters on windows)
@@ -971,48 +960,6 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
texture.extension = 'CLIP' # Default of "Repeat" can cause artifacts
- # -------------------------------------------------------------------------
- # Blender Internal Material
- def create_image_textures(self, context, img_spec):
- image = img_spec.image
- fn_full = os.path.normpath(bpy.path.abspath(image.filepath))
-
- # look for texture referencing this file
- for texture in bpy.data.textures:
- if texture.type == 'IMAGE':
- tex_img = texture.image
- if (tex_img is not None) and (tex_img.library is None):
- fn_tex_full = os.path.normpath(bpy.path.abspath(tex_img.filepath))
- if fn_full == fn_tex_full:
- if self.overwrite_material:
- self.apply_texture_options(texture, img_spec)
- return texture
-
- # if no texture is found: create one
- name_compat = bpy.path.display_name_from_filepath(image.filepath)
- texture = bpy.data.textures.new(name=name_compat, type='IMAGE')
- texture.image = image
- self.apply_texture_options(texture, img_spec)
- return texture
-
- def create_material_for_texture(self, texture):
- # look for material with the needed texture
- for material in bpy.data.materials:
- slot = material.texture_slots[0]
- if slot and slot.texture == texture:
- if self.overwrite_material:
- self.apply_material_options(material, slot)
- return material
-
- # if no material found: create one
- name_compat = bpy.path.display_name_from_filepath(texture.image.filepath)
- material = bpy.data.materials.new(name=name_compat)
- slot = material.texture_slots.add()
- slot.texture = texture
- slot.texture_coords = 'UV'
- self.apply_material_options(material, slot)
- return material
-
def apply_material_options(self, material, slot):
shader = self.shader
@@ -1034,7 +981,7 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
material.emit = self.emit_strength if shader == 'EMISSION' else 0.0
# -------------------------------------------------------------------------
- # Cycles
+ # Cycles/Eevee
def create_cycles_texnode(self, context, node_tree, img_spec):
tex_image = node_tree.nodes.new('ShaderNodeTexImage')
tex_image.image = img_spec.image
@@ -1092,14 +1039,13 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
# Create new mesh
bpy.ops.mesh.primitive_plane_add('INVOKE_REGION_WIN')
- plane = context.scene.objects.active
+ plane = context.active_object
# Why does mesh.primitive_plane_add leave the object in edit mode???
if plane.mode is not 'OBJECT':
bpy.ops.object.mode_set(mode='OBJECT')
plane.dimensions = width, height, 0.0
plane.data.name = plane.name = name
bpy.ops.object.transform_apply(scale=True)
- plane.data.uv_textures.new()
# If sizing for camera, also insert into the camera's field of view
if self.size_mode == 'CAMERA':
@@ -1148,7 +1094,7 @@ class IMPORT_IMAGE_OT_to_plane(Operator, AddObjectHelper):
camera = context.scene.camera
if (camera):
# Find the axis that best corresponds to the camera's view direction
- axis = camera.matrix_world * \
+ axis = camera.matrix_world @ \
Vector((0, 0, 1)) - camera.matrix_world.col[3].xyz
# pick the axis with the greatest magnitude
mag = max(map(abs, axis))
@@ -1213,16 +1159,16 @@ def register():
for cls in classes:
bpy.utils.register_class(cls)
- bpy.types.INFO_MT_file_import.append(import_images_button)
- bpy.types.INFO_MT_mesh_add.append(import_images_button)
+ bpy.types.TOPBAR_MT_file_import.append(import_images_button)
+ bpy.types.VIEW3D_MT_mesh_add.append(import_images_button)
bpy.app.handlers.load_post.append(register_driver)
register_driver()
def unregister():
- bpy.types.INFO_MT_file_import.remove(import_images_button)
- bpy.types.INFO_MT_mesh_add.remove(import_images_button)
+ bpy.types.TOPBAR_MT_file_import.remove(import_images_button)
+ bpy.types.VIEW3D_MT_mesh_add.remove(import_images_button)
# This will only exist if drivers are active
if check_drivers in bpy.app.handlers.scene_update_post:
diff --git a/io_import_scene_lwo.py b/io_import_scene_lwo.py
index 3cfe207c..be5f55aa 100644
--- a/io_import_scene_lwo.py
+++ b/io_import_scene_lwo.py
@@ -1251,13 +1251,13 @@ def menu_func(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_import.append(menu_func)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_import.remove(menu_func)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func)
if __name__ == "__main__":
register()
diff --git a/io_import_scene_unreal_psa_psk.py b/io_import_scene_unreal_psa_psk.py
index 5fb0c8f6..461cd05d 100644
--- a/io_import_scene_unreal_psa_psk.py
+++ b/io_import_scene_unreal_psa_psk.py
@@ -1275,11 +1275,11 @@ def menu_func(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_import.append(menu_func)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_import.remove(menu_func)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func)
if __name__ == "__main__":
register()
diff --git a/io_mesh_pdb/__init__.py b/io_mesh_pdb/__init__.py
index 1355d73b..4e731cf5 100644
--- a/io_mesh_pdb/__init__.py
+++ b/io_mesh_pdb/__init__.py
@@ -82,7 +82,7 @@ class ImportPDB(Operator, ImportHelper):
use_camera = BoolProperty(
name="Camera", default=False,
description="Do you need a camera?")
- use_lamp = BoolProperty(
+ use_light = BoolProperty(
name="Lamp", default=False,
description = "Do you need a lamp?")
ball = EnumProperty(
@@ -162,7 +162,7 @@ class ImportPDB(Operator, ImportHelper):
layout = self.layout
row = layout.row()
row.prop(self, "use_camera")
- row.prop(self, "use_lamp")
+ row.prop(self, "use_light")
row = layout.row()
row.prop(self, "use_center")
# Balls
@@ -256,7 +256,7 @@ class ImportPDB(Operator, ImportHelper):
self.sticks_radius,
self.use_center,
self.use_camera,
- self.use_lamp,
+ self.use_light,
filepath_pdb)
return {'FINISHED'}
@@ -301,13 +301,13 @@ def menu_func_export(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_import.append(menu_func_import)
- bpy.types.INFO_MT_file_export.append(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_import.remove(menu_func_import)
- bpy.types.INFO_MT_file_export.remove(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
diff --git a/io_mesh_pdb/import_pdb.py b/io_mesh_pdb/import_pdb.py
index a7067692..8256d108 100644
--- a/io_mesh_pdb/import_pdb.py
+++ b/io_mesh_pdb/import_pdb.py
@@ -536,7 +536,7 @@ def build_stick(radius, length, sectors):
# Function, which puts a camera and light source into the 3D scene
def camera_light_source(use_camera,
- use_lamp,
+ use_light,
object_center_vec,
object_size):
@@ -592,27 +592,27 @@ def camera_light_source(use_camera,
release_confirm=False)
# Here a lamp is put into the scene, if chosen.
- if use_lamp == True:
+ if use_light == True:
# This is the distance from the object measured in terms of %
# of the camera distance. It is set onto 50% (1/2) distance.
- lamp_dl = sqrt(object_size) * 15 * 0.5
+ light_dl = sqrt(object_size) * 15 * 0.5
# This is a factor to which extend the lamp shall go to the right
# (from the camera point of view).
- lamp_dy_right = lamp_dl * (3.0/4.0)
+ light_dy_right = light_dl * (3.0/4.0)
# Create x, y and z for the lamp.
- object_lamp_vec = Vector((lamp_dl,lamp_dy_right,lamp_dl))
- lamp_xyz_vec = object_center_vec + object_lamp_vec
+ object_light_vec = Vector((light_dl,light_dy_right,light_dl))
+ light_xyz_vec = object_center_vec + object_light_vec
# Create the lamp
current_layers=bpy.context.scene.layers
- lamp_data = bpy.data.lamps.new(name="A_lamp", type="POINT")
- lamp_data.distance = 500.0
- lamp_data.energy = 3.0
- lamp_data.shadow_method = 'RAY_SHADOW'
- lamp = bpy.data.objects.new("A_lamp", lamp_data)
- lamp.location = lamp_xyz_vec
+ light_data = bpy.data.lights.new(name="A_light", type="POINT")
+ light_data.distance = 500.0
+ light_data.energy = 3.0
+ light_data.shadow_method = 'RAY_SHADOW'
+ lamp = bpy.data.objects.new("A_light", light_data)
+ lamp.location = light_xyz_vec
lamp.layers = current_layers
bpy.context.scene.objects.link(lamp)
@@ -1145,7 +1145,7 @@ def import_pdb(Ball_type,
Stick_diameter,
put_to_center,
use_camera,
- use_lamp,
+ use_light,
filepath_pdb):
@@ -1376,7 +1376,7 @@ def import_pdb(Ball_type,
# CAMERA and LIGHT SOURCES
camera_light_source(use_camera,
- use_lamp,
+ use_light,
object_center_vec,
object_size)
diff --git a/io_mesh_ply/__init__.py b/io_mesh_ply/__init__.py
index 6764dcb4..30051796 100644
--- a/io_mesh_ply/__init__.py
+++ b/io_mesh_ply/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Stanford PLY format",
"author": "Bruce Merry, Campbell Barton",
"version": (1, 0, 0),
- "blender": (2, 74, 0),
+ "blender": (2, 80, 0),
"location": "File > Import-Export",
"description": "Import-Export PLY mesh data with UV's and vertex colors",
"warning": "",
@@ -56,29 +56,26 @@ from bpy.props import (
from bpy_extras.io_utils import (
ImportHelper,
ExportHelper,
- orientation_helper_factory,
axis_conversion,
+ orientation_helper
)
-IOPLYOrientationHelper = orientation_helper_factory("IOPLYOrientationHelper", axis_forward='Y', axis_up='Z')
-
-
class ImportPLY(bpy.types.Operator, ImportHelper):
"""Load a PLY geometry file"""
bl_idname = "import_mesh.ply"
bl_label = "Import PLY"
bl_options = {'UNDO'}
- files = CollectionProperty(name="File Path",
+ files: CollectionProperty(name="File Path",
description="File path used for importing "
"the PLY file",
type=bpy.types.OperatorFileListElement)
- directory = StringProperty()
+ directory: StringProperty()
filename_ext = ".ply"
- filter_glob = StringProperty(default="*.ply", options={'HIDDEN'})
+ filter_glob: StringProperty(default="*.ply", options={'HIDDEN'})
def execute(self, context):
paths = [os.path.join(self.directory, name.name)
@@ -94,21 +91,22 @@ class ImportPLY(bpy.types.Operator, ImportHelper):
return {'FINISHED'}
-class ExportPLY(bpy.types.Operator, ExportHelper, IOPLYOrientationHelper):
+@orientation_helper(axis_forward='Y', axis_up='Z')
+class ExportPLY(bpy.types.Operator, ExportHelper):
"""Export a single object as a Stanford PLY with normals, """ \
"""colors and texture coordinates"""
bl_idname = "export_mesh.ply"
bl_label = "Export PLY"
filename_ext = ".ply"
- filter_glob = StringProperty(default="*.ply", options={'HIDDEN'})
+ filter_glob: StringProperty(default="*.ply", options={'HIDDEN'})
- use_mesh_modifiers = BoolProperty(
+ use_mesh_modifiers: BoolProperty(
name="Apply Modifiers",
description="Apply Modifiers to the exported mesh",
default=True,
)
- use_normals = BoolProperty(
+ use_normals: BoolProperty(
name="Normals",
description="Export Normals for smooth and "
"hard shaded faces "
@@ -116,18 +114,18 @@ class ExportPLY(bpy.types.Operator, ExportHelper, IOPLYOrientationHelper):
"as individual faces)",
default=True,
)
- use_uv_coords = BoolProperty(
+ use_uv_coords: BoolProperty(
name="UVs",
description="Export the active UV layer",
default=True,
)
- use_colors = BoolProperty(
+ use_colors: BoolProperty(
name="Vertex Colors",
description="Export the active vertex color layer",
default=True,
)
- global_scale = FloatProperty(
+ global_scale: FloatProperty(
name="Scale",
min=0.01, max=1000.0,
default=1.0,
@@ -150,7 +148,7 @@ class ExportPLY(bpy.types.Operator, ExportHelper, IOPLYOrientationHelper):
))
global_matrix = axis_conversion(to_forward=self.axis_forward,
to_up=self.axis_up,
- ).to_4x4() * Matrix.Scale(self.global_scale, 4)
+ ).to_4x4() @ Matrix.Scale(self.global_scale, 4)
keywords["global_matrix"] = global_matrix
filepath = self.filepath
@@ -191,16 +189,16 @@ def register():
for cls in classes:
bpy.utils.register_class(cls)
- bpy.types.INFO_MT_file_import.append(menu_func_import)
- bpy.types.INFO_MT_file_export.append(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
- bpy.types.INFO_MT_file_import.remove(menu_func_import)
- bpy.types.INFO_MT_file_export.remove(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
diff --git a/io_mesh_ply/export_ply.py b/io_mesh_ply/export_ply.py
index 8de5d674..b50b6544 100644
--- a/io_mesh_ply/export_ply.py
+++ b/io_mesh_ply/export_ply.py
@@ -44,12 +44,12 @@ def save_mesh(filepath,
file = open(filepath, "w", encoding="utf8", newline="\n")
fw = file.write
- # Be sure tessface & co are available!
- if not mesh.tessfaces and mesh.polygons:
- mesh.calc_tessface()
+ # Be sure tessellated loop trianlges are available!
+ if not mesh.loop_triangles and mesh.polygons:
+ mesh.calc_loop_triangles()
- has_uv = bool(mesh.tessface_uv_textures)
- has_vcol = bool(mesh.tessface_vertex_colors)
+ has_uv = bool(mesh.uv_layers)
+ has_vcol = bool(mesh.vertex_colors)
if not has_uv:
use_uv_coords = False
@@ -62,7 +62,7 @@ def save_mesh(filepath,
has_vcol = False
if has_uv:
- active_uv_layer = mesh.tessface_uv_textures.active
+ active_uv_layer = mesh.uv_layers.active
if not active_uv_layer:
use_uv_coords = False
has_uv = False
@@ -70,7 +70,7 @@ def save_mesh(filepath,
active_uv_layer = active_uv_layer.data
if has_vcol:
- active_col_layer = mesh.tessface_vertex_colors.active
+ active_col_layer = mesh.vertex_colors.active
if not active_col_layer:
use_colors = False
has_vcol = False
@@ -84,9 +84,9 @@ def save_mesh(filepath,
ply_verts = [] # list of dictionaries
# vdict = {} # (index, normal, uv) -> new index
vdict = [{} for i in range(len(mesh_verts))]
- ply_faces = [[] for f in range(len(mesh.tessfaces))]
+ ply_faces = [[] for f in range(len(mesh.loop_triangles))]
vert_count = 0
- for i, f in enumerate(mesh.tessfaces):
+ for i, f in enumerate(mesh.loop_triangles):
smooth = not use_normals or f.use_smooth
if not smooth:
@@ -94,16 +94,12 @@ def save_mesh(filepath,
normal_key = rvec3d(normal)
if has_uv:
- uv = active_uv_layer[i]
- uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4
+ uv = [active_uv_layer[l].uv[:] for l in f.loops]
if has_vcol:
- col = active_col_layer[i]
- col = col.color1[:], col.color2[:], col.color3[:], col.color4[:]
-
- f_verts = f.vertices
+ col = [active_col_layer[l].color[:] for l in f.loops]
pf = ply_faces[i]
- for j, vidx in enumerate(f_verts):
+ for j, vidx in enumerate(f.vertices):
v = mesh_verts[vidx]
if smooth:
@@ -119,6 +115,7 @@ def save_mesh(filepath,
color = (int(color[0] * 255.0),
int(color[1] * 255.0),
int(color[2] * 255.0),
+ 255
)
key = normal_key, uvcoord_key, color
@@ -157,7 +154,7 @@ def save_mesh(filepath,
"property uchar blue\n"
"property uchar alpha\n")
- fw("element face %d\n" % len(mesh.tessfaces))
+ fw("element face %d\n" % len(mesh.loop_triangles))
fw("property list uchar uint vertex_indices\n")
fw("end_header\n")
@@ -193,7 +190,6 @@ def save(operator,
global_matrix=None
):
- scene = context.scene
obj = context.active_object
if global_matrix is None:
@@ -204,14 +200,15 @@ def save(operator,
bpy.ops.object.mode_set(mode='OBJECT')
if use_mesh_modifiers and obj.modifiers:
- mesh = obj.to_mesh(scene, True, 'PREVIEW')
+ mesh = obj.to_mesh(context.depsgraph, True)
+
else:
mesh = obj.data.copy()
if not mesh:
raise Exception("Error, could not get mesh data from active object")
- mesh.transform(global_matrix * obj.matrix_world)
+ mesh.transform(global_matrix @ obj.matrix_world)
if use_normals:
mesh.calc_normals()
@@ -221,7 +218,6 @@ def save(operator,
use_colors=use_colors,
)
- if use_mesh_modifiers:
- bpy.data.meshes.remove(mesh)
+ bpy.data.meshes.remove(mesh)
return ret
diff --git a/io_mesh_ply/import_ply.py b/io_mesh_ply/import_ply.py
index 86fc2e1b..f05e1caa 100644
--- a/io_mesh_ply/import_ply.py
+++ b/io_mesh_ply/import_ply.py
@@ -176,6 +176,7 @@ def read(filepath):
else:
texture = tokens[2]
continue
+
elif tokens[0] == b'obj_info':
continue
elif tokens[0] == b'format':
@@ -222,9 +223,9 @@ import bpy
def load_ply_mesh(filepath, ply_name):
from bpy_extras.io_utils import unpack_face_list
- # from bpy_extras.image_utils import load_image # UNUSED
obj_spec, obj, texture = read(filepath)
+ # XXX28: use texture
if obj is None:
print('Invalid file')
return
@@ -262,9 +263,9 @@ def load_ply_mesh(filepath, ply_name):
def add_face(vertices, indices, uvindices, colindices):
mesh_faces.append(indices)
if uvindices:
- mesh_uvs.append([(vertices[index][uvindices[0]], vertices[index][uvindices[1]]) for index in indices])
+ mesh_uvs.extend([(vertices[index][uvindices[0]], vertices[index][uvindices[1]]) for index in indices])
if colindices:
- mesh_colors.append([(vertices[index][colindices[0]] * colmultiply[0],
+ mesh_colors.extend([(vertices[index][colindices[0]] * colmultiply[0],
vertices[index][colindices[1]] * colmultiply[1],
vertices[index][colindices[2]] * colmultiply[2],
vertices[index][colindices[3]] * colmultiply[3],
@@ -316,41 +317,45 @@ def load_ply_mesh(filepath, ply_name):
mesh.edges.foreach_set("vertices", [a for e in obj[b'edge'] for a in (e[eindex1], e[eindex2])])
if mesh_faces:
- mesh.tessfaces.add(len(mesh_faces))
- mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(mesh_faces))
-
- if uvindices or colindices:
- if uvindices:
- uvlay = mesh.tessface_uv_textures.new()
- if colindices:
- vcol_lay = mesh.tessface_vertex_colors.new()
-
- if uvindices:
- for i, f in enumerate(uvlay.data):
- ply_uv = mesh_uvs[i]
- for j, uv in enumerate(f.uv):
- uv[0], uv[1] = ply_uv[j]
-
- if colindices:
- for i, f in enumerate(vcol_lay.data):
- # XXX, colors dont come in right, needs further investigation.
- ply_col = mesh_colors[i]
- if len(ply_col) == 4:
- f_col = f.color1, f.color2, f.color3, f.color4
- else:
- f_col = f.color1, f.color2, f.color3
+ loops_vert_idx = []
+ faces_loop_start = []
+ faces_loop_total = []
+ lidx = 0
+ for f in mesh_faces:
+ nbr_vidx = len(f)
+ loops_vert_idx.extend(f)
+ faces_loop_start.append(lidx)
+ faces_loop_total.append(nbr_vidx)
+ lidx += nbr_vidx
+
+ mesh.loops.add(len(loops_vert_idx))
+ mesh.polygons.add(len(mesh_faces))
+
+ mesh.loops.foreach_set("vertex_index", loops_vert_idx)
+ mesh.polygons.foreach_set("loop_start", faces_loop_start)
+ mesh.polygons.foreach_set("loop_total", faces_loop_total)
+
+ if uvindices:
+ uv_layer = mesh.uv_layers.new()
+ for i, uv in enumerate(uv_layer.data):
+ uv.uv = mesh_uvs[i]
- for j, col in enumerate(f_col):
- col[0] = ply_col[j][0]
- col[1] = ply_col[j][1]
- col[2] = ply_col[j][2]
- col[3] = ply_col[j][3]
+ if colindices:
+ vcol_lay = mesh.vertex_colors.new()
+
+ for i, col in enumerate(vcol_lay.data):
+ col.color[0] = mesh_colors[i][0]
+ col.color[1] = mesh_colors[i][1]
+ col.color[2] = mesh_colors[i][2]
+ col.color[3] = mesh_colors[i][3]
- mesh.validate()
mesh.update()
+ mesh.validate()
if texture and uvindices:
-
+ pass
+ # XXX28: add support for using texture.
+ '''
import os
import sys
from bpy_extras.image_utils import load_image
@@ -375,6 +380,7 @@ def load_ply_mesh(filepath, ply_name):
mesh.materials.append(material)
for face in mesh.uv_textures[0].data:
face.image = image
+ '''
return mesh
@@ -389,12 +395,10 @@ def load_ply(filepath):
if not mesh:
return {'CANCELLED'}
- scn = bpy.context.scene
-
obj = bpy.data.objects.new(ply_name, mesh)
- scn.objects.link(obj)
- scn.objects.active = obj
- obj.select = True
+ bpy.context.collection.objects.link(obj)
+ bpy.context.view_layer.objects.active = obj
+ obj.select_set("SELECT")
print('\nSuccessfully imported %r in %.3f sec' % (filepath, time.time() - t))
return {'FINISHED'}
diff --git a/io_mesh_raw/__init__.py b/io_mesh_raw/__init__.py
index 69640932..5ad4c6f5 100644
--- a/io_mesh_raw/__init__.py
+++ b/io_mesh_raw/__init__.py
@@ -107,15 +107,15 @@ def menu_export(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_import.append(menu_import)
- bpy.types.INFO_MT_file_export.append(menu_export)
+ bpy.types.TOPBAR_MT_file_import.append(menu_import)
+ bpy.types.TOPBAR_MT_file_export.append(menu_export)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_import.remove(menu_import)
- bpy.types.INFO_MT_file_export.remove(menu_export)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_import)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_export)
if __name__ == "__main__":
register()
diff --git a/io_mesh_stl/__init__.py b/io_mesh_stl/__init__.py
index fc8bced2..6859627c 100644
--- a/io_mesh_stl/__init__.py
+++ b/io_mesh_stl/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "STL format",
"author": "Guillaume Bouchard (Guillaum)",
"version": (1, 1, 2),
- "blender": (2, 74, 0),
+ "blender": (2, 80, 0),
"location": "File > Import-Export > Stl",
"description": "Import-Export STL files",
"warning": "",
@@ -67,7 +67,7 @@ from bpy.props import (
from bpy_extras.io_utils import (
ImportHelper,
ExportHelper,
- orientation_helper_factory,
+ orientation_helper,
axis_conversion,
)
from bpy.types import (
@@ -76,10 +76,8 @@ from bpy.types import (
)
-IOSTLOrientationHelper = orientation_helper_factory("IOSTLOrientationHelper", axis_forward='Y', axis_up='Z')
-
-
-class ImportSTL(Operator, ImportHelper, IOSTLOrientationHelper):
+@orientation_helper(axis_forward='Y', axis_up='Z')
+class ImportSTL(Operator, ImportHelper):
"""Load STL triangle mesh data"""
bl_idname = "import_mesh.stl"
bl_label = "Import STL"
@@ -87,32 +85,32 @@ class ImportSTL(Operator, ImportHelper, IOSTLOrientationHelper):
filename_ext = ".stl"
- filter_glob = StringProperty(
+ filter_glob: StringProperty(
default="*.stl",
options={'HIDDEN'},
)
- files = CollectionProperty(
+ files: CollectionProperty(
name="File Path",
type=OperatorFileListElement,
)
- directory = StringProperty(
+ directory: StringProperty(
subtype='DIR_PATH',
)
- global_scale = FloatProperty(
+ global_scale: FloatProperty(
name="Scale",
soft_min=0.001, soft_max=1000.0,
min=1e-6, max=1e6,
default=1.0,
)
- use_scene_unit = BoolProperty(
+ use_scene_unit: BoolProperty(
name="Scene Unit",
description="Apply current scene's unit (as defined by unit scale) to imported data",
default=False,
)
- use_facet_normal = BoolProperty(
+ use_facet_normal: BoolProperty(
name="Facet Normals",
description="Use (import) facet normals (note that this will still give flat shading)",
default=False,
@@ -135,7 +133,7 @@ class ImportSTL(Operator, ImportHelper, IOSTLOrientationHelper):
global_matrix = axis_conversion(from_forward=self.axis_forward,
from_up=self.axis_up,
- ).to_4x4() * Matrix.Scale(global_scale, 4)
+ ).to_4x4() @ Matrix.Scale(global_scale, 4)
if not paths:
paths.append(self.filepath)
@@ -155,41 +153,42 @@ class ImportSTL(Operator, ImportHelper, IOSTLOrientationHelper):
return {'FINISHED'}
-class ExportSTL(Operator, ExportHelper, IOSTLOrientationHelper):
+@orientation_helper(axis_forward='Y', axis_up='Z')
+class ExportSTL(Operator, ExportHelper):
"""Save STL triangle mesh data from the active object"""
bl_idname = "export_mesh.stl"
bl_label = "Export STL"
filename_ext = ".stl"
- filter_glob = StringProperty(default="*.stl", options={'HIDDEN'})
+ filter_glob: StringProperty(default="*.stl", options={'HIDDEN'})
- use_selection = BoolProperty(
+ use_selection: BoolProperty(
name="Selection Only",
description="Export selected objects only",
default=False,
)
- global_scale = FloatProperty(
+ global_scale: FloatProperty(
name="Scale",
min=0.01, max=1000.0,
default=1.0,
)
- use_scene_unit = BoolProperty(
+ use_scene_unit: BoolProperty(
name="Scene Unit",
description="Apply current scene's unit (as defined by unit scale) to exported data",
default=False,
)
- ascii = BoolProperty(
+ ascii: BoolProperty(
name="Ascii",
description="Save the file in ASCII file format",
default=False,
)
- use_mesh_modifiers = BoolProperty(
+ use_mesh_modifiers: BoolProperty(
name="Apply Modifiers",
description="Apply the modifiers before saving",
default=True,
)
- batch_mode = EnumProperty(
+ batch_mode: EnumProperty(
name="Batch Mode",
items=(('OFF', "Off", "All data in one file"),
('OBJECT', "Object", "Each object as a file"),
@@ -228,7 +227,7 @@ class ExportSTL(Operator, ExportHelper, IOSTLOrientationHelper):
global_matrix = axis_conversion(to_forward=self.axis_forward,
to_up=self.axis_up,
- ).to_4x4() * Matrix.Scale(global_scale, 4)
+ ).to_4x4() @ Matrix.Scale(global_scale, 4)
if self.batch_mode == 'OFF':
faces = itertools.chain.from_iterable(
@@ -252,22 +251,28 @@ def menu_import(self, context):
def menu_export(self, context):
- default_path = os.path.splitext(bpy.data.filepath)[0] + ".stl"
self.layout.operator(ExportSTL.bl_idname, text="Stl (.stl)")
+classes = (
+ ImportSTL,
+ ExportSTL
+)
+
def register():
- bpy.utils.register_module(__name__)
+ for cls in classes:
+ bpy.utils.register_class(cls)
- bpy.types.INFO_MT_file_import.append(menu_import)
- bpy.types.INFO_MT_file_export.append(menu_export)
+ bpy.types.TOPBAR_MT_file_import.append(menu_import)
+ bpy.types.TOPBAR_MT_file_export.append(menu_export)
def unregister():
- bpy.utils.unregister_module(__name__)
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
- bpy.types.INFO_MT_file_import.remove(menu_import)
- bpy.types.INFO_MT_file_export.remove(menu_export)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_import)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_export)
if __name__ == "__main__":
diff --git a/io_mesh_stl/blender_utils.py b/io_mesh_stl/blender_utils.py
index 864335ab..ee5cb098 100644
--- a/io_mesh_stl/blender_utils.py
+++ b/io_mesh_stl/blender_utils.py
@@ -57,15 +57,13 @@ def create_and_link_mesh(name, faces, face_nors, points, global_matrix):
mesh.update()
- scene = bpy.context.scene
-
obj = bpy.data.objects.new(name, mesh)
- scene.objects.link(obj)
- scene.objects.active = obj
- obj.select = True
+ bpy.context.collection.objects.link(obj)
+ bpy.context.view_layer.objects.active = obj
+ obj.select_set("SELECT")
-def faces_from_mesh(ob, global_matrix, use_mesh_modifiers=False, triangulate=True):
+def faces_from_mesh(ob, global_matrix, use_mesh_modifiers=False):
"""
From an object, return a generator over a list of faces.
@@ -84,34 +82,19 @@ def faces_from_mesh(ob, global_matrix, use_mesh_modifiers=False, triangulate=Tru
# get the modifiers
try:
- mesh = ob.to_mesh(bpy.context.scene, use_mesh_modifiers, "PREVIEW")
+ mesh = ob.to_mesh(bpy.context.depsgraph, use_mesh_modifiers)
except RuntimeError:
raise StopIteration
- mat = global_matrix * ob.matrix_world
+ mat = global_matrix @ ob.matrix_world
mesh.transform(mat)
if mat.is_negative:
mesh.flip_normals()
- mesh.calc_tessface()
-
- if triangulate:
- # From a list of faces, return the face triangulated if needed.
- def iter_face_index():
- for face in mesh.tessfaces:
- vertices = face.vertices[:]
- if len(vertices) == 4:
- yield vertices[0], vertices[1], vertices[2]
- yield vertices[2], vertices[3], vertices[0]
- else:
- yield vertices
- else:
- def iter_face_index():
- for face in mesh.tessfaces:
- yield face.vertices[:]
+ mesh.calc_loop_triangles()
vertices = mesh.vertices
- for indexes in iter_face_index():
- yield [vertices[index].co.copy() for index in indexes]
+ for tri in mesh.loop_triangles:
+ yield [vertices[index].co.copy() for index in tri.vertices]
bpy.data.meshes.remove(mesh)
diff --git a/io_mesh_uv_layout/__init__.py b/io_mesh_uv_layout/__init__.py
index 30dff949..bd2c97bd 100644
--- a/io_mesh_uv_layout/__init__.py
+++ b/io_mesh_uv_layout/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "UV Layout",
"author": "Campbell Barton, Matt Ebb",
"version": (1, 1, 1),
- "blender": (2, 75, 0),
+ "blender": (2, 80, 0),
"location": "Image-Window > UVs > Export UV Layout",
"description": "Export the UV layout as a 2D graphic",
"warning": "",
@@ -43,15 +43,16 @@ if "bpy" in locals():
if "export_uv_svg" in locals():
importlib.reload(export_uv_svg)
+import os
import bpy
from bpy.props import (
- StringProperty,
- BoolProperty,
- EnumProperty,
- IntVectorProperty,
- FloatProperty,
- )
+ StringProperty,
+ BoolProperty,
+ EnumProperty,
+ IntVectorProperty,
+ FloatProperty,
+)
class ExportUVLayout(bpy.types.Operator):
@@ -61,172 +62,171 @@ class ExportUVLayout(bpy.types.Operator):
bl_label = "Export UV Layout"
bl_options = {'REGISTER', 'UNDO'}
- filepath = StringProperty(
- subtype='FILE_PATH',
- )
- check_existing = BoolProperty(
- name="Check Existing",
- description="Check and warn on overwriting existing files",
- default=True,
- options={'HIDDEN'},
- )
- export_all = BoolProperty(
- name="All UVs",
- description="Export all UVs in this mesh (not just visible ones)",
- default=False,
- )
- modified = BoolProperty(
- name="Modified",
- description="Exports UVs from the modified mesh",
- default=False,
- )
- mode = EnumProperty(
- items=(('SVG', "Scalable Vector Graphic (.svg)",
- "Export the UV layout to a vector SVG file"),
- ('EPS', "Encapsulate PostScript (.eps)",
- "Export the UV layout to a vector EPS file"),
- ('PNG', "PNG Image (.png)",
- "Export the UV layout to a bitmap image"),
- ),
- name="Format",
- description="File format to export the UV layout to",
- default='PNG',
- )
- size = IntVectorProperty(
- size=2,
- default=(1024, 1024),
- min=8, max=32768,
- description="Dimensions of the exported file",
- )
- opacity = FloatProperty(
- name="Fill Opacity",
- min=0.0, max=1.0,
- default=0.25,
- description="Set amount of opacity for exported UV layout"
- )
- tessellated = BoolProperty(
- name="Tessellated UVs",
- description="Export tessellated UVs instead of polygons ones",
- default=False,
- options={'HIDDEN'}, # As not working currently :/
- )
+ filepath: StringProperty(
+ subtype='FILE_PATH',
+ )
+ export_all: BoolProperty(
+ name="All UVs",
+ description="Export all UVs in this mesh (not just visible ones)",
+ default=False,
+ )
+ modified: BoolProperty(
+ name="Modified",
+ description="Exports UVs from the modified mesh",
+ default=False,
+ )
+ mode: EnumProperty(
+ items=(
+ ('SVG', "Scalable Vector Graphic (.svg)",
+ "Export the UV layout to a vector SVG file"),
+ ('EPS', "Encapsulate PostScript (.eps)",
+ "Export the UV layout to a vector EPS file"),
+ ('PNG', "PNG Image (.png)",
+ "Export the UV layout to a bitmap image"),
+ ),
+ name="Format",
+ description="File format to export the UV layout to",
+ default='PNG',
+ )
+ size: IntVectorProperty(
+ size=2,
+ default=(1024, 1024),
+ min=8, max=32768,
+ description="Dimensions of the exported file",
+ )
+ opacity: FloatProperty(
+ name="Fill Opacity",
+ min=0.0, max=1.0,
+ default=0.25,
+ description="Set amount of opacity for exported UV layout",
+ )
@classmethod
def poll(cls, context):
obj = context.active_object
- return (obj and obj.type == 'MESH' and obj.data.uv_textures)
+ return obj is not None and obj.type == 'MESH' and obj.data.uv_layers
- def _space_image(self, context):
- space_data = context.space_data
- if isinstance(space_data, bpy.types.SpaceImageEditor):
- return space_data
- else:
- return None
-
- def _image_size(self, context, default_width=1024, default_height=1024):
- # fallback if not in image context.
- image_width, image_height = default_width, default_height
+ def invoke(self, context, event):
+ self.size = self.get_image_size(context)
+ self.filepath = self.get_default_file_name(context) + "." + self.mode.lower()
+ context.window_manager.fileselect_add(self)
+ return {'RUNNING_MODAL'}
- space_data = self._space_image(context)
- if space_data:
- image = space_data.image
- if image:
- width, height = tuple(context.space_data.image.size)
- # in case no data is found.
- if width and height:
- image_width, image_height = width, height
+ def get_default_file_name(self, context):
+ AMOUNT = 3
+ objects = list(self.iter_objects_to_export(context))
+ name = " ".join(sorted([obj.name for obj in objects[:AMOUNT]]))
+ if len(objects) > AMOUNT:
+ name += " and more"
+ return name
- return image_width, image_height
+ def check(self, context):
+ if any(self.filepath.endswith(ext) for ext in (".png", ".eps", ".svg")):
+ self.filepath = self.filepath[:-4]
- def _face_uv_iter(self, context, mesh, tessellated):
- uv_layer = mesh.uv_layers.active.data
- polys = mesh.polygons
-
- if not self.export_all:
- uv_tex = mesh.uv_textures.active.data
- local_image = Ellipsis
-
- if context.tool_settings.show_uv_local_view:
- space_data = self._space_image(context)
- if space_data:
- local_image = space_data.image
-
- for i, p in enumerate(polys):
- # context checks
- if polys[i].select and local_image in {Ellipsis,
- uv_tex[i].image}:
- start = p.loop_start
- end = start + p.loop_total
- uvs = tuple((uv.uv[0], uv.uv[1])
- for uv in uv_layer[start:end])
-
- # just write what we see.
- yield (i, uvs)
- else:
- # all, simple
- for i, p in enumerate(polys):
- start = p.loop_start
- end = start + p.loop_total
- uvs = tuple((uv.uv[0], uv.uv[1]) for uv in uv_layer[start:end])
- yield (i, uvs)
+ ext = "." + self.mode.lower()
+ self.filepath = bpy.path.ensure_ext(self.filepath, ext)
+ return True
def execute(self, context):
-
obj = context.active_object
is_editmode = (obj.mode == 'EDIT')
if is_editmode:
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
- mode = self.mode
-
filepath = self.filepath
- filepath = bpy.path.ensure_ext(filepath, "." + mode.lower())
- file = open(filepath, "w")
- fw = file.write
-
- if mode == 'EPS':
- from . import export_uv_eps
- func = export_uv_eps.write
- elif mode == 'PNG':
- from . import export_uv_png
- func = export_uv_png.write
- elif mode == 'SVG':
- from . import export_uv_svg
- func = export_uv_svg.write
+ filepath = bpy.path.ensure_ext(filepath, "." + self.mode.lower())
+ meshes = list(self.iter_meshes_to_export(context))
+ polygon_data = list(self.iter_polygon_data_to_draw(context, meshes))
+ different_colors = set(color for _, color in polygon_data)
if self.modified:
- mesh = obj.to_mesh(context.scene, True, 'PREVIEW')
- else:
- mesh = obj.data
+ self.free_meshes(meshes)
- func(fw, mesh, self.size[0], self.size[1], self.opacity,
- lambda: self._face_uv_iter(context, mesh, self.tessellated))
-
- if self.modified:
- bpy.data.meshes.remove(mesh)
+ export = self.get_exporter()
+ export(filepath, polygon_data, different_colors, self.size[0], self.size[1], self.opacity)
if is_editmode:
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
- file.close()
-
return {'FINISHED'}
- def check(self, context):
- filepath = bpy.path.ensure_ext(self.filepath, "." + self.mode.lower())
- if filepath != self.filepath:
- self.filepath = filepath
- return True
- else:
- return False
+ def iter_meshes_to_export(self, context):
+ for obj in self.iter_objects_to_export(context):
+ if self.modified:
+ yield obj.to_mesh(context.depsgraph, apply_modifiers=True)
+ else:
+ yield obj.data
+
+ @staticmethod
+ def iter_objects_to_export(context):
+ for obj in context.selected_objects:
+ if obj.type != 'MESH':
+ continue
+ mesh = obj.data
+ if mesh.uv_layers.active is None:
+ continue
+ yield obj
- def invoke(self, context, event):
- import os
- self.size = self._image_size(context)
- self.filepath = os.path.splitext(bpy.data.filepath)[0]
- wm = context.window_manager
- wm.fileselect_add(self)
- return {'RUNNING_MODAL'}
+ @staticmethod
+ def free_meshes(meshes):
+ for mesh in meshes:
+ bpy.data.meshes.remove(mesh)
+
+ @staticmethod
+ def currently_image_image_editor(context):
+ return isinstance(context.space_data, bpy.types.SpaceImageEditor)
+
+ def get_currently_opened_image(self, context):
+ if not self.currently_image_image_editor(context):
+ return None
+ return context.space_data.image
+
+ def get_image_size(self, context):
+ # fallback if not in image context
+ image_width = self.size[0]
+ image_height = self.size[1]
+
+ # get size of "active" image if some exist
+ image = self.get_currently_opened_image(context)
+ if image is not None:
+ width, height = image.size
+ if width and height:
+ image_width = width
+ image_height = height
+
+ return image_width, image_height
+
+ def iter_polygon_data_to_draw(self, context, meshes):
+ for mesh in meshes:
+ uv_layer = mesh.uv_layers.active.data
+ for polygon in mesh.polygons:
+ if self.export_all or polygon.select:
+ start = polygon.loop_start
+ end = start + polygon.loop_total
+ uvs = tuple(tuple(uv.uv) for uv in uv_layer[start:end])
+ yield (uvs, self.get_polygon_color(mesh, polygon))
+
+ @staticmethod
+ def get_polygon_color(mesh, polygon, default=(0.8, 0.8, 0.8)):
+ if polygon.material_index < len(mesh.materials):
+ material = mesh.materials[polygon.material_index]
+ if material is not None:
+ return tuple(material.diffuse_color)
+ return default
+
+ def get_exporter(self):
+ if self.mode == 'PNG':
+ from . import export_uv_png
+ return export_uv_png.export
+ elif self.mode == 'EPS':
+ from . import export_uv_eps
+ return export_uv_eps.export
+ elif self.mode == 'SVG':
+ from . import export_uv_svg
+ return export_uv_svg.export
+ else:
+ assert False
def menu_func(self, context):
@@ -234,13 +234,14 @@ def menu_func(self, context):
def register():
- bpy.utils.register_module(__name__)
+ bpy.utils.register_class(ExportUVLayout)
bpy.types.IMAGE_MT_uvs.append(menu_func)
def unregister():
- bpy.utils.unregister_module(__name__)
+ bpy.utils.unregister_class(ExportUVLayout)
bpy.types.IMAGE_MT_uvs.remove(menu_func)
+
if __name__ == "__main__":
register()
diff --git a/io_mesh_uv_layout/export_uv_eps.py b/io_mesh_uv_layout/export_uv_eps.py
index a15dc266..3280cefa 100644
--- a/io_mesh_uv_layout/export_uv_eps.py
+++ b/io_mesh_uv_layout/export_uv_eps.py
@@ -21,66 +21,72 @@
import bpy
-def write(fw, mesh, image_width, image_height, opacity, face_iter_func):
- fw("%!PS-Adobe-3.0 EPSF-3.0\n")
- fw("%%%%Creator: Blender %s\n" % bpy.app.version_string)
- fw("%%Pages: 1\n")
- fw("%%Orientation: Portrait\n")
- fw("%%%%BoundingBox: 0 0 %d %d\n" % (image_width, image_height))
- fw("%%%%HiResBoundingBox: 0.0 0.0 %.4f %.4f\n" %
- (image_width, image_height))
- fw("%%EndComments\n")
- fw("%%Page: 1 1\n")
- fw("0 0 translate\n")
- fw("1.0 1.0 scale\n")
- fw("0 0 0 setrgbcolor\n")
- fw("[] 0 setdash\n")
- fw("1 setlinewidth\n")
- fw("1 setlinejoin\n")
- fw("1 setlinecap\n")
-
- polys = mesh.polygons
+def export(filepath, face_data, colors, width, height, opacity):
+ with open(filepath, "w") as file:
+ for text in get_file_parts(face_data, colors, width, height, opacity):
+ file.write(text)
+def get_file_parts(face_data, colors, width, height, opacity):
+ yield from header(width, height)
if opacity > 0.0:
- for i, mat in enumerate(mesh.materials if mesh.materials else [None]):
- fw("/DRAW_%d {" % i)
- fw("gsave\n")
- if mat:
- color = tuple((1.0 - ((1.0 - c) * opacity))
- for c in mat.diffuse_color)
- else:
- color = 1.0, 1.0, 1.0
- fw("%.3g %.3g %.3g setrgbcolor\n" % color)
- fw("fill\n")
- fw("grestore\n")
- fw("0 setgray\n")
- fw("} def\n")
+ name_by_color = {}
+ yield from prepare_colors(colors, name_by_color)
+ yield from draw_colored_polygons(face_data, name_by_color, width, height)
+ yield from draw_lines(face_data, width, height)
+ yield from footer()
+
+
+def header(width, height):
+ yield "%!PS-Adobe-3.0 EPSF-3.0\n"
+ yield f"%%Creator: Blender {bpy.app.version_string}\n"
+ yield "%%Pages: 1\n"
+ yield "%%Orientation: Portrait\n"
+ yield f"%%BoundingBox: 0 0 {width} {height}\n"
+ yield f"%%HiResBoundingBox: 0.0 0.0 {width:.4f} {height:.4f}\n"
+ yield "%%EndComments\n"
+ yield "%%Page: 1 1\n"
+ yield "0 0 translate\n"
+ yield "1.0 1.0 scale\n"
+ yield "0 0 0 setrgbcolor\n"
+ yield "[] 0 setdash\n"
+ yield "1 setlinewidth\n"
+ yield "1 setlinejoin\n"
+ yield "1 setlinecap\n"
+
+def prepare_colors(colors, out_name_by_color):
+ for i, color in enumerate(colors):
+ name = f"COLOR_{i}"
+ yield "/%s {" % name
+ out_name_by_color[color] = name
- # fill
- for i, uvs in face_iter_func():
- fw("newpath\n")
- for j, uv in enumerate(uvs):
- uv_scale = (uv[0] * image_width, uv[1] * image_height)
- if j == 0:
- fw("%.5f %.5f moveto\n" % uv_scale)
- else:
- fw("%.5f %.5f lineto\n" % uv_scale)
+ yield "gsave\n"
+ yield "%.3g %.3g %.3g setrgbcolor\n" % color
+ yield "fill\n"
+ yield "grestore\n"
+ yield "0 setgray\n"
+ yield "} def\n"
- fw("closepath\n")
- fw("DRAW_%d\n" % polys[i].material_index)
+def draw_colored_polygons(face_data, name_by_color, width, height):
+ for uvs, color in face_data:
+ yield from draw_polygon_path(uvs, width, height)
+ yield "closepath\n"
+ yield "%s\n" % name_by_color[color]
- # stroke only
- for i, uvs in face_iter_func():
- fw("newpath\n")
- for j, uv in enumerate(uvs):
- uv_scale = (uv[0] * image_width, uv[1] * image_height)
- if j == 0:
- fw("%.5f %.5f moveto\n" % uv_scale)
- else:
- fw("%.5f %.5f lineto\n" % uv_scale)
+def draw_lines(face_data, width, height):
+ for uvs, _ in face_data:
+ yield from draw_polygon_path(uvs, width, height)
+ yield "closepath\n"
+ yield "stroke\n"
- fw("closepath\n")
- fw("stroke\n")
+def draw_polygon_path(uvs, width, height):
+ yield "newpath\n"
+ for j, uv in enumerate(uvs):
+ uv_scale = (uv[0] * width, uv[1] * height)
+ if j == 0:
+ yield "%.5f %.5f moveto\n" % uv_scale
+ else:
+ yield "%.5f %.5f lineto\n" % uv_scale
- fw("showpage\n")
- fw("%%EOF\n")
+def footer():
+ yield "showpage\n"
+ yield "%%EOF\n" \ No newline at end of file
diff --git a/io_mesh_uv_layout/export_uv_png.py b/io_mesh_uv_layout/export_uv_png.py
index b556c982..f23d516c 100644
--- a/io_mesh_uv_layout/export_uv_png.py
+++ b/io_mesh_uv_layout/export_uv_png.py
@@ -20,132 +20,134 @@
import bpy
+# maybe we could also just use the svg exporter, import it again
+# and render it. Unfortunately the svg importer does not work atm.
+def export(filepath, face_data, colors, width, height, opacity):
+ aspect = width / height
+
+ # curves for lines
+ lines = curve_from_uvs(face_data, aspect, 1 / min(width, height))
+ lines_object = bpy.data.objects.new("temp_lines_object", lines)
+ black_material = make_colored_material((0, 0, 0))
+ lines.materials.append(black_material)
+
+ # background mesh
+ background_mesh = background_mesh_from_uvs(face_data, colors, aspect, opacity)
+ background_object = bpy.data.objects.new("temp_background_object", background_mesh)
+ background_object.location = (0, 0, -1)
+
+ # camera
+ camera = bpy.data.cameras.new("temp_camera")
+ camera_object = bpy.data.objects.new("temp_camera_object", camera)
+ camera.type = "ORTHO"
+ camera.ortho_scale = max(1, aspect)
+ camera_object.location = (aspect / 2, 0.5, 1)
+ camera_object.rotation_euler = (0, 0, 0)
+
+ # scene
+ scene = bpy.data.scenes.new("temp_scene")
+ scene.render.engine = "BLENDER_EEVEE"
+ scene.render.resolution_x = width
+ scene.render.resolution_y = height
+ scene.render.image_settings.color_mode = "RGBA"
+ scene.render.alpha_mode = "TRANSPARENT"
+ scene.render.filepath = filepath
-def write(fw, mesh_source, image_width, image_height, opacity, face_iter_func):
- filepath = fw.__self__.name
- fw.__self__.close()
-
- material_solids = [bpy.data.materials.new("uv_temp_solid")
- for i in range(max(1, len(mesh_source.materials)))]
-
- material_wire = bpy.data.materials.new("uv_temp_wire")
-
- scene = bpy.data.scenes.new("uv_temp")
- mesh = bpy.data.meshes.new("uv_temp")
- for mat_solid in material_solids:
- mesh.materials.append(mat_solid)
+ # Link everything to the scene
+ scene.collection.objects.link(lines_object)
+ scene.collection.objects.link(camera_object)
+ scene.collection.objects.link(background_object)
+ scene.camera = camera_object
+
+ # Render
+ override = {"scene" : scene}
+ bpy.ops.render.render(override, write_still=True)
+
+ # Cleanup
+ bpy.data.objects.remove(lines_object)
+ bpy.data.objects.remove(camera_object)
+ bpy.data.objects.remove(background_object)
+
+ for material in background_mesh.materials:
+ bpy.data.materials.remove(material)
+ bpy.data.meshes.remove(background_mesh)
+
+ bpy.data.cameras.remove(camera)
+ bpy.data.curves.remove(lines)
+ bpy.data.materials.remove(black_material)
+ bpy.data.scenes.remove(scene)
+
+def curve_from_uvs(face_data, aspect, thickness):
+ lines = bpy.data.curves.new("temp_curve", "CURVE")
+ lines.fill_mode = "BOTH"
+ lines.bevel_depth = thickness
+ lines.offset = -thickness / 2
+ lines.dimensions = "3D"
+
+ for uvs, _ in face_data:
+ for i in range(len(uvs)):
+ start = uvs[i]
+ end = uvs[(i+1) % len(uvs)]
+
+ spline = lines.splines.new("POLY")
+ # one point is already there
+ spline.points.add(1)
+ points = spline.points
+
+ points[0].co.x = start[0] * aspect
+ points[0].co.y = start[1]
+
+ points[1].co.x = end[0] * aspect
+ points[1].co.y = end[1]
+
+ return lines
+
+def background_mesh_from_uvs(face_data, colors, aspect, opacity):
+ mesh = bpy.data.meshes.new("temp_background")
+
+ vertices = []
+ polygons = []
+ for uvs, _ in face_data:
+ polygon = []
+ for uv in uvs:
+ polygon.append(len(vertices))
+ vertices.append((uv[0] * aspect, uv[1], 0))
+ polygons.append(tuple(polygon))
- polys_source = mesh_source.polygons
+ mesh.from_pydata(vertices, [], polygons)
- # get unique UV's in case there are many overlapping
- # which slow down filling.
- face_hash = {(uvs, polys_source[i].material_index)
- for i, uvs in face_iter_func()}
+ materials, material_index_by_color = make_polygon_background_materials(colors, opacity)
+ for material in materials:
+ mesh.materials.append(material)
- # now set the faces coords and locations
- # build mesh data
- mesh_new_vertices = []
- mesh_new_materials = []
- mesh_new_polys_startloop = []
- mesh_new_polys_totloop = []
- mesh_new_loops_vertices = []
+ for generated_polygon, (_, color) in zip(mesh.polygons, face_data):
+ generated_polygon.material_index = material_index_by_color[color]
- current_vert = 0
+ mesh.update()
+ mesh.validate()
- for uvs, mat_idx in face_hash:
- num_verts = len(uvs)
- dummy = (0.0,) * num_verts
- for uv in uvs:
- mesh_new_vertices += (uv[0], uv[1], 0.0)
- mesh_new_polys_startloop.append(current_vert)
- mesh_new_polys_totloop.append(num_verts)
- mesh_new_loops_vertices += range(current_vert,
- current_vert + num_verts)
- mesh_new_materials.append(mat_idx)
- current_vert += num_verts
-
- mesh.vertices.add(current_vert)
- mesh.loops.add(current_vert)
- mesh.polygons.add(len(mesh_new_polys_startloop))
-
- mesh.vertices.foreach_set("co", mesh_new_vertices)
- mesh.loops.foreach_set("vertex_index", mesh_new_loops_vertices)
- mesh.polygons.foreach_set("loop_start", mesh_new_polys_startloop)
- mesh.polygons.foreach_set("loop_total", mesh_new_polys_totloop)
- mesh.polygons.foreach_set("material_index", mesh_new_materials)
-
- mesh.update(calc_edges=True)
-
- obj_solid = bpy.data.objects.new("uv_temp_solid", mesh)
- obj_wire = bpy.data.objects.new("uv_temp_wire", mesh)
- base_solid = scene.objects.link(obj_solid)
- base_wire = scene.objects.link(obj_wire)
- base_solid.layers[0] = True
- base_wire.layers[0] = True
-
- # place behind the wire
- obj_solid.location = 0, 0, -1
-
- obj_wire.material_slots[0].link = 'OBJECT'
- obj_wire.material_slots[0].material = material_wire
-
- # setup the camera
- cam = bpy.data.cameras.new("uv_temp")
- cam.type = 'ORTHO'
- cam.ortho_scale = 1.0
- obj_cam = bpy.data.objects.new("uv_temp_cam", cam)
- obj_cam.location = 0.5, 0.5, 1.0
- scene.objects.link(obj_cam)
- scene.camera = obj_cam
-
- # setup materials
- for i, mat_solid in enumerate(material_solids):
- if mesh_source.materials and mesh_source.materials[i]:
- mat_solid.diffuse_color = mesh_source.materials[i].diffuse_color
-
- mat_solid.use_shadeless = True
- mat_solid.use_transparency = True
- mat_solid.alpha = opacity
-
- material_wire.type = 'WIRE'
- material_wire.use_shadeless = True
- material_wire.diffuse_color = 0, 0, 0
- material_wire.use_transparency = True
-
- # scene render settings
- scene.render.use_raytrace = False
- scene.render.alpha_mode = 'TRANSPARENT'
- scene.render.image_settings.color_mode = 'RGBA'
-
- scene.render.resolution_x = image_width
- scene.render.resolution_y = image_height
- scene.render.resolution_percentage = 100
-
- if image_width > image_height:
- scene.render.pixel_aspect_y = image_width / image_height
- elif image_width < image_height:
- scene.render.pixel_aspect_x = image_height / image_width
-
- scene.frame_start = 1
- scene.frame_end = 1
-
- scene.render.image_settings.file_format = 'PNG'
- scene.render.filepath = filepath
+ return mesh
- scene.update()
+def make_polygon_background_materials(colors, opacity=1):
+ materials = []
+ material_index_by_color = {}
+ for i, color in enumerate(colors):
+ material = make_colored_material(color, opacity)
+ materials.append(material)
+ material_index_by_color[color] = i
+ return materials, material_index_by_color
- data_context = {"blend_data": bpy.context.blend_data, "scene": scene}
- bpy.ops.render.render(data_context, write_still=True)
+def make_colored_material(color, opacity=1):
+ material = bpy.data.materials.new("temp_material")
+ material.use_nodes = True
+ material.blend_method = "BLEND"
+ tree = material.node_tree
+ tree.nodes.clear()
- # cleanup
- bpy.data.scenes.remove(scene, do_unlink=True)
- bpy.data.objects.remove(obj_cam, do_unlink=True)
- bpy.data.objects.remove(obj_solid, do_unlink=True)
- bpy.data.objects.remove(obj_wire, do_unlink=True)
+ output_node = tree.nodes.new("ShaderNodeOutputMaterial")
+ emission_node = tree.nodes.new("ShaderNodeEmission")
- bpy.data.cameras.remove(cam, do_unlink=True)
- bpy.data.meshes.remove(mesh, do_unlink=True)
+ emission_node.inputs["Color"].default_value = [color[0], color[1], color[2], opacity]
+ tree.links.new(emission_node.outputs["Emission"], output_node.inputs["Surface"])
- bpy.data.materials.remove(material_wire, do_unlink=True)
- for mat_solid in material_solids:
- bpy.data.materials.remove(mat_solid, do_unlink=True)
+ return material
diff --git a/io_mesh_uv_layout/export_uv_svg.py b/io_mesh_uv_layout/export_uv_svg.py
index 764f0d34..d00f9402 100644
--- a/io_mesh_uv_layout/export_uv_svg.py
+++ b/io_mesh_uv_layout/export_uv_svg.py
@@ -19,50 +19,46 @@
# <pep8-80 compliant>
import bpy
+from os.path import basename
+from xml.sax.saxutils import escape
+def export(filepath, face_data, colors, width, height, opacity):
+ with open(filepath, "w") as file:
+ for text in get_file_parts(face_data, colors, width, height, opacity):
+ file.write(text)
-def write(fw, mesh, image_width, image_height, opacity, face_iter_func):
- # for making an XML compatible string
- from xml.sax.saxutils import escape
- from os.path import basename
+def get_file_parts(face_data, colors, width, height, opacity):
+ yield from header(width, height)
+ yield from draw_polygons(face_data, width, height, opacity)
+ yield from footer()
- fw('<?xml version="1.0" standalone="no"?>\n')
- fw('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" \n')
- fw(' "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')
- fw('<svg width="%d" height="%d" viewBox="0 0 %d %d"\n' %
- (image_width, image_height, image_width, image_height))
- fw(' xmlns="http://www.w3.org/2000/svg" version="1.1">\n')
- desc = ("%r, %s, (Blender %s)" %
- (basename(bpy.data.filepath), mesh.name, bpy.app.version_string))
- fw('<desc>%s</desc>\n' % escape(desc))
+def header(width, height):
+ yield '<?xml version="1.0" standalone="no"?>\n'
+ yield '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" \n'
+ yield ' "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n'
+ yield f'<svg width="{width}" height="{height}" viewBox="0 0 {width} {height}"\n'
+ yield ' xmlns="http://www.w3.org/2000/svg" version="1.1">\n'
+ desc = f"{basename(bpy.data.filepath)}, (Blender {bpy.app.version_string})"
+ yield f'<desc>{escape(desc)}</desc>\n'
- # svg colors
- fill_settings = []
- fill_default = 'fill="grey"'
- for mat in mesh.materials if mesh.materials else [None]:
- if mat:
- fill_settings.append('fill="rgb(%d, %d, %d)"' %
- tuple(int(c * 255)
- for c in mat.diffuse_color))
- else:
- fill_settings.append(fill_default)
+def draw_polygons(face_data, width, height, opacity):
+ for uvs, color in face_data:
+ fill = f'fill="{get_color_string(color)}"'
- polys = mesh.polygons
- for i, uvs in face_iter_func():
- try: # rare cases material index is invalid.
- fill = fill_settings[polys[i].material_index]
- except IndexError:
- fill = fill_default
+ yield '<polygon stroke="black" stroke-width="1"'
+ yield f' {fill} fill-opacity="{opacity:.2g}"'
- fw('<polygon stroke="black" stroke-width="1"')
- if opacity > 0.0:
- fw(' %s fill-opacity="%.2g"' % (fill, opacity))
+ yield ' points="'
- fw(' points="')
-
- for j, uv in enumerate(uvs):
+ for uv in uvs:
x, y = uv[0], 1.0 - uv[1]
- fw('%.3f,%.3f ' % (x * image_width, y * image_height))
- fw('" />\n')
- fw('\n')
- fw('</svg>\n')
+ yield f'{x*width:.3f},{y*height:.3f} '
+ yield '" />\n'
+
+def get_color_string(color):
+ r, g, b = color
+ return f"rgb({round(r*255)}, {round(g*255)}, {round(b*255)})"
+
+def footer():
+ yield '\n'
+ yield '</svg>\n' \ No newline at end of file
diff --git a/io_online_sketchfab/__init__.py b/io_online_sketchfab/__init__.py
index ba73bd19..2205f497 100644
--- a/io_online_sketchfab/__init__.py
+++ b/io_online_sketchfab/__init__.py
@@ -247,7 +247,7 @@ class ExportSketchfab(Operator):
with open(SKETCHFAB_EXPORT_DATA_FILE, 'w') as s:
json.dump({
"models": props.models,
- "lamps": props.lamps,
+ "lights": props.lights,
}, s)
subprocess.check_call([
@@ -311,7 +311,7 @@ class VIEW3D_PT_sketchfab(Panel):
layout.label("Export:")
col = layout.box().column(align=True)
col.prop(props, "models")
- col.prop(props, "lamps")
+ col.prop(props, "lights")
layout.label("Model info:")
col = layout.box().column(align=True)
diff --git a/io_online_sketchfab/pack_for_export.py b/io_online_sketchfab/pack_for_export.py
index 587c94c2..972735c8 100644
--- a/io_online_sketchfab/pack_for_export.py
+++ b/io_online_sketchfab/pack_for_export.py
@@ -87,12 +87,12 @@ def prepare_assets(export_settings):
images.add(image)
if ((export_settings['models'] == 'SELECTION' and ob.type == 'MESH') or
- (export_settings['lamps'] == 'SELECTION' and ob.type == 'LAMP')):
+ (export_settings['lamps'] == 'SELECTION' and ob.type == 'LIGHT')):
if not ob.select and not ob.hide:
ob.hide = True
hidden.add(ob)
- elif export_settings['lamps'] == 'NONE' and ob.type == 'LAMP':
+ elif export_settings['lamps'] == 'NONE' and ob.type == 'LIGHT':
if not ob.hide:
ob.hide = True
hidden.add(ob)
diff --git a/io_scene_3ds/__init__.py b/io_scene_3ds/__init__.py
index 9236c07e..4daa4c29 100644
--- a/io_scene_3ds/__init__.py
+++ b/io_scene_3ds/__init__.py
@@ -50,15 +50,13 @@ from bpy.props import (
from bpy_extras.io_utils import (
ImportHelper,
ExportHelper,
- orientation_helper_factory,
+ orientation_helper,
axis_conversion,
)
-IO3DSOrientationHelper = orientation_helper_factory("IO3DSOrientationHelper", axis_forward='Y', axis_up='Z')
-
-
-class Import3DS(bpy.types.Operator, ImportHelper, IO3DSOrientationHelper):
+@orientation_helper(axis_forward='Y', axis_up='Z')
+class Import3DS(bpy.types.Operator, ImportHelper):
"""Import from 3DS file format (.3ds)"""
bl_idname = "import_scene.autodesk_3ds"
bl_label = 'Import 3DS'
@@ -104,7 +102,8 @@ class Import3DS(bpy.types.Operator, ImportHelper, IO3DSOrientationHelper):
return import_3ds.load(self, context, **keywords)
-class Export3DS(bpy.types.Operator, ExportHelper, IO3DSOrientationHelper):
+@orientation_helper(axis_forward='Y', axis_up='Z')
+class Export3DS(bpy.types.Operator, ExportHelper):
"""Export to 3DS file format (.3ds)"""
bl_idname = "export_scene.autodesk_3ds"
bl_label = 'Export 3DS'
@@ -149,15 +148,15 @@ def menu_func_import(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_import.append(menu_func_import)
- bpy.types.INFO_MT_file_export.append(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_import.remove(menu_func_import)
- bpy.types.INFO_MT_file_export.remove(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
# NOTES:
# why add 1 extra vertex? and remove it when done? -
diff --git a/io_scene_3ds/import_3ds.py b/io_scene_3ds/import_3ds.py
index 862fe2a7..cf17edcd 100644
--- a/io_scene_3ds/import_3ds.py
+++ b/io_scene_3ds/import_3ds.py
@@ -83,27 +83,27 @@ MAT_24BIT_COLOR = 0x0011 # color defined as 3 bytes
#>------ sub defines of OBJECT
OBJECT_MESH = 0x4100 # This lets us know that we are reading a new object
-OBJECT_LAMP = 0x4600 # This lets un know we are reading a light object
-OBJECT_LAMP_SPOT = 0x4610 # The light is a spotloght.
-OBJECT_LAMP_OFF = 0x4620 # The light off.
-OBJECT_LAMP_ATTENUATE = 0x4625
-OBJECT_LAMP_RAYSHADE = 0x4627
-OBJECT_LAMP_SHADOWED = 0x4630
-OBJECT_LAMP_LOCAL_SHADOW = 0x4640
-OBJECT_LAMP_LOCAL_SHADOW2 = 0x4641
-OBJECT_LAMP_SEE_CONE = 0x4650
-OBJECT_LAMP_SPOT_RECTANGULAR = 0x4651
-OBJECT_LAMP_SPOT_OVERSHOOT = 0x4652
-OBJECT_LAMP_SPOT_PROJECTOR = 0x4653
-OBJECT_LAMP_EXCLUDE = 0x4654
-OBJECT_LAMP_RANGE = 0x4655
-OBJECT_LAMP_ROLL = 0x4656
-OBJECT_LAMP_SPOT_ASPECT = 0x4657
-OBJECT_LAMP_RAY_BIAS = 0x4658
-OBJECT_LAMP_INNER_RANGE = 0x4659
-OBJECT_LAMP_OUTER_RANGE = 0x465A
-OBJECT_LAMP_MULTIPLIER = 0x465B
-OBJECT_LAMP_AMBIENT_LIGHT = 0x4680
+OBJECT_LIGHT = 0x4600 # This lets un know we are reading a light object
+OBJECT_LIGHT_SPOT = 0x4610 # The light is a spotloght.
+OBJECT_LIGHT_OFF = 0x4620 # The light off.
+OBJECT_LIGHT_ATTENUATE = 0x4625
+OBJECT_LIGHT_RAYSHADE = 0x4627
+OBJECT_LIGHT_SHADOWED = 0x4630
+OBJECT_LIGHT_LOCAL_SHADOW = 0x4640
+OBJECT_LIGHT_LOCAL_SHADOW2 = 0x4641
+OBJECT_LIGHT_SEE_CONE = 0x4650
+OBJECT_LIGHT_SPOT_RECTANGULAR = 0x4651
+OBJECT_LIGHT_SPOT_OVERSHOOT = 0x4652
+OBJECT_LIGHT_SPOT_PROJECTOR = 0x4653
+OBJECT_LIGHT_EXCLUDE = 0x4654
+OBJECT_LIGHT_RANGE = 0x4655
+OBJECT_LIGHT_ROLL = 0x4656
+OBJECT_LIGHT_SPOT_ASPECT = 0x4657
+OBJECT_LIGHT_RAY_BIAS = 0x4658
+OBJECT_LIGHT_INNER_RANGE = 0x4659
+OBJECT_LIGHT_OUTER_RANGE = 0x465A
+OBJECT_LIGHT_MULTIPLIER = 0x465B
+OBJECT_LIGHT_AMBIENT_LIGHT = 0x4680
OBJECT_CAMERA = 0x4700 # This lets un know we are reading a camera object
@@ -596,7 +596,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
new_chunk.bytes_read += temp_chunk.bytes_read
- elif new_chunk.ID == OBJECT_LAMP: # Basic lamp support.
+ elif new_chunk.ID == OBJECT_LIGHT: # Basic lamp support.
temp_data = file.read(STRUCT_SIZE_3FLOAT)
@@ -604,7 +604,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
new_chunk.bytes_read += STRUCT_SIZE_3FLOAT
# no lamp in dict that would be confusing
- contextLamp[1] = bpy.data.lamps.new("Lamp", 'POINT')
+ contextLamp[1] = bpy.data.lights.new("Lamp", 'POINT')
contextLamp[0] = ob = bpy.data.objects.new("Lamp", contextLamp[1])
SCN.objects.link(ob)
@@ -946,8 +946,8 @@ def load_3ds(filepath,
axis_min = [1000000000] * 3
axis_max = [-1000000000] * 3
- global_clamp_size = IMPORT_CONSTRAIN_BOUNDS
- if global_clamp_size != 0.0:
+ global_clight_size = IMPORT_CONSTRAIN_BOUNDS
+ if global_clight_size != 0.0:
# Get all object bounds
for ob in importedObjects:
for v in ob.bound_box:
@@ -963,7 +963,7 @@ def load_3ds(filepath,
axis_max[2] - axis_min[2])
scale = 1.0
- while global_clamp_size < max_axis * scale:
+ while global_clight_size < max_axis * scale:
scale = scale / 10.0
scale_mat = mathutils.Matrix.Scale(scale, 4)
diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index fddeda6c..490a2ff6 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -21,8 +21,8 @@
bl_info = {
"name": "FBX format",
"author": "Campbell Barton, Bastien Montagne, Jens Restemeier",
- "version": (3, 10, 0),
- "blender": (2, 79, 1),
+ "version": (4, 12, 1),
+ "blender": (2, 80, 0),
"location": "File > Import-Export",
"description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions",
"warning": "",
@@ -52,27 +52,25 @@ from bpy.props import (
from bpy_extras.io_utils import (
ImportHelper,
ExportHelper,
- orientation_helper_factory,
+ orientation_helper,
path_reference_mode,
axis_conversion,
)
-IOFBXOrientationHelper = orientation_helper_factory("IOFBXOrientationHelper", axis_forward='-Z', axis_up='Y')
-
-
-class ImportFBX(bpy.types.Operator, ImportHelper, IOFBXOrientationHelper):
+@orientation_helper(axis_forward='-Z', axis_up='Y')
+class ImportFBX(bpy.types.Operator, ImportHelper):
"""Load a FBX file"""
bl_idname = "import_scene.fbx"
bl_label = "Import FBX"
bl_options = {'UNDO', 'PRESET'}
- directory = StringProperty()
+ directory: StringProperty()
filename_ext = ".fbx"
- filter_glob = StringProperty(default="*.fbx", options={'HIDDEN'})
+ filter_glob: StringProperty(default="*.fbx", options={'HIDDEN'})
- ui_tab = EnumProperty(
+ ui_tab: EnumProperty(
items=(('MAIN', "Main", "Main basic settings"),
('ARMATURE', "Armatures", "Armature-related settings"),
),
@@ -80,17 +78,17 @@ class ImportFBX(bpy.types.Operator, ImportHelper, IOFBXOrientationHelper):
description="Import options categories",
)
- use_manual_orientation = BoolProperty(
+ use_manual_orientation: BoolProperty(
name="Manual Orientation",
description="Specify orientation and scale, instead of using embedded data in FBX file",
default=False,
)
- global_scale = FloatProperty(
+ global_scale: FloatProperty(
name="Scale",
min=0.001, max=1000.0,
default=1.0,
)
- bake_space_transform = BoolProperty(
+ bake_space_transform: BoolProperty(
name="!EXPERIMENTAL! Apply Transform",
description="Bake space transform into object data, avoids getting unwanted rotations to objects when "
"target space is not aligned with Blender's space "
@@ -98,69 +96,69 @@ class ImportFBX(bpy.types.Operator, ImportHelper, IOFBXOrientationHelper):
default=False,
)
- use_custom_normals = BoolProperty(
+ use_custom_normals: BoolProperty(
name="Import Normals",
description="Import custom normals, if available (otherwise Blender will recompute them)",
default=True,
)
- use_image_search = BoolProperty(
+ use_image_search: BoolProperty(
name="Image Search",
description="Search subdirs for any associated images (WARNING: may be slow)",
default=True,
)
- use_alpha_decals = BoolProperty(
+ use_alpha_decals: BoolProperty(
name="Alpha Decals",
description="Treat materials with alpha as decals (no shadow casting)",
default=False,
)
- decal_offset = FloatProperty(
+ decal_offset: FloatProperty(
name="Decal Offset",
description="Displace geometry of alpha meshes",
min=0.0, max=1.0,
default=0.0,
)
- use_anim = BoolProperty(
+ use_anim: BoolProperty(
name="Import Animation",
description="Import FBX animation",
default=True,
)
- anim_offset = FloatProperty(
+ anim_offset: FloatProperty(
name="Animation Offset",
description="Offset to apply to animation during import, in frames",
default=1.0,
)
- use_custom_props = BoolProperty(
+ use_custom_props: BoolProperty(
name="Import User Properties",
description="Import user properties as custom properties",
default=True,
)
- use_custom_props_enum_as_string = BoolProperty(
+ use_custom_props_enum_as_string: BoolProperty(
name="Import Enums As Strings",
description="Store enumeration values as strings",
default=True,
)
- ignore_leaf_bones = BoolProperty(
+ ignore_leaf_bones: BoolProperty(
name="Ignore Leaf Bones",
description="Ignore the last bone at the end of each chain (used to mark the length of the previous bone)",
default=False,
)
- force_connect_children = BoolProperty(
+ force_connect_children: BoolProperty(
name="Force Connect Children",
description="Force connection of children bones to their parent, even if their computed head/tail "
"positions do not match (can be useful with pure-joints-type armatures)",
default=False,
)
- automatic_bone_orientation = BoolProperty(
+ automatic_bone_orientation: BoolProperty(
name="Automatic Bone Orientation",
description="Try to align the major bone axis with the bone children",
default=False,
)
- primary_bone_axis = EnumProperty(
+ primary_bone_axis: EnumProperty(
name="Primary Bone Axis",
items=(('X', "X Axis", ""),
('Y', "Y Axis", ""),
@@ -171,7 +169,7 @@ class ImportFBX(bpy.types.Operator, ImportHelper, IOFBXOrientationHelper):
),
default='Y',
)
- secondary_bone_axis = EnumProperty(
+ secondary_bone_axis: EnumProperty(
name="Secondary Bone Axis",
items=(('X', "X Axis", ""),
('Y', "Y Axis", ""),
@@ -183,7 +181,7 @@ class ImportFBX(bpy.types.Operator, ImportHelper, IOFBXOrientationHelper):
default='X',
)
- use_prepost_rot = BoolProperty(
+ use_prepost_rot: BoolProperty(
name="Use Pre/Post Rotation",
description="Use pre/post rotation from FBX transform (you may have to disable that in some cases)",
default=True,
@@ -228,25 +226,25 @@ class ImportFBX(bpy.types.Operator, ImportHelper, IOFBXOrientationHelper):
def execute(self, context):
keywords = self.as_keywords(ignore=("filter_glob", "directory", "ui_tab"))
- keywords["use_cycles"] = (context.scene.render.engine == 'CYCLES')
from . import import_fbx
return import_fbx.load(self, context, **keywords)
-class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
+@orientation_helper(axis_forward='-Z', axis_up='Y')
+class ExportFBX(bpy.types.Operator, ExportHelper):
"""Write a FBX file"""
bl_idname = "export_scene.fbx"
bl_label = "Export FBX"
bl_options = {'UNDO', 'PRESET'}
filename_ext = ".fbx"
- filter_glob = StringProperty(default="*.fbx", options={'HIDDEN'})
+ filter_glob: StringProperty(default="*.fbx", options={'HIDDEN'})
# List of operator properties, the attributes will be assigned
# to the class instance from the operator settings before calling.
- ui_tab = EnumProperty(
+ ui_tab: EnumProperty(
items=(('MAIN', "Main", "Main basic settings"),
('GEOMETRY', "Geometries", "Geometry-related settings"),
('ARMATURE', "Armatures", "Armature-related settings"),
@@ -256,24 +254,24 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
description="Export options categories",
)
- use_selection = BoolProperty(
+ use_selection: BoolProperty(
name="Selected Objects",
description="Export selected objects on visible layers",
default=False,
)
- global_scale = FloatProperty(
+ global_scale: FloatProperty(
name="Scale",
description="Scale all data (Some importers do not support scaled armatures!)",
min=0.001, max=1000.0,
soft_min=0.01, soft_max=1000.0,
default=1.0,
)
- apply_unit_scale = BoolProperty(
+ apply_unit_scale: BoolProperty(
name="Apply Unit",
description="Take into account current Blender units settings (if unset, raw Blender Units values are used as-is)",
default=True,
)
- apply_scale_options = EnumProperty(
+ apply_scale_options: EnumProperty(
items=(('FBX_SCALE_NONE', "All Local",
"Apply custom scaling and units scaling to each object transformation, FBX scale remains at 1.0"),
('FBX_SCALE_UNITS', "FBX Units Scale",
@@ -288,7 +286,7 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
"(Blender uses FBX scale to detect units on import, "
"but many other applications do not handle the same way)",
)
- bake_space_transform = BoolProperty(
+ bake_space_transform: BoolProperty(
name="!EXPERIMENTAL! Apply Transform",
description="Bake space transform into object data, avoids getting unwanted rotations to objects when "
"target space is not aligned with Blender's space "
@@ -296,32 +294,32 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
default=False,
)
- object_types = EnumProperty(
+ object_types: EnumProperty(
name="Object Types",
options={'ENUM_FLAG'},
items=(('EMPTY', "Empty", ""),
('CAMERA', "Camera", ""),
- ('LAMP', "Lamp", ""),
+ ('LIGHT', "Lamp", ""),
('ARMATURE', "Armature", "WARNING: not supported in dupli/group instances"),
('MESH', "Mesh", ""),
('OTHER', "Other", "Other geometry types, like curve, metaball, etc. (converted to meshes)"),
),
description="Which kind of object to export",
- default={'EMPTY', 'CAMERA', 'LAMP', 'ARMATURE', 'MESH', 'OTHER'},
+ default={'EMPTY', 'CAMERA', 'LIGHT', 'ARMATURE', 'MESH', 'OTHER'},
)
- use_mesh_modifiers = BoolProperty(
+ use_mesh_modifiers: BoolProperty(
name="Apply Modifiers",
description="Apply modifiers to mesh objects (except Armature ones) - "
"WARNING: prevents exporting shape keys",
default=True,
)
- use_mesh_modifiers_render = BoolProperty(
+ use_mesh_modifiers_render: BoolProperty(
name="Use Modifiers Render Setting",
description="Use render settings when applying modifiers to mesh objects",
default=True,
)
- mesh_smooth_type = EnumProperty(
+ mesh_smooth_type: EnumProperty(
name="Smoothing",
items=(('OFF', "Normals Only", "Export only normals instead of writing edge or face smoothing data"),
('FACE', "Face", "Write face smoothing"),
@@ -331,29 +329,29 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
"(prefer 'Normals Only' option if your target importer understand split normals)",
default='OFF',
)
- use_mesh_edges = BoolProperty(
+ use_mesh_edges: BoolProperty(
name="Loose Edges",
description="Export loose edges (as two-vertices polygons)",
default=False,
)
- use_tspace = BoolProperty(
+ use_tspace: BoolProperty(
name="Tangent Space",
description="Add binormal and tangent vectors, together with normal they form the tangent space "
"(will only work correctly with tris/quads only meshes!)",
default=False,
)
- use_custom_props = BoolProperty(
+ use_custom_props: BoolProperty(
name="Custom Properties",
description="Export custom properties",
default=False,
)
- add_leaf_bones = BoolProperty(
+ add_leaf_bones: BoolProperty(
name="Add Leaf Bones",
description="Append a final bone to the end of each chain to specify last bone length "
"(use this when you intend to edit the armature from exported data)",
default=True # False for commit!
)
- primary_bone_axis = EnumProperty(
+ primary_bone_axis: EnumProperty(
name="Primary Bone Axis",
items=(('X', "X Axis", ""),
('Y', "Y Axis", ""),
@@ -364,7 +362,7 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
),
default='Y',
)
- secondary_bone_axis = EnumProperty(
+ secondary_bone_axis: EnumProperty(
name="Secondary Bone Axis",
items=(('X', "X Axis", ""),
('Y', "Y Axis", ""),
@@ -375,12 +373,12 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
),
default='X',
)
- use_armature_deform_only = BoolProperty(
+ use_armature_deform_only: BoolProperty(
name="Only Deform Bones",
description="Only write deforming bones (and non-deforming ones when they have deforming children)",
default=False,
)
- armature_nodetype = EnumProperty(
+ armature_nodetype: EnumProperty(
name="Armature FBXNode Type",
items=(('NULL', "Null", "'Null' FBX node, similar to Blender's Empty (default)"),
('ROOT', "Root", "'Root' FBX node, supposed to be the root of chains of bones..."),
@@ -391,68 +389,68 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
"perfectly in Blender...)",
default='NULL',
)
- bake_anim = BoolProperty(
+ bake_anim: BoolProperty(
name="Baked Animation",
description="Export baked keyframe animation",
default=True,
)
- bake_anim_use_all_bones = BoolProperty(
+ bake_anim_use_all_bones: BoolProperty(
name="Key All Bones",
description="Force exporting at least one key of animation for all bones "
"(needed with some target applications, like UE4)",
default=True,
)
- bake_anim_use_nla_strips = BoolProperty(
+ bake_anim_use_nla_strips: BoolProperty(
name="NLA Strips",
description="Export each non-muted NLA strip as a separated FBX's AnimStack, if any, "
"instead of global scene animation",
default=True,
)
- bake_anim_use_all_actions = BoolProperty(
+ bake_anim_use_all_actions: BoolProperty(
name="All Actions",
description="Export each action as a separated FBX's AnimStack, instead of global scene animation "
"(note that animated objects will get all actions compatible with them, "
"others will get no animation at all)",
default=True,
)
- bake_anim_force_startend_keying = BoolProperty(
+ bake_anim_force_startend_keying: BoolProperty(
name="Force Start/End Keying",
description="Always add a keyframe at start and end of actions for animated channels",
default=True,
)
- bake_anim_step = FloatProperty(
+ bake_anim_step: FloatProperty(
name="Sampling Rate",
description="How often to evaluate animated values (in frames)",
min=0.01, max=100.0,
soft_min=0.1, soft_max=10.0,
default=1.0,
)
- bake_anim_simplify_factor = FloatProperty(
+ bake_anim_simplify_factor: FloatProperty(
name="Simplify",
description="How much to simplify baked values (0.0 to disable, the higher the more simplified)",
min=0.0, max=100.0, # No simplification to up to 10% of current magnitude tolerance.
soft_min=0.0, soft_max=10.0,
default=1.0, # default: min slope: 0.005, max frame step: 10.
)
- path_mode = path_reference_mode
- embed_textures = BoolProperty(
+ path_mode: path_reference_mode
+ embed_textures: BoolProperty(
name="Embed Textures",
description="Embed textures in FBX binary file (only for \"Copy\" path mode!)",
default=False,
)
- batch_mode = EnumProperty(
+ batch_mode: EnumProperty(
name="Batch Mode",
items=(('OFF', "Off", "Active scene to file"),
('SCENE', "Scene", "Each scene as a file"),
('GROUP', "Group", "Each group as a file"),
),
)
- use_batch_own_dir = BoolProperty(
+ use_batch_own_dir: BoolProperty(
name="Batch Own Dir",
description="Create a dir for each exported file",
default=True,
)
- use_metadata = BoolProperty(
+ use_metadata: BoolProperty(
name="Use Metadata",
default=True,
options={'HIDDEN'},
@@ -559,13 +557,13 @@ def register():
for cls in classes:
bpy.utils.register_class(cls)
- bpy.types.INFO_MT_file_import.append(menu_func_import)
- bpy.types.INFO_MT_file_export.append(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
- bpy.types.INFO_MT_file_import.remove(menu_func_import)
- bpy.types.INFO_MT_file_export.remove(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
for cls in classes:
bpy.utils.unregister_class(cls)
diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index e82ceadd..f6c53272 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -27,7 +27,6 @@ import math
import os
import time
-from collections import OrderedDict
from itertools import zip_longest, chain
if "bpy" in locals():
@@ -41,6 +40,7 @@ if "bpy" in locals():
import bpy
import bpy_extras
+from bpy_extras import node_shader_utils
from mathutils import Vector, Matrix
from . import encode_bin, data_types, fbx_utils
@@ -75,6 +75,7 @@ from .fbx_utils import (
get_blender_bindpose_key, get_blender_armature_skin_key, get_blender_bone_cluster_key,
get_blender_anim_id_base, get_blender_anim_stack_key, get_blender_anim_layer_key,
get_blender_anim_curve_node_key, get_blender_anim_curve_key,
+ get_blender_nodetexture_key,
# FBX element data.
elem_empty,
elem_data_single_bool, elem_data_single_int16, elem_data_single_int32, elem_data_single_int64,
@@ -110,7 +111,7 @@ convert_rad_to_deg_iter = units_convertor_iter("radian", "degree")
# TODO: check all those "default" values, they should match Blender's default as much as possible, I guess?
def fbx_template_def_globalsettings(scene, settings, override_defaults=None, nbr_users=0):
- props = OrderedDict()
+ props = {}
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"GlobalSettings", b"", props, nbr_users, [False])
@@ -118,91 +119,91 @@ def fbx_template_def_globalsettings(scene, settings, override_defaults=None, nbr
def fbx_template_def_model(scene, settings, override_defaults=None, nbr_users=0):
gscale = settings.global_scale
- props = OrderedDict((
- # Name, Value, Type, Animatable
- (b"QuaternionInterpolate", (0, "p_enum", False)), # 0 = no quat interpolation.
- (b"RotationOffset", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"RotationPivot", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"ScalingOffset", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"ScalingPivot", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"TranslationActive", (False, "p_bool", False)),
- (b"TranslationMin", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"TranslationMax", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"TranslationMinX", (False, "p_bool", False)),
- (b"TranslationMinY", (False, "p_bool", False)),
- (b"TranslationMinZ", (False, "p_bool", False)),
- (b"TranslationMaxX", (False, "p_bool", False)),
- (b"TranslationMaxY", (False, "p_bool", False)),
- (b"TranslationMaxZ", (False, "p_bool", False)),
- (b"RotationOrder", (0, "p_enum", False)), # we always use 'XYZ' order.
- (b"RotationSpaceForLimitOnly", (False, "p_bool", False)),
- (b"RotationStiffnessX", (0.0, "p_double", False)),
- (b"RotationStiffnessY", (0.0, "p_double", False)),
- (b"RotationStiffnessZ", (0.0, "p_double", False)),
- (b"AxisLen", (10.0, "p_double", False)),
- (b"PreRotation", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"PostRotation", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"RotationActive", (False, "p_bool", False)),
- (b"RotationMin", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"RotationMax", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"RotationMinX", (False, "p_bool", False)),
- (b"RotationMinY", (False, "p_bool", False)),
- (b"RotationMinZ", (False, "p_bool", False)),
- (b"RotationMaxX", (False, "p_bool", False)),
- (b"RotationMaxY", (False, "p_bool", False)),
- (b"RotationMaxZ", (False, "p_bool", False)),
- (b"InheritType", (0, "p_enum", False)), # RrSs
- (b"ScalingActive", (False, "p_bool", False)),
- (b"ScalingMin", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"ScalingMax", ((1.0, 1.0, 1.0), "p_vector_3d", False)),
- (b"ScalingMinX", (False, "p_bool", False)),
- (b"ScalingMinY", (False, "p_bool", False)),
- (b"ScalingMinZ", (False, "p_bool", False)),
- (b"ScalingMaxX", (False, "p_bool", False)),
- (b"ScalingMaxY", (False, "p_bool", False)),
- (b"ScalingMaxZ", (False, "p_bool", False)),
- (b"GeometricTranslation", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"GeometricRotation", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"GeometricScaling", ((1.0, 1.0, 1.0), "p_vector_3d", False)),
- (b"MinDampRangeX", (0.0, "p_double", False)),
- (b"MinDampRangeY", (0.0, "p_double", False)),
- (b"MinDampRangeZ", (0.0, "p_double", False)),
- (b"MaxDampRangeX", (0.0, "p_double", False)),
- (b"MaxDampRangeY", (0.0, "p_double", False)),
- (b"MaxDampRangeZ", (0.0, "p_double", False)),
- (b"MinDampStrengthX", (0.0, "p_double", False)),
- (b"MinDampStrengthY", (0.0, "p_double", False)),
- (b"MinDampStrengthZ", (0.0, "p_double", False)),
- (b"MaxDampStrengthX", (0.0, "p_double", False)),
- (b"MaxDampStrengthY", (0.0, "p_double", False)),
- (b"MaxDampStrengthZ", (0.0, "p_double", False)),
- (b"PreferedAngleX", (0.0, "p_double", False)),
- (b"PreferedAngleY", (0.0, "p_double", False)),
- (b"PreferedAngleZ", (0.0, "p_double", False)),
- (b"LookAtProperty", (None, "p_object", False)),
- (b"UpVectorProperty", (None, "p_object", False)),
- (b"Show", (True, "p_bool", False)),
- (b"NegativePercentShapeSupport", (True, "p_bool", False)),
- (b"DefaultAttributeIndex", (-1, "p_integer", False)),
- (b"Freeze", (False, "p_bool", False)),
- (b"LODBox", (False, "p_bool", False)),
- (b"Lcl Translation", ((0.0, 0.0, 0.0), "p_lcl_translation", True)),
- (b"Lcl Rotation", ((0.0, 0.0, 0.0), "p_lcl_rotation", True)),
- (b"Lcl Scaling", ((1.0, 1.0, 1.0), "p_lcl_scaling", True)),
- (b"Visibility", (1.0, "p_visibility", True)),
- (b"Visibility Inheritance", (1, "p_visibility_inheritance", False)),
- ))
+ props = {
+ # Name, Value, Type, Animatable
+ b"QuaternionInterpolate": (0, "p_enum", False), # 0 = no quat interpolation.
+ b"RotationOffset": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"RotationPivot": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"ScalingOffset": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"ScalingPivot": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"TranslationActive": (False, "p_bool", False),
+ b"TranslationMin": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"TranslationMax": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"TranslationMinX": (False, "p_bool", False),
+ b"TranslationMinY": (False, "p_bool", False),
+ b"TranslationMinZ": (False, "p_bool", False),
+ b"TranslationMaxX": (False, "p_bool", False),
+ b"TranslationMaxY": (False, "p_bool", False),
+ b"TranslationMaxZ": (False, "p_bool", False),
+ b"RotationOrder": (0, "p_enum", False), # we always use 'XYZ' order.
+ b"RotationSpaceForLimitOnly": (False, "p_bool", False),
+ b"RotationStiffnessX": (0.0, "p_double", False),
+ b"RotationStiffnessY": (0.0, "p_double", False),
+ b"RotationStiffnessZ": (0.0, "p_double", False),
+ b"AxisLen": (10.0, "p_double", False),
+ b"PreRotation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"PostRotation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"RotationActive": (False, "p_bool", False),
+ b"RotationMin": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"RotationMax": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"RotationMinX": (False, "p_bool", False),
+ b"RotationMinY": (False, "p_bool", False),
+ b"RotationMinZ": (False, "p_bool", False),
+ b"RotationMaxX": (False, "p_bool", False),
+ b"RotationMaxY": (False, "p_bool", False),
+ b"RotationMaxZ": (False, "p_bool", False),
+ b"InheritType": (0, "p_enum", False), # RrSs
+ b"ScalingActive": (False, "p_bool", False),
+ b"ScalingMin": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"ScalingMax": ((1.0, 1.0, 1.0), "p_vector_3d", False),
+ b"ScalingMinX": (False, "p_bool", False),
+ b"ScalingMinY": (False, "p_bool", False),
+ b"ScalingMinZ": (False, "p_bool", False),
+ b"ScalingMaxX": (False, "p_bool", False),
+ b"ScalingMaxY": (False, "p_bool", False),
+ b"ScalingMaxZ": (False, "p_bool", False),
+ b"GeometricTranslation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"GeometricRotation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"GeometricScaling": ((1.0, 1.0, 1.0), "p_vector_3d", False),
+ b"MinDampRangeX": (0.0, "p_double", False),
+ b"MinDampRangeY": (0.0, "p_double", False),
+ b"MinDampRangeZ": (0.0, "p_double", False),
+ b"MaxDampRangeX": (0.0, "p_double", False),
+ b"MaxDampRangeY": (0.0, "p_double", False),
+ b"MaxDampRangeZ": (0.0, "p_double", False),
+ b"MinDampStrengthX": (0.0, "p_double", False),
+ b"MinDampStrengthY": (0.0, "p_double", False),
+ b"MinDampStrengthZ": (0.0, "p_double", False),
+ b"MaxDampStrengthX": (0.0, "p_double", False),
+ b"MaxDampStrengthY": (0.0, "p_double", False),
+ b"MaxDampStrengthZ": (0.0, "p_double", False),
+ b"PreferedAngleX": (0.0, "p_double", False),
+ b"PreferedAngleY": (0.0, "p_double", False),
+ b"PreferedAngleZ": (0.0, "p_double", False),
+ b"LookAtProperty": (None, "p_object", False),
+ b"UpVectorProperty": (None, "p_object", False),
+ b"Show": (True, "p_bool", False),
+ b"NegativePercentShapeSupport": (True, "p_bool", False),
+ b"DefaultAttributeIndex": (-1, "p_integer", False),
+ b"Freeze": (False, "p_bool", False),
+ b"LODBox": (False, "p_bool", False),
+ b"Lcl Translation": ((0.0, 0.0, 0.0), "p_lcl_translation", True),
+ b"Lcl Rotation": ((0.0, 0.0, 0.0), "p_lcl_rotation", True),
+ b"Lcl Scaling": ((1.0, 1.0, 1.0), "p_lcl_scaling", True),
+ b"Visibility": (1.0, "p_visibility", True),
+ b"Visibility Inheritance": (1, "p_visibility_inheritance", False),
+ }
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"Model", b"FbxNode", props, nbr_users, [False])
def fbx_template_def_null(scene, settings, override_defaults=None, nbr_users=0):
- props = OrderedDict((
- (b"Color", ((0.8, 0.8, 0.8), "p_color_rgb", False)),
- (b"Size", (100.0, "p_double", False)),
- (b"Look", (1, "p_enum", False)), # Cross (0 is None, i.e. invisible?).
- ))
+ props = {
+ b"Color": ((0.8, 0.8, 0.8), "p_color_rgb", False),
+ b"Size": (100.0, "p_double", False),
+ b"Look": (1, "p_enum", False), # Cross (0 is None, i.e. invisible?).
+ }
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"NodeAttribute", b"FbxNull", props, nbr_users, [False])
@@ -210,17 +211,17 @@ def fbx_template_def_null(scene, settings, override_defaults=None, nbr_users=0):
def fbx_template_def_light(scene, settings, override_defaults=None, nbr_users=0):
gscale = settings.global_scale
- props = OrderedDict((
- (b"LightType", (0, "p_enum", False)), # Point light.
- (b"CastLight", (True, "p_bool", False)),
- (b"Color", ((1.0, 1.0, 1.0), "p_color", True)),
- (b"Intensity", (100.0, "p_number", True)), # Times 100 compared to Blender values...
- (b"DecayType", (2, "p_enum", False)), # Quadratic.
- (b"DecayStart", (30.0 * gscale, "p_double", False)),
- (b"CastShadows", (True, "p_bool", False)),
- (b"ShadowColor", ((0.0, 0.0, 0.0), "p_color", True)),
- (b"AreaLightShape", (0, "p_enum", False)), # Rectangle.
- ))
+ props = {
+ b"LightType": (0, "p_enum", False), # Point light.
+ b"CastLight": (True, "p_bool", False),
+ b"Color": ((1.0, 1.0, 1.0), "p_color", True),
+ b"Intensity": (100.0, "p_number", True), # Times 100 compared to Blender values...
+ b"DecayType": (2, "p_enum", False), # Quadratic.
+ b"DecayStart": (30.0 * gscale, "p_double", False),
+ b"CastShadows": (True, "p_bool", False),
+ b"ShadowColor": ((0.0, 0.0, 0.0), "p_color", True),
+ b"AreaLightShape": (0, "p_enum", False), # Rectangle.
+ }
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"NodeAttribute", b"FbxLight", props, nbr_users, [False])
@@ -228,137 +229,137 @@ def fbx_template_def_light(scene, settings, override_defaults=None, nbr_users=0)
def fbx_template_def_camera(scene, settings, override_defaults=None, nbr_users=0):
r = scene.render
- props = OrderedDict((
- (b"Color", ((0.8, 0.8, 0.8), "p_color_rgb", False)),
- (b"Position", ((0.0, 0.0, -50.0), "p_vector", True)),
- (b"UpVector", ((0.0, 1.0, 0.0), "p_vector", True)),
- (b"InterestPosition", ((0.0, 0.0, 0.0), "p_vector", True)),
- (b"Roll", (0.0, "p_roll", True)),
- (b"OpticalCenterX", (0.0, "p_opticalcenterx", True)),
- (b"OpticalCenterY", (0.0, "p_opticalcentery", True)),
- (b"BackgroundColor", ((0.63, 0.63, 0.63), "p_color", True)),
- (b"TurnTable", (0.0, "p_number", True)),
- (b"DisplayTurnTableIcon", (False, "p_bool", False)),
- (b"UseMotionBlur", (False, "p_bool", False)),
- (b"UseRealTimeMotionBlur", (True, "p_bool", False)),
- (b"Motion Blur Intensity", (1.0, "p_number", True)),
- (b"AspectRatioMode", (0, "p_enum", False)), # WindowSize.
- (b"AspectWidth", (320.0, "p_double", False)),
- (b"AspectHeight", (200.0, "p_double", False)),
- (b"PixelAspectRatio", (1.0, "p_double", False)),
- (b"FilmOffsetX", (0.0, "p_number", True)),
- (b"FilmOffsetY", (0.0, "p_number", True)),
- (b"FilmWidth", (0.816, "p_double", False)),
- (b"FilmHeight", (0.612, "p_double", False)),
- (b"FilmAspectRatio", (1.3333333333333333, "p_double", False)),
- (b"FilmSqueezeRatio", (1.0, "p_double", False)),
- (b"FilmFormatIndex", (0, "p_enum", False)), # Assuming this is ApertureFormat, 0 = custom.
- (b"PreScale", (1.0, "p_number", True)),
- (b"FilmTranslateX", (0.0, "p_number", True)),
- (b"FilmTranslateY", (0.0, "p_number", True)),
- (b"FilmRollPivotX", (0.0, "p_number", True)),
- (b"FilmRollPivotY", (0.0, "p_number", True)),
- (b"FilmRollValue", (0.0, "p_number", True)),
- (b"FilmRollOrder", (0, "p_enum", False)), # 0 = rotate first (default).
- (b"ApertureMode", (2, "p_enum", False)), # 2 = Vertical.
- (b"GateFit", (0, "p_enum", False)), # 0 = no resolution gate fit.
- (b"FieldOfView", (25.114999771118164, "p_fov", True)),
- (b"FieldOfViewX", (40.0, "p_fov_x", True)),
- (b"FieldOfViewY", (40.0, "p_fov_y", True)),
- (b"FocalLength", (34.89327621672628, "p_number", True)),
- (b"CameraFormat", (0, "p_enum", False)), # Custom camera format.
- (b"UseFrameColor", (False, "p_bool", False)),
- (b"FrameColor", ((0.3, 0.3, 0.3), "p_color_rgb", False)),
- (b"ShowName", (True, "p_bool", False)),
- (b"ShowInfoOnMoving", (True, "p_bool", False)),
- (b"ShowGrid", (True, "p_bool", False)),
- (b"ShowOpticalCenter", (False, "p_bool", False)),
- (b"ShowAzimut", (True, "p_bool", False)),
- (b"ShowTimeCode", (False, "p_bool", False)),
- (b"ShowAudio", (False, "p_bool", False)),
- (b"AudioColor", ((0.0, 1.0, 0.0), "p_vector_3d", False)), # Yep, vector3d, not corlorgb… :cry:
- (b"NearPlane", (10.0, "p_double", False)),
- (b"FarPlane", (4000.0, "p_double", False)),
- (b"AutoComputeClipPanes", (False, "p_bool", False)),
- (b"ViewCameraToLookAt", (True, "p_bool", False)),
- (b"ViewFrustumNearFarPlane", (False, "p_bool", False)),
- (b"ViewFrustumBackPlaneMode", (2, "p_enum", False)), # 2 = show back plane if texture added.
- (b"BackPlaneDistance", (4000.0, "p_number", True)),
- (b"BackPlaneDistanceMode", (1, "p_enum", False)), # 1 = relative to camera.
- (b"ViewFrustumFrontPlaneMode", (2, "p_enum", False)), # 2 = show front plane if texture added.
- (b"FrontPlaneDistance", (10.0, "p_number", True)),
- (b"FrontPlaneDistanceMode", (1, "p_enum", False)), # 1 = relative to camera.
- (b"LockMode", (False, "p_bool", False)),
- (b"LockInterestNavigation", (False, "p_bool", False)),
+ props = {
+ b"Color": ((0.8, 0.8, 0.8), "p_color_rgb", False),
+ b"Position": ((0.0, 0.0, -50.0), "p_vector", True),
+ b"UpVector": ((0.0, 1.0, 0.0), "p_vector", True),
+ b"InterestPosition": ((0.0, 0.0, 0.0), "p_vector", True),
+ b"Roll": (0.0, "p_roll", True),
+ b"OpticalCenterX": (0.0, "p_opticalcenterx", True),
+ b"OpticalCenterY": (0.0, "p_opticalcentery", True),
+ b"BackgroundColor": ((0.63, 0.63, 0.63), "p_color", True),
+ b"TurnTable": (0.0, "p_number", True),
+ b"DisplayTurnTableIcon": (False, "p_bool", False),
+ b"UseMotionBlur": (False, "p_bool", False),
+ b"UseRealTimeMotionBlur": (True, "p_bool", False),
+ b"Motion Blur Intensity": (1.0, "p_number", True),
+ b"AspectRatioMode": (0, "p_enum", False), # WindowSize.
+ b"AspectWidth": (320.0, "p_double", False),
+ b"AspectHeight": (200.0, "p_double", False),
+ b"PixelAspectRatio": (1.0, "p_double", False),
+ b"FilmOffsetX": (0.0, "p_number", True),
+ b"FilmOffsetY": (0.0, "p_number", True),
+ b"FilmWidth": (0.816, "p_double", False),
+ b"FilmHeight": (0.612, "p_double", False),
+ b"FilmAspectRatio": (1.3333333333333333, "p_double", False),
+ b"FilmSqueezeRatio": (1.0, "p_double", False),
+ b"FilmFormatIndex": (0, "p_enum", False), # Assuming this is ApertureFormat, 0 = custom.
+ b"PreScale": (1.0, "p_number", True),
+ b"FilmTranslateX": (0.0, "p_number", True),
+ b"FilmTranslateY": (0.0, "p_number", True),
+ b"FilmRollPivotX": (0.0, "p_number", True),
+ b"FilmRollPivotY": (0.0, "p_number", True),
+ b"FilmRollValue": (0.0, "p_number", True),
+ b"FilmRollOrder": (0, "p_enum", False), # 0 = rotate first (default).
+ b"ApertureMode": (2, "p_enum", False), # 2 = Vertical.
+ b"GateFit": (0, "p_enum", False), # 0 = no resolution gate fit.
+ b"FieldOfView": (25.114999771118164, "p_fov", True),
+ b"FieldOfViewX": (40.0, "p_fov_x", True),
+ b"FieldOfViewY": (40.0, "p_fov_y", True),
+ b"FocalLength": (34.89327621672628, "p_number", True),
+ b"CameraFormat": (0, "p_enum", False), # Custom camera format.
+ b"UseFrameColor": (False, "p_bool", False),
+ b"FrameColor": ((0.3, 0.3, 0.3), "p_color_rgb", False),
+ b"ShowName": (True, "p_bool", False),
+ b"ShowInfoOnMoving": (True, "p_bool", False),
+ b"ShowGrid": (True, "p_bool", False),
+ b"ShowOpticalCenter": (False, "p_bool", False),
+ b"ShowAzimut": (True, "p_bool", False),
+ b"ShowTimeCode": (False, "p_bool", False),
+ b"ShowAudio": (False, "p_bool", False),
+ b"AudioColor": ((0.0, 1.0, 0.0), "p_vector_3d", False), # Yep, vector3d, not corlorgb… :cry:
+ b"NearPlane": (10.0, "p_double", False),
+ b"FarPlane": (4000.0, "p_double", False),
+ b"AutoComputeClipPanes": (False, "p_bool", False),
+ b"ViewCameraToLookAt": (True, "p_bool", False),
+ b"ViewFrustumNearFarPlane": (False, "p_bool", False),
+ b"ViewFrustumBackPlaneMode": (2, "p_enum", False), # 2 = show back plane if texture added.
+ b"BackPlaneDistance": (4000.0, "p_number", True),
+ b"BackPlaneDistanceMode": (1, "p_enum", False), # 1 = relative to camera.
+ b"ViewFrustumFrontPlaneMode": (2, "p_enum", False), # 2 = show front plane if texture added.
+ b"FrontPlaneDistance": (10.0, "p_number", True),
+ b"FrontPlaneDistanceMode": (1, "p_enum", False), # 1 = relative to camera.
+ b"LockMode": (False, "p_bool", False),
+ b"LockInterestNavigation": (False, "p_bool", False),
# BackPlate... properties **arggggg!**
- (b"FitImage", (False, "p_bool", False)),
- (b"Crop", (False, "p_bool", False)),
- (b"Center", (True, "p_bool", False)),
- (b"KeepRatio", (True, "p_bool", False)),
+ b"FitImage": (False, "p_bool", False),
+ b"Crop": (False, "p_bool", False),
+ b"Center": (True, "p_bool", False),
+ b"KeepRatio": (True, "p_bool", False),
# End of BackPlate...
- (b"BackgroundAlphaTreshold", (0.5, "p_double", False)),
- (b"ShowBackplate", (True, "p_bool", False)),
- (b"BackPlaneOffsetX", (0.0, "p_number", True)),
- (b"BackPlaneOffsetY", (0.0, "p_number", True)),
- (b"BackPlaneRotation", (0.0, "p_number", True)),
- (b"BackPlaneScaleX", (1.0, "p_number", True)),
- (b"BackPlaneScaleY", (1.0, "p_number", True)),
- (b"Background Texture", (None, "p_object", False)),
- (b"FrontPlateFitImage", (True, "p_bool", False)),
- (b"FrontPlateCrop", (False, "p_bool", False)),
- (b"FrontPlateCenter", (True, "p_bool", False)),
- (b"FrontPlateKeepRatio", (True, "p_bool", False)),
- (b"Foreground Opacity", (1.0, "p_double", False)),
- (b"ShowFrontplate", (True, "p_bool", False)),
- (b"FrontPlaneOffsetX", (0.0, "p_number", True)),
- (b"FrontPlaneOffsetY", (0.0, "p_number", True)),
- (b"FrontPlaneRotation", (0.0, "p_number", True)),
- (b"FrontPlaneScaleX", (1.0, "p_number", True)),
- (b"FrontPlaneScaleY", (1.0, "p_number", True)),
- (b"Foreground Texture", (None, "p_object", False)),
- (b"DisplaySafeArea", (False, "p_bool", False)),
- (b"DisplaySafeAreaOnRender", (False, "p_bool", False)),
- (b"SafeAreaDisplayStyle", (1, "p_enum", False)), # 1 = rounded corners.
- (b"SafeAreaAspectRatio", (1.3333333333333333, "p_double", False)),
- (b"Use2DMagnifierZoom", (False, "p_bool", False)),
- (b"2D Magnifier Zoom", (100.0, "p_number", True)),
- (b"2D Magnifier X", (50.0, "p_number", True)),
- (b"2D Magnifier Y", (50.0, "p_number", True)),
- (b"CameraProjectionType", (0, "p_enum", False)), # 0 = perspective, 1 = orthogonal.
- (b"OrthoZoom", (1.0, "p_double", False)),
- (b"UseRealTimeDOFAndAA", (False, "p_bool", False)),
- (b"UseDepthOfField", (False, "p_bool", False)),
- (b"FocusSource", (0, "p_enum", False)), # 0 = camera interest, 1 = distance from camera interest.
- (b"FocusAngle", (3.5, "p_double", False)), # ???
- (b"FocusDistance", (200.0, "p_double", False)),
- (b"UseAntialiasing", (False, "p_bool", False)),
- (b"AntialiasingIntensity", (0.77777, "p_double", False)),
- (b"AntialiasingMethod", (0, "p_enum", False)), # 0 = oversampling, 1 = hardware.
- (b"UseAccumulationBuffer", (False, "p_bool", False)),
- (b"FrameSamplingCount", (7, "p_integer", False)),
- (b"FrameSamplingType", (1, "p_enum", False)), # 0 = uniform, 1 = stochastic.
- ))
+ b"BackgroundAlphaTreshold": (0.5, "p_double", False),
+ b"ShowBackplate": (True, "p_bool", False),
+ b"BackPlaneOffsetX": (0.0, "p_number", True),
+ b"BackPlaneOffsetY": (0.0, "p_number", True),
+ b"BackPlaneRotation": (0.0, "p_number", True),
+ b"BackPlaneScaleX": (1.0, "p_number", True),
+ b"BackPlaneScaleY": (1.0, "p_number", True),
+ b"Background Texture": (None, "p_object", False),
+ b"FrontPlateFitImage": (True, "p_bool", False),
+ b"FrontPlateCrop": (False, "p_bool", False),
+ b"FrontPlateCenter": (True, "p_bool", False),
+ b"FrontPlateKeepRatio": (True, "p_bool", False),
+ b"Foreground Opacity": (1.0, "p_double", False),
+ b"ShowFrontplate": (True, "p_bool", False),
+ b"FrontPlaneOffsetX": (0.0, "p_number", True),
+ b"FrontPlaneOffsetY": (0.0, "p_number", True),
+ b"FrontPlaneRotation": (0.0, "p_number", True),
+ b"FrontPlaneScaleX": (1.0, "p_number", True),
+ b"FrontPlaneScaleY": (1.0, "p_number", True),
+ b"Foreground Texture": (None, "p_object", False),
+ b"DisplaySafeArea": (False, "p_bool", False),
+ b"DisplaySafeAreaOnRender": (False, "p_bool", False),
+ b"SafeAreaDisplayStyle": (1, "p_enum", False), # 1 = rounded corners.
+ b"SafeAreaAspectRatio": (1.3333333333333333, "p_double", False),
+ b"Use2DMagnifierZoom": (False, "p_bool", False),
+ b"2D Magnifier Zoom": (100.0, "p_number", True),
+ b"2D Magnifier X": (50.0, "p_number", True),
+ b"2D Magnifier Y": (50.0, "p_number", True),
+ b"CameraProjectionType": (0, "p_enum", False), # 0 = perspective, 1 = orthogonal.
+ b"OrthoZoom": (1.0, "p_double", False),
+ b"UseRealTimeDOFAndAA": (False, "p_bool", False),
+ b"UseDepthOfField": (False, "p_bool", False),
+ b"FocusSource": (0, "p_enum", False), # 0 = camera interest, 1 = distance from camera interest.
+ b"FocusAngle": (3.5, "p_double", False), # ???
+ b"FocusDistance": (200.0, "p_double", False),
+ b"UseAntialiasing": (False, "p_bool", False),
+ b"AntialiasingIntensity": (0.77777, "p_double", False),
+ b"AntialiasingMethod": (0, "p_enum", False), # 0 = oversampling, 1 = hardware.
+ b"UseAccumulationBuffer": (False, "p_bool", False),
+ b"FrameSamplingCount": (7, "p_integer", False),
+ b"FrameSamplingType": (1, "p_enum", False), # 0 = uniform, 1 = stochastic.
+ }
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"NodeAttribute", b"FbxCamera", props, nbr_users, [False])
def fbx_template_def_bone(scene, settings, override_defaults=None, nbr_users=0):
- props = OrderedDict()
+ props = {}
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"NodeAttribute", b"LimbNode", props, nbr_users, [False])
def fbx_template_def_geometry(scene, settings, override_defaults=None, nbr_users=0):
- props = OrderedDict((
- (b"Color", ((0.8, 0.8, 0.8), "p_color_rgb", False)),
- (b"BBoxMin", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"BBoxMax", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"Primary Visibility", (True, "p_bool", False)),
- (b"Casts Shadows", (True, "p_bool", False)),
- (b"Receive Shadows", (True, "p_bool", False)),
- ))
+ props = {
+ b"Color": ((0.8, 0.8, 0.8), "p_color_rgb", False),
+ b"BBoxMin": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"BBoxMax": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"Primary Visibility": (True, "p_bool", False),
+ b"Casts Shadows": (True, "p_bool", False),
+ b"Receive Shadows": (True, "p_bool", False),
+ }
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"Geometry", b"FbxMesh", props, nbr_users, [False])
@@ -366,37 +367,37 @@ def fbx_template_def_geometry(scene, settings, override_defaults=None, nbr_users
def fbx_template_def_material(scene, settings, override_defaults=None, nbr_users=0):
# WIP...
- props = OrderedDict((
- (b"ShadingModel", ("Phong", "p_string", False)),
- (b"MultiLayer", (False, "p_bool", False)),
+ props = {
+ b"ShadingModel": ("Phong", "p_string", False),
+ b"MultiLayer": (False, "p_bool", False),
# Lambert-specific.
- (b"EmissiveColor", ((0.0, 0.0, 0.0), "p_color", True)),
- (b"EmissiveFactor", (1.0, "p_number", True)),
- (b"AmbientColor", ((0.2, 0.2, 0.2), "p_color", True)),
- (b"AmbientFactor", (1.0, "p_number", True)),
- (b"DiffuseColor", ((0.8, 0.8, 0.8), "p_color", True)),
- (b"DiffuseFactor", (1.0, "p_number", True)),
- (b"TransparentColor", ((0.0, 0.0, 0.0), "p_color", True)),
- (b"TransparencyFactor", (0.0, "p_number", True)),
- (b"Opacity", (1.0, "p_number", True)),
- (b"NormalMap", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"Bump", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"BumpFactor", (1.0, "p_double", False)),
- (b"DisplacementColor", ((0.0, 0.0, 0.0), "p_color_rgb", False)),
- (b"DisplacementFactor", (1.0, "p_double", False)),
- (b"VectorDisplacementColor", ((0.0, 0.0, 0.0), "p_color_rgb", False)),
- (b"VectorDisplacementFactor", (1.0, "p_double", False)),
+ b"EmissiveColor": ((0.0, 0.0, 0.0), "p_color", True),
+ b"EmissiveFactor": (1.0, "p_number", True),
+ b"AmbientColor": ((0.2, 0.2, 0.2), "p_color", True),
+ b"AmbientFactor": (1.0, "p_number", True),
+ b"DiffuseColor": ((0.8, 0.8, 0.8), "p_color", True),
+ b"DiffuseFactor": (1.0, "p_number", True),
+ b"TransparentColor": ((0.0, 0.0, 0.0), "p_color", True),
+ b"TransparencyFactor": (0.0, "p_number", True),
+ b"Opacity": (1.0, "p_number", True),
+ b"NormalMap": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"Bump": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"BumpFactor": (1.0, "p_double", False),
+ b"DisplacementColor": ((0.0, 0.0, 0.0), "p_color_rgb", False),
+ b"DisplacementFactor": (1.0, "p_double", False),
+ b"VectorDisplacementColor": ((0.0, 0.0, 0.0), "p_color_rgb", False),
+ b"VectorDisplacementFactor": (1.0, "p_double", False),
# Phong-specific.
- (b"SpecularColor", ((0.2, 0.2, 0.2), "p_color", True)),
- (b"SpecularFactor", (1.0, "p_number", True)),
+ b"SpecularColor": ((0.2, 0.2, 0.2), "p_color", True),
+ b"SpecularFactor": (1.0, "p_number", True),
# Not sure about the name, importer uses this (but ShininessExponent for tex prop name!)
# And in fbx exported by sdk, you have one in template, the other in actual material!!! :/
# For now, using both.
- (b"Shininess", (20.0, "p_number", True)),
- (b"ShininessExponent", (20.0, "p_number", True)),
- (b"ReflectionColor", ((0.0, 0.0, 0.0), "p_color", True)),
- (b"ReflectionFactor", (1.0, "p_number", True)),
- ))
+ b"Shininess": (20.0, "p_number", True),
+ b"ShininessExponent": (20.0, "p_number", True),
+ b"ReflectionColor": ((0.0, 0.0, 0.0), "p_color", True),
+ b"ReflectionFactor": (1.0, "p_number", True),
+ }
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"Material", b"FbxSurfacePhong", props, nbr_users, [False])
@@ -405,26 +406,26 @@ def fbx_template_def_material(scene, settings, override_defaults=None, nbr_users
def fbx_template_def_texture_file(scene, settings, override_defaults=None, nbr_users=0):
# WIP...
# XXX Not sure about all names!
- props = OrderedDict((
- (b"TextureTypeUse", (0, "p_enum", False)), # Standard.
- (b"AlphaSource", (2, "p_enum", False)), # Black (i.e. texture's alpha), XXX name guessed!.
- (b"Texture alpha", (1.0, "p_double", False)),
- (b"PremultiplyAlpha", (True, "p_bool", False)),
- (b"CurrentTextureBlendMode", (1, "p_enum", False)), # Additive...
- (b"CurrentMappingType", (0, "p_enum", False)), # UV.
- (b"UVSet", ("default", "p_string", False)), # UVMap name.
- (b"WrapModeU", (0, "p_enum", False)), # Repeat.
- (b"WrapModeV", (0, "p_enum", False)), # Repeat.
- (b"UVSwap", (False, "p_bool", False)),
- (b"Translation", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"Rotation", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"Scaling", ((1.0, 1.0, 1.0), "p_vector_3d", False)),
- (b"TextureRotationPivot", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
- (b"TextureScalingPivot", ((0.0, 0.0, 0.0), "p_vector_3d", False)),
+ props = {
+ b"TextureTypeUse": (0, "p_enum", False), # Standard.
+ b"AlphaSource": (2, "p_enum", False), # Black (i.e. texture's alpha), XXX name guessed!.
+ b"Texture alpha": (1.0, "p_double", False),
+ b"PremultiplyAlpha": (True, "p_bool", False),
+ b"CurrentTextureBlendMode": (1, "p_enum", False), # Additive...
+ b"CurrentMappingType": (0, "p_enum", False), # UV.
+ b"UVSet": ("default", "p_string", False), # UVMap name.
+ b"WrapModeU": (0, "p_enum", False), # Repeat.
+ b"WrapModeV": (0, "p_enum", False), # Repeat.
+ b"UVSwap": (False, "p_bool", False),
+ b"Translation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"Rotation": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"Scaling": ((1.0, 1.0, 1.0), "p_vector_3d", False),
+ b"TextureRotationPivot": ((0.0, 0.0, 0.0), "p_vector_3d", False),
+ b"TextureScalingPivot": ((0.0, 0.0, 0.0), "p_vector_3d", False),
# Not sure about those two...
- (b"UseMaterial", (False, "p_bool", False)),
- (b"UseMipMap", (False, "p_bool", False)),
- ))
+ b"UseMaterial": (False, "p_bool", False),
+ b"UseMipMap": (False, "p_bool", False),
+ }
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"Texture", b"FbxFileTexture", props, nbr_users, [False])
@@ -432,86 +433,86 @@ def fbx_template_def_texture_file(scene, settings, override_defaults=None, nbr_u
def fbx_template_def_video(scene, settings, override_defaults=None, nbr_users=0):
# WIP...
- props = OrderedDict((
+ props = {
# All pictures.
- (b"Width", (0, "p_integer", False)),
- (b"Height", (0, "p_integer", False)),
- (b"Path", ("", "p_string_url", False)),
- (b"AccessMode", (0, "p_enum", False)), # Disk (0=Disk, 1=Mem, 2=DiskAsync).
+ b"Width": (0, "p_integer", False),
+ b"Height": (0, "p_integer", False),
+ b"Path": ("", "p_string_url", False),
+ b"AccessMode": (0, "p_enum", False), # Disk (0=Disk, 1=Mem, 2=DiskAsync).
# All videos.
- (b"StartFrame", (0, "p_integer", False)),
- (b"StopFrame", (0, "p_integer", False)),
- (b"Offset", (0, "p_timestamp", False)),
- (b"PlaySpeed", (0.0, "p_double", False)),
- (b"FreeRunning", (False, "p_bool", False)),
- (b"Loop", (False, "p_bool", False)),
- (b"InterlaceMode", (0, "p_enum", False)), # None, i.e. progressive.
+ b"StartFrame": (0, "p_integer", False),
+ b"StopFrame": (0, "p_integer", False),
+ b"Offset": (0, "p_timestamp", False),
+ b"PlaySpeed": (0.0, "p_double", False),
+ b"FreeRunning": (False, "p_bool", False),
+ b"Loop": (False, "p_bool", False),
+ b"InterlaceMode": (0, "p_enum", False), # None, i.e. progressive.
# Image sequences.
- (b"ImageSequence", (False, "p_bool", False)),
- (b"ImageSequenceOffset", (0, "p_integer", False)),
- (b"FrameRate", (0.0, "p_double", False)),
- (b"LastFrame", (0, "p_integer", False)),
- ))
+ b"ImageSequence": (False, "p_bool", False),
+ b"ImageSequenceOffset": (0, "p_integer", False),
+ b"FrameRate": (0.0, "p_double", False),
+ b"LastFrame": (0, "p_integer", False),
+ }
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"Video", b"FbxVideo", props, nbr_users, [False])
def fbx_template_def_pose(scene, settings, override_defaults=None, nbr_users=0):
- props = OrderedDict()
+ props = {}
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"Pose", b"", props, nbr_users, [False])
def fbx_template_def_deformer(scene, settings, override_defaults=None, nbr_users=0):
- props = OrderedDict()
+ props = {}
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"Deformer", b"", props, nbr_users, [False])
def fbx_template_def_animstack(scene, settings, override_defaults=None, nbr_users=0):
- props = OrderedDict((
- (b"Description", ("", "p_string", False)),
- (b"LocalStart", (0, "p_timestamp", False)),
- (b"LocalStop", (0, "p_timestamp", False)),
- (b"ReferenceStart", (0, "p_timestamp", False)),
- (b"ReferenceStop", (0, "p_timestamp", False)),
- ))
+ props = {
+ b"Description": ("", "p_string", False),
+ b"LocalStart": (0, "p_timestamp", False),
+ b"LocalStop": (0, "p_timestamp", False),
+ b"ReferenceStart": (0, "p_timestamp", False),
+ b"ReferenceStop": (0, "p_timestamp", False),
+ }
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"AnimationStack", b"FbxAnimStack", props, nbr_users, [False])
def fbx_template_def_animlayer(scene, settings, override_defaults=None, nbr_users=0):
- props = OrderedDict((
- (b"Weight", (100.0, "p_number", True)),
- (b"Mute", (False, "p_bool", False)),
- (b"Solo", (False, "p_bool", False)),
- (b"Lock", (False, "p_bool", False)),
- (b"Color", ((0.8, 0.8, 0.8), "p_color_rgb", False)),
- (b"BlendMode", (0, "p_enum", False)),
- (b"RotationAccumulationMode", (0, "p_enum", False)),
- (b"ScaleAccumulationMode", (0, "p_enum", False)),
- (b"BlendModeBypass", (0, "p_ulonglong", False)),
- ))
+ props = {
+ b"Weight": (100.0, "p_number", True),
+ b"Mute": (False, "p_bool", False),
+ b"Solo": (False, "p_bool", False),
+ b"Lock": (False, "p_bool", False),
+ b"Color": ((0.8, 0.8, 0.8), "p_color_rgb", False),
+ b"BlendMode": (0, "p_enum", False),
+ b"RotationAccumulationMode": (0, "p_enum", False),
+ b"ScaleAccumulationMode": (0, "p_enum", False),
+ b"BlendModeBypass": (0, "p_ulonglong", False),
+ }
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"AnimationLayer", b"FbxAnimLayer", props, nbr_users, [False])
def fbx_template_def_animcurvenode(scene, settings, override_defaults=None, nbr_users=0):
- props = OrderedDict((
- (FBX_ANIM_PROPSGROUP_NAME.encode(), (None, "p_compound", False)),
- ))
+ props = {
+ FBX_ANIM_PROPSGROUP_NAME.encode(): (None, "p_compound", False),
+ }
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"AnimationCurveNode", b"FbxAnimCurveNode", props, nbr_users, [False])
def fbx_template_def_animcurve(scene, settings, override_defaults=None, nbr_users=0):
- props = OrderedDict()
+ props = {}
if override_defaults is not None:
props.update(override_defaults)
return FBXTemplate(b"AnimationCurve", b"", props, nbr_users, [False])
@@ -571,13 +572,13 @@ def fbx_data_empty_elements(root, empty, scene_data):
# No custom properties, already saved with object (Model).
-def fbx_data_lamp_elements(root, lamp, scene_data):
+def fbx_data_light_elements(root, lamp, scene_data):
"""
Write the Lamp data block.
"""
gscale = scene_data.settings.global_scale
- lamp_key = scene_data.data_lamps[lamp]
+ light_key = scene_data.data_lights[lamp]
do_light = True
decay_type = FBX_LIGHT_DECAY_TYPES['CONSTANT']
do_shadow = False
@@ -585,11 +586,11 @@ def fbx_data_lamp_elements(root, lamp, scene_data):
if lamp.type not in {'HEMI'}:
if lamp.type not in {'SUN', 'AREA'}:
decay_type = FBX_LIGHT_DECAY_TYPES[lamp.falloff_type]
- do_light = (not lamp.use_only_shadow) and (lamp.use_specular or lamp.use_diffuse)
- do_shadow = lamp.shadow_method not in {'NOSHADOW'}
+ do_light = True
+ do_shadow = lamp.use_shadow
shadow_color = lamp.shadow_color
- light = elem_data_single_int64(root, b"NodeAttribute", get_fbx_uuid_from_key(lamp_key))
+ light = elem_data_single_int64(root, b"NodeAttribute", get_fbx_uuid_from_key(light_key))
light.add_string(fbx_name_class(lamp.name.encode(), b"NodeAttribute"))
light.add_string(b"Light")
@@ -629,8 +630,8 @@ def fbx_data_camera_elements(root, cam_obj, scene_data):
# Real data now, good old camera!
# Object transform info.
loc, rot, scale, matrix, matrix_rot = cam_obj.fbx_object_tx(scene_data)
- up = matrix_rot * Vector((0.0, 1.0, 0.0))
- to = matrix_rot * Vector((0.0, 0.0, -1.0))
+ up = matrix_rot @ Vector((0.0, 1.0, 0.0))
+ to = matrix_rot @ Vector((0.0, 0.0, -1.0))
# Render settings.
# TODO We could export much more...
render = scene_data.scene.render
@@ -1111,38 +1112,39 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
del _uvtuples_gen
# Face's materials.
- me_fbxmats_idx = scene_data.mesh_mat_indices.get(me)
- if me_fbxmats_idx is not None:
- me_blmats = me.materials
- if me_fbxmats_idx and me_blmats:
- lay_mat = elem_data_single_int32(geom, b"LayerElementMaterial", 0)
- elem_data_single_int32(lay_mat, b"Version", FBX_GEOMETRY_MATERIAL_VERSION)
- elem_data_single_string(lay_mat, b"Name", b"")
- nbr_mats = len(me_fbxmats_idx)
+ me_fbxmaterials_idx = scene_data.mesh_material_indices.get(me)
+ if me_fbxmaterials_idx is not None:
+ me_blmaterials = me.materials
+ if me_fbxmaterials_idx and me_blmaterials:
+ lay_ma = elem_data_single_int32(geom, b"LayerElementMaterial", 0)
+ elem_data_single_int32(lay_ma, b"Version", FBX_GEOMETRY_MATERIAL_VERSION)
+ elem_data_single_string(lay_ma, b"Name", b"")
+ nbr_mats = len(me_fbxmaterials_idx)
if nbr_mats > 1:
t_pm = array.array(data_types.ARRAY_INT32, (0,)) * len(me.polygons)
me.polygons.foreach_get("material_index", t_pm)
# We have to validate mat indices, and map them to FBX indices.
# Note a mat might not be in me_fbxmats_idx (e.g. node mats are ignored).
- blmats_to_fbxmats_idxs = [me_fbxmats_idx[m] for m in me_blmats if m in me_fbxmats_idx]
- mat_idx_limit = len(blmats_to_fbxmats_idxs)
- def_mat = blmats_to_fbxmats_idxs[0]
- _gen = (blmats_to_fbxmats_idxs[m] if m < mat_idx_limit else def_mat for m in t_pm)
+ blmaterials_to_fbxmaterials_idxs = [me_fbxmaterials_idx[m]
+ for m in me_blmaterials if m in me_fbxmaterials_idx]
+ ma_idx_limit = len(blmaterials_to_fbxmaterials_idxs)
+ def_ma = blmaterials_to_fbxmaterials_idxs[0]
+ _gen = (blmaterials_to_fbxmaterials_idxs[m] if m < ma_idx_limit else def_ma for m in t_pm)
t_pm = array.array(data_types.ARRAY_INT32, _gen)
- elem_data_single_string(lay_mat, b"MappingInformationType", b"ByPolygon")
+ elem_data_single_string(lay_ma, b"MappingInformationType", b"ByPolygon")
# XXX Logically, should be "Direct" reference type, since we do not have any index array, and have one
# value per polygon...
# But looks like FBX expects it to be IndexToDirect here (maybe because materials are already
# indices??? *sigh*).
- elem_data_single_string(lay_mat, b"ReferenceInformationType", b"IndexToDirect")
- elem_data_single_int32_array(lay_mat, b"Materials", t_pm)
+ elem_data_single_string(lay_ma, b"ReferenceInformationType", b"IndexToDirect")
+ elem_data_single_int32_array(lay_ma, b"Materials", t_pm)
del t_pm
else:
- elem_data_single_string(lay_mat, b"MappingInformationType", b"AllSame")
- elem_data_single_string(lay_mat, b"ReferenceInformationType", b"IndexToDirect")
- elem_data_single_int32_array(lay_mat, b"Materials", [0])
+ elem_data_single_string(lay_ma, b"MappingInformationType", b"AllSame")
+ elem_data_single_string(lay_ma, b"ReferenceInformationType", b"IndexToDirect")
+ elem_data_single_int32_array(lay_ma, b"Materials", [0])
# And the "layer TOC"...
@@ -1171,10 +1173,10 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
lay_uv = elem_empty(layer, b"LayerElement")
elem_data_single_string(lay_uv, b"Type", b"LayerElementUV")
elem_data_single_int32(lay_uv, b"TypedIndex", 0)
- if me_fbxmats_idx is not None:
- lay_mat = elem_empty(layer, b"LayerElement")
- elem_data_single_string(lay_mat, b"Type", b"LayerElementMaterial")
- elem_data_single_int32(lay_mat, b"TypedIndex", 0)
+ if me_fbxmaterials_idx is not None:
+ lay_ma = elem_empty(layer, b"LayerElement")
+ elem_data_single_string(lay_ma, b"Type", b"LayerElementMaterial")
+ elem_data_single_int32(lay_ma, b"TypedIndex", 0)
# Add other uv and/or vcol layers...
for vcolidx, uvidx, tspaceidx in zip_longest(range(1, vcolnumber), range(1, uvnumber), range(1, tspacenumber),
@@ -1204,76 +1206,70 @@ def fbx_data_mesh_elements(root, me_obj, scene_data, done_meshes):
done_meshes.add(me_key)
-def check_skip_material(mat):
- """Simple helper to check whether we actually support exporting that material or not"""
- return mat.type not in {'SURFACE'}
-
-
-def fbx_data_material_elements(root, mat, scene_data):
+def fbx_data_material_elements(root, ma, scene_data):
"""
Write the Material data block.
"""
+
ambient_color = (0.0, 0.0, 0.0)
if scene_data.data_world:
- ambient_color = next(iter(scene_data.data_world.keys())).ambient_color
+ ambient_color = next(iter(scene_data.data_world.keys())).color
- mat_key, _objs = scene_data.data_materials[mat]
- skip_mat = check_skip_material(mat)
- node_mat = mat.use_nodes
- mat_type = b"Phong"
- # Approximation...
- if not skip_mat and not node_mat and mat.specular_shader not in {'COOKTORR', 'PHONG', 'BLINN'}:
- mat_type = b"Lambert"
+ ma_wrap = node_shader_utils.PrincipledBSDFWrapper(ma, is_readonly=True)
+ ma_key, _objs = scene_data.data_materials[ma]
+ ma_type = b"Phong"
- fbx_mat = elem_data_single_int64(root, b"Material", get_fbx_uuid_from_key(mat_key))
- fbx_mat.add_string(fbx_name_class(mat.name.encode(), b"Material"))
- fbx_mat.add_string(b"")
+ fbx_ma = elem_data_single_int64(root, b"Material", get_fbx_uuid_from_key(ma_key))
+ fbx_ma.add_string(fbx_name_class(ma.name.encode(), b"Material"))
+ fbx_ma.add_string(b"")
- elem_data_single_int32(fbx_mat, b"Version", FBX_MATERIAL_VERSION)
+ elem_data_single_int32(fbx_ma, b"Version", FBX_MATERIAL_VERSION)
# those are not yet properties, it seems...
- elem_data_single_string(fbx_mat, b"ShadingModel", mat_type)
- elem_data_single_int32(fbx_mat, b"MultiLayer", 0) # Should be bool...
+ elem_data_single_string(fbx_ma, b"ShadingModel", ma_type)
+ elem_data_single_int32(fbx_ma, b"MultiLayer", 0) # Should be bool...
tmpl = elem_props_template_init(scene_data.templates, b"Material")
- props = elem_properties(fbx_mat)
-
- if not skip_mat:
- elem_props_template_set(tmpl, props, "p_string", b"ShadingModel", mat_type.decode())
- elem_props_template_set(tmpl, props, "p_color", b"DiffuseColor", mat.diffuse_color)
- elem_props_template_set(tmpl, props, "p_number", b"DiffuseFactor", mat.diffuse_intensity)
- if not node_mat:
- elem_props_template_set(tmpl, props, "p_color", b"EmissiveColor", mat.diffuse_color)
- elem_props_template_set(tmpl, props, "p_number", b"EmissiveFactor", mat.emit)
- elem_props_template_set(tmpl, props, "p_color", b"AmbientColor", ambient_color)
- elem_props_template_set(tmpl, props, "p_number", b"AmbientFactor", mat.ambient)
- elem_props_template_set(tmpl, props, "p_color", b"TransparentColor",
- mat.diffuse_color if mat.use_transparency else (1.0, 1.0, 1.0))
- elem_props_template_set(tmpl, props, "p_number", b"TransparencyFactor",
- 1.0 - mat.alpha if mat.use_transparency else 0.0)
- elem_props_template_set(tmpl, props, "p_number", b"Opacity", mat.alpha if mat.use_transparency else 1.0)
- elem_props_template_set(tmpl, props, "p_vector_3d", b"NormalMap", (0.0, 0.0, 0.0))
- # Not sure about those...
- """
- b"Bump": ((0.0, 0.0, 0.0), "p_vector_3d"),
- b"BumpFactor": (1.0, "p_double"),
- b"DisplacementColor": ((0.0, 0.0, 0.0), "p_color_rgb"),
- b"DisplacementFactor": (0.0, "p_double"),
- """
- if mat_type == b"Phong":
- elem_props_template_set(tmpl, props, "p_color", b"SpecularColor", mat.specular_color)
- elem_props_template_set(tmpl, props, "p_number", b"SpecularFactor", mat.specular_intensity / 2.0)
- # See Material template about those two!
- elem_props_template_set(tmpl, props, "p_number", b"Shininess", (mat.specular_hardness - 1.0) / 5.10)
- elem_props_template_set(tmpl, props, "p_number", b"ShininessExponent", (mat.specular_hardness - 1.0) / 5.10)
- elem_props_template_set(tmpl, props, "p_color", b"ReflectionColor", mat.mirror_color)
- elem_props_template_set(tmpl, props, "p_number", b"ReflectionFactor",
- mat.raytrace_mirror.reflect_factor if mat.raytrace_mirror.use else 0.0)
+ props = elem_properties(fbx_ma)
+
+ elem_props_template_set(tmpl, props, "p_string", b"ShadingModel", ma_type.decode())
+ elem_props_template_set(tmpl, props, "p_color", b"DiffuseColor", ma_wrap.base_color)
+ # Not in Principled BSDF, so assuming always 1
+ elem_props_template_set(tmpl, props, "p_number", b"DiffuseFactor", 1.0)
+ # Not in Principled BSDF, so assuming always 0
+ elem_props_template_set(tmpl, props, "p_color", b"EmissiveColor", ma_wrap.base_color)
+ elem_props_template_set(tmpl, props, "p_number", b"EmissiveFactor", 0.0)
+ # Not in Principled BSDF, so assuming always 0
+ elem_props_template_set(tmpl, props, "p_color", b"AmbientColor", ambient_color)
+ elem_props_template_set(tmpl, props, "p_number", b"AmbientFactor", 0.0)
+ elem_props_template_set(tmpl, props, "p_color", b"TransparentColor", ma_wrap.base_color)
+ elem_props_template_set(tmpl, props, "p_number", b"TransparencyFactor", ma_wrap.transmission)
+ elem_props_template_set(tmpl, props, "p_number", b"Opacity", 1.0 - ma_wrap.transmission)
+ elem_props_template_set(tmpl, props, "p_vector_3d", b"NormalMap", (0.0, 0.0, 0.0))
+ # Not sure about those...
+ """
+ b"Bump": ((0.0, 0.0, 0.0), "p_vector_3d"),
+ b"BumpFactor": (1.0, "p_double"),
+ b"DisplacementColor": ((0.0, 0.0, 0.0), "p_color_rgb"),
+ b"DisplacementFactor": (0.0, "p_double"),
+ """
+ # TODO: use specular tint?
+ elem_props_template_set(tmpl, props, "p_color", b"SpecularColor", ma_wrap.base_color)
+ elem_props_template_set(tmpl, props, "p_number", b"SpecularFactor", ma_wrap.specular / 2.0)
+ # See Material template about those two!
+ # XXX Totally empirical conversion, trying to adapt it
+ # (from 0.0 - 100.0 FBX shininess range to 1.0 - 0.0 Principled BSDF range)...
+ shininess = (1.0 - ma_wrap.roughness) * 10
+ shininess *= shininess
+ elem_props_template_set(tmpl, props, "p_number", b"Shininess", shininess)
+ elem_props_template_set(tmpl, props, "p_number", b"ShininessExponent", shininess)
+ elem_props_template_set(tmpl, props, "p_color", b"ReflectionColor", ma_wrap.base_color)
+ elem_props_template_set(tmpl, props, "p_number", b"ReflectionFactor", ma_wrap.metallic)
elem_props_template_finalize(tmpl, props)
# Custom properties.
if scene_data.settings.use_custom_props:
- fbx_data_element_custom_properties(props, mat)
+ fbx_data_element_custom_properties(props, ma)
def _gen_vid_path(img, scene_data):
@@ -1284,7 +1280,7 @@ def _gen_vid_path(img, scene_data):
return fname_abs, fname_rel
-def fbx_data_texture_file_elements(root, tex, scene_data):
+def fbx_data_texture_file_elements(root, blender_tex_key, scene_data):
"""
Write the (file) Texture data block.
"""
@@ -1292,45 +1288,50 @@ def fbx_data_texture_file_elements(root, tex, scene_data):
# Textures do not seem to use properties as much as they could.
# For now assuming most logical and simple stuff.
- tex_key, _mats = scene_data.data_textures[tex]
- img = tex.texture.image
+ ma, sock_name = blender_tex_key
+ ma_wrap = node_shader_utils.PrincipledBSDFWrapper(ma, is_readonly=True)
+ tex_key, _fbx_prop = scene_data.data_textures[blender_tex_key]
+ tex = getattr(ma_wrap, sock_name)
+ img = tex.image
fname_abs, fname_rel = _gen_vid_path(img, scene_data)
fbx_tex = elem_data_single_int64(root, b"Texture", get_fbx_uuid_from_key(tex_key))
- fbx_tex.add_string(fbx_name_class(tex.name.encode(), b"Texture"))
+ fbx_tex.add_string(fbx_name_class(sock_name.encode(), b"Texture"))
fbx_tex.add_string(b"")
elem_data_single_string(fbx_tex, b"Type", b"TextureVideoClip")
elem_data_single_int32(fbx_tex, b"Version", FBX_TEXTURE_VERSION)
- elem_data_single_string(fbx_tex, b"TextureName", fbx_name_class(tex.name.encode(), b"Texture"))
+ elem_data_single_string(fbx_tex, b"TextureName", fbx_name_class(sock_name.encode(), b"Texture"))
elem_data_single_string(fbx_tex, b"Media", fbx_name_class(img.name.encode(), b"Video"))
elem_data_single_string_unicode(fbx_tex, b"FileName", fname_abs)
elem_data_single_string_unicode(fbx_tex, b"RelativeFilename", fname_rel)
alpha_source = 0 # None
if img.use_alpha:
- if tex.texture.use_calculate_alpha:
- alpha_source = 1 # RGBIntensity as alpha.
- else:
- alpha_source = 2 # Black, i.e. alpha channel.
+ # ~ if tex.texture.use_calculate_alpha:
+ # ~ alpha_source = 1 # RGBIntensity as alpha.
+ # ~ else:
+ # ~ alpha_source = 2 # Black, i.e. alpha channel.
+ alpha_source = 2 # Black, i.e. alpha channel.
# BlendMode not useful for now, only affects layered textures afaics.
mapping = 0 # UV.
uvset = None
- if tex.texture_coords in {'ORCO'}: # XXX Others?
- if tex.mapping in {'FLAT'}:
+ if tex.texcoords == 'ORCO': # XXX Others?
+ if tex.projection == 'FLAT':
mapping = 1 # Planar
- elif tex.mapping in {'CUBE'}:
+ elif tex.projection == 'CUBE':
mapping = 4 # Box
- elif tex.mapping in {'TUBE'}:
+ elif tex.projection == 'TUBE':
mapping = 3 # Cylindrical
- elif tex.mapping in {'SPHERE'}:
+ elif tex.projection == 'SPHERE':
mapping = 2 # Spherical
- elif tex.texture_coords in {'UV'}:
+ elif tex.texcoords == 'UV':
mapping = 0 # UV
# Yuck, UVs are linked by mere names it seems... :/
- uvset = tex.uv_layer
+ # XXX TODO how to get that now???
+ # uvset = tex.uv_layer
wrap_mode = 1 # Clamp
- if tex.texture.extension in {'REPEAT'}:
+ if tex.extension == 'REPEAT':
wrap_mode = 0 # Repeat
tmpl = elem_props_template_init(scene_data.templates, b"TextureFile")
@@ -1343,16 +1344,15 @@ def fbx_data_texture_file_elements(root, tex, scene_data):
elem_props_template_set(tmpl, props, "p_string", b"UVSet", uvset)
elem_props_template_set(tmpl, props, "p_enum", b"WrapModeU", wrap_mode)
elem_props_template_set(tmpl, props, "p_enum", b"WrapModeV", wrap_mode)
- elem_props_template_set(tmpl, props, "p_vector_3d", b"Translation", tex.offset)
- elem_props_template_set(tmpl, props, "p_vector_3d", b"Scaling", tex.scale)
+ elem_props_template_set(tmpl, props, "p_vector_3d", b"Translation", tex.translation)
+ elem_props_template_set(tmpl, props, "p_vector_3d", b"Rotation", (-r for r in tex.rotation))
+ elem_props_template_set(tmpl, props, "p_vector_3d", b"Scaling", (((1.0 / s) if s != 0.0 else 1.0) for s in tex.scale))
# UseMaterial should always be ON imho.
elem_props_template_set(tmpl, props, "p_bool", b"UseMaterial", True)
- elem_props_template_set(tmpl, props, "p_bool", b"UseMipMap", tex.texture.use_mipmap)
+ elem_props_template_set(tmpl, props, "p_bool", b"UseMipMap", False)
elem_props_template_finalize(tmpl, props)
- # Custom properties.
- if scene_data.settings.use_custom_props:
- fbx_data_element_custom_properties(props, tex.texture)
+ # No custom properties, since that's not a data-block anymore.
def fbx_data_video_elements(root, vid, scene_data):
@@ -1462,7 +1462,7 @@ def fbx_data_armature_elements(root, arm_obj, scene_data):
bo_vg_idx = {bo_obj.bdata.name: ob.vertex_groups[bo_obj.bdata.name].index
for bo_obj in clusters.keys() if bo_obj.bdata.name in ob.vertex_groups}
valid_idxs = set(bo_vg_idx.values())
- vgroups = {vg.index: OrderedDict() for vg in ob.vertex_groups}
+ vgroups = {vg.index: {} for vg in ob.vertex_groups}
verts_vgroups = (sorted(((vg.group, vg.weight) for vg in v.groups if vg.weight and vg.group in valid_idxs),
key=lambda e: e[1], reverse=True)
for v in me.vertices)
@@ -1497,7 +1497,7 @@ def fbx_data_armature_elements(root, arm_obj, scene_data):
# http://area.autodesk.com/forum/autodesk-fbx/fbx-sdk/why-the-values-return-
# by-fbxcluster-gettransformmatrix-x-not-same-with-the-value-in-ascii-fbx-file/
elem_data_single_float64_array(fbx_clstr, b"Transform",
- matrix4_to_array(mat_world_bones[bo_obj].inverted_safe() * mat_world_obj))
+ matrix4_to_array(mat_world_bones[bo_obj].inverted_safe() @ mat_world_obj))
elem_data_single_float64_array(fbx_clstr, b"TransformLink", matrix4_to_array(mat_world_bones[bo_obj]))
elem_data_single_float64_array(fbx_clstr, b"TransformAssociateModel", matrix4_to_array(mat_world_arm))
@@ -1570,7 +1570,7 @@ def fbx_data_object_elements(root, ob_obj, scene_data):
obj_type = b"Null"
elif (ob_obj.type in BLENDER_OBJECT_TYPES_MESHLIKE):
obj_type = b"Mesh"
- elif (ob_obj.type == 'LAMP'):
+ elif (ob_obj.type == 'LIGHT'):
obj_type = b"Light"
elif (ob_obj.type == 'CAMERA'):
obj_type = b"Camera"
@@ -1717,46 +1717,30 @@ def fbx_data_animation_elements(root, scene_data):
# ##### Top-level FBX data container. #####
-def fbx_mat_properties_from_texture(tex):
- """
- Returns a set of FBX metarial properties that are affected by the given texture.
- Quite obviously, this is a fuzzy and far-from-perfect mapping! Amounts of influence are completely lost, e.g.
- Note tex is actually expected to be a texture slot.
- """
- # Mapping Blender -> FBX (blend_use_name, blend_fact_name, fbx_name).
- blend_to_fbx = (
- # Lambert & Phong...
- ("diffuse", "diffuse", b"DiffuseFactor"),
- ("color_diffuse", "diffuse_color", b"DiffuseColor"),
- ("alpha", "alpha", b"TransparencyFactor"),
- ("diffuse", "diffuse", b"TransparentColor"), # Uses diffuse color in Blender!
- ("emit", "emit", b"EmissiveFactor"),
- ("diffuse", "diffuse", b"EmissiveColor"), # Uses diffuse color in Blender!
- ("ambient", "ambient", b"AmbientFactor"),
- # ("", "", b"AmbientColor"), # World stuff in Blender, for now ignore...
- ("normal", "normal", b"NormalMap"),
- # Note: unsure about those... :/
- # ("", "", b"Bump"),
- # ("", "", b"BumpFactor"),
- # ("", "", b"DisplacementColor"),
- # ("", "", b"DisplacementFactor"),
- # Phong only.
- ("specular", "specular", b"SpecularFactor"),
- ("color_spec", "specular_color", b"SpecularColor"),
- # See Material template about those two!
- ("hardness", "hardness", b"Shininess"),
- ("hardness", "hardness", b"ShininessExponent"),
- ("mirror", "mirror", b"ReflectionColor"),
- ("raymir", "raymir", b"ReflectionFactor"),
- )
-
- tex_fbx_props = set()
- for use_map_name, name_factor, fbx_prop_name in blend_to_fbx:
- # Always export enabled textures, even if they have a null influence...
- if getattr(tex, "use_map_" + use_map_name):
- tex_fbx_props.add(fbx_prop_name)
-
- return tex_fbx_props
+# Mapping Blender -> FBX (principled_socket_name, fbx_name).
+PRINCIPLED_TEXTURE_SOCKETS_TO_FBX = (
+ # ("diffuse", "diffuse", b"DiffuseFactor"),
+ ("base_color_texture", b"DiffuseColor"),
+ ("transmission_texture", b"TransparencyFactor"),
+ # ("base_color_texture", b"TransparentColor"), # Uses diffuse color in Blender!
+ # ("emit", "emit", b"EmissiveFactor"),
+ # ("diffuse", "diffuse", b"EmissiveColor"), # Uses diffuse color in Blender!
+ # ("ambient", "ambient", b"AmbientFactor"),
+ # ("", "", b"AmbientColor"), # World stuff in Blender, for now ignore...
+ ("normalmap_texture", b"NormalMap"),
+ # Note: unsure about those... :/
+ # ("", "", b"Bump"),
+ # ("", "", b"BumpFactor"),
+ # ("", "", b"DisplacementColor"),
+ # ("", "", b"DisplacementFactor"),
+ ("specular_texture", b"SpecularFactor"),
+ # ("base_color", b"SpecularColor"), # TODO: use tint?
+ # See Material template about those two!
+ ("roughness_texture", b"Shininess"),
+ ("roughness_texture", b"ShininessExponent"),
+ # ("mirror", "mirror", b"ReflectionColor"),
+ ("metallic_texture", b"ReflectionFactor"),
+)
def fbx_skeleton_from_armature(scene, settings, arm_obj, objects, data_meshes,
@@ -1771,7 +1755,7 @@ def fbx_skeleton_from_armature(scene, settings, arm_obj, objects, data_meshes,
data_empties[arm_obj] = get_blender_empty_key(arm_obj.bdata)
arm_data = arm_obj.bdata.data
- bones = OrderedDict()
+ bones = {}
for bo in arm_obj.bones:
if settings.use_armature_deform_only:
if bo.bdata.use_deform:
@@ -1785,7 +1769,7 @@ def fbx_skeleton_from_armature(scene, settings, arm_obj, objects, data_meshes,
else:
bones[bo] = True
- bones = OrderedDict((bo, None) for bo, use in bones.items() if use)
+ bones = {bo: None for bo, use in bones.items() if use}
if not bones:
return
@@ -1813,8 +1797,8 @@ def fbx_skeleton_from_armature(scene, settings, arm_obj, objects, data_meshes,
# Note: bindpose have no relations at all (no connections), so no need for any preprocess for them.
# Create skin & clusters relations (note skins are connected to geometry, *not* model!).
_key, me, _free = data_meshes[ob_obj]
- clusters = OrderedDict((bo, get_blender_bone_cluster_key(arm_obj.bdata, me, bo.bdata)) for bo in bones)
- data_deformers_skin.setdefault(arm_obj, OrderedDict())[me] = (get_blender_armature_skin_key(arm_obj.bdata, me),
+ clusters = {bo: get_blender_bone_cluster_key(arm_obj.bdata, me, bo.bdata) for bo in bones}
+ data_deformers_skin.setdefault(arm_obj, {})[me] = (get_blender_armature_skin_key(arm_obj.bdata, me),
ob_obj, clusters)
# We don't want a regular parent relationship for those in FBX...
@@ -1849,9 +1833,9 @@ def fbx_generate_leaf_bones(settings, data_bones):
bone_length = (parent.bdata.tail_local - parent.bdata.head_local).length
matrix = Matrix.Translation((0, bone_length, 0))
if settings.bone_correction_matrix_inv:
- matrix = settings.bone_correction_matrix_inv * matrix
+ matrix = settings.bone_correction_matrix_inv @ matrix
if settings.bone_correction_matrix:
- matrix = matrix * settings.bone_correction_matrix
+ matrix = matrix @ settings.bone_correction_matrix
leaf_bones.append((node_name, parent_uuid, node_uuid, attr_uuid, matrix, hide, size))
return leaf_bones
@@ -1864,6 +1848,7 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
bake_step = scene_data.settings.bake_anim_step
simplify_fac = scene_data.settings.bake_anim_simplify_factor
scene = scene_data.scene
+ depsgraph = scene_data.depsgraph
force_keying = scene_data.settings.bake_anim_use_all_bones
force_sek = scene_data.settings.bake_anim_force_startend_keying
@@ -1874,16 +1859,14 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
continue
if ob_obj.type == 'ARMATURE':
objects |= {bo_obj for bo_obj in ob_obj.bones if bo_obj in scene_data.objects}
- ob_obj.dupli_list_create(scene, 'RENDER')
- for dp_obj in ob_obj.dupli_list:
+ for dp_obj in ob_obj.dupli_list_gen(depsgraph):
if dp_obj in scene_data.objects:
objects.add(dp_obj)
- ob_obj.dupli_list_clear()
else:
objects = scene_data.objects
back_currframe = scene.frame_current
- animdata_ob = OrderedDict()
+ animdata_ob = {}
p_rots = {}
for ob_obj in objects:
@@ -1899,8 +1882,8 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
p_rots[ob_obj] = rot
force_key = (simplify_fac == 0.0)
+ animdata_shapes = {}
- animdata_shapes = OrderedDict()
for me, (me_key, _shapes_key, shapes) in scene_data.data_deformers_shape.items():
# Ignore absolute shape keys for now!
if not me.shape_keys.use_relative:
@@ -1911,7 +1894,7 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
acnode.add_group(me_key, shape.name, shape.name, (shape.name,))
animdata_shapes[channel_key] = (acnode, me, shape)
- animdata_cameras = OrderedDict()
+ animdata_cameras = {}
for cam_obj, cam_key in scene_data.data_cameras.items():
cam = cam_obj.bdata.data
acnode = AnimationCurveNodeWrapper(cam_key, 'CAMERA_FOCAL', force_key, force_sek, (cam.lens,))
@@ -1920,10 +1903,10 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
currframe = f_start
while currframe <= f_end:
real_currframe = currframe - f_start if start_zero else currframe
- scene.frame_set(int(currframe), currframe - int(currframe))
+ scene.frame_set(int(currframe), subframe=currframe - int(currframe))
- for ob_obj in animdata_ob:
- ob_obj.dupli_list_create(scene, 'RENDER')
+ for dp_obj in ob_obj.dupli_list_gen(depsgraph):
+ pass # Merely updating dupli matrix of ObjectWrapper...
for ob_obj, (anim_loc, anim_rot, anim_scale) in animdata_ob.items():
# We compute baked loc/rot/scale for all objects (rot being euler-compat with previous value!).
p_rot = p_rots.get(ob_obj, None)
@@ -1932,17 +1915,15 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
anim_loc.add_keyframe(real_currframe, loc)
anim_rot.add_keyframe(real_currframe, tuple(convert_rad_to_deg_iter(rot)))
anim_scale.add_keyframe(real_currframe, scale)
- for ob_obj in objects:
- ob_obj.dupli_list_clear()
for anim_shape, me, shape in animdata_shapes.values():
anim_shape.add_keyframe(real_currframe, (shape.value * 100.0,))
for anim_camera, camera in animdata_cameras.values():
anim_camera.add_keyframe(real_currframe, (camera.lens,))
currframe += bake_step
- scene.frame_set(back_currframe, 0.0)
+ scene.frame_set(back_currframe, subframe=0.0)
- animations = OrderedDict()
+ animations = {}
# And now, produce final data (usable by FBX export code)
# Objects-like loc/rot/scale...
@@ -1952,34 +1933,28 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
if not anim:
continue
for obj_key, group_key, group, fbx_group, fbx_gname in anim.get_final_data(scene, ref_id, force_keep):
- anim_data = animations.get(obj_key)
- if anim_data is None:
- anim_data = animations[obj_key] = ("dummy_unused_key", OrderedDict())
+ anim_data = animations.setdefault(obj_key, ("dummy_unused_key", {}))
anim_data[1][fbx_group] = (group_key, group, fbx_gname)
# And meshes' shape keys.
for channel_key, (anim_shape, me, shape) in animdata_shapes.items():
- final_keys = OrderedDict()
+ final_keys = {}
anim_shape.simplify(simplify_fac, bake_step, force_keep)
if not anim_shape:
continue
for elem_key, group_key, group, fbx_group, fbx_gname in anim_shape.get_final_data(scene, ref_id, force_keep):
- anim_data = animations.get(elem_key)
- if anim_data is None:
- anim_data = animations[elem_key] = ("dummy_unused_key", OrderedDict())
- anim_data[1][fbx_group] = (group_key, group, fbx_gname)
+ anim_data = animations.setdefault(elem_key, ("dummy_unused_key", {}))
+ anim_data[1][fbx_group] = (group_key, group, fbx_gname)
# And cameras' lens keys.
for cam_key, (anim_camera, camera) in animdata_cameras.items():
- final_keys = OrderedDict()
+ final_keys = {}
anim_camera.simplify(simplify_fac, bake_step, force_keep)
if not anim_camera:
continue
for elem_key, group_key, group, fbx_group, fbx_gname in anim_camera.get_final_data(scene, ref_id, force_keep):
- anim_data = animations.get(elem_key)
- if anim_data is None:
- anim_data = animations[elem_key] = ("dummy_unused_key", OrderedDict())
- anim_data[1][fbx_group] = (group_key, group, fbx_gname)
+ anim_data = animations.setdefault(elem_key, ("dummy_unused_key", {}))
+ anim_data[1][fbx_group] = (group_key, group, fbx_gname)
astack_key = get_blender_anim_stack_key(scene, ref_id)
alayer_key = get_blender_anim_layer_key(scene, ref_id)
@@ -2045,7 +2020,7 @@ def fbx_animations(scene_data):
add_anim(animations, animated,
fbx_animations_do(scene_data, strip, strip.frame_start, strip.frame_end, True, force_keep=True))
strip.mute = True
- scene.frame_set(scene.frame_current, 0.0)
+ scene.frame_set(scene.frame_current, subframe=0.0)
for strip in strips:
strip.mute = False
@@ -2072,14 +2047,14 @@ def fbx_animations(scene_data):
'location', 'rotation_quaternion', 'rotation_axis_angle', 'rotation_euler', 'rotation_mode', 'scale',
'delta_location', 'delta_rotation_euler', 'delta_rotation_quaternion', 'delta_scale',
'lock_location', 'lock_rotation', 'lock_rotation_w', 'lock_rotations_4d', 'lock_scale',
- 'tag', 'layers', 'select', 'track_axis', 'up_axis', 'active_material', 'active_material_index',
- 'matrix_parent_inverse', 'empty_draw_type', 'empty_draw_size', 'empty_image_offset', 'pass_index',
- 'color', 'hide', 'hide_select', 'hide_render', 'use_slow_parent', 'slow_parent_offset',
- 'use_extra_recalc_object', 'use_extra_recalc_data', 'dupli_type', 'use_dupli_frames_speed',
- 'use_dupli_vertices_rotation', 'use_dupli_faces_scale', 'dupli_faces_scale', 'dupli_group',
+ 'tag', 'track_axis', 'up_axis', 'active_material', 'active_material_index',
+ 'matrix_parent_inverse', 'empty_display_type', 'empty_display_size', 'empty_image_offset', 'pass_index',
+ 'color', 'hide_viewport', 'hide_select', 'hide_render', 'use_slow_parent', 'slow_parent_offset',
+ 'dupli_type', 'use_dupli_frames_speed',
+ 'use_dupli_vertices_rotation', 'use_dupli_faces_scale', 'dupli_faces_scale',
'dupli_frames_start', 'dupli_frames_end', 'dupli_frames_on', 'dupli_frames_off',
- 'draw_type', 'show_bounds', 'draw_bounds_type', 'show_name', 'show_axis', 'show_texture_space',
- 'show_wire', 'show_all_edges', 'show_transparent', 'show_x_ray',
+ 'display_type', 'show_bounds', 'display_bounds_type', 'show_name', 'show_axis', 'show_texture_space',
+ 'show_wire', 'show_all_edges', 'show_transparent', 'show_in_front',
'show_only_shape_key', 'use_shape_key_edit_mode', 'active_shape_key_index',
)
for p in props:
@@ -2124,7 +2099,7 @@ def fbx_animations(scene_data):
pbo.matrix_basis = mat.copy()
ob.animation_data.action = org_act
restore_object(ob, ob_copy)
- scene.frame_set(scene.frame_current, 0.0)
+ scene.frame_set(scene.frame_current, subframe=0.0)
if pbones_matrices is not ...:
for pbo, mat in zip(ob.pose.bones, pbones_matrices):
@@ -2132,19 +2107,19 @@ def fbx_animations(scene_data):
ob.animation_data.action = org_act
bpy.data.objects.remove(ob_copy)
- scene.frame_set(scene.frame_current, 0.0)
+ scene.frame_set(scene.frame_current, subframe=0.0)
# Global (containing everything) animstack, only if not exporting NLA strips and/or all actions.
if not scene_data.settings.bake_anim_use_nla_strips and not scene_data.settings.bake_anim_use_all_actions:
add_anim(animations, animated, fbx_animations_do(scene_data, None, scene.frame_start, scene.frame_end, False))
# Be sure to update all matrices back to org state!
- scene.frame_set(scene.frame_current, 0.0)
+ scene.frame_set(scene.frame_current, subframe=0.0)
return animations, animated, frame_start, frame_end
-def fbx_data_from_scene(scene, settings):
+def fbx_data_from_scene(scene, depsgraph, settings):
"""
Do some pre-processing over scene's data...
"""
@@ -2159,34 +2134,32 @@ def fbx_data_from_scene(scene, settings):
# This is rather simple for now, maybe we could end generating templates with most-used values
# instead of default ones?
- objects = OrderedDict() # Because we do not have any ordered set...
+ objects = {} # Because we do not have any ordered set...
for ob in settings.context_objects:
if ob.type not in objtypes:
continue
ob_obj = ObjectWrapper(ob)
objects[ob_obj] = None
# Duplis...
- ob_obj.dupli_list_create(scene, 'RENDER')
- for dp_obj in ob_obj.dupli_list:
+ for dp_obj in ob_obj.dupli_list_gen(depsgraph):
if dp_obj.type not in dp_objtypes:
continue
objects[dp_obj] = None
- ob_obj.dupli_list_clear()
perfmon.step("FBX export prepare: Wrapping Data (lamps, cameras, empties)...")
- data_lamps = OrderedDict((ob_obj.bdata.data, get_blenderID_key(ob_obj.bdata.data))
- for ob_obj in objects if ob_obj.type == 'LAMP')
+ data_lights = {ob_obj.bdata.data: get_blenderID_key(ob_obj.bdata.data)
+ for ob_obj in objects if ob_obj.type == 'LIGHT'}
# Unfortunately, FBX camera data contains object-level data (like position, orientation, etc.)...
- data_cameras = OrderedDict((ob_obj, get_blenderID_key(ob_obj.bdata.data))
- for ob_obj in objects if ob_obj.type == 'CAMERA')
+ data_cameras = {ob_obj: get_blenderID_key(ob_obj.bdata.data)
+ for ob_obj in objects if ob_obj.type == 'CAMERA'}
# Yep! Contains nothing, but needed!
- data_empties = OrderedDict((ob_obj, get_blender_empty_key(ob_obj.bdata))
- for ob_obj in objects if ob_obj.type == 'EMPTY')
+ data_empties = {ob_obj: get_blender_empty_key(ob_obj.bdata)
+ for ob_obj in objects if ob_obj.type == 'EMPTY'}
perfmon.step("FBX export prepare: Wrapping Meshes...")
- data_meshes = OrderedDict()
+ data_meshes = {}
for ob_obj in objects:
if ob_obj.type not in BLENDER_OBJECT_TYPES_MESHLIKE:
continue
@@ -2218,10 +2191,8 @@ def fbx_data_from_scene(scene, settings):
use_org_data = False
if not use_org_data:
tmp_me = ob.to_mesh(
- scene,
- apply_modifiers=settings.use_mesh_modifiers,
- settings='RENDER' if settings.use_mesh_modifiers_render else 'PREVIEW',
- )
+ depsgraph,
+ apply_modifiers=settings.use_mesh_modifiers)
data_meshes[ob_obj] = (get_blenderID_key(tmp_me), tmp_me, True)
# Re-enable temporary disabled modifiers.
for mod, show_render in tmp_mods:
@@ -2236,7 +2207,7 @@ def fbx_data_from_scene(scene, settings):
perfmon.step("FBX export prepare: Wrapping ShapeKeys...")
# ShapeKeys.
- data_deformers_shape = OrderedDict()
+ data_deformers_shape = {}
geom_mat_co = settings.global_matrix if settings.bake_space_transform else None
for me_key, me, _free in data_meshes.values():
if not (me.shape_keys and len(me.shape_keys.key_blocks) > 1): # We do not want basis-only relative skeys...
@@ -2274,13 +2245,13 @@ def fbx_data_from_scene(scene, settings):
continue
channel_key, geom_key = get_blender_mesh_shape_channel_key(me, shape)
data = (channel_key, geom_key, shape_verts_co, shape_verts_idx)
- data_deformers_shape.setdefault(me, (me_key, shapes_key, OrderedDict()))[2][shape] = data
+ data_deformers_shape.setdefault(me, (me_key, shapes_key, {}))[2][shape] = data
perfmon.step("FBX export prepare: Wrapping Armatures...")
# Armatures!
- data_deformers_skin = OrderedDict()
- data_bones = OrderedDict()
+ data_deformers_skin = {}
+ data_bones = {}
arm_parents = set()
for ob_obj in tuple(objects):
if not (ob_obj.is_object and ob_obj.type in {'ARMATURE'}):
@@ -2297,71 +2268,51 @@ def fbx_data_from_scene(scene, settings):
# Some world settings are embedded in FBX materials...
if scene.world:
- data_world = OrderedDict(((scene.world, get_blenderID_key(scene.world)),))
+ data_world = {scene.world: get_blenderID_key(scene.world)}
else:
- data_world = OrderedDict()
+ data_world = {}
perfmon.step("FBX export prepare: Wrapping Materials...")
- # TODO: Check all the mat stuff works even when mats are linked to Objects
+ # TODO: Check all the material stuff works even when they are linked to Objects
# (we can then have the same mesh used with different materials...).
# *Should* work, as FBX always links its materials to Models (i.e. objects).
# XXX However, material indices would probably break...
- data_materials = OrderedDict()
+ data_materials = {}
for ob_obj in objects:
# If obj is not a valid object for materials, wrapper will just return an empty tuple...
- for mat_s in ob_obj.material_slots:
- mat = mat_s.material
- if mat is None:
+ for ma_s in ob_obj.material_slots:
+ ma = ma_s.material
+ if ma is None:
continue # Empty slots!
# Note theoretically, FBX supports any kind of materials, even GLSL shaders etc.
# However, I doubt anything else than Lambert/Phong is really portable!
- # We support any kind of 'surface' shader though, better to have some kind of default Lambert than nothing.
- # Note we want to keep a 'dummy' empty mat even when we can't really support it, see T41396.
- mat_data = data_materials.get(mat)
- if mat_data is not None:
- mat_data[1].append(ob_obj)
- else:
- data_materials[mat] = (get_blenderID_key(mat), [ob_obj])
+ # Note we want to keep a 'dummy' empty material even when we can't really support it, see T41396.
+ ma_data = data_materials.setdefault(ma, (get_blenderID_key(ma), []))
+ ma_data[1].append(ob_obj)
perfmon.step("FBX export prepare: Wrapping Textures...")
# Note FBX textures also hold their mapping info.
# TODO: Support layers?
- data_textures = OrderedDict()
+ data_textures = {}
# FbxVideo also used to store static images...
- data_videos = OrderedDict()
+ data_videos = {}
# For now, do not use world textures, don't think they can be linked to anything FBX wise...
- for mat in data_materials.keys():
- if check_skip_material(mat):
- continue
- for tex, use_tex in zip(mat.texture_slots, mat.use_textures):
- if tex is None or tex.texture is None or not use_tex:
- continue
- # For now, only consider image textures.
- # Note FBX does has support for procedural, but this is not portable at all (opaque blob),
- # so not useful for us.
- # TODO I think ENVIRONMENT_MAP should be usable in FBX as well, but for now let it aside.
- # if tex.texture.type not in {'IMAGE', 'ENVIRONMENT_MAP'}:
- if tex.texture.type not in {'IMAGE'}:
- continue
- img = tex.texture.image
- if img is None:
+ for ma in data_materials.keys():
+ # Note: with nodal shaders, we'll could be generating much more textures, but that's kind of unavoidable,
+ #  given that textures actually do not exist anymore in material context in Blender...
+ ma_wrap = node_shader_utils.PrincipledBSDFWrapper(ma, is_readonly=True)
+ for sock_name, fbx_name in PRINCIPLED_TEXTURE_SOCKETS_TO_FBX:
+ tex = getattr(ma_wrap, sock_name)
+ if tex is None or tex.image is None:
continue
- # Find out whether we can actually use this texture for this material, in FBX context.
- tex_fbx_props = fbx_mat_properties_from_texture(tex)
- if not tex_fbx_props:
- continue
- tex_data = data_textures.get(tex)
- if tex_data is not None:
- tex_data[1][mat] = tex_fbx_props
- else:
- data_textures[tex] = (get_blenderID_key(tex), OrderedDict(((mat, tex_fbx_props),)))
- vid_data = data_videos.get(img)
- if vid_data is not None:
- vid_data[1].append(tex)
- else:
- data_videos[img] = (get_blenderID_key(img), [tex])
+ blender_tex_key = (ma, sock_name)
+ data_textures[blender_tex_key] = (get_blender_nodetexture_key(*blender_tex_key), fbx_name)
+
+ img = tex.image
+ vid_data = data_videos.setdefault(img, (get_blenderID_key(img), []))
+ vid_data[1].append(blender_tex_key)
perfmon.step("FBX export prepare: Wrapping Animations...")
@@ -2375,8 +2326,8 @@ def fbx_data_from_scene(scene, settings):
# Kind of hack, we need a temp scene_data for object's space handling to bake animations...
tmp_scdata = FBXExportData(
None, None, None,
- settings, scene, objects, None, None, 0.0, 0.0,
- data_empties, data_lamps, data_cameras, data_meshes, None,
+ settings, scene, depsgraph, objects, None, None, 0.0, 0.0,
+ data_empties, data_lights, data_cameras, data_meshes, None,
data_bones, data_leaf_bones, data_deformers_skin, data_deformers_shape,
data_world, data_materials, data_textures, data_videos,
)
@@ -2386,14 +2337,14 @@ def fbx_data_from_scene(scene, settings):
perfmon.step("FBX export prepare: Generating templates...")
- templates = OrderedDict()
+ templates = {}
templates[b"GlobalSettings"] = fbx_template_def_globalsettings(scene, settings, nbr_users=1)
if data_empties:
templates[b"Null"] = fbx_template_def_null(scene, settings, nbr_users=len(data_empties))
- if data_lamps:
- templates[b"Light"] = fbx_template_def_light(scene, settings, nbr_users=len(data_lamps))
+ if data_lights:
+ templates[b"Light"] = fbx_template_def_light(scene, settings, nbr_users=len(data_lights))
if data_cameras:
templates[b"Camera"] = fbx_template_def_camera(scene, settings, nbr_users=len(data_cameras))
@@ -2491,9 +2442,9 @@ def fbx_data_from_scene(scene, settings):
bo_data_key = data_bones[ob_obj]
connections.append((b"OO", get_fbx_uuid_from_key(bo_data_key), ob_obj.fbx_uuid, None))
else:
- if ob_obj.type == 'LAMP':
- lamp_key = data_lamps[ob_obj.bdata.data]
- connections.append((b"OO", get_fbx_uuid_from_key(lamp_key), ob_obj.fbx_uuid, None))
+ if ob_obj.type == 'LIGHT':
+ light_key = data_lights[ob_obj.bdata.data]
+ connections.append((b"OO", get_fbx_uuid_from_key(light_key), ob_obj.fbx_uuid, None))
elif ob_obj.type == 'CAMERA':
cam_key = data_cameras[ob_obj]
connections.append((b"OO", get_fbx_uuid_from_key(cam_key), ob_obj.fbx_uuid, None))
@@ -2533,35 +2484,33 @@ def fbx_data_from_scene(scene, settings):
connections.append((b"OO", bo_obj.fbx_uuid, get_fbx_uuid_from_key(clstr_key), None))
# Materials
- mesh_mat_indices = OrderedDict()
+ mesh_material_indices = {}
_objs_indices = {}
- for mat, (mat_key, ob_objs) in data_materials.items():
+ for ma, (ma_key, ob_objs) in data_materials.items():
for ob_obj in ob_objs:
- connections.append((b"OO", get_fbx_uuid_from_key(mat_key), ob_obj.fbx_uuid, None))
- # Get index of this mat for this object (or dupliobject).
- # Mat indices for mesh faces are determined by their order in 'mat to ob' connections.
- # Only mats for meshes currently...
- # Note in case of dupliobjects a same me/mat idx will be generated several times...
+ connections.append((b"OO", get_fbx_uuid_from_key(ma_key), ob_obj.fbx_uuid, None))
+ # Get index of this material for this object (or dupliobject).
+ # Material indices for mesh faces are determined by their order in 'ma to ob' connections.
+ # Only materials for meshes currently...
+ # Note in case of dupliobjects a same me/ma idx will be generated several times...
# Should not be an issue in practice, and it's needed in case we export duplis but not the original!
if ob_obj.type not in BLENDER_OBJECT_TYPES_MESHLIKE:
continue
_mesh_key, me, _free = data_meshes[ob_obj]
idx = _objs_indices[ob_obj] = _objs_indices.get(ob_obj, -1) + 1
- mesh_mat_indices.setdefault(me, OrderedDict())[mat] = idx
+ mesh_material_indices.setdefault(me, {})[ma] = idx
del _objs_indices
# Textures
- for tex, (tex_key, mats) in data_textures.items():
- for mat, fbx_mat_props in mats.items():
- mat_key, _ob_objs = data_materials[mat]
- for fbx_prop in fbx_mat_props:
- # texture -> material properties
- connections.append((b"OP", get_fbx_uuid_from_key(tex_key), get_fbx_uuid_from_key(mat_key), fbx_prop))
+ for (ma, sock_name), (tex_key, fbx_prop) in data_textures.items():
+ ma_key, _ob_objs = data_materials[ma]
+ # texture -> material properties
+ connections.append((b"OP", get_fbx_uuid_from_key(tex_key), get_fbx_uuid_from_key(ma_key), fbx_prop))
# Images
- for vid, (vid_key, texs) in data_videos.items():
- for tex in texs:
- tex_key, _texs = data_textures[tex]
+ for vid, (vid_key, blender_tex_keys) in data_videos.items():
+ for blender_tex_key in blender_tex_keys:
+ tex_key, _fbx_prop = data_textures[blender_tex_key]
connections.append((b"OO", get_fbx_uuid_from_key(vid_key), get_fbx_uuid_from_key(tex_key), None))
# Animations
@@ -2593,8 +2542,8 @@ def fbx_data_from_scene(scene, settings):
return FBXExportData(
templates, templates_users, connections,
- settings, scene, objects, animations, animated, frame_start, frame_end,
- data_empties, data_lamps, data_cameras, data_meshes, mesh_mat_indices,
+ settings, scene, depsgraph, objects, animations, animated, frame_start, frame_end,
+ data_empties, data_lights, data_cameras, data_meshes, mesh_material_indices,
data_bones, data_leaf_bones, data_deformers_skin, data_deformers_shape,
data_world, data_materials, data_textures, data_videos,
)
@@ -2803,10 +2752,10 @@ def fbx_objects_elements(root, scene_data):
for empty in scene_data.data_empties:
fbx_data_empty_elements(objects, empty, scene_data)
- perfmon.step("FBX export fetch lamps (%d)..." % len(scene_data.data_lamps))
+ perfmon.step("FBX export fetch lamps (%d)..." % len(scene_data.data_lights))
- for lamp in scene_data.data_lamps:
- fbx_data_lamp_elements(objects, lamp, scene_data)
+ for lamp in scene_data.data_lights:
+ fbx_data_light_elements(objects, lamp, scene_data)
perfmon.step("FBX export fetch cameras (%d)..." % len(scene_data.data_cameras))
@@ -2827,12 +2776,10 @@ def fbx_objects_elements(root, scene_data):
if ob_obj.is_dupli:
continue
fbx_data_object_elements(objects, ob_obj, scene_data)
- ob_obj.dupli_list_create(scene_data.scene, 'RENDER')
- for dp_obj in ob_obj.dupli_list:
+ for dp_obj in ob_obj.dupli_list_gen(scene_data.depsgraph):
if dp_obj not in scene_data.objects:
continue
fbx_data_object_elements(objects, dp_obj, scene_data)
- ob_obj.dupli_list_clear()
perfmon.step("FBX export fetch remaining...")
@@ -2844,11 +2791,11 @@ def fbx_objects_elements(root, scene_data):
if scene_data.data_leaf_bones:
fbx_data_leaf_bone_elements(objects, scene_data)
- for mat in scene_data.data_materials:
- fbx_data_material_elements(objects, mat, scene_data)
+ for ma in scene_data.data_materials:
+ fbx_data_material_elements(objects, ma, scene_data)
- for tex in scene_data.data_textures:
- fbx_data_texture_file_elements(objects, tex, scene_data)
+ for blender_tex_key in scene_data.data_textures:
+ fbx_data_texture_file_elements(objects, blender_tex_key, scene_data)
for vid in scene_data.data_videos:
fbx_data_video_elements(objects, vid, scene_data)
@@ -2897,7 +2844,7 @@ def fbx_takes_elements(root, scene_data):
# ##### "Main" functions. #####
# This func can be called with just the filepath
-def save_single(operator, scene, filepath="",
+def save_single(operator, scene, depsgraph, filepath="",
global_matrix=Matrix(),
apply_unit_scale=False,
global_scale=1.0,
@@ -2935,7 +2882,7 @@ def save_single(operator, scene, filepath="",
ObjectWrapper.cache_clear()
if object_types is None:
- object_types = {'EMPTY', 'CAMERA', 'LAMP', 'ARMATURE', 'MESH', 'OTHER'}
+ object_types = {'EMPTY', 'CAMERA', 'LIGHT', 'ARMATURE', 'MESH', 'OTHER'}
if 'OTHER' in object_types:
object_types |= BLENDER_OTHER_OBJECT_TYPES
@@ -2943,12 +2890,12 @@ def save_single(operator, scene, filepath="",
# Default Blender unit is equivalent to meter, while FBX one is centimeter...
unit_scale = units_blender_to_fbx_factor(scene) if apply_unit_scale else 100.0
if apply_scale_options == 'FBX_SCALE_NONE':
- global_matrix = Matrix.Scale(unit_scale * global_scale, 4) * global_matrix
+ global_matrix = Matrix.Scale(unit_scale * global_scale, 4) @ global_matrix
unit_scale = 1.0
elif apply_scale_options == 'FBX_SCALE_UNITS':
- global_matrix = Matrix.Scale(global_scale, 4) * global_matrix
+ global_matrix = Matrix.Scale(global_scale, 4) @ global_matrix
elif apply_scale_options == 'FBX_SCALE_CUSTOM':
- global_matrix = Matrix.Scale(unit_scale, 4) * global_matrix
+ global_matrix = Matrix.Scale(unit_scale, 4) @ global_matrix
unit_scale = global_scale
else: # if apply_scale_options == 'FBX_SCALE_ALL':
unit_scale = global_scale * unit_scale
@@ -3004,7 +2951,7 @@ def save_single(operator, scene, filepath="",
start_time = time.process_time()
# Generate some data about exported scene...
- scene_data = fbx_data_from_scene(scene, settings)
+ scene_data = fbx_data_from_scene(scene, depsgraph, settings)
root = elem_empty(None, b"") # Root element has no id, as it is not saved per se!
@@ -3098,7 +3045,7 @@ def save(operator, context,
ret = None
- active_object = context.scene.objects.active
+ active_object = context.view_layer.objects.active
org_mode = None
if active_object and active_object.mode != 'OBJECT' and bpy.ops.object.mode_set.poll():
@@ -3110,10 +3057,11 @@ def save(operator, context,
if use_selection:
kwargs_mod["context_objects"] = context.selected_objects
else:
- kwargs_mod["context_objects"] = context.scene.objects
+ kwargs_mod["context_objects"] = context.view_layer.objects
- ret = save_single(operator, context.scene, filepath, **kwargs_mod)
+ ret = save_single(operator, context.scene, context.depsgraph, filepath, **kwargs_mod)
else:
+ return # TODO Update for 2.8
fbxpath = filepath
prefix = os.path.basename(fbxpath)
diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py
index 0ed26b6a..7b3b9d0f 100644
--- a/io_scene_fbx/fbx_utils.py
+++ b/io_scene_fbx/fbx_utils.py
@@ -24,13 +24,13 @@
import math
import time
-from collections import namedtuple, OrderedDict
+from collections import namedtuple
from collections.abc import Iterable
from itertools import zip_longest, chain
import bpy
import bpy_extras
-from bpy.types import Object, Bone, PoseBone, DupliObject
+from bpy.types import Object, Bone, PoseBone, DepsgraphObjectInstance
from mathutils import Vector, Matrix
from . import encode_bin, data_types
@@ -71,7 +71,7 @@ FBX_ANIM_PROPSGROUP_NAME = "d"
FBX_KTIME = 46186158000 # This is the number of "ktimes" in one second (yep, precision over the nanosecond...)
-MAT_CONVERT_LAMP = Matrix.Rotation(math.pi / 2.0, 4, 'X') # Blender is -Z, FBX is -Y.
+MAT_CONVERT_LIGHT = Matrix.Rotation(math.pi / 2.0, 4, 'X') # Blender is -Z, FBX is -Y.
MAT_CONVERT_CAMERA = Matrix.Rotation(math.pi / 2.0, 4, 'Y') # Blender is -Z, FBX is +X.
# XXX I can't get this working :(
# MAT_CONVERT_BONE = Matrix.Rotation(math.pi / 2.0, 4, 'Z') # Blender is +Y, FBX is -X.
@@ -271,14 +271,14 @@ def similar_values_iter(v1, v2, e=1e-6):
def vcos_transformed_gen(raw_cos, m=None):
# Note: we could most likely get much better performances with numpy, but will leave this as TODO for now.
gen = zip(*(iter(raw_cos),) * 3)
- return gen if m is None else (m * Vector(v) for v in gen)
+ return gen if m is None else (m @ Vector(v) for v in gen)
def nors_transformed_gen(raw_nors, m=None):
# Great, now normals are also expected 4D!
# XXX Back to 3D normals for now!
# gen = zip(*(iter(raw_nors),) * 3 + (_infinite_gen(1.0),))
gen = zip(*(iter(raw_nors),) * 3)
- return gen if m is None else (m * Vector(v) for v in gen)
+ return gen if m is None else (m @ Vector(v) for v in gen)
# ##### UIDs code. #####
@@ -324,7 +324,7 @@ def _key_to_uuid(uuids, key):
def get_fbx_uuid_from_key(key):
"""
- Return an UUID for given key, which is assumed hasable.
+ Return an UUID for given key, which is assumed to be hashable.
"""
uuid = _keys_to_uuids.get(key, None)
if uuid is None:
@@ -431,6 +431,10 @@ def get_blender_anim_curve_key(scene, ref_id, obj_key, fbx_prop_name, fbx_prop_i
fbx_prop_item_name, "AnimCurve"))
+def get_blender_nodetexture_key(ma, socket_names):
+ return "|".join((get_blenderID_key(ma), *socket_names))
+
+
# ##### Element generators. #####
# Note: elem may be None, in this case the element is not added to any parent.
@@ -614,12 +618,12 @@ def elem_props_template_init(templates, template_type):
"""
Init a writing template of given type, for *one* element's properties.
"""
- ret = OrderedDict()
+ ret = {}
tmpl = templates.get(template_type)
if tmpl is not None:
written = tmpl.written[0]
props = tmpl.properties
- ret = OrderedDict((name, [val, ptype, anim, written]) for name, (val, ptype, anim) in props.items())
+ ret = {name: [val, ptype, anim, written] for name, (val, ptype, anim) in props.items()}
return ret
@@ -671,14 +675,11 @@ def fbx_templates_generate(root, fbx_templates):
# for Lights, Cameras, LibNodes, etc.).
ref_templates = {(tmpl.type_name, tmpl.prop_type_name): tmpl for tmpl in fbx_templates.values()}
- templates = OrderedDict()
+ templates = {}
for type_name, prop_type_name, properties, nbr_users, _written in fbx_templates.values():
- tmpl = templates.get(type_name)
- if tmpl is None:
- templates[type_name] = [OrderedDict(((prop_type_name, (properties, nbr_users)),)), nbr_users]
- else:
- tmpl[0][prop_type_name] = (properties, nbr_users)
- tmpl[1] += nbr_users
+ tmpl = templates.setdefault(type_name, [{}, 0])
+ tmpl[0][prop_type_name] = (properties, nbr_users)
+ tmpl[1] += nbr_users
for type_name, (subprops, nbr_users) in templates.items():
template = elem_data_single_string(root, b"ObjectType", type_name)
@@ -844,7 +845,7 @@ class AnimationCurveNodeWrapper:
for elem_key, fbx_group, fbx_gname, fbx_props in \
zip(self.elem_keys, self.fbx_group, self.fbx_gname, self.fbx_props):
group_key = get_blender_anim_curve_node_key(scene, ref_id, elem_key, fbx_group)
- group = OrderedDict()
+ group = {}
for c, def_val, fbx_item in zip(curves, self.default_values, fbx_props):
fbx_item = FBX_ANIM_PROPSGROUP_NAME + "|" + fbx_item
curve_key = get_blender_anim_curve_key(scene, ref_id, elem_key, fbx_group, fbx_item)
@@ -856,7 +857,7 @@ class AnimationCurveNodeWrapper:
# ##### FBX objects generators. #####
-# FBX Model-like data (i.e. Blender objects, dupliobjects and bones) are wrapped in ObjectWrapper.
+# FBX Model-like data (i.e. Blender objects, depsgraph instances and bones) are wrapped in ObjectWrapper.
# This allows us to have a (nearly) same code FBX-wise for all those types.
# The wrapper tries to stay as small as possible, by mostly using callbacks (property(get...))
# to actual Blender data it contains.
@@ -870,9 +871,13 @@ class MetaObjectWrapper(type):
dup_mat = None
if isinstance(bdata, Object):
key = get_blenderID_key(bdata)
- elif isinstance(bdata, DupliObject):
- key = "|".join((get_blenderID_key((bdata.id_data, bdata.object)), cls._get_dup_num_id(bdata)))
- dup_mat = bdata.matrix.copy()
+ elif isinstance(bdata, DepsgraphObjectInstance):
+ if bdata.is_instance:
+ key = "|".join((get_blenderID_key((bdata.parent.original, bdata.instance_object.original)),
+ cls._get_dup_num_id(bdata)))
+ dup_mat = bdata.matrix_world.copy()
+ else:
+ key = get_blenderID_key(bdata.object.original)
else: # isinstance(bdata, (Bone, PoseBone)):
if isinstance(bdata, PoseBone):
bdata = armature.data.bones[bdata.name]
@@ -883,9 +888,9 @@ class MetaObjectWrapper(type):
cache = cls._cache = {}
instance = cache.get(key)
if instance is not None:
- # Duplis hack: since duplis are not persistent in Blender (we have to re-create them to get updated
+ # Duplis hack: since dupli instances are not persistent in Blender (we have to re-create them to get updated
# info like matrix...), we *always* need to reset that matrix when calling ObjectWrapper() (all
- # other data is supposed valid during whole cache live, so we can skip resetting it).
+ # other data is supposed valid during whole cache live span, so we can skip resetting it).
instance._dupli_matrix = dup_mat
return instance
@@ -902,7 +907,7 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
This class provides a same common interface for all (FBX-wise) object-like elements:
* Blender Object
* Blender Bone and PoseBone
- * Blender DupliObject
+ * Blender DepsgraphObjectInstance (for dulis).
Note since a same Blender object might be 'mapped' to several FBX models (esp. with duplis),
we need to use a key to identify each.
"""
@@ -918,24 +923,42 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
@staticmethod
def _get_dup_num_id(bdata):
- return ".".join(str(i) for i in bdata.persistent_id if i != 2147483647)
+ INVALID_IDS = {2147483647, 0}
+ pids = tuple(bdata.persistent_id)
+ idx_valid = 0
+ prev_i = ...
+ for idx, i in enumerate(pids[::-1]):
+ if i not in INVALID_IDS or (idx == len(pids) and i == 0 and prev_i != 0):
+ idx_valid = len(pids) - idx
+ break
+ prev_i = i
+ return ".".join(str(i) for i in pids[:idx_valid])
def __init__(self, bdata, armature=None):
"""
- bdata might be an Object, DupliObject, Bone or PoseBone.
+ bdata might be an Object (deprecated), DepsgraphObjectInstance, Bone or PoseBone.
If Bone or PoseBone, armature Object must be provided.
"""
- if isinstance(bdata, Object):
+ # Note: DepsgraphObjectInstance are purely runtime data, they become invalid as soon as we step to the next item!
+ # Hence we have to immediately copy *all* needed data...
+ if isinstance(bdata, Object): # DEPRECATED
self._tag = 'OB'
self.name = get_blenderID_name(bdata)
self.bdata = bdata
self._ref = None
- elif isinstance(bdata, DupliObject):
- self._tag = 'DP'
- self.name = "|".join((get_blenderID_name((bdata.id_data, bdata.object)),
- "Dupli", self._get_dup_num_id(bdata)))
- self.bdata = bdata.object
- self._ref = bdata.id_data
+ elif isinstance(bdata, DepsgraphObjectInstance):
+ if bdata.is_instance:
+ # Note that dupli instance matrix is set by meta-class initialization.
+ self._tag = 'DP'
+ self.name = "|".join((get_blenderID_name((bdata.parent.original, bdata.instance_object.original)),
+ "Dupli", self._get_dup_num_id(bdata)))
+ self.bdata = bdata.instance_object.original
+ self._ref = bdata.parent.original
+ else:
+ self._tag = 'OB'
+ self.name = get_blenderID_name(bdata)
+ self.bdata = bdata.object.original
+ self._ref = None
else: # isinstance(bdata, (Bone, PoseBone)):
if isinstance(bdata, PoseBone):
bdata = armature.data.bones[bdata.name]
@@ -951,13 +974,17 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
def __hash__(self):
return hash(self.key)
+ def __repr__(self):
+ return self.key
+
# #### Common to all _tag values.
def get_fbx_uuid(self):
return get_fbx_uuid_from_key(self.key)
fbx_uuid = property(get_fbx_uuid)
+ # XXX Not sure how much that’s useful now... :/
def get_hide(self):
- return self.bdata.hide
+ return self.bdata.hide_viewport if self._tag in {'OB', 'DP'} else self.bdata.hide
hide = property(get_hide)
def get_parent(self):
@@ -974,7 +1001,7 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
# Mere object parenting.
return ObjectWrapper(self.bdata.parent)
elif self._tag == 'DP':
- return ObjectWrapper(self.bdata.parent or self._ref)
+ return ObjectWrapper(self._ref)
else: # self._tag == 'BO'
return ObjectWrapper(self.bdata.parent, self._ref) or ObjectWrapper(self._ref)
parent = property(get_parent)
@@ -983,12 +1010,12 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
if self._tag == 'OB':
return self.bdata.matrix_local.copy()
elif self._tag == 'DP':
- return self._ref.matrix_world.inverted_safe() * self._dupli_matrix
+ return self._ref.matrix_world.inverted_safe() @ self._dupli_matrix
else: # 'BO', current pose
# PoseBone.matrix is in armature space, bring in back in real local one!
par = self.bdata.parent
par_mat_inv = self._ref.pose.bones[par.name].matrix.inverted_safe() if par else Matrix()
- return par_mat_inv * self._ref.pose.bones[self.bdata.name].matrix
+ return par_mat_inv @ self._ref.pose.bones[self.bdata.name].matrix
matrix_local = property(get_matrix_local)
def get_matrix_global(self):
@@ -997,7 +1024,7 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
elif self._tag == 'DP':
return self._dupli_matrix
else: # 'BO', current pose
- return self._ref.matrix_world * self._ref.pose.bones[self.bdata.name].matrix
+ return self._ref.matrix_world @ self._ref.pose.bones[self.bdata.name].matrix
matrix_global = property(get_matrix_global)
def get_matrix_rest_local(self):
@@ -1005,14 +1032,14 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
# Bone.matrix_local is in armature space, bring in back in real local one!
par = self.bdata.parent
par_mat_inv = par.matrix_local.inverted_safe() if par else Matrix()
- return par_mat_inv * self.bdata.matrix_local
+ return par_mat_inv @ self.bdata.matrix_local
else:
return self.matrix_local.copy()
matrix_rest_local = property(get_matrix_rest_local)
def get_matrix_rest_global(self):
if self._tag == 'BO':
- return self._ref.matrix_world * self.bdata.matrix_local
+ return self._ref.matrix_world @ self.bdata.matrix_local
else:
return self.matrix_global.copy()
matrix_rest_global = property(get_matrix_rest_global)
@@ -1065,41 +1092,41 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
if self._tag == 'BO':
# If we have a bone parent we need to undo the parent correction.
if not is_global and scene_data.settings.bone_correction_matrix_inv and parent and parent.is_bone:
- matrix = scene_data.settings.bone_correction_matrix_inv * matrix
+ matrix = scene_data.settings.bone_correction_matrix_inv @ matrix
# Apply the bone correction.
if scene_data.settings.bone_correction_matrix:
- matrix = matrix * scene_data.settings.bone_correction_matrix
- elif self.bdata.type == 'LAMP':
- matrix = matrix * MAT_CONVERT_LAMP
+ matrix = matrix @ scene_data.settings.bone_correction_matrix
+ elif self.bdata.type == 'LIGHT':
+ matrix = matrix @ MAT_CONVERT_LIGHT
elif self.bdata.type == 'CAMERA':
- matrix = matrix * MAT_CONVERT_CAMERA
+ matrix = matrix @ MAT_CONVERT_CAMERA
if self._tag in {'DP', 'OB'} and parent:
if parent._tag == 'BO':
# In bone parent case, we get transformation in **bone tip** space (sigh).
# Have to bring it back into bone root, which is FBX expected value.
- matrix = Matrix.Translation((0, (parent.bdata.tail - parent.bdata.head).length, 0)) * matrix
+ matrix = Matrix.Translation((0, (parent.bdata.tail - parent.bdata.head).length, 0)) @ matrix
# Our matrix is in local space, time to bring it in its final desired space.
if parent:
if is_global:
# Move matrix to global Blender space.
- matrix = (parent.matrix_rest_global if rest else parent.matrix_global) * matrix
+ matrix = (parent.matrix_rest_global if rest else parent.matrix_global) @ matrix
elif parent.use_bake_space_transform(scene_data):
# Blender's and FBX's local space of parent may differ if we use bake_space_transform...
# Apply parent's *Blender* local space...
- matrix = (parent.matrix_rest_local if rest else parent.matrix_local) * matrix
+ matrix = (parent.matrix_rest_local if rest else parent.matrix_local) @ matrix
# ...and move it back into parent's *FBX* local space.
par_mat = parent.fbx_object_matrix(scene_data, rest=rest, local_space=True)
- matrix = par_mat.inverted_safe() * matrix
+ matrix = par_mat.inverted_safe() @ matrix
if self.use_bake_space_transform(scene_data):
# If we bake the transforms we need to post-multiply inverse global transform.
# This means that the global transform will not apply to children of this transform.
- matrix = matrix * scene_data.settings.global_matrix_inv
+ matrix = matrix @ scene_data.settings.global_matrix_inv
if is_global:
# In any case, pre-multiply the global matrix to get it in FBX global space!
- matrix = scene_data.settings.global_matrix * matrix
+ matrix = scene_data.settings.global_matrix @ matrix
return matrix
@@ -1164,19 +1191,11 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
return True
# #### Duplis...
- def dupli_list_create(self, scene, settings='PREVIEW'):
+ def dupli_list_gen(self, depsgraph):
if self._tag == 'OB' and self.bdata.is_duplicator:
- self.bdata.dupli_list_create(scene, settings)
-
- def dupli_list_clear(self):
- if self._tag == 'OB'and self.bdata.is_duplicator:
- self.bdata.dupli_list_clear()
-
- def get_dupli_list(self):
- if self._tag == 'OB'and self.bdata.is_duplicator:
- return (ObjectWrapper(dup) for dup in self.bdata.dupli_list)
+ return (ObjectWrapper(dup) for dup in depsgraph.object_instances
+ if dup.parent and ObjectWrapper(dup.parent.original) == self)
return ()
- dupli_list = property(get_dupli_list)
def fbx_name_class(name, cls):
@@ -1213,8 +1232,8 @@ FBXExportSettings = namedtuple("FBXExportSettings", (
# * animations.
FBXExportData = namedtuple("FBXExportData", (
"templates", "templates_users", "connections",
- "settings", "scene", "objects", "animations", "animated", "frame_start", "frame_end",
- "data_empties", "data_lamps", "data_cameras", "data_meshes", "mesh_mat_indices",
+ "settings", "scene", "depsgraph", "objects", "animations", "animated", "frame_start", "frame_end",
+ "data_empties", "data_lights", "data_cameras", "data_meshes", "mesh_material_indices",
"data_bones", "data_leaf_bones", "data_deformers_skin", "data_deformers_shape",
"data_world", "data_materials", "data_textures", "data_videos",
))
@@ -1223,11 +1242,11 @@ FBXExportData = namedtuple("FBXExportData", (
FBXImportSettings = namedtuple("FBXImportSettings", (
"report", "to_axes", "global_matrix", "global_scale",
"bake_space_transform", "global_matrix_inv", "global_matrix_inv_transposed",
- "use_custom_normals", "use_cycles", "use_image_search",
+ "use_custom_normals", "use_image_search",
"use_alpha_decals", "decal_offset",
"use_anim", "anim_offset",
"use_custom_props", "use_custom_props_enum_as_string",
- "cycles_material_wrap_map", "image_cache",
+ "nodal_material_wrap_map", "image_cache",
"ignore_leaf_bones", "force_connect_children", "automatic_bone_orientation", "bone_correction_matrix",
"use_prepost_rot",
))
diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py
index 90dc08df..353a027f 100644
--- a/io_scene_fbx/import_fbx.py
+++ b/io_scene_fbx/import_fbx.py
@@ -60,7 +60,7 @@ fbx_elem_nil = None
convert_deg_to_rad_iter = units_convertor_iter("degree", "radian")
MAT_CONVERT_BONE = fbx_utils.MAT_CONVERT_BONE.inverted()
-MAT_CONVERT_LAMP = fbx_utils.MAT_CONVERT_LAMP.inverted()
+MAT_CONVERT_LIGHT = fbx_utils.MAT_CONVERT_LIGHT.inverted()
MAT_CONVERT_CAMERA = fbx_utils.MAT_CONVERT_CAMERA.inverted()
@@ -369,7 +369,7 @@ def blen_read_custom_properties(fbx_obj, blen_obj, settings):
def blen_read_object_transform_do(transform_data):
# This is a nightmare. FBX SDK uses Maya way to compute the transformation matrix of a node - utterly simple:
#
- # WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1
+ # WorldTransform = ParentWorldTransform @ T @ Roff @ Rp @ Rpre @ R @ Rpost @ Rp-1 @ Soff @ Sp @ S @ Sp-1
#
# Where all those terms are 4 x 4 matrices that contain:
# WorldTransform: Transformation matrix of the node in global space.
@@ -389,7 +389,7 @@ def blen_read_object_transform_do(transform_data):
# But it was still too simple, and FBX notion of compatibility is... quite specific. So we also have to
# support 3DSMax way:
#
- # WorldTransform = ParentWorldTransform * T * R * S * OT * OR * OS
+ # WorldTransform = ParentWorldTransform @ T @ R @ S @ OT @ OR @ OS
#
# Where all those terms are 4 x 4 matrices that contain:
# WorldTransform: Transformation matrix of the node in global space
@@ -414,7 +414,7 @@ def blen_read_object_transform_do(transform_data):
# rotation
to_rot = lambda rot, rot_ord: Euler(convert_deg_to_rad_iter(rot), rot_ord).to_matrix().to_4x4()
- lcl_rot = to_rot(transform_data.rot, transform_data.rot_ord) * transform_data.rot_alt_mat
+ lcl_rot = to_rot(transform_data.rot, transform_data.rot_ord) @ transform_data.rot_alt_mat
pre_rot = to_rot(transform_data.pre_rot, transform_data.rot_ord)
pst_rot = to_rot(transform_data.pst_rot, transform_data.rot_ord)
geom_rot = to_rot(transform_data.geom_rot, transform_data.rot_ord)
@@ -431,21 +431,21 @@ def blen_read_object_transform_do(transform_data):
geom_scale[0][0], geom_scale[1][1], geom_scale[2][2] = transform_data.geom_sca
base_mat = (
- lcl_translation *
- rot_ofs *
- rot_piv *
- pre_rot *
- lcl_rot *
- pst_rot *
- rot_piv.inverted_safe() *
- sca_ofs *
- sca_piv *
- lcl_scale *
+ lcl_translation @
+ rot_ofs @
+ rot_piv @
+ pre_rot @
+ lcl_rot @
+ pst_rot @
+ rot_piv.inverted_safe() @
+ sca_ofs @
+ sca_piv @
+ lcl_scale @
sca_piv.inverted_safe()
)
- geom_mat = geom_loc * geom_rot * geom_scale
+ geom_mat = geom_loc @ geom_rot @ geom_scale
# We return mat without 'geometric transforms' too, because it is to be used for children, sigh...
- return (base_mat * geom_mat, base_mat, geom_mat)
+ return (base_mat @ geom_mat, base_mat, geom_mat)
# XXX This might be weak, now that we can add vgroups from both bones and shapes, name collisions become
@@ -457,7 +457,7 @@ def add_vgroup_to_objects(vg_indices, vg_weights, vg_name, objects):
# We replace/override here...
vg = obj.vertex_groups.get(vg_name)
if vg is None:
- vg = obj.vertex_groups.new(vg_name)
+ vg = obj.vertex_groups.new(name=vg_name)
for i, w in zip(vg_indices, vg_weights):
vg.add((i,), w, 'REPLACE')
@@ -601,7 +601,7 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
else: # Euler
props[1] = (bl_obj.path_from_id("rotation_euler"), 3, grpname or "Euler Rotation")
- blen_curves = [action.fcurves.new(prop, channel, grpname)
+ blen_curves = [action.fcurves.new(prop, index=channel, action_group=grpname)
for prop, nbr_channels, grpname in props for channel in range(nbr_channels)]
if isinstance(item, Material):
@@ -613,7 +613,7 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
value[channel] = v
for fc, v in zip(blen_curves, value):
- fc.keyframe_points.insert(frame, v, {'NEEDED', 'FAST'}).interpolation = 'LINEAR'
+ fc.keyframe_points.insert(frame, v, options={'NEEDED', 'FAST'}).interpolation = 'LINEAR'
elif isinstance(item, ShapeKey):
for frame, values in blen_read_animations_curves_iter(fbx_curves, anim_offset, 0, fps):
@@ -624,7 +624,7 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
value = v / 100.0
for fc, v in zip(blen_curves, (value,)):
- fc.keyframe_points.insert(frame, v, {'NEEDED', 'FAST'}).interpolation = 'LINEAR'
+ fc.keyframe_points.insert(frame, v, options={'NEEDED', 'FAST'}).interpolation = 'LINEAR'
elif isinstance(item, Camera):
for frame, values in blen_read_animations_curves_iter(fbx_curves, anim_offset, 0, fps):
@@ -635,7 +635,7 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
value = v
for fc, v in zip(blen_curves, (value,)):
- fc.keyframe_points.insert(frame, v, {'NEEDED', 'FAST'}).interpolation = 'LINEAR'
+ fc.keyframe_points.insert(frame, v, options={'NEEDED', 'FAST'}).interpolation = 'LINEAR'
else: # Object or PoseBone:
if item.is_bone:
@@ -661,19 +661,19 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
# compensate for changes in the local matrix during processing
if item.anim_compensation_matrix:
- mat = mat * item.anim_compensation_matrix
+ mat = mat @ item.anim_compensation_matrix
# apply pre- and post matrix
# post-matrix will contain any correction for lights, camera and bone orientation
# pre-matrix will contain any correction for a parent's correction matrix or the global matrix
if item.pre_matrix:
- mat = item.pre_matrix * mat
+ mat = item.pre_matrix @ mat
if item.post_matrix:
- mat = mat * item.post_matrix
+ mat = mat @ item.post_matrix
# And now, remove that rest pose matrix from current mat (also in parent space).
if restmat_inv:
- mat = restmat_inv * mat
+ mat = restmat_inv @ mat
# Now we have a virtual matrix of transform from AnimCurves, we can insert keyframes!
loc, rot, sca = mat.decompose()
@@ -686,7 +686,7 @@ def blen_read_animations_action_item(action, item, cnodes, fps, anim_offset):
rot = rot.to_euler(rot_mode, rot_prev)
rot_prev = rot
for fc, value in zip(blen_curves, chain(loc, rot, sca)):
- fc.keyframe_points.insert(frame, value, {'NEEDED', 'FAST'}).interpolation = 'LINEAR'
+ fc.keyframe_points.insert(frame, value, options={'NEEDED', 'FAST'}).interpolation = 'LINEAR'
# Since we inserted our keyframes in 'FAST' mode, we have to update the fcurves now.
for fc in blen_curves:
@@ -1006,8 +1006,7 @@ def blen_read_geom_layer_uv(fbx_obj, mesh):
fbx_layer_data = elem_prop_first(elem_find_first(fbx_layer, b'UV'))
fbx_layer_index = elem_prop_first(elem_find_first(fbx_layer, b'UVIndex'))
- uv_tex = mesh.uv_textures.new(name=fbx_layer_name)
- uv_lay = mesh.uv_layers[-1]
+ uv_lay = mesh.uv_layers.new(name=fbx_layer_name)
blen_data = uv_lay.data
# some valid files omit this data
@@ -1087,7 +1086,6 @@ def blen_read_geom_layer_smooth(fbx_obj, mesh):
)
# We only set sharp edges here, not face smoothing itself...
mesh.use_auto_smooth = True
- mesh.show_edge_sharp = True
return False
elif fbx_layer_mapping == b'ByPolygon':
blen_data = mesh.polygons
@@ -1165,7 +1163,7 @@ def blen_read_geom(fbx_tmpl, fbx_obj, settings):
if geom_mat_co is not None:
def _vcos_transformed_gen(raw_cos, m=None):
# Note: we could most likely get much better performances with numpy, but will leave this as TODO for now.
- return chain(*(m * Vector(v) for v in zip(*(iter(raw_cos),) * 3)))
+ return chain(*(m @ Vector(v) for v in zip(*(iter(raw_cos),) * 3)))
fbx_verts = array.array(fbx_verts.typecode, _vcos_transformed_gen(fbx_verts, geom_mat_co))
if fbx_verts is None:
@@ -1242,7 +1240,7 @@ def blen_read_geom(fbx_tmpl, fbx_obj, settings):
ok_normals = blen_read_geom_layer_normal(fbx_obj, mesh)
else:
def nortrans(v):
- return geom_mat_no * Vector(v)
+ return geom_mat_no @ Vector(v)
ok_normals = blen_read_geom_layer_normal(fbx_obj, mesh, nortrans)
mesh.validate(clean_customdata=False) # *Very* important to not remove lnors here!
@@ -1257,7 +1255,6 @@ def blen_read_geom(fbx_tmpl, fbx_obj, settings):
mesh.normals_split_custom_set(tuple(zip(*(iter(clnors),) * 3)))
mesh.use_auto_smooth = True
- mesh.show_edge_sharp = True
else:
mesh.calc_normals()
@@ -1319,9 +1316,12 @@ def blen_read_shape(fbx_tmpl, fbx_sdata, fbx_bcdata, meshes, scene):
# Material
def blen_read_material(fbx_tmpl, fbx_obj, settings):
+ from bpy_extras import node_shader_utils
+ from math import sqrt
+
elem_name_utf8 = elem_name_ensure_class(fbx_obj, b'Material')
- cycles_material_wrap_map = settings.cycles_material_wrap_map
+ nodal_material_wrap_map = settings.nodal_material_wrap_map
ma = bpy.data.materials.new(name=elem_name_utf8)
const_color_white = 1.0, 1.0, 1.0
@@ -1329,43 +1329,23 @@ def blen_read_material(fbx_tmpl, fbx_obj, settings):
fbx_props = (elem_find_first(fbx_obj, b'Properties70'),
elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
- ma_diff = elem_props_get_color_rgb(fbx_props, b'DiffuseColor', const_color_white)
- ma_spec = elem_props_get_color_rgb(fbx_props, b'SpecularColor', const_color_white)
- ma_alpha = elem_props_get_number(fbx_props, b'Opacity', 1.0)
- ma_spec_intensity = ma.specular_intensity = elem_props_get_number(fbx_props, b'SpecularFactor', 0.25) * 2.0
- ma_spec_hardness = elem_props_get_number(fbx_props, b'Shininess', 9.6)
- ma_refl_factor = elem_props_get_number(fbx_props, b'ReflectionFactor', 0.0)
- ma_refl_color = elem_props_get_color_rgb(fbx_props, b'ReflectionColor', const_color_white)
-
- if settings.use_cycles:
- from modules import cycles_shader_compat
- # viewport color
- ma.diffuse_color = ma_diff
-
- ma_wrap = cycles_shader_compat.CyclesShaderWrapper(ma)
- ma_wrap.diffuse_color_set(ma_diff)
- ma_wrap.specular_color_set([c * ma_spec_intensity for c in ma_spec])
- ma_wrap.hardness_value_set(((ma_spec_hardness + 3.0) / 5.0) - 0.65)
- ma_wrap.alpha_value_set(ma_alpha)
- ma_wrap.reflect_factor_set(ma_refl_factor)
- ma_wrap.reflect_color_set(ma_refl_color)
-
- cycles_material_wrap_map[ma] = ma_wrap
- else:
- # TODO, number BumpFactor isnt used yet
- ma.diffuse_color = ma_diff
- ma.specular_color = ma_spec
- ma.alpha = ma_alpha
- if ma_alpha < 1.0:
- ma.use_transparency = True
- ma.transparency_method = 'RAYTRACE'
- ma.specular_intensity = ma_spec_intensity
- ma.specular_hardness = ma_spec_hardness * 5.10 + 1.0
-
- if ma_refl_factor != 0.0:
- ma.raytrace_mirror.use = True
- ma.raytrace_mirror.reflect_factor = ma_refl_factor
- ma.mirror_color = ma_refl_color
+ ma_wrap = node_shader_utils.PrincipledBSDFWrapper(ma, is_readonly=False, use_nodes=True)
+ ma_wrap.base_color = elem_props_get_color_rgb(fbx_props, b'DiffuseColor', const_color_white)
+ # No specular color in Principled BSDF shader, assumed to be either white or take some tint from diffuse one...
+ # TODO: add way to handle tint option (guesstimate from spec color + intensity...)?
+ ma_wrap.specular = elem_props_get_number(fbx_props, b'SpecularFactor', 0.25) * 2.0
+ # XXX Totally empirical conversion, trying to adapt it
+ # (from 1.0 - 0.0 Principled BSDF range to 0.0 - 100.0 FBX shininess range)...
+ fbx_shininess = elem_props_get_number(fbx_props, b'Shininess', 20.0)
+ ma_wrap.roughness = 1.0 - (sqrt(fbx_shininess) / 10.0)
+ ma_wrap.transmission = 1.0 - elem_props_get_number(fbx_props, b'Opacity', 1.0)
+ ma_wrap.metallic = elem_props_get_number(fbx_props, b'ReflectionFactor', 0.0)
+ # We have no metallic (a.k.a. reflection) color...
+ # elem_props_get_color_rgb(fbx_props, b'ReflectionColor', const_color_white)
+ # (x / 7.142) is only a guess, cycles usable range is (0.0 -> 0.5)
+ ma_wrap.normalmap_strength = elem_props_get_number(fbx_props, b'BumpFactor', 2.5) / 7.142
+
+ nodal_material_wrap_map[ma] = ma_wrap
if settings.use_custom_props:
blen_read_custom_properties(fbx_obj, ma, settings)
@@ -1479,7 +1459,7 @@ def blen_read_light(fbx_tmpl, fbx_obj, global_scale):
1: 'SUN',
2: 'SPOT'}.get(elem_props_get_enum(fbx_props, b'LightType', 0), 'POINT')
- lamp = bpy.data.lamps.new(name=elem_name_utf8, type=light_type)
+ lamp = bpy.data.lights.new(name=elem_name_utf8, type=light_type)
if light_type == 'SPOT':
spot_size = elem_props_get_number(fbx_props, b'OuterAngle', None)
@@ -1494,11 +1474,14 @@ def blen_read_light(fbx_tmpl, fbx_obj, global_scale):
spot_blend = elem_props_get_number(fbx_props, b'HotSpot', 45.0)
lamp.spot_blend = 1.0 - (spot_blend / spot_size)
- # TODO, cycles
+ # TODO, cycles nodes???
lamp.color = elem_props_get_color_rgb(fbx_props, b'Color', (1.0, 1.0, 1.0))
lamp.energy = elem_props_get_number(fbx_props, b'Intensity', 100.0) / 100.0
lamp.distance = elem_props_get_number(fbx_props, b'DecayStart', 25.0) * global_scale
- lamp.shadow_method = ('RAY_SHADOW' if elem_props_get_bool(fbx_props, b'CastShadow', True) else 'NOSHADOW')
+ lamp.use_shadow = elem_props_get_bool(fbx_props, b'CastShadow', True)
+ if hasattr(lamp, "cycles"):
+ lamp.cycles.cast_shadow = lamp.use_shadow
+ # Keeping this for now, but this is not used nor exposed anymore afaik...
lamp.shadow_color = elem_props_get_color_rgb(fbx_props, b'ShadowColor', (0.0, 0.0, 0.0))
return lamp
@@ -1612,7 +1595,7 @@ class FbxImportHelperNode:
self.pre_matrix = settings.global_matrix
if parent_correction_inv:
- self.pre_matrix = parent_correction_inv * (self.pre_matrix if self.pre_matrix else Matrix())
+ self.pre_matrix = parent_correction_inv @ (self.pre_matrix if self.pre_matrix else Matrix())
correction_matrix = None
@@ -1700,12 +1683,12 @@ class FbxImportHelperNode:
if self.fbx_type == b'Camera':
correction_matrix = MAT_CONVERT_CAMERA
elif self.fbx_type == b'Light':
- correction_matrix = MAT_CONVERT_LAMP
+ correction_matrix = MAT_CONVERT_LIGHT
self.post_matrix = correction_matrix
if self.do_bake_transform(settings):
- self.post_matrix = settings.global_matrix_inv * (self.post_matrix if self.post_matrix else Matrix())
+ self.post_matrix = settings.global_matrix_inv @ (self.post_matrix if self.post_matrix else Matrix())
# process children
correction_matrix_inv = correction_matrix.inverted_safe() if correction_matrix else None
@@ -1782,29 +1765,29 @@ class FbxImportHelperNode:
def get_world_matrix_as_parent(self):
matrix = self.parent.get_world_matrix_as_parent() if self.parent else Matrix()
if self.matrix_as_parent:
- matrix = matrix * self.matrix_as_parent
+ matrix = matrix @ self.matrix_as_parent
return matrix
def get_world_matrix(self):
matrix = self.parent.get_world_matrix_as_parent() if self.parent else Matrix()
if self.matrix:
- matrix = matrix * self.matrix
+ matrix = matrix @ self.matrix
return matrix
def get_matrix(self):
matrix = self.matrix if self.matrix else Matrix()
if self.pre_matrix:
- matrix = self.pre_matrix * matrix
+ matrix = self.pre_matrix @ matrix
if self.post_matrix:
- matrix = matrix * self.post_matrix
+ matrix = matrix @ self.post_matrix
return matrix
def get_bind_matrix(self):
matrix = self.bind_matrix if self.bind_matrix else Matrix()
if self.pre_matrix:
- matrix = self.pre_matrix * matrix
+ matrix = self.pre_matrix @ matrix
if self.post_matrix:
- matrix = matrix * self.post_matrix
+ matrix = matrix @ self.post_matrix
return matrix
def make_bind_pose_local(self, parent_matrix=None):
@@ -1812,13 +1795,13 @@ class FbxImportHelperNode:
parent_matrix = Matrix()
if self.bind_matrix:
- bind_matrix = parent_matrix.inverted_safe() * self.bind_matrix
+ bind_matrix = parent_matrix.inverted_safe() @ self.bind_matrix
else:
bind_matrix = self.matrix.copy() if self.matrix else None
self.bind_matrix = bind_matrix
if bind_matrix:
- parent_matrix = parent_matrix * bind_matrix
+ parent_matrix = parent_matrix @ bind_matrix
for child in self.children:
child.make_bind_pose_local(parent_matrix)
@@ -1838,8 +1821,8 @@ class FbxImportHelperNode:
child.collect_skeleton_meshes(meshes)
for m in meshes:
old_matrix = m.matrix
- m.matrix = armature_matrix_inv * m.get_world_matrix()
- m.anim_compensation_matrix = old_matrix.inverted_safe() * m.matrix
+ m.matrix = armature_matrix_inv @ m.get_world_matrix()
+ m.anim_compensation_matrix = old_matrix.inverted_safe() @ m.matrix
m.is_global_animation = True
m.parent = self
self.meshes = meshes
@@ -1914,7 +1897,7 @@ class FbxImportHelperNode:
bone.tail = bone_tail
# And rotate/move it to its final "rest pose".
- bone_matrix = parent_matrix * self.get_bind_matrix().normalized()
+ bone_matrix = parent_matrix @ self.get_bind_matrix().normalized()
bone.matrix = bone_matrix
@@ -1927,7 +1910,7 @@ class FbxImportHelperNode:
if child.is_leaf and force_connect_children:
# Arggggggggggggggggg! We do not want to create this bone, but we need its 'virtual head' location
# to orient current one!!!
- child_head = (bone_matrix * child.get_bind_matrix().normalized()).translation
+ child_head = (bone_matrix @ child.get_bind_matrix().normalized()).translation
child_connect(bone, None, child_head, connect_ctx)
elif child.is_bone and not child.ignore:
child_bone = child.build_skeleton(arm, bone_matrix, bone_size,
@@ -1958,7 +1941,7 @@ class FbxImportHelperNode:
# Misc Attributes
obj.color[0:3] = elem_props_get_color_rgb(fbx_props, b'Color', (0.8, 0.8, 0.8))
- obj.hide = not bool(elem_props_get_visibility(fbx_props, b'Visibility', 1.0))
+ obj.hide_viewport = not bool(elem_props_get_visibility(fbx_props, b'Visibility', 1.0))
obj.matrix_basis = self.get_matrix()
@@ -1967,12 +1950,12 @@ class FbxImportHelperNode:
return obj
- def build_skeleton_children(self, fbx_tmpl, settings, scene):
+ def build_skeleton_children(self, fbx_tmpl, settings, scene, view_layer):
if self.is_bone:
for child in self.children:
if child.ignore:
continue
- child.build_skeleton_children(fbx_tmpl, settings, scene)
+ child.build_skeleton_children(fbx_tmpl, settings, scene, view_layer)
return None
else:
# child is not a bone
@@ -1984,11 +1967,11 @@ class FbxImportHelperNode:
for child in self.children:
if child.ignore:
continue
- child.build_skeleton_children(fbx_tmpl, settings, scene)
+ child.build_skeleton_children(fbx_tmpl, settings, scene, view_layer)
# instance in scene
- obj_base = scene.objects.link(obj)
- obj_base.select = True
+ view_layer.collections.active.collection.objects.link(obj)
+ obj.select_set('SELECT')
return obj
@@ -2007,7 +1990,7 @@ class FbxImportHelperNode:
# Blender attaches to the end of a bone, while FBX attaches to the start.
# bone_child_matrix corrects for that.
if child.pre_matrix:
- child.pre_matrix = self.bone_child_matrix * child.pre_matrix
+ child.pre_matrix = self.bone_child_matrix @ child.pre_matrix
else:
child.pre_matrix = self.bone_child_matrix
@@ -2027,7 +2010,7 @@ class FbxImportHelperNode:
def set_pose_matrix(self, arm):
pose_bone = arm.bl_obj.pose.bones[self.bl_bone]
- pose_bone.matrix_basis = self.get_bind_matrix().inverted_safe() * self.get_matrix()
+ pose_bone.matrix_basis = self.get_bind_matrix().inverted_safe() @ self.get_matrix()
for child in self.children:
if child.ignore:
@@ -2094,7 +2077,7 @@ class FbxImportHelperNode:
if child.is_bone and not child.ignore:
child.set_bone_weights()
- def build_hierarchy(self, fbx_tmpl, settings, scene):
+ def build_hierarchy(self, fbx_tmpl, settings, scene, view_layer):
if self.is_armature:
# create when linking since we need object data
elem_name_utf8 = self.fbx_name
@@ -2114,15 +2097,15 @@ class FbxImportHelperNode:
blen_read_custom_properties(self.fbx_elem, arm, settings)
# instance in scene
- obj_base = scene.objects.link(arm)
- obj_base.select = True
+ view_layer.collections.active.collection.objects.link(arm)
+ arm.select_set('SELECT')
# Add bones:
# Switch to Edit mode.
- scene.objects.active = arm
- is_hidden = arm.hide
- arm.hide = False # Can't switch to Edit mode hidden objects...
+ view_layer.objects.active = arm
+ is_hidden = arm.hide_viewport
+ arm.hide_viewport = False # Can't switch to Edit mode hidden objects...
bpy.ops.object.mode_set(mode='EDIT')
for child in self.children:
@@ -2133,7 +2116,7 @@ class FbxImportHelperNode:
bpy.ops.object.mode_set(mode='OBJECT')
- arm.hide = is_hidden
+ arm.hide_viewport = is_hidden
# Set pose matrix
for child in self.children:
@@ -2146,7 +2129,7 @@ class FbxImportHelperNode:
for child in self.children:
if child.ignore:
continue
- child_obj = child.build_skeleton_children(fbx_tmpl, settings, scene)
+ child_obj = child.build_skeleton_children(fbx_tmpl, settings, scene, view_layer)
return arm
elif self.fbx_elem and not self.is_bone:
@@ -2154,16 +2137,16 @@ class FbxImportHelperNode:
# walk through children
for child in self.children:
- child.build_hierarchy(fbx_tmpl, settings, scene)
+ child.build_hierarchy(fbx_tmpl, settings, scene, view_layer)
# instance in scene
- obj_base = scene.objects.link(obj)
- obj_base.select = True
+ view_layer.collections.active.collection.objects.link(obj)
+ obj.select_set('SELECT')
return obj
else:
for child in self.children:
- child.build_hierarchy(fbx_tmpl, settings, scene)
+ child.build_hierarchy(fbx_tmpl, settings, scene, view_layer)
return None
@@ -2192,16 +2175,16 @@ class FbxImportHelperNode:
# which we obviously cannot do in Blender. :/
if amat is None:
amat = self.bind_matrix
- amat = settings.global_matrix * (Matrix() if amat is None else amat)
+ amat = settings.global_matrix @ (Matrix() if amat is None else amat)
if self.matrix_geom:
- amat = amat * self.matrix_geom
- mmat = settings.global_matrix * mmat
+ amat = amat @ self.matrix_geom
+ mmat = settings.global_matrix @ mmat
if mesh.matrix_geom:
- mmat = mmat * mesh.matrix_geom
+ mmat = mmat @ mesh.matrix_geom
# Now that we have armature and mesh in there (global) bind 'state' (matrix),
# we can compute inverse parenting matrix of the mesh.
- me_obj.matrix_parent_inverse = amat.inverted_safe() * mmat * me_obj.matrix_basis.inverted_safe()
+ me_obj.matrix_parent_inverse = amat.inverted_safe() @ mmat @ me_obj.matrix_basis.inverted_safe()
mod = mesh.bl_obj.modifiers.new(arm.name, 'ARMATURE')
mod.object = arm
@@ -2249,7 +2232,6 @@ def load(operator, context, filepath="",
global_scale=1.0,
bake_space_transform=False,
use_custom_normals=True,
- use_cycles=True,
use_image_search=False,
use_alpha_decals=False,
decal_offset=0.0,
@@ -2311,10 +2293,8 @@ def load(operator, context, filepath="",
basedir = os.path.dirname(filepath)
- cycles_material_wrap_map = {}
+ nodal_material_wrap_map = {}
image_cache = {}
- if not use_cycles:
- texture_cache = {}
# Tables: (FBX_byte_id -> [FBX_data, None or Blender_datablock])
fbx_table_nodes = {}
@@ -2325,6 +2305,7 @@ def load(operator, context, filepath="",
material_decals = None
scene = context.scene
+ view_layer = context.view_layer
# #### Get some info from GlobalSettings.
@@ -2350,7 +2331,7 @@ def load(operator, context, filepath="",
elem_props_get_integer(fbx_settings_props, b'CoordAxisSign', 1))
axis_key = (axis_up, axis_forward, axis_coord)
axis_up, axis_forward = {v: k for k, v in RIGHT_HAND_AXES.items()}.get(axis_key, ('Z', 'Y'))
- global_matrix = (Matrix.Scale(global_scale, 4) *
+ global_matrix = (Matrix.Scale(global_scale, 4) @
axis_conversion(from_forward=axis_forward, from_up=axis_up).to_4x4())
# To cancel out unwanted rotation/scale on nodes.
@@ -2381,11 +2362,11 @@ def load(operator, context, filepath="",
settings = FBXImportSettings(
operator.report, (axis_up, axis_forward), global_matrix, global_scale,
bake_space_transform, global_matrix_inv, global_matrix_inv_transposed,
- use_custom_normals, use_cycles, use_image_search,
+ use_custom_normals, use_image_search,
use_alpha_decals, decal_offset,
use_anim, anim_offset,
use_custom_props, use_custom_props_enum_as_string,
- cycles_material_wrap_map, image_cache,
+ nodal_material_wrap_map, image_cache,
ignore_leaf_bones, force_connect_children, automatic_bone_orientation, bone_correction_matrix,
use_prepost_rot,
)
@@ -2682,7 +2663,7 @@ def load(operator, context, filepath="",
armature_matrix = tx_arm
if tx_bone:
- mesh_matrix = tx_bone * mesh_matrix
+ mesh_matrix = tx_bone @ mesh_matrix
helper_node.bind_matrix = tx_bone # overwrite the bind matrix
# Get the meshes driven by this cluster: (Shouldn't that be only one?)
@@ -2725,7 +2706,7 @@ def load(operator, context, filepath="",
root_helper.find_correction_matrix(settings)
# build the Object/Armature/Bone hierarchy
- root_helper.build_hierarchy(fbx_tmpl, settings, scene)
+ root_helper.build_hierarchy(fbx_tmpl, settings, scene, view_layer)
# Link the Object/Armature/Bone hierarchy
root_helper.link_hierarchy(fbx_tmpl, settings, scene)
@@ -2857,8 +2838,7 @@ def load(operator, context, filepath="",
continue
mat = fbx_item[1]
items.append((mat, lnk_prop))
- if settings.use_cycles:
- print("WARNING! Importing material's animation is not supported for Cycles materials...")
+ print("WARNING! Importing material's animation is not supported for Nodal materials...")
for al_uuid, al_ctype in fbx_connection_map.get(acn_uuid, ()):
if al_ctype.props[0] != b'OO':
continue
@@ -2919,17 +2899,17 @@ def load(operator, context, filepath="",
# So we have to be careful not to re-add endlessly the same material to a mesh!
# This can easily happen with 'baked' dupliobjects, see T44386.
# TODO: add an option to link materials to objects in Blender instead?
- done_mats = set()
+ done_materials = set()
for (fbx_lnk, fbx_lnk_item, fbx_lnk_type) in connection_filter_forward(fbx_uuid, b'Model'):
# link materials
fbx_lnk_uuid = elem_uuid(fbx_lnk)
for (fbx_lnk_material, material, fbx_lnk_material_type) in connection_filter_reverse(fbx_lnk_uuid, b'Material'):
- if material not in done_mats:
+ if material not in done_materials:
mesh.materials.append(material)
- done_mats.add(material)
+ done_materials.add(material)
- # We have to validate mesh polygons' mat_idx, see T41015!
+ # We have to validate mesh polygons' ma_idx, see T41015!
# Some FBX seem to have an extra 'default' material which is not defined in FBX file.
if mesh.validate_material_indices():
print("WARNING: mesh '%s' had invalid material indices, those were reset to first material" % mesh.name)
@@ -2943,51 +2923,36 @@ def load(operator, context, filepath="",
fbx_tmpl = fbx_template_get((b'Material', b'KFbxSurfacePhong'))
# b'KFbxSurfaceLambert'
- # textures that use this material
- def texture_bumpfac_get(fbx_obj):
- assert(fbx_obj.id == b'Material')
- fbx_props = (elem_find_first(fbx_obj, b'Properties70'),
- elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
- # (x / 7.142) is only a guess, cycles usable range is (0.0 -> 0.5)
- return elem_props_get_number(fbx_props, b'BumpFactor', 2.5) / 7.142
-
- def texture_mapping_get(fbx_obj):
+ def texture_mapping_set(fbx_obj, node_texture):
assert(fbx_obj.id == b'Texture')
fbx_props = (elem_find_first(fbx_obj, b'Properties70'),
elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
- return (elem_props_get_vector_3d(fbx_props, b'Translation', (0.0, 0.0, 0.0)),
- elem_props_get_vector_3d(fbx_props, b'Rotation', (0.0, 0.0, 0.0)),
- elem_props_get_vector_3d(fbx_props, b'Scaling', (1.0, 1.0, 1.0)),
- (bool(elem_props_get_enum(fbx_props, b'WrapModeU', 0)),
- bool(elem_props_get_enum(fbx_props, b'WrapModeV', 0))))
-
- if not use_cycles:
- # Simple function to make a new mtex and set defaults
- def material_mtex_new(material, image, tex_map):
- tex = texture_cache.get(image)
- if tex is None:
- tex = bpy.data.textures.new(name=image.name, type='IMAGE')
- tex.image = image
- texture_cache[image] = tex
-
- # copy custom properties from image object to texture
- for key, value in image.items():
- tex[key] = value
-
- # delete custom properties on the image object
- for key in image.keys():
- del image[key]
-
- mtex = material.texture_slots.add()
- mtex.texture = tex
- mtex.texture_coords = 'UV'
- mtex.use_map_color_diffuse = False
-
- # No rotation here...
- mtex.offset[:] = tex_map[0]
- mtex.scale[:] = tex_map[2]
- return mtex
+ loc = elem_props_get_vector_3d(fbx_props, b'Translation', (0.0, 0.0, 0.0))
+ rot = tuple(-r for r in elem_props_get_vector_3d(fbx_props, b'Rotation', (0.0, 0.0, 0.0)))
+ scale = tuple(((1.0 / s) if s != 0.0 else 1.0)
+ for s in elem_props_get_vector_3d(fbx_props, b'Scaling', (1.0, 1.0, 1.0)))
+ clamp_uv = (bool(elem_props_get_enum(fbx_props, b'WrapModeU', 0)),
+ bool(elem_props_get_enum(fbx_props, b'WrapModeV', 0)))
+
+ if (loc == (0.0, 0.0, 0.0) and
+ rot == (0.0, 0.0, 0.0) and
+ scale == (1.0, 1.0, 1.0) and
+ clamp_uv == (False, False)):
+ return
+
+ node_texture.translation = loc
+ node_texture.rotation = rot
+ node_texture.scale = scale
+
+ # awkward conversion UV clamping to min/max
+ node_texture.min = (0.0, 0.0, 0.0)
+ node_texture.max = (1.0, 1.0, 1.0)
+ node_texture.use_min = node_texture.use_max = clamp_uv[0] or clamp_uv[1]
+ if clamp_uv[0] != clamp_uv[1]:
+ # use bool as index
+ node_texture.min[not clamp[0]] = -1e9
+ node_texture.max[not clamp[0]] = 1e9
for fbx_uuid, fbx_item in fbx_table_nodes.items():
fbx_obj, blen_data = fbx_item
@@ -2999,112 +2964,44 @@ def load(operator, context, filepath="",
image,
fbx_lnk_type) in connection_filter_reverse(fbx_uuid, b'Texture'):
- if use_cycles:
- if fbx_lnk_type.props[0] == b'OP':
- lnk_type = fbx_lnk_type.props[3]
-
- ma_wrap = cycles_material_wrap_map[material]
-
- # tx/rot/scale
- tex_map = texture_mapping_get(fbx_lnk)
- if (tex_map[0] == (0.0, 0.0, 0.0) and
- tex_map[1] == (0.0, 0.0, 0.0) and
- tex_map[2] == (1.0, 1.0, 1.0) and
- tex_map[3] == (False, False)):
- use_mapping = False
- else:
- use_mapping = True
- tex_map_kw = {
- "translation": tex_map[0],
- "rotation": [-i for i in tex_map[1]],
- "scale": [((1.0 / i) if i != 0.0 else 1.0) for i in tex_map[2]],
- "clamp": tex_map[3],
- }
-
- if lnk_type in {b'DiffuseColor', b'3dsMax|maps|texmap_diffuse'}:
- ma_wrap.diffuse_image_set(image)
- if use_mapping:
- ma_wrap.diffuse_mapping_set(**tex_map_kw)
- elif lnk_type == b'SpecularColor':
- ma_wrap.specular_image_set(image)
- if use_mapping:
- ma_wrap.specular_mapping_set(**tex_map_kw)
- elif lnk_type in {b'ReflectionColor', b'3dsMax|maps|texmap_reflection'}:
- ma_wrap.reflect_image_set(image)
- if use_mapping:
- ma_wrap.reflect_mapping_set(**tex_map_kw)
- elif lnk_type == b'TransparentColor': # alpha
- ma_wrap.alpha_image_set(image)
- if use_mapping:
- ma_wrap.alpha_mapping_set(**tex_map_kw)
- if use_alpha_decals:
- material_decals.add(material)
- elif lnk_type == b'DiffuseFactor':
- pass # TODO
- elif lnk_type == b'ShininessExponent':
- ma_wrap.hardness_image_set(image)
- if use_mapping:
- ma_wrap.hardness_mapping_set(**tex_map_kw)
- # XXX, applications abuse bump!
- elif lnk_type in {b'NormalMap', b'Bump', b'3dsMax|maps|texmap_bump'}:
- ma_wrap.normal_image_set(image)
- ma_wrap.normal_factor_set(texture_bumpfac_get(fbx_obj))
- if use_mapping:
- ma_wrap.normal_mapping_set(**tex_map_kw)
- """
- elif lnk_type == b'Bump':
- ma_wrap.bump_image_set(image)
- ma_wrap.bump_factor_set(texture_bumpfac_get(fbx_obj))
- if use_mapping:
- ma_wrap.bump_mapping_set(**tex_map_kw)
- """
- else:
- print("WARNING: material link %r ignored" % lnk_type)
-
- material_images.setdefault(material, {})[lnk_type] = (image, tex_map)
- else:
- if fbx_lnk_type.props[0] == b'OP':
- lnk_type = fbx_lnk_type.props[3]
-
- # tx/rot/scale (rot is ignored here!).
- tex_map = texture_mapping_get(fbx_lnk)
-
- mtex = material_mtex_new(material, image, tex_map)
-
- if lnk_type in {b'DiffuseColor', b'3dsMax|maps|texmap_diffuse'}:
- mtex.use_map_color_diffuse = True
- mtex.blend_type = 'MULTIPLY'
- elif lnk_type == b'SpecularColor':
- mtex.use_map_color_spec = True
- mtex.blend_type = 'MULTIPLY'
- elif lnk_type in {b'ReflectionColor', b'3dsMax|maps|texmap_reflection'}:
- mtex.use_map_raymir = True
- elif lnk_type == b'TransparentColor': # alpha
- material.use_transparency = True
- material.transparency_method = 'RAYTRACE'
- material.alpha = 0.0
- mtex.use_map_alpha = True
- mtex.alpha_factor = 1.0
- if use_alpha_decals:
- material_decals.add(material)
- elif lnk_type == b'DiffuseFactor':
- mtex.use_map_diffuse = True
- elif lnk_type == b'ShininessExponent':
- mtex.use_map_hardness = True
- # XXX, applications abuse bump!
- elif lnk_type in {b'NormalMap', b'Bump', b'3dsMax|maps|texmap_bump'}:
- mtex.texture.use_normal_map = True # not ideal!
- mtex.use_map_normal = True
- mtex.normal_factor = texture_bumpfac_get(fbx_obj)
- """
- elif lnk_type == b'Bump':
- mtex.use_map_normal = True
- mtex.normal_factor = texture_bumpfac_get(fbx_obj)
- """
- else:
- print("WARNING: material link %r ignored" % lnk_type)
+ if fbx_lnk_type.props[0] == b'OP':
+ lnk_type = fbx_lnk_type.props[3]
+
+ ma_wrap = nodal_material_wrap_map[material]
+
+ if lnk_type in {b'DiffuseColor', b'3dsMax|maps|texmap_diffuse'}:
+ ma_wrap.base_color_texture.image = image
+ texture_mapping_set(fbx_lnk, ma_wrap.base_color_texture)
+ elif lnk_type in {b'SpecularColor', b'SpecularFactor'}:
+ # Intensity actually, not color...
+ ma_wrap.specular_texture.image = image
+ texture_mapping_set(fbx_lnk, ma_wrap.specular_texture)
+ elif lnk_type in {b'ReflectionColor', b'ReflectionFactor', b'3dsMax|maps|texmap_reflection'}:
+ # Intensity actually, not color...
+ ma_wrap.metallic_texture.image = image
+ texture_mapping_set(fbx_lnk, ma_wrap.metallic_texture)
+ elif lnk_type in {b'TransparentColor', b'TransparentFactor'}:
+ # Transparency... sort of...
+ ma_wrap.transmission_texture.image = image
+ texture_mapping_set(fbx_lnk, ma_wrap.transmission_texture)
+ if use_alpha_decals:
+ material_decals.add(material)
+ elif lnk_type == b'ShininessExponent':
+ # That is probably reversed compared to expected results? TODO...
+ ma_wrap.roughness_texture.image = image
+ texture_mapping_set(fbx_lnk, ma_wrap.roughness_texture)
+ # XXX, applications abuse bump!
+ elif lnk_type in {b'NormalMap', b'Bump', b'3dsMax|maps|texmap_bump'}:
+ ma_wrap.normalmap_texture.image = image
+ texture_mapping_set(fbx_lnk, ma_wrap.normalmap_texture)
+ """
+ elif lnk_type == b'Bump':
+ # TODO displacement...
+ """
+ else:
+ print("WARNING: material link %r ignored" % lnk_type)
- material_images.setdefault(material, {})[lnk_type] = (image, tex_map)
+ material_images.setdefault(material, {})[lnk_type] = image
# Check if the diffuse image has an alpha channel,
# if so, use the alpha channel.
@@ -3115,30 +3012,21 @@ def load(operator, context, filepath="",
if fbx_obj.id != b'Material':
continue
material = fbx_table_nodes.get(fbx_uuid, (None, None))[1]
- image, tex_map = material_images.get(material, {}).get(b'DiffuseColor', (None, None))
+ image = material_images.get(material, {}).get(b'DiffuseColor', None)
# do we have alpha?
if image and image.depth == 32:
if use_alpha_decals:
material_decals.add(material)
- if use_cycles:
- ma_wrap = cycles_material_wrap_map[material]
- if ma_wrap.node_bsdf_alpha.mute:
- ma_wrap.alpha_image_set_from_diffuse()
- else:
- if not any((True for mtex in material.texture_slots if mtex and mtex.use_map_alpha)):
- mtex = material_mtex_new(material, image, tex_map)
+ ma_wrap = nodal_material_wrap_map[material]
+ ma_wrap.transmission_texture.use_alpha = True
+ ma_wrap.transmission_texture.copy_from(ma_wrap.base_color_texture)
- material.use_transparency = True
- material.transparency_method = 'RAYTRACE'
- material.alpha = 0.0
- mtex.use_map_alpha = True
- mtex.alpha_factor = 1.0
-
- # propagate mapping from diffuse to all other channels which have none defined.
- if use_cycles:
- ma_wrap = cycles_material_wrap_map[material]
- ma_wrap.mapping_set_from_diffuse()
+ # Propagate mapping from diffuse to all other channels which have none defined.
+ # XXX Commenting for now, I do not really understand the logic here, why should diffuse mapping
+ # be applied to all others if not defined for them???
+ # ~ ma_wrap = nodal_material_wrap_map[material]
+ # ~ ma_wrap.mapping_set_from_diffuse()
_(); del _
@@ -3161,14 +3049,8 @@ def load(operator, context, filepath="",
v.co += v.normal * decal_offset
break
- if use_cycles:
- for obj in (obj for obj in bpy.data.objects if obj.data == mesh):
- obj.cycles_visibility.shadow = False
- else:
- for material in mesh.materials:
- if material in material_decals:
- # receive but dont cast shadows
- material.use_raytrace = False
+ for obj in (obj for obj in bpy.data.objects if obj.data == mesh):
+ obj.cycles_visibility.shadow = False
_(); del _
perfmon.level_down()
diff --git a/io_scene_ms3d/__init__.py b/io_scene_ms3d/__init__.py
index 794aae6b..805b1d83 100644
--- a/io_scene_ms3d/__init__.py
+++ b/io_scene_ms3d/__init__.py
@@ -64,8 +64,8 @@ from bpy.utils import (
unregister_module,
)
from bpy.types import (
- INFO_MT_file_export,
- INFO_MT_file_import,
+ TOPBAR_MT_file_export,
+ TOPBAR_MT_file_import,
)
@@ -82,16 +82,16 @@ def register():
ms3d_ui.register()
register_module(__name__)
- INFO_MT_file_export.append(Ms3dExportOperator.menu_func)
- INFO_MT_file_import.append(Ms3dImportOperator.menu_func)
+ TOPBAR_MT_file_export.append(Ms3dExportOperator.menu_func)
+ TOPBAR_MT_file_import.append(Ms3dImportOperator.menu_func)
def unregister():
ms3d_ui.unregister()
unregister_module(__name__)
- INFO_MT_file_export.remove(Ms3dExportOperator.menu_func)
- INFO_MT_file_import.remove(Ms3dImportOperator.menu_func)
+ TOPBAR_MT_file_export.remove(Ms3dExportOperator.menu_func)
+ TOPBAR_MT_file_import.remove(Ms3dImportOperator.menu_func)
###############################################################################
diff --git a/io_scene_ms3d/ms3d_import.py b/io_scene_ms3d/ms3d_import.py
index a2205556..9a6fb42f 100644
--- a/io_scene_ms3d/ms3d_import.py
+++ b/io_scene_ms3d/ms3d_import.py
@@ -690,14 +690,14 @@ class Ms3dImporter():
blender_armature = blender_context.blend_data.armatures.new(
ms3d_armature_name)
blender_armature.ms3d.name = ms3d_model.name
- blender_armature.draw_type = 'STICK'
+ blender_armature.display_type = 'STICK'
blender_armature.show_axes = True
blender_armature.use_auto_ik = True
blender_armature_object = blender_context.blend_data.objects.new(
ms3d_armature_object_name, blender_armature)
blender_scene.objects.link(blender_armature_object)
#blender_armature_object.location = blender_scene.cursor_location
- blender_armature_object.show_x_ray = True
+ blender_armature_object.show_in_front = True
##########################
# create new modifier
diff --git a/io_scene_ms3d/ms3d_ui.py b/io_scene_ms3d/ms3d_ui.py
index e7b1dfc4..c483df8a 100644
--- a/io_scene_ms3d/ms3d_ui.py
+++ b/io_scene_ms3d/ms3d_ui.py
@@ -210,7 +210,7 @@ class Ms3dUi:
return ms3d_value
###########################################################################
- ICON_OPTIONS = 'LAMP'
+ ICON_OPTIONS = 'LIGHT'
ICON_OBJECT = 'WORLD'
ICON_PROCESSING = 'OBJECT_DATAMODE'
ICON_MODIFIER = 'MODIFIER'
diff --git a/io_scene_obj/__init__.py b/io_scene_obj/__init__.py
index 3bebdecd..e3d3d830 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, 7),
- "blender": (2, 78, 0),
+ "version": (3, 4, 3),
+ "blender": (2, 80, 0),
"location": "File > Import-Export",
"description": "Import-Export OBJ, Import OBJ mesh, UV's, materials and textures",
"warning": "",
@@ -48,70 +48,68 @@ from bpy.props import (
from bpy_extras.io_utils import (
ImportHelper,
ExportHelper,
- orientation_helper_factory,
+ orientation_helper,
path_reference_mode,
axis_conversion,
)
-IOOBJOrientationHelper = orientation_helper_factory("IOOBJOrientationHelper", axis_forward='-Z', axis_up='Y')
-
-
-class ImportOBJ(bpy.types.Operator, ImportHelper, IOOBJOrientationHelper):
+@orientation_helper(axis_forward='-Z', axis_up='Y')
+class ImportOBJ(bpy.types.Operator, ImportHelper):
"""Load a Wavefront OBJ File"""
bl_idname = "import_scene.obj"
bl_label = "Import OBJ"
bl_options = {'PRESET', 'UNDO'}
filename_ext = ".obj"
- filter_glob = StringProperty(
+ filter_glob: StringProperty(
default="*.obj;*.mtl",
options={'HIDDEN'},
)
- use_edges = BoolProperty(
+ use_edges: BoolProperty(
name="Lines",
description="Import lines and faces with 2 verts as edge",
default=True,
)
- use_smooth_groups = BoolProperty(
+ use_smooth_groups: BoolProperty(
name="Smooth Groups",
description="Surround smooth groups by sharp edges",
default=True,
)
- use_split_objects = BoolProperty(
+ use_split_objects: BoolProperty(
name="Object",
description="Import OBJ Objects into Blender Objects",
default=True,
)
- use_split_groups = BoolProperty(
+ use_split_groups: BoolProperty(
name="Group",
description="Import OBJ Groups into Blender Objects",
default=True,
)
- use_groups_as_vgroups = BoolProperty(
+ use_groups_as_vgroups: BoolProperty(
name="Poly Groups",
description="Import OBJ groups as vertex groups",
default=False,
)
- use_image_search = BoolProperty(
+ use_image_search: BoolProperty(
name="Image Search",
description="Search subdirs for any associated images "
"(Warning, may be slow)",
default=True,
)
- split_mode = EnumProperty(
+ split_mode: EnumProperty(
name="Split",
items=(('ON', "Split", "Split geometry, omits unused verts"),
('OFF', "Keep Vert Order", "Keep vertex order from file"),
),
)
- global_clamp_size = FloatProperty(
+ global_clight_size: FloatProperty(
name="Clamp Size",
description="Clamp bounds under this value (zero to disable)",
min=0.0, max=1000.0,
@@ -139,7 +137,6 @@ class ImportOBJ(bpy.types.Operator, ImportHelper, IOOBJOrientationHelper):
from_up=self.axis_up,
).to_4x4()
keywords["global_matrix"] = global_matrix
- keywords["use_cycles"] = (context.scene.render.engine == 'CYCLES')
if bpy.data.is_saved and context.user_preferences.filepaths.use_relative_paths:
import os
@@ -166,15 +163,16 @@ class ImportOBJ(bpy.types.Operator, ImportHelper, IOOBJOrientationHelper):
else:
row.prop(self, "use_groups_as_vgroups")
- row = layout.split(percentage=0.67)
- row.prop(self, "global_clamp_size")
+ row = layout.split(factor=0.67)
+ row.prop(self, "global_clight_size")
layout.prop(self, "axis_forward")
layout.prop(self, "axis_up")
layout.prop(self, "use_image_search")
-class ExportOBJ(bpy.types.Operator, ExportHelper, IOOBJOrientationHelper):
+@orientation_helper(axis_forward='-Z', axis_up='Y')
+class ExportOBJ(bpy.types.Operator, ExportHelper):
"""Save a Wavefront OBJ File"""
bl_idname = "export_scene.obj"
@@ -182,113 +180,113 @@ class ExportOBJ(bpy.types.Operator, ExportHelper, IOOBJOrientationHelper):
bl_options = {'PRESET'}
filename_ext = ".obj"
- filter_glob = StringProperty(
+ filter_glob: StringProperty(
default="*.obj;*.mtl",
options={'HIDDEN'},
)
# context group
- use_selection = BoolProperty(
+ use_selection: BoolProperty(
name="Selection Only",
description="Export selected objects only",
default=False,
)
- use_animation = BoolProperty(
+ use_animation: BoolProperty(
name="Animation",
description="Write out an OBJ for each frame",
default=False,
)
# object group
- use_mesh_modifiers = BoolProperty(
+ use_mesh_modifiers: BoolProperty(
name="Apply Modifiers",
description="Apply modifiers",
default=True,
)
- use_mesh_modifiers_render = BoolProperty(
+ use_mesh_modifiers_render: BoolProperty(
name="Use Modifiers Render Settings",
description="Use render settings when applying modifiers to mesh objects",
default=False,
)
# extra data group
- use_edges = BoolProperty(
+ use_edges: BoolProperty(
name="Include Edges",
description="",
default=True,
)
- use_smooth_groups = BoolProperty(
+ use_smooth_groups: BoolProperty(
name="Smooth Groups",
description="Write sharp edges as smooth groups",
default=False,
)
- use_smooth_groups_bitflags = BoolProperty(
+ use_smooth_groups_bitflags: BoolProperty(
name="Bitflag Smooth Groups",
description="Same as 'Smooth Groups', but generate smooth groups IDs as bitflags "
"(produces at most 32 different smooth groups, usually much less)",
default=False,
)
- use_normals = BoolProperty(
+ use_normals: BoolProperty(
name="Write Normals",
description="Export one normal per vertex and per face, to represent flat faces and sharp edges",
default=True,
)
- use_uvs = BoolProperty(
+ use_uvs: BoolProperty(
name="Include UVs",
description="Write out the active UV coordinates",
default=True,
)
- use_materials = BoolProperty(
+ use_materials: BoolProperty(
name="Write Materials",
description="Write out the MTL file",
default=True,
)
- use_triangles = BoolProperty(
+ use_triangles: BoolProperty(
name="Triangulate Faces",
description="Convert all faces to triangles",
default=False,
)
- use_nurbs = BoolProperty(
+ use_nurbs: BoolProperty(
name="Write Nurbs",
description="Write nurbs curves as OBJ nurbs rather than "
"converting to geometry",
default=False,
)
- use_vertex_groups = BoolProperty(
+ use_vertex_groups: BoolProperty(
name="Polygroups",
description="",
default=False,
)
# grouping group
- use_blen_objects = BoolProperty(
+ use_blen_objects: BoolProperty(
name="Objects as OBJ Objects",
description="",
default=True,
)
- group_by_object = BoolProperty(
+ group_by_object: BoolProperty(
name="Objects as OBJ Groups ",
description="",
default=False,
)
- group_by_material = BoolProperty(
+ group_by_material: BoolProperty(
name="Material Groups",
description="",
default=False,
)
- keep_vertex_order = BoolProperty(
+ keep_vertex_order: BoolProperty(
name="Keep Vertex Order",
description="",
default=False,
)
- global_scale = FloatProperty(
+ global_scale: FloatProperty(
name="Scale",
min=0.01, max=1000.0,
default=1.0,
)
- path_mode = path_reference_mode
+ path_mode: path_reference_mode
check_extension = True
@@ -303,7 +301,7 @@ class ExportOBJ(bpy.types.Operator, ExportHelper, IOOBJOrientationHelper):
"filter_glob",
))
- global_matrix = (Matrix.Scale(self.global_scale, 4) *
+ global_matrix = (Matrix.Scale(self.global_scale, 4) @
axis_conversion(to_forward=self.axis_forward,
to_up=self.axis_up,
).to_4x4())
@@ -330,13 +328,13 @@ def register():
for cls in classes:
bpy.utils.register_class(cls)
- bpy.types.INFO_MT_file_import.append(menu_func_import)
- bpy.types.INFO_MT_file_export.append(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
- bpy.types.INFO_MT_file_import.remove(menu_func_import)
- bpy.types.INFO_MT_file_export.remove(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
for cls in classes:
bpy.utils.unregister_class(cls)
diff --git a/io_scene_obj/export_obj.py b/io_scene_obj/export_obj.py
index acdcbc6c..22a82234 100644
--- a/io_scene_obj/export_obj.py
+++ b/io_scene_obj/export_obj.py
@@ -21,8 +21,8 @@
import os
import bpy
-import mathutils
-import bpy_extras.io_utils
+from mathutils import Matrix, Vector, Color
+from bpy_extras import io_utils, node_shader_utils
from progress_report import ProgressReport, ProgressReportSubstep
@@ -44,13 +44,8 @@ def mesh_triangulate(me):
def write_mtl(scene, filepath, path_mode, copy_set, mtl_dict):
- from mathutils import Color, Vector
-
world = scene.world
- if world:
- world_amb = world.ambient_color
- else:
- world_amb = Color((0.0, 0.0, 0.0))
+ world_amb = Color((0.8, 0.8, 0.8))
source_dir = os.path.dirname(bpy.data.filepath)
dest_dir = os.path.dirname(filepath)
@@ -66,133 +61,100 @@ def write_mtl(scene, filepath, path_mode, copy_set, mtl_dict):
# Write material/image combinations we have used.
# Using mtl_dict.values() directly gives un-predictable order.
- for mtl_mat_name, mat, face_img in mtl_dict_values:
+ for mtl_mat_name, mat in mtl_dict_values:
# Get the Blender data for the material and the image.
# Having an image named None will make a bug, dont do it :)
fw('\nnewmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname
- if mat:
- use_mirror = mat.raytrace_mirror.use and mat.raytrace_mirror.reflect_factor != 0.0
+ mat_wrap = node_shader_utils.PrincipledBSDFWrapper(mat) if mat else None
- # convert from blenders spec to 0 - 1000 range.
- if mat.specular_shader == 'WARDISO':
- tspec = (0.4 - mat.specular_slope) / 0.0004
- else:
- tspec = (mat.specular_hardness - 1) / 0.51
- fw('Ns %.6f\n' % tspec)
- del tspec
+ if mat_wrap:
+ use_mirror = mat_wrap.metallic != 0.0
+ use_transparency = mat_wrap.transmission != 0.0
+
+ # XXX Totally empirical conversion, trying to adapt it
+ # (from 1.0 - 0.0 Principled BSDF range to 0.0 - 900.0 OBJ specular exponent range)...
+ spec = (1.0 - mat_wrap.roughness) * 30
+ spec *= spec
+ fw('Ns %.6f\n' % spec)
# Ambient
if use_mirror:
- fw('Ka %.6f %.6f %.6f\n' % (mat.raytrace_mirror.reflect_factor * mat.mirror_color)[:])
+ fw('Ka %.6f %.6f %.6f\n' % (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic))
else:
- fw('Ka %.6f %.6f %.6f\n' % (mat.ambient, mat.ambient, mat.ambient)) # Do not use world color!
- fw('Kd %.6f %.6f %.6f\n' % (mat.diffuse_intensity * mat.diffuse_color)[:]) # Diffuse
- fw('Ks %.6f %.6f %.6f\n' % (mat.specular_intensity * mat.specular_color)[:]) # Specular
+ fw('Ka %.6f %.6f %.6f\n' % (1.0, 1.0, 1.0))
+ fw('Kd %.6f %.6f %.6f\n' % mat_wrap.base_color[:3]) # Diffuse
+ # XXX TODO Find a way to handle tint and diffuse color, in a consistent way with import...
+ fw('Ks %.6f %.6f %.6f\n' % (mat_wrap.specular, mat_wrap.specular, mat_wrap.specular)) # Specular
# Emission, not in original MTL standard but seems pretty common, see T45766.
- # XXX Blender has no color emission, it's using diffuse color instead...
- fw('Ke %.6f %.6f %.6f\n' % (mat.emit * mat.diffuse_color)[:])
- if hasattr(mat, "raytrace_transparency") and hasattr(mat.raytrace_transparency, "ior"):
- fw('Ni %.6f\n' % mat.raytrace_transparency.ior) # Refraction index
- else:
- fw('Ni %.6f\n' % 1.0)
- fw('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve)
+ # XXX Not supported by current Principled-based shader.
+ fw('Ke 0.0 0.0 0.0\n')
+ fw('Ni %.6f\n' % mat_wrap.ior) # Refraction index
+ fw('d %.6f\n' % (1.0 - mat_wrap.transmission)) # Alpha (obj uses 'd' for dissolve)
# See http://en.wikipedia.org/wiki/Wavefront_.obj_file for whole list of values...
# Note that mapping is rather fuzzy sometimes, trying to do our best here.
- if mat.use_shadeless:
- fw('illum 0\n') # ignore lighting
- elif mat.specular_intensity == 0:
+ if mat_wrap.specular == 0:
fw('illum 1\n') # no specular.
elif use_mirror:
- if mat.use_transparency and mat.transparency_method == 'RAYTRACE':
- if mat.raytrace_mirror.fresnel != 0.0:
- fw('illum 7\n') # Reflection, Transparency, Ray trace and Fresnel
- else:
- fw('illum 6\n') # Reflection, Transparency, Ray trace
- elif mat.raytrace_mirror.fresnel != 0.0:
- fw('illum 5\n') # Reflection, Ray trace and Fresnel
+ if use_transparency:
+ fw('illum 6\n') # Reflection, Transparency, Ray trace
else:
fw('illum 3\n') # Reflection and Ray trace
- elif mat.use_transparency and mat.transparency_method == 'RAYTRACE':
+ elif use_transparency:
fw('illum 9\n') # 'Glass' transparency and no Ray trace reflection... fuzzy matching, but...
else:
fw('illum 2\n') # light normally
- else:
- # Write a dummy material here?
- fw('Ns 0\n')
- fw('Ka %.6f %.6f %.6f\n' % world_amb[:]) # Ambient, uses mirror color,
- fw('Kd 0.8 0.8 0.8\n')
- fw('Ks 0.8 0.8 0.8\n')
- fw('d 1\n') # No alpha
- fw('illum 2\n') # light normally
-
- # Write images!
- if face_img: # We have an image on the face!
- filepath = face_img.filepath
- if filepath: # may be '' for generated images
- # write relative image path
- filepath = bpy_extras.io_utils.path_reference(filepath, source_dir, dest_dir,
- path_mode, "", copy_set, face_img.library)
- fw('map_Kd %s\n' % filepath) # Diffuse mapping image
- del filepath
- else:
- # so we write the materials image.
- face_img = None
-
- if mat: # No face image. if we havea material search for MTex image.
- image_map = {}
- # backwards so topmost are highest priority
- for mtex in reversed(mat.texture_slots):
- if mtex and mtex.texture and mtex.texture.type == 'IMAGE':
- image = mtex.texture.image
- if image:
- # texface overrides others
- if (mtex.use_map_color_diffuse and (face_img is None) and
- (mtex.use_map_warp is False) and (mtex.texture_coords != 'REFLECTION')):
- image_map["map_Kd"] = (mtex, image)
- if mtex.use_map_ambient:
- image_map["map_Ka"] = (mtex, image)
- # this is the Spec intensity channel but Ks stands for specular Color
- '''
- if mtex.use_map_specular:
- image_map["map_Ks"] = (mtex, image)
- '''
- if mtex.use_map_color_spec: # specular color
- image_map["map_Ks"] = (mtex, image)
- if mtex.use_map_hardness: # specular hardness/glossiness
- image_map["map_Ns"] = (mtex, image)
- if mtex.use_map_alpha:
- image_map["map_d"] = (mtex, image)
- if mtex.use_map_translucency:
- image_map["map_Tr"] = (mtex, image)
- if mtex.use_map_normal:
- image_map["map_Bump"] = (mtex, image)
- if mtex.use_map_displacement:
- image_map["disp"] = (mtex, image)
- if mtex.use_map_color_diffuse and (mtex.texture_coords == 'REFLECTION'):
- image_map["refl"] = (mtex, image)
- if mtex.use_map_emit:
- image_map["map_Ke"] = (mtex, image)
-
- for key, (mtex, image) in sorted(image_map.items()):
- filepath = bpy_extras.io_utils.path_reference(image.filepath, source_dir, dest_dir,
- path_mode, "", copy_set, image.library)
+ #### And now, the image textures...
+ image_map = {
+ "map_Kd": "base_color_texture",
+ "map_Ka": None, # ambient...
+ "map_Ks": "specular_texture",
+ "map_Ns": "roughness_texture",
+ "map_d": "transmission_texture",
+ "map_Tr": None, # transmission roughness?
+ "map_Bump": "normalmap_texture",
+ "disp": None, # displacement...
+ "refl": "metallic_texture",
+ "map_Ke": None # emission...
+ }
+
+ for key, mat_wrap_key in sorted(image_map.items()):
+ if mat_wrap_key is None:
+ continue
+ tex_wrap = getattr(mat_wrap, mat_wrap_key, None)
+ if tex_wrap is None:
+ continue
+ image = tex_wrap.image
+ if image is None:
+ continue
+
+ filepath = io_utils.path_reference(image.filepath, source_dir, dest_dir,
+ path_mode, "", copy_set, image.library)
options = []
if key == "map_Bump":
- if mtex.normal_factor != 1.0:
- options.append('-bm %.6f' % mtex.normal_factor)
- if mtex.offset != Vector((0.0, 0.0, 0.0)):
- options.append('-o %.6f %.6f %.6f' % mtex.offset[:])
- if mtex.scale != Vector((1.0, 1.0, 1.0)):
- options.append('-s %.6f %.6f %.6f' % mtex.scale[:])
+ if mat_wrap.normalmap_strengh != 1.0:
+ options.append('-bm %.6f' % mat_wrap.normalmap_strengh)
+ if tex_wrap.translation != Vector((0.0, 0.0, 0.0)):
+ options.append('-o %.6f %.6f %.6f' % tex_wrap.translation[:])
+ if tex_wrap.scale != Vector((1.0, 1.0, 1.0)):
+ options.append('-s %.6f %.6f %.6f' % tex_wrap.scale[:])
if options:
fw('%s %s %s\n' % (key, " ".join(options), repr(filepath)[1:-1]))
else:
fw('%s %s\n' % (key, repr(filepath)[1:-1]))
+ else:
+ # Write a dummy material here?
+ fw('Ns 500\n')
+ fw('Ka 0.8 0.8 0.8\n')
+ fw('Kd 0.8 0.8 0.8\n')
+ fw('Ks 0.8 0.8 0.8\n')
+ fw('d 1\n') # No alpha
+ fw('illum 2\n') # light normally
+
def test_nurbs_compat(ob):
if ob.type != 'CURVE':
@@ -233,7 +195,7 @@ def write_nurb(fw, ob, ob_mat):
do_endpoints = (do_closed == 0) and nu.use_endpoint_u
for pt in nu.points:
- fw('v %.6f %.6f %.6f\n' % (ob_mat * pt.co.to_3d())[:])
+ fw('v %.6f %.6f %.6f\n' % (ob_mat @ pt.co.to_3d())[:])
pt_num += 1
tot_verts += pt_num
@@ -271,7 +233,7 @@ def write_nurb(fw, ob, ob_mat):
return tot_verts
-def write_file(filepath, objects, scene,
+def write_file(filepath, objects, depsgraph, scene,
EXPORT_TRI=False,
EXPORT_EDGES=False,
EXPORT_SMOOTH_GROUPS=False,
@@ -298,7 +260,7 @@ def write_file(filepath, objects, scene,
write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options.
"""
if EXPORT_GLOBAL_MATRIX is None:
- EXPORT_GLOBAL_MATRIX = mathutils.Matrix()
+ EXPORT_GLOBAL_MATRIX = Matrix()
def veckey3d(v):
return round(v.x, 4), round(v.y, 4), round(v.z, 4)
@@ -382,14 +344,13 @@ def write_file(filepath, objects, scene,
# Nurbs curve support
if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob):
- ob_mat = EXPORT_GLOBAL_MATRIX * ob_mat
+ ob_mat = EXPORT_GLOBAL_MATRIX @ ob_mat
totverts += write_nurb(fw, ob, ob_mat)
continue
# END NURBS
try:
- me = ob.to_mesh(scene, EXPORT_APPLY_MODIFIERS, calc_tessface=False,
- settings='RENDER' if EXPORT_APPLY_MODIFIERS_RENDER else 'PREVIEW')
+ me = ob.to_mesh(depsgraph, EXPORT_APPLY_MODIFIERS)
except RuntimeError:
me = None
@@ -401,15 +362,14 @@ def write_file(filepath, objects, scene,
# _must_ do this first since it re-allocs arrays
mesh_triangulate(me)
- me.transform(EXPORT_GLOBAL_MATRIX * ob_mat)
+ 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_UV:
- faceuv = len(me.uv_textures) > 0
+ faceuv = len(me.uv_layers) > 0
if faceuv:
- uv_texture = me.uv_textures.active.data[:]
uv_layer = me.uv_layers.active.data[:]
else:
faceuv = False
@@ -418,7 +378,6 @@ def write_file(filepath, objects, scene,
# Make our own list so it can be sorted to reduce context switching
face_index_pairs = [(face, index) for index, face in enumerate(me.polygons)]
- # faces = [ f for f in me.tessfaces ]
if EXPORT_EDGES:
edges = me.edges
@@ -456,16 +415,7 @@ def write_file(filepath, objects, scene,
if EXPORT_KEEP_VERT_ORDER:
pass
else:
- if faceuv:
- if smooth_groups:
- sort_func = lambda a: (a[0].material_index,
- hash(uv_texture[a[1]].image),
- smooth_groups[a[1]] if a[0].use_smooth else False)
- else:
- sort_func = lambda a: (a[0].material_index,
- hash(uv_texture[a[1]].image),
- a[0].use_smooth)
- elif len(materials) > 1:
+ if len(materials) > 1:
if smooth_groups:
sort_func = lambda a: (a[0].material_index,
smooth_groups[a[1]] if a[0].use_smooth else False)
@@ -559,9 +509,6 @@ def write_file(filepath, objects, scene,
else:
loops_to_normals = []
- if not faceuv:
- f_image = None
-
subprogress2.step()
# XXX
@@ -581,15 +528,8 @@ def write_file(filepath, objects, scene,
f_smooth = smooth_groups[f_index]
f_mat = min(f.material_index, len(materials) - 1)
- if faceuv:
- tface = uv_texture[f_index]
- f_image = tface.image
-
# MAKE KEY
- if faceuv and f_image: # Object is always true.
- key = material_names[f_mat], f_image.name
- else:
- key = material_names[f_mat], None # No image, use None instead.
+ key = material_names[f_mat], None # No image, use None instead.
# Write the vertex group
if EXPORT_POLYGROUPS:
@@ -635,7 +575,7 @@ def write_file(filepath, objects, scene,
i += 1
tmp_ext = "_%3d" % i
mtl_name += tmp_ext
- mat_data = mtl_dict[key] = mtl_name, materials[f_mat], f_image
+ mat_data = mtl_dict[key] = mtl_name, materials[f_mat]
mtl_rev_dict[mtl_name] = key
if EXPORT_GROUP_BY_MAT:
@@ -714,7 +654,7 @@ def write_file(filepath, objects, scene,
write_mtl(scene, mtlfilepath, EXPORT_PATH_MODE, copy_set, mtl_dict)
# copy all collected files.
- bpy_extras.io_utils.path_reference_copy(copy_set)
+ io_utils.path_reference_copy(copy_set)
def _write(context, filepath,
@@ -743,6 +683,7 @@ def _write(context, filepath,
base_name, ext = os.path.splitext(filepath)
context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension
+ depsgraph = context.depsgraph
scene = context.scene
# Exit edit mode before exporting, so current object states are exported properly.
@@ -763,7 +704,7 @@ def _write(context, filepath,
if EXPORT_ANIMATION: # Add frame to the filepath.
context_name[2] = '_%.6d' % frame
- scene.frame_set(frame, 0.0)
+ scene.frame_set(frame, subframe=0.0)
if EXPORT_SEL_ONLY:
objects = context.selected_objects
else:
@@ -774,7 +715,7 @@ def _write(context, filepath,
# erm... bit of a problem here, this can overwrite files when exporting frames. not too bad.
# EXPORT THE FILE.
progress.enter_substeps(1)
- write_file(full_path, objects, scene,
+ write_file(full_path, objects, depsgraph, scene,
EXPORT_TRI,
EXPORT_EDGES,
EXPORT_SMOOTH_GROUPS,
@@ -796,7 +737,7 @@ def _write(context, filepath,
)
progress.leave_substeps()
- scene.frame_set(orig_frame, 0.0)
+ scene.frame_set(orig_frame, subframe=0.0)
progress.leave_substeps()
diff --git a/io_scene_obj/import_obj.py b/io_scene_obj/import_obj.py
index 52a9a291..4f3ee24a 100644
--- a/io_scene_obj/import_obj.py
+++ b/io_scene_obj/import_obj.py
@@ -87,21 +87,23 @@ def obj_image_load(context_imagepath_map, line, DIR, recursive, relpath):
def create_materials(filepath, relpath,
- material_libs, unique_materials, unique_material_images,
- use_image_search, use_cycles, float_func):
+ material_libs, unique_materials,
+ use_image_search, float_func):
"""
Create all the used materials in this obj,
assign colors and images to the materials from all referenced material libs
"""
+ from math import sqrt
+
DIR = os.path.dirname(filepath)
context_material_vars = set()
# Don't load the same image multiple times
context_imagepath_map = {}
- cycles_material_wrap_map = {}
+ nodal_material_wrap_map = {}
- def load_material_image(blender_material, mat_wrap, use_cycles, context_material_name, img_data, line, type):
+ def load_material_image(blender_material, mat_wrap, context_material_name, img_data, line, type):
"""
Set textures defined in .mtl file.
"""
@@ -120,105 +122,47 @@ def create_materials(filepath, relpath,
# Absolute path - c:\.. etc would work here
image = obj_image_load(context_imagepath_map, line, DIR, use_image_search, relpath)
- texture = bpy.data.textures.new(name=type, type='IMAGE')
- if image is not None:
- texture.image = image
-
map_offset = map_options.get(b'-o')
map_scale = map_options.get(b'-s')
+ def _generic_tex_set(nodetex, image, texcoords, translation, scale):
+ nodetex.image = image
+ nodetex.texcoords = texcoords
+ if translation is not None:
+ nodetex.translation = translation
+ if scale is not None:
+ nodetex.scale = scale
+
# Adds textures for materials (rendering)
if type == 'Kd':
- if use_cycles:
- mat_wrap.diffuse_image_set(image)
- mat_wrap.diffuse_mapping_set(coords='UV', translation=map_offset, scale=map_scale)
-
- mtex = blender_material.texture_slots.add()
- mtex.texture = texture
- mtex.texture_coords = 'UV'
- mtex.use_map_color_diffuse = True
-
- # adds textures to faces (Textured/Alt-Z mode)
- # Only apply the diffuse texture to the face if the image has not been set with the inline usemat func.
- unique_material_images[context_material_name] = image # set the texface image
+ _generic_tex_set(mat_wrap.base_color_texture, image, 'UV', map_offset, map_scale)
elif type == 'Ka':
- if use_cycles:
- # XXX Not supported?
- print("WARNING, currently unsupported ambient texture, skipped.")
-
- mtex = blender_material.texture_slots.add()
- mtex.use_map_color_diffuse = False
- mtex.texture = texture
- mtex.texture_coords = 'UV'
- mtex.use_map_ambient = True
+ # XXX Not supported?
+ print("WARNING, currently unsupported ambient texture, skipped.")
elif type == 'Ks':
- if use_cycles:
- mat_wrap.specular_image_set(image)
- mat_wrap.specular_mapping_set(coords='UV', translation=map_offset, scale=map_scale)
-
- mtex = blender_material.texture_slots.add()
- mtex.use_map_color_diffuse = False
- mtex.texture = texture
- mtex.texture_coords = 'UV'
- mtex.use_map_color_spec = True
+ _generic_tex_set(mat_wrap.specular_texture, image, 'UV', map_offset, map_scale)
elif type == 'Ke':
- if use_cycles:
- # XXX Not supported?
- print("WARNING, currently unsupported emit texture, skipped.")
-
- mtex = blender_material.texture_slots.add()
- mtex.use_map_color_diffuse = False
- mtex.texture = texture
- mtex.texture_coords = 'UV'
- mtex.use_map_emit = True
+ # XXX Not supported?
+ print("WARNING, currently unsupported emit texture, skipped.")
elif type == 'Bump':
bump_mult = map_options.get(b'-bm')
bump_mult = float(bump_mult[0]) if (bump_mult and len(bump_mult[0]) > 1) else 1.0
+ mat_wrap.normalmap_strength_set(bump_mult)
- if use_cycles:
- mat_wrap.normal_image_set(image)
- mat_wrap.normal_mapping_set(coords='UV', translation=map_offset, scale=map_scale)
- if bump_mult:
- mat_wrap.normal_factor_set(bump_mult)
-
- mtex = blender_material.texture_slots.add()
- mtex.use_map_color_diffuse = False
- mtex.texture = texture
- mtex.texture_coords = 'UV'
- mtex.use_map_normal = True
- if bump_mult:
- mtex.normal_factor = bump_mult
+ _generic_tex_set(mat_wrap.normalmap_texture, image, 'UV', map_offset, map_scale)
elif type == 'D':
- if use_cycles:
- mat_wrap.alpha_image_set(image)
- mat_wrap.alpha_mapping_set(coords='UV', translation=map_offset, scale=map_scale)
-
- mtex = blender_material.texture_slots.add()
- mtex.use_map_color_diffuse = False
- mtex.texture = texture
- mtex.texture_coords = 'UV'
- mtex.use_map_alpha = True
- blender_material.use_transparency = True
- blender_material.transparency_method = 'Z_TRANSPARENCY'
- if "alpha" not in context_material_vars:
- blender_material.alpha = 0.0
- # Todo, unset diffuse material alpha if it has an alpha channel
+ _generic_tex_set(mat_wrap.transmission_texture, image, 'UV', map_offset, map_scale)
elif type == 'disp':
- if use_cycles:
- mat_wrap.bump_image_set(image)
- mat_wrap.bump_mapping_set(coords='UV', translation=map_offset, scale=map_scale)
-
- mtex = blender_material.texture_slots.add()
- mtex.use_map_color_diffuse = False
- mtex.texture = texture
- mtex.texture_coords = 'UV'
- mtex.use_map_displacement = True
+ # XXX Not supported?
+ print("WARNING, currently unsupported displacement texture, skipped.")
+ # ~ mat_wrap.bump_image_set(image)
+ # ~ mat_wrap.bump_mapping_set(coords='UV', translation=map_offset, scale=map_scale)
elif type == 'refl':
map_type = map_options.get(b'-type')
@@ -226,32 +170,12 @@ def create_materials(filepath, relpath,
print("WARNING, unsupported reflection type '%s', defaulting to 'sphere'"
"" % ' '.join(i.decode() for i in map_type))
- if use_cycles:
- mat_wrap.diffuse_image_set(image, projection='SPHERE')
- mat_wrap.diffuse_mapping_set(coords='Reflection', translation=map_offset, scale=map_scale)
+ _generic_tex_set(mat_wrap.base_color_texture, image, 'Reflection', map_offset, map_scale)
+ mat_wrap.base_color_texture.projection = 'SPHERE'
- mtex = blender_material.texture_slots.add()
- mtex.use_map_color_diffuse = False
- mtex.texture = texture
- mtex.texture_coords = 'REFLECTION'
- mtex.use_map_color_diffuse = True
- mtex.mapping = 'SPHERE'
else:
raise Exception("invalid type %r" % type)
- if map_offset:
- mtex.offset.x = float(map_offset[0])
- if len(map_offset) >= 2:
- mtex.offset.y = float(map_offset[1])
- if len(map_offset) >= 3:
- mtex.offset.z = float(map_offset[2])
- if map_scale:
- mtex.scale.x = float(map_scale[0])
- if len(map_scale) >= 2:
- mtex.scale.y = float(map_scale[1])
- if len(map_scale) >= 3:
- mtex.scale.z = float(map_scale[2])
-
# Add an MTL with the same name as the obj if no MTLs are spesified.
temp_mtl = os.path.splitext((os.path.basename(filepath)))[0] + ".mtl"
@@ -263,17 +187,10 @@ def create_materials(filepath, relpath,
for name in unique_materials: # .keys()
if name is not None:
ma = unique_materials[name] = bpy.data.materials.new(name.decode('utf-8', "replace"))
- unique_material_images[name] = None # assign None to all material images to start with, add to later.
- if use_cycles:
- from modules import cycles_shader_compat
- ma_wrap = cycles_shader_compat.CyclesShaderWrapper(ma)
- cycles_material_wrap_map[ma] = ma_wrap
-
-
- # XXX Why was this needed? Cannot find any good reason, and adds stupid empty matslot in case we do not separate
- # mesh (see T44947).
- #~ unique_materials[None] = None
- #~ unique_material_images[None] = None
+ from bpy_extras import node_shader_utils
+ ma_wrap = node_shader_utils.PrincipledBSDFWrapper(ma, is_readonly=False)
+ nodal_material_wrap_map[ma] = ma_wrap
+ ma_wrap.use_nodes = True
for libname in sorted(material_libs):
# print(libname)
@@ -281,13 +198,13 @@ def create_materials(filepath, relpath,
if not os.path.exists(mtlpath):
print("\tMaterial not found MTL: %r" % mtlpath)
else:
- do_ambient = True
+ # Note: with modern Principled BSDF shader, things like ambient, raytrace or fresnel are always 'ON'
+ # (i.e. automatically controlled by other parameters).
do_highlight = False
do_reflection = False
do_transparency = False
do_glass = False
- do_fresnel = False
- do_raytrace = False
+ spec_colors = [0.0, 0.0, 0.0]
emit_colors = [0.0, 0.0, 0.0]
# print('\t\tloading mtl: %e' % mtlpath)
@@ -305,133 +222,112 @@ def create_materials(filepath, relpath,
if line_id == b'newmtl':
# Finalize previous mat, if any.
if context_material:
+ if "specular" in context_material_vars:
+ # XXX This is highly approximated, not sure whether we can do better...
+ # TODO: Find a way to guesstimate best value from diffuse color...
+ # IDEA: Use standard deviation of both spec and diff colors (i.e. how far away they are
+ # from some grey), and apply the the proportion between those two as tint factor?
+ spec = sum(spec_color) / 3.0
+ # ~ spec_var = math.sqrt(sum((c - spec) ** 2 for c in spec_color) / 3.0)
+ # ~ diff = sum(context_mat_wrap.base_color) / 3.0
+ # ~ diff_var = math.sqrt(sum((c - diff) ** 2 for c in context_mat_wrap.base_color) / 3.0)
+ # ~ tint = min(1.0, spec_var / diff_var)
+ context_mat_wrap.specular = spec
+ context_mat_wrap.specular_tint = 0.0
+ if "roughness" not in context_material_vars:
+ context_mat_wrap.roughness = 0.0
+
+
emit_value = sum(emit_colors) / 3.0
if emit_value > 1e-6:
- if use_cycles:
- print("WARNING, currently unsupported emit value, skipped.")
+ print("WARNING, emit value unsupported by Principled BSDF shader, skipped.")
# We have to adapt it to diffuse color too...
emit_value /= sum(context_material.diffuse_color) / 3.0
- context_material.emit = emit_value
-
- if not do_ambient:
- context_material.ambient = 0.0
+ # ~ context_material.emit = emit_value
+ # FIXME, how else to use this?
if do_highlight:
- if use_cycles:
- context_mat_wrap.hardness_value_set(1.0)
- # FIXME, how else to use this?
- context_material.specular_intensity = 1.0
+ if "specular" not in context_material_vars:
+ context_mat_wrap.specular = 1.0
+ if "roughness" not in context_material_vars:
+ context_mat_wrap.roughness = 0.0
else:
- if use_cycles:
- context_mat_wrap.hardness_value_set(0.0)
+ if "specular" not in context_material_vars:
+ context_mat_wrap.specular = 0.0
+ if "roughness" not in context_material_vars:
+ context_mat_wrap.roughness = 1.0
if do_reflection:
- if use_cycles:
- context_mat_wrap.reflect_factor_set(1.0)
- context_material.raytrace_mirror.use = True
- context_material.raytrace_mirror.reflect_factor = 1.0
+ if "metallic" not in context_material_vars:
+ context_mat_wrap.metallic = 1.0
if do_transparency:
- context_material.use_transparency = True
- context_material.transparency_method = 'RAYTRACE' if do_raytrace else 'Z_TRANSPARENCY'
- if "alpha" not in context_material_vars:
- if use_cycles:
- context_mat_wrap.alpha_value_set(0.0)
- context_material.alpha = 0.0
+ if "ior" not in context_material_vars:
+ context_mat_wrap.ior = 1.0
+ if "transmission" not in context_material_vars:
+ context_mat_wrap.transmission = 1.0
+ # EEVEE only
+ context_material.blend_method = 'BLEND'
if do_glass:
- if use_cycles:
- print("WARNING, currently unsupported glass material, skipped.")
if "ior" not in context_material_vars:
- context_material.raytrace_transparency.ior = 1.5
-
- if do_fresnel:
- if use_cycles:
- print("WARNING, currently unsupported fresnel option, skipped.")
- context_material.raytrace_mirror.fresnel = 1.0 # could be any value for 'ON'
-
- """
- if do_raytrace:
- context_material.use_raytrace = True
- else:
- context_material.use_raytrace = False
- """
- # XXX, this is not following the OBJ spec, but this was
- # written when raytracing wasnt default, annoying to disable for blender users.
- context_material.use_raytrace = True
+ context_mat_wrap.ior = 1.5
context_material_name = line_value(line_split)
context_material = unique_materials.get(context_material_name)
- if use_cycles and context_material is not None:
- context_mat_wrap = cycles_material_wrap_map[context_material]
+ if context_material is not None:
+ context_mat_wrap = nodal_material_wrap_map[context_material]
context_material_vars.clear()
+ spec_colors = [0.0, 0.0, 0.0]
emit_colors[:] = [0.0, 0.0, 0.0]
- do_ambient = True
do_highlight = False
do_reflection = False
do_transparency = False
do_glass = False
- do_fresnel = False
- do_raytrace = False
elif context_material:
# we need to make a material to assign properties to it.
if line_id == b'ka':
- col = (float_func(line_split[1]), float_func(line_split[2]), float_func(line_split[3]))
- if use_cycles:
- context_mat_wrap.reflect_color_set(col)
- context_material.mirror_color = col
- # This is highly approximated, but let's try to stick as close from exporter as possible... :/
- context_material.ambient = sum(context_material.mirror_color) / 3
+ refl = (float_func(line_split[1]) + float_func(line_split[2]) + float_func(line_split[3])) / 3.0
+ context_mat_wrap.metallic = refl
+ context_material_vars.add("metallic")
elif line_id == b'kd':
col = (float_func(line_split[1]), float_func(line_split[2]), float_func(line_split[3]))
- if use_cycles:
- context_mat_wrap.diffuse_color_set(col)
- context_material.diffuse_color = col
- context_material.diffuse_intensity = 1.0
+ context_mat_wrap.base_color = col
elif line_id == b'ks':
- col = (float_func(line_split[1]), float_func(line_split[2]), float_func(line_split[3]))
- if use_cycles:
- context_mat_wrap.specular_color_set(col)
- context_mat_wrap.hardness_value_set(1.0)
- context_material.specular_color = col
- context_material.specular_intensity = 1.0
+ spec_color = (float_func(line_split[1]) + float_func(line_split[2]) + float_func(line_split[3]))
+ context_material_vars.add("specular")
elif line_id == b'ke':
# We cannot set context_material.emit right now, we need final diffuse color as well for this.
+ # XXX Unsupported currently
emit_colors[:] = [
float_func(line_split[1]), float_func(line_split[2]), float_func(line_split[3])]
elif line_id == b'ns':
- if use_cycles:
- context_mat_wrap.hardness_value_set(((float_func(line_split[1]) + 3.0) / 50.0) - 0.65)
- context_material.specular_hardness = int((float_func(line_split[1]) * 0.51) + 1)
- elif line_id == b'ni': # Refraction index (between 1 and 3).
- if use_cycles:
- print("WARNING, currently unsupported glass material, skipped.")
- context_material.raytrace_transparency.ior = max(1, min(float_func(line_split[1]), 3))
+ # XXX Totally empirical conversion, trying to adapt it
+ # (from 0.0 - 900.0 OBJ specular exponent range to 1.0 - 0.0 Principled BSDF range)...
+ context_mat_wrap.roughness = 1.0 - (sqrt(float_func(line_split[1])) / 30)
+ context_material_vars.add("roughness")
+ elif line_id == b'ni': # Refraction index (between 0.001 and 10).
+ context_mat_wrap.ior = float_func(line_split[1])
context_material_vars.add("ior")
elif line_id == b'd': # dissolve (transparency)
- if use_cycles:
- context_mat_wrap.alpha_value_set(float_func(line_split[1]))
- context_material.alpha = float_func(line_split[1])
- context_material.use_transparency = True
- context_material.transparency_method = 'Z_TRANSPARENCY'
- context_material_vars.add("alpha")
+ context_mat_wrap.transmission = 1.0 - float_func(line_split[1])
+ context_material_vars.add("transmission")
elif line_id == b'tr': # translucency
- if use_cycles:
- print("WARNING, currently unsupported translucency option, skipped.")
- context_material.translucency = float_func(line_split[1])
+ print("WARNING, currently unsupported 'tr' translucency option, skipped.")
elif line_id == b'tf':
# rgb, filter color, blender has no support for this.
- pass
+ print("WARNING, currently unsupported 'tf' filter color option, skipped.")
elif line_id == b'illum':
illum = get_int(line_split[1])
# inline comments are from the spec, v4.2
if illum == 0:
# Color on and Ambient off
- do_ambient = False
+ print("WARNING, Principled BSDF shader does not support illumination 0 mode "
+ "(colors with no ambient), skipped.")
elif illum == 1:
# Color on and Ambient on
pass
@@ -441,32 +337,25 @@ def create_materials(filepath, relpath,
elif illum == 3:
# Reflection on and Ray trace on
do_reflection = True
- do_raytrace = True
elif illum == 4:
# Transparency: Glass on
# Reflection: Ray trace on
do_transparency = True
do_reflection = True
do_glass = True
- do_raytrace = True
elif illum == 5:
# Reflection: Fresnel on and Ray trace on
do_reflection = True
- do_fresnel = True
- do_raytrace = True
elif illum == 6:
# Transparency: Refraction on
# Reflection: Fresnel off and Ray trace on
do_transparency = True
do_reflection = True
- do_raytrace = True
elif illum == 7:
# Transparency: Refraction on
# Reflection: Fresnel on and Ray trace on
do_transparency = True
do_reflection = True
- do_fresnel = True
- do_raytrace = True
elif illum == 8:
# Reflection on and Ray trace off
do_reflection = True
@@ -474,58 +363,58 @@ def create_materials(filepath, relpath,
# Transparency: Glass on
# Reflection: Ray trace off
do_transparency = True
- do_reflection = True
+ do_reflection = False
do_glass = True
elif illum == 10:
# Casts shadows onto invisible surfaces
-
- # blender can't do this
+ print("WARNING, Principled BSDF shader does not support illumination 10 mode "
+ "(cast shadows on invisible surfaces), skipped.")
pass
elif line_id == b'map_ka':
img_data = line.split()[1:]
if img_data:
- load_material_image(context_material, context_mat_wrap, use_cycles,
+ load_material_image(context_material, context_mat_wrap,
context_material_name, img_data, line, 'Ka')
elif line_id == b'map_ks':
img_data = line.split()[1:]
if img_data:
- load_material_image(context_material, context_mat_wrap, use_cycles,
+ load_material_image(context_material, context_mat_wrap,
context_material_name, img_data, line, 'Ks')
elif line_id == b'map_kd':
img_data = line.split()[1:]
if img_data:
- load_material_image(context_material, context_mat_wrap, use_cycles,
+ load_material_image(context_material, context_mat_wrap,
context_material_name, img_data, line, 'Kd')
elif line_id == b'map_ke':
img_data = line.split()[1:]
if img_data:
- load_material_image(context_material, context_mat_wrap, use_cycles,
+ load_material_image(context_material, context_mat_wrap,
context_material_name, img_data, line, 'Ke')
elif line_id in {b'map_bump', b'bump'}: # 'bump' is incorrect but some files use it.
img_data = line.split()[1:]
if img_data:
- load_material_image(context_material, context_mat_wrap, use_cycles,
+ load_material_image(context_material, context_mat_wrap,
context_material_name, img_data, line, 'Bump')
elif line_id in {b'map_d', b'map_tr'}: # Alpha map - Dissolve
img_data = line.split()[1:]
if img_data:
- load_material_image(context_material, context_mat_wrap, use_cycles,
+ load_material_image(context_material, context_mat_wrap,
context_material_name, img_data, line, 'D')
elif line_id in {b'map_disp', b'disp'}: # displacementmap
img_data = line.split()[1:]
if img_data:
- load_material_image(context_material, context_mat_wrap, use_cycles,
+ load_material_image(context_material, context_mat_wrap,
context_material_name, img_data, line, 'disp')
elif line_id in {b'map_refl', b'refl'}: # reflectionmap
img_data = line.split()[1:]
if img_data:
- load_material_image(context_material, context_mat_wrap, use_cycles,
+ load_material_image(context_material, context_mat_wrap,
context_material_name, img_data, line, 'refl')
else:
- print("\t%r:%r (ignored)" % (filepath, line))
+ print("WARNING: %r:%r (ignored)" % (filepath, line))
mtl.close()
@@ -601,7 +490,6 @@ def create_mesh(new_objects,
verts_tex,
faces,
unique_materials,
- unique_material_images,
unique_smooth_groups,
vertex_groups,
dataname,
@@ -756,7 +644,7 @@ def create_mesh(new_objects,
me.create_normals_split()
if verts_tex and me.polygons:
- me.uv_textures.new()
+ me.uv_layers.new()
context_material_old = -1 # avoid a dict lookup
mat = 0 # rare case it may be un-initialized.
@@ -788,11 +676,6 @@ def create_mesh(new_objects,
me.loops[lidx].normal[:] = verts_nor[0 if (face_noidx is ...) else face_noidx]
if verts_tex and face_vert_tex_indices:
- if context_material:
- image = unique_material_images[context_material]
- if image: # Can be none if the material dosnt have an image.
- me.uv_textures[0].data[i].image = image
-
blen_uvs = me.uv_layers[0]
for face_uvidx, lidx in zip(face_vert_tex_indices, blen_poly.loop_indices):
blen_uvs.data[lidx].uv = verts_tex[0 if (face_uvidx is ...) else face_uvidx]
@@ -829,7 +712,6 @@ def create_mesh(new_objects,
for e in me.edges:
if e.key in sharp_edges:
e.use_edge_sharp = True
- me.show_edge_sharp = True
if verts_nor:
clnors = array.array('f', [0.0] * (len(me.loops) * 3))
@@ -840,7 +722,6 @@ def create_mesh(new_objects,
me.normals_split_custom_set(tuple(zip(*(iter(clnors),) * 3)))
me.use_auto_smooth = True
- me.show_edge_sharp = True
ob = bpy.data.objects.new(me.name, me)
new_objects.append(ob)
@@ -966,14 +847,13 @@ def get_int(svalue):
def load(context,
filepath,
*,
- global_clamp_size=0.0,
+ global_clight_size=0.0,
use_smooth_groups=True,
use_edges=True,
use_split_objects=True,
use_split_groups=True,
use_image_search=True,
use_groups_as_vgroups=False,
- use_cycles=True,
relpath=None,
global_matrix=None
):
@@ -1042,7 +922,6 @@ def load(context,
# Until we can use sets
unique_materials = {}
- unique_material_images = {}
unique_smooth_groups = {}
# unique_obects= {} - no use for this variable since the objects are stored in the face.
@@ -1264,7 +1143,7 @@ def load(context,
progress.step("Done, loading materials and images...")
create_materials(filepath, relpath, material_libs, unique_materials,
- unique_material_images, use_image_search, use_cycles, float_func)
+ use_image_search, float_func)
progress.step("Done, building geometries (verts:%i faces:%i materials: %i smoothgroups:%i) ..." %
(len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups)))
@@ -1290,7 +1169,6 @@ def load(context,
verts_tex if use_vtex else [],
faces_split,
unique_materials_split,
- unique_material_images,
unique_smooth_groups,
vertex_groups,
dataname,
@@ -1300,10 +1178,17 @@ def load(context,
for context_nurbs in nurbs:
create_nurbs(context_nurbs, verts_loc, new_objects)
+ view_layer = context.view_layer
+ if view_layer.collections.active:
+ collection = view_layer.collections.active.collection
+ else:
+ collection = scene.master_collection.new()
+ view_layer.collections.link(collection)
+
# Create new obj
for obj in new_objects:
- base = scene.objects.link(obj)
- base.select = True
+ collection.objects.link(obj)
+ obj.select_set('SELECT')
# we could apply this anywhere before scaling.
obj.matrix_world = global_matrix
@@ -1313,7 +1198,7 @@ def load(context,
axis_min = [1000000000] * 3
axis_max = [-1000000000] * 3
- if global_clamp_size:
+ if global_clight_size:
# Get all object bounds
for ob in new_objects:
for v in ob.bound_box:
@@ -1327,7 +1212,7 @@ def load(context,
max_axis = max(axis_max[0] - axis_min[0], axis_max[1] - axis_min[1], axis_max[2] - axis_min[2])
scale = 1.0
- while global_clamp_size < max_axis * scale:
+ while global_clight_size < max_axis * scale:
scale = scale / 10.0
for obj in new_objects:
diff --git a/io_scene_vrml2/__init__.py b/io_scene_vrml2/__init__.py
index d6c0da2f..4a420f70 100644
--- a/io_scene_vrml2/__init__.py
+++ b/io_scene_vrml2/__init__.py
@@ -47,16 +47,14 @@ from bpy.props import (
)
from bpy_extras.io_utils import (
ExportHelper,
- orientation_helper_factory,
+ orientation_helper,
path_reference_mode,
axis_conversion,
)
-ExportVRMLOrientationHelper = orientation_helper_factory("ExportVRMLOrientationHelper", axis_forward='Z', axis_up='Y')
-
-
-class ExportVRML(bpy.types.Operator, ExportHelper, ExportVRMLOrientationHelper):
+@orientation_helper(axis_forward='Z', axis_up='Y')
+class ExportVRML(bpy.types.Operator, ExportHelper):
"""Export mesh objects as a VRML2, colors and texture coordinates"""
bl_idname = "export_scene.vrml2"
bl_label = "Export VRML2"
@@ -151,13 +149,13 @@ def menu_func_export(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_export.append(menu_func_export)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_export.remove(menu_func_export)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
diff --git a/io_scene_vrml2/export_vrml2.py b/io_scene_vrml2/export_vrml2.py
index 06f79fc1..22114582 100644
--- a/io_scene_vrml2/export_vrml2.py
+++ b/io_scene_vrml2/export_vrml2.py
@@ -163,7 +163,7 @@ def save_object(fw, global_matrix,
if is_editmode:
bpy.ops.object.editmode_toggle()
- me = obj.to_mesh(scene, True, 'PREVIEW', calc_tessface=False)
+ me = obj.to_mesh(scene, True, 'PREVIEW')
bm = bmesh.new()
bm.from_mesh(me)
diff --git a/io_scene_x/__init__.py b/io_scene_x/__init__.py
index 001dca61..404d9dc2 100644
--- a/io_scene_x/__init__.py
+++ b/io_scene_x/__init__.py
@@ -176,13 +176,13 @@ def menu_func(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_export.append(menu_func)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_export.remove(menu_func)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func)
if __name__ == "__main__":
diff --git a/io_scene_x3d/__init__.py b/io_scene_x3d/__init__.py
index d5c555a1..06a9a122 100644
--- a/io_scene_x3d/__init__.py
+++ b/io_scene_x3d/__init__.py
@@ -48,16 +48,14 @@ from bpy.props import (
from bpy_extras.io_utils import (
ImportHelper,
ExportHelper,
- orientation_helper_factory,
+ orientation_helper,
axis_conversion,
path_reference_mode,
)
-IOX3DOrientationHelper = orientation_helper_factory("IOX3DOrientationHelper", axis_forward='Z', axis_up='Y')
-
-
-class ImportX3D(bpy.types.Operator, ImportHelper, IOX3DOrientationHelper):
+@orientation_helper(axis_forward='Z', axis_up='Y')
+class ImportX3D(bpy.types.Operator, ImportHelper):
"""Import an X3D or VRML2 file"""
bl_idname = "import_scene.x3d"
bl_label = "Import X3D/VRML2"
@@ -81,7 +79,8 @@ class ImportX3D(bpy.types.Operator, ImportHelper, IOX3DOrientationHelper):
return import_x3d.load(context, **keywords)
-class ExportX3D(bpy.types.Operator, ExportHelper, IOX3DOrientationHelper):
+@orientation_helper(axis_forward='Z', axis_up='Y')
+class ExportX3D(bpy.types.Operator, ExportHelper):
"""Export selection to Extensible 3D file (.x3d)"""
bl_idname = "export_scene.x3d"
bl_label = 'Export X3D'
@@ -172,15 +171,15 @@ def menu_func_export(self, context):
def register():
bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_import.append(menu_func_import)
- bpy.types.INFO_MT_file_export.append(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_import.remove(menu_func_import)
- bpy.types.INFO_MT_file_export.remove(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
# NOTES
# - blender version is hardcoded
diff --git a/io_scene_x3d/export_x3d.py b/io_scene_x3d/export_x3d.py
index c2ebfca7..d6c4a293 100644
--- a/io_scene_x3d/export_x3d.py
+++ b/io_scene_x3d/export_x3d.py
@@ -48,7 +48,7 @@ H3D_CAMERA_FOLLOW = 'CAMERA_FOLLOW_TRANSFORM'
H3D_VIEW_MATRIX = 'view_matrix'
-def clamp_color(col):
+def clight_color(col):
return tuple([max(min(c, 1.0), 0.0) for c in col])
@@ -164,14 +164,14 @@ def h3d_shader_glsl_frag_patch(filepath, scene, global_vars, frag_uniform_var_ma
lines.append("%s\n" % v)
lines.append("// h3d custom vars end\n")
lines.append("\n")
- elif l.lstrip().startswith("lamp_visibility_other("):
+ elif l.lstrip().startswith("light_visibility_other("):
w = l.split(', ')
last_transform = w[1] + "_transform" # XXX - HACK!!!
w[1] = '(view_matrix * %s_transform * vec4(%s.x, %s.y, %s.z, 1.0)).xyz' % (w[1], w[1], w[1], w[1])
l = ", ".join(w)
- elif l.lstrip().startswith("lamp_visibility_sun_hemi("):
+ elif l.lstrip().startswith("light_visibility_sun_hemi("):
w = l.split(', ')
- w[0] = w[0][len("lamp_visibility_sun_hemi(") + 1:]
+ w[0] = w[0][len("light_visibility_sun_hemi(") + 1:]
if not h3d_is_object_view(scene, frag_uniform_var_map[w[0]]):
w[0] = '(mat3(normalize(view_matrix[0].xyz), normalize(view_matrix[1].xyz), normalize(view_matrix[2].xyz)) * -%s)' % w[0]
@@ -179,10 +179,10 @@ def h3d_shader_glsl_frag_patch(filepath, scene, global_vars, frag_uniform_var_ma
w[0] = ('(mat3(normalize((view_matrix*%s)[0].xyz), normalize((view_matrix*%s)[1].xyz), normalize((view_matrix*%s)[2].xyz)) * -%s)' %
(last_transform, last_transform, last_transform, w[0]))
- l = "\tlamp_visibility_sun_hemi(" + ", ".join(w)
- elif l.lstrip().startswith("lamp_visibility_spot_circle("):
+ l = "\tlight_visibility_sun_hemi(" + ", ".join(w)
+ elif l.lstrip().startswith("light_visibility_spot_circle("):
w = l.split(', ')
- w[0] = w[0][len("lamp_visibility_spot_circle(") + 1:]
+ w[0] = w[0][len("light_visibility_spot_circle(") + 1:]
if not h3d_is_object_view(scene, frag_uniform_var_map[w[0]]):
w[0] = '(mat3(normalize(view_matrix[0].xyz), normalize(view_matrix[1].xyz), normalize(view_matrix[2].xyz)) * -%s)' % w[0]
@@ -190,7 +190,7 @@ def h3d_shader_glsl_frag_patch(filepath, scene, global_vars, frag_uniform_var_ma
w[0] = ('(mat3(normalize((view_matrix*%s)[0].xyz), normalize((view_matrix*%s)[1].xyz), normalize((view_matrix*%s)[2].xyz)) * %s)' %
(last_transform, last_transform, last_transform, w[0]))
- l = "\tlamp_visibility_spot_circle(" + ", ".join(w)
+ l = "\tlight_visibility_spot_circle(" + ", ".join(w)
lines.append(l)
@@ -241,7 +241,7 @@ def export(file,
# since objects of different types will always have
# different decorated names.
uuid_cache_object = {} # object
- uuid_cache_lamp = {} # 'LA_' + object.name
+ uuid_cache_light = {} # 'LA_' + object.name
uuid_cache_view = {} # object, different namespace
uuid_cache_mesh = {} # mesh
uuid_cache_material = {} # material
@@ -261,7 +261,7 @@ def export(file,
# prevent uuid collisions.
uuid_cache = {}
uuid_cache_object = uuid_cache # object
- uuid_cache_lamp = uuid_cache # 'LA_' + object.name
+ uuid_cache_light = uuid_cache # 'LA_' + object.name
uuid_cache_view = uuid_cache # object, different namespace
uuid_cache_mesh = uuid_cache # mesh
uuid_cache_material = uuid_cache # material
@@ -370,16 +370,16 @@ def export(file,
ident_step = ident + (' ' * (-len(ident) + \
fw('%s<Fog ' % ident)))
fw('fogType="%s"\n' % ('LINEAR' if (mtype == 'LINEAR') else 'EXPONENTIAL'))
- fw(ident_step + 'color="%.3f %.3f %.3f"\n' % clamp_color(world.horizon_color))
+ fw(ident_step + 'color="%.3f %.3f %.3f"\n' % clight_color(world.horizon_color))
fw(ident_step + 'visibilityRange="%.3f"\n' % mparam.depth)
fw(ident_step + '/>\n')
else:
return
- def writeNavigationInfo(ident, scene, has_lamp):
+ def writeNavigationInfo(ident, scene, has_light):
ident_step = ident + (' ' * (-len(ident) + \
fw('%s<NavigationInfo ' % ident)))
- fw('headlight="%s"\n' % bool_as_str(not has_lamp))
+ fw('headlight="%s"\n' % bool_as_str(not has_light))
fw(ident_step + 'visibilityLimit="0.0"\n')
fw(ident_step + 'type=\'"EXAMINE", "ANY"\'\n')
fw(ident_step + 'avatarSize="0.25, 1.75, 0.75"\n')
@@ -411,8 +411,8 @@ def export(file,
return ident
def writeSpotLight(ident, obj, matrix, lamp, world):
- # note, lamp_id is not re-used
- lamp_id = quoteattr(unique_name(obj, LA_ + obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_"))
+ # note, light_id is not re-used
+ light_id = quoteattr(unique_name(obj, LA_ + obj.name, uuid_cache_light, clean_func=clean_def, sep="_"))
if world:
ambi = world.ambient_color
@@ -435,11 +435,11 @@ def export(file,
# radius = lamp.dist*math.cos(beamWidth)
ident_step = ident + (' ' * (-len(ident) + \
fw('%s<SpotLight ' % ident)))
- fw('DEF=%s\n' % lamp_id)
+ fw('DEF=%s\n' % light_id)
fw(ident_step + 'radius="%.4f"\n' % radius)
fw(ident_step + 'ambientIntensity="%.4f"\n' % amb_intensity)
fw(ident_step + 'intensity="%.4f"\n' % intensity)
- fw(ident_step + 'color="%.4f %.4f %.4f"\n' % clamp_color(lamp.color))
+ fw(ident_step + 'color="%.4f %.4f %.4f"\n' % clight_color(lamp.color))
fw(ident_step + 'beamWidth="%.4f"\n' % beamWidth)
fw(ident_step + 'cutOffAngle="%.4f"\n' % cutOffAngle)
fw(ident_step + 'direction="%.4f %.4f %.4f"\n' % orientation)
@@ -447,8 +447,8 @@ def export(file,
fw(ident_step + '/>\n')
def writeDirectionalLight(ident, obj, matrix, lamp, world):
- # note, lamp_id is not re-used
- lamp_id = quoteattr(unique_name(obj, LA_ + obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_"))
+ # note, light_id is not re-used
+ light_id = quoteattr(unique_name(obj, LA_ + obj.name, uuid_cache_light, clean_func=clean_def, sep="_"))
if world:
ambi = world.ambient_color
@@ -464,16 +464,16 @@ def export(file,
ident_step = ident + (' ' * (-len(ident) + \
fw('%s<DirectionalLight ' % ident)))
- fw('DEF=%s\n' % lamp_id)
+ fw('DEF=%s\n' % light_id)
fw(ident_step + 'ambientIntensity="%.4f"\n' % amb_intensity)
- fw(ident_step + 'color="%.4f %.4f %.4f"\n' % clamp_color(lamp.color))
+ fw(ident_step + 'color="%.4f %.4f %.4f"\n' % clight_color(lamp.color))
fw(ident_step + 'intensity="%.4f"\n' % intensity)
fw(ident_step + 'direction="%.4f %.4f %.4f"\n' % orientation)
fw(ident_step + '/>\n')
def writePointLight(ident, obj, matrix, lamp, world):
- # note, lamp_id is not re-used
- lamp_id = quoteattr(unique_name(obj, LA_ + obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_"))
+ # note, light_id is not re-used
+ light_id = quoteattr(unique_name(obj, LA_ + obj.name, uuid_cache_light, clean_func=clean_def, sep="_"))
if world:
ambi = world.ambient_color
@@ -488,9 +488,9 @@ def export(file,
ident_step = ident + (' ' * (-len(ident) + \
fw('%s<PointLight ' % ident)))
- fw('DEF=%s\n' % lamp_id)
+ fw('DEF=%s\n' % light_id)
fw(ident_step + 'ambientIntensity="%.4f"\n' % amb_intensity)
- fw(ident_step + 'color="%.4f %.4f %.4f"\n' % clamp_color(lamp.color))
+ fw(ident_step + 'color="%.4f %.4f %.4f"\n' % clight_color(lamp.color))
fw(ident_step + 'intensity="%.4f"\n' % intensity)
fw(ident_step + 'radius="%.4f" \n' % lamp.distance)
@@ -1002,9 +1002,9 @@ def export(file,
ident_step = ident + (' ' * (-len(ident) + \
fw('%s<Material ' % ident)))
fw('DEF=%s\n' % material_id)
- fw(ident_step + 'diffuseColor="%.3f %.3f %.3f"\n' % clamp_color(diffuseColor))
- fw(ident_step + 'specularColor="%.3f %.3f %.3f"\n' % clamp_color(specColor))
- fw(ident_step + 'emissiveColor="%.3f %.3f %.3f"\n' % clamp_color(emitColor))
+ fw(ident_step + 'diffuseColor="%.3f %.3f %.3f"\n' % clight_color(diffuseColor))
+ fw(ident_step + 'specularColor="%.3f %.3f %.3f"\n' % clight_color(specColor))
+ fw(ident_step + 'emissiveColor="%.3f %.3f %.3f"\n' % clight_color(emitColor))
fw(ident_step + 'ambientIntensity="%.3f"\n' % ambient)
fw(ident_step + 'shininess="%.3f"\n' % shininess)
fw(ident_step + 'transparency="%s"\n' % transp)
@@ -1035,12 +1035,12 @@ def export(file,
#~ GPU_DATA_4F 5
#~ GPU_DATA_4UB 8
#~ GPU_DATA_9F 6
- #~ GPU_DYNAMIC_LAMP_DYNCO 7
- #~ GPU_DYNAMIC_LAMP_DYNCOL 11
- #~ GPU_DYNAMIC_LAMP_DYNENERGY 10
- #~ GPU_DYNAMIC_LAMP_DYNIMAT 8
- #~ GPU_DYNAMIC_LAMP_DYNPERSMAT 9
- #~ GPU_DYNAMIC_LAMP_DYNVEC 6
+ #~ GPU_DYNAMIC_LIGHT_DYNCO 7
+ #~ GPU_DYNAMIC_LIGHT_DYNCOL 11
+ #~ GPU_DYNAMIC_LIGHT_DYNENERGY 10
+ #~ GPU_DYNAMIC_LIGHT_DYNIMAT 8
+ #~ GPU_DYNAMIC_LIGHT_DYNPERSMAT 9
+ #~ GPU_DYNAMIC_LIGHT_DYNVEC 6
#~ GPU_DYNAMIC_OBJECT_COLOR 5
#~ GPU_DYNAMIC_OBJECT_IMAT 4
#~ GPU_DYNAMIC_OBJECT_MAT 2
@@ -1134,45 +1134,45 @@ def export(file,
writeImageTexture(ident + '\t', uniform['image'])
fw('%s</field>\n' % ident)
- elif uniform['type'] == gpu.GPU_DYNAMIC_LAMP_DYNCO:
- lamp_obj = uniform['lamp']
- frag_uniform_var_map[uniform['varname']] = lamp_obj
+ elif uniform['type'] == gpu.GPU_DYNAMIC_LIGHT_DYNCO:
+ light_obj = uniform['lamp']
+ frag_uniform_var_map[uniform['varname']] = light_obj
if uniform['datatype'] == gpu.GPU_DATA_3F: # should always be true!
- lamp_obj_id = quoteattr(unique_name(lamp_obj, LA_ + lamp_obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_"))
- lamp_obj_transform_id = quoteattr(unique_name(lamp_obj, lamp_obj.name, uuid_cache_object, clean_func=clean_def, sep="_"))
+ light_obj_id = quoteattr(unique_name(light_obj, LA_ + light_obj.name, uuid_cache_light, clean_func=clean_def, sep="_"))
+ light_obj_transform_id = quoteattr(unique_name(light_obj, light_obj.name, uuid_cache_object, clean_func=clean_def, sep="_"))
- value = '%.6f %.6f %.6f' % (global_matrix * lamp_obj.matrix_world).to_translation()[:]
- field_descr = " <!--- Lamp DynCo '%s' -->" % lamp_obj.name
+ value = '%.6f %.6f %.6f' % (global_matrix * light_obj.matrix_world).to_translation()[:]
+ field_descr = " <!--- Lamp DynCo '%s' -->" % light_obj.name
fw('%s<field name="%s" type="SFVec3f" accessType="inputOutput" value="%s" />%s\n' % (ident, uniform['varname'], value, field_descr))
# ------------------------------------------------------
# shader-patch
- field_descr = " <!--- Lamp DynCo '%s' (shader patch) -->" % lamp_obj.name
+ field_descr = " <!--- Lamp DynCo '%s' (shader patch) -->" % light_obj.name
fw('%s<field name="%s_transform" type="SFMatrix4f" accessType="inputOutput" />%s\n' % (ident, uniform['varname'], field_descr))
# transform
frag_vars.append("uniform mat4 %s_transform;" % uniform['varname'])
h3d_material_route.append(
'<ROUTE fromNode=%s fromField="accumulatedForward" toNode=%s toField="%s_transform" />%s' %
- (suffix_quoted_str(lamp_obj_transform_id, _TRANSFORM), material_id, uniform['varname'], field_descr))
+ (suffix_quoted_str(light_obj_transform_id, _TRANSFORM), material_id, uniform['varname'], field_descr))
h3d_material_route.append(
'<ROUTE fromNode=%s fromField="location" toNode=%s toField="%s" /> %s' %
- (lamp_obj_id, material_id, uniform['varname'], field_descr))
+ (light_obj_id, material_id, uniform['varname'], field_descr))
# ------------------------------------------------------
else:
assert(0)
- elif uniform['type'] == gpu.GPU_DYNAMIC_LAMP_DYNCOL:
+ elif uniform['type'] == gpu.GPU_DYNAMIC_LIGHT_DYNCOL:
# odd we have both 3, 4 types.
- lamp_obj = uniform['lamp']
- frag_uniform_var_map[uniform['varname']] = lamp_obj
+ light_obj = uniform['lamp']
+ frag_uniform_var_map[uniform['varname']] = light_obj
- lamp = lamp_obj.data
+ lamp = light_obj.data
value = '%.6f %.6f %.6f' % (lamp.color * lamp.energy)[:]
- field_descr = " <!--- Lamp DynColor '%s' -->" % lamp_obj.name
+ field_descr = " <!--- Lamp DynColor '%s' -->" % light_obj.name
if uniform['datatype'] == gpu.GPU_DATA_3F:
fw('%s<field name="%s" type="SFVec3f" accessType="inputOutput" value="%s" />%s\n' % (ident, uniform['varname'], value, field_descr))
elif uniform['datatype'] == gpu.GPU_DATA_4F:
@@ -1180,26 +1180,26 @@ def export(file,
else:
assert(0)
- elif uniform['type'] == gpu.GPU_DYNAMIC_LAMP_DYNENERGY:
+ elif uniform['type'] == gpu.GPU_DYNAMIC_LIGHT_DYNENERGY:
# not used ?
assert(0)
- elif uniform['type'] == gpu.GPU_DYNAMIC_LAMP_DYNVEC:
- lamp_obj = uniform['lamp']
- frag_uniform_var_map[uniform['varname']] = lamp_obj
+ elif uniform['type'] == gpu.GPU_DYNAMIC_LIGHT_DYNVEC:
+ light_obj = uniform['lamp']
+ frag_uniform_var_map[uniform['varname']] = light_obj
if uniform['datatype'] == gpu.GPU_DATA_3F:
- lamp_obj = uniform['lamp']
- value = '%.6f %.6f %.6f' % ((global_matrix * lamp_obj.matrix_world).to_quaternion() * mathutils.Vector((0.0, 0.0, 1.0))).normalized()[:]
- field_descr = " <!--- Lamp DynDirection '%s' -->" % lamp_obj.name
+ light_obj = uniform['lamp']
+ value = '%.6f %.6f %.6f' % ((global_matrix * light_obj.matrix_world).to_quaternion() * mathutils.Vector((0.0, 0.0, 1.0))).normalized()[:]
+ field_descr = " <!--- Lamp DynDirection '%s' -->" % light_obj.name
fw('%s<field name="%s" type="SFVec3f" accessType="inputOutput" value="%s" />%s\n' % (ident, uniform['varname'], value, field_descr))
# route so we can have the lamp update the view
- if h3d_is_object_view(scene, lamp_obj):
- lamp_id = quoteattr(unique_name(lamp_obj, LA_ + lamp_obj.name, uuid_cache_lamp, clean_func=clean_def, sep="_"))
+ if h3d_is_object_view(scene, light_obj):
+ light_id = quoteattr(unique_name(light_obj, LA_ + light_obj.name, uuid_cache_light, clean_func=clean_def, sep="_"))
h3d_material_route.append(
'<ROUTE fromNode=%s fromField="direction" toNode=%s toField="%s" />%s' %
- (lamp_id, material_id, uniform['varname'], field_descr))
+ (light_id, material_id, uniform['varname'], field_descr))
else:
assert(0)
@@ -1330,9 +1330,9 @@ def export(file,
blending = world.use_sky_blend, world.use_sky_paper, world.use_sky_real
- grd_triple = clamp_color(world.horizon_color)
- sky_triple = clamp_color(world.zenith_color)
- mix_triple = clamp_color((grd_triple[i] + sky_triple[i]) / 2.0 for i in range(3))
+ grd_triple = clight_color(world.horizon_color)
+ sky_triple = clight_color(world.zenith_color)
+ mix_triple = clight_color((grd_triple[i] + sky_triple[i]) / 2.0 for i in range(3))
ident_step = ident + (' ' * (-len(ident) + \
fw('%s<Background ' % ident)))
@@ -1469,7 +1469,7 @@ def export(file,
if do_remove:
bpy.data.meshes.remove(me)
- elif obj_type == 'LAMP':
+ elif obj_type == 'LIGHT':
data = obj.data
datatype = data.type
if datatype == 'POINT':
@@ -1521,7 +1521,7 @@ def export(file,
ident = ''
ident = writeHeader(ident)
- writeNavigationInfo(ident, scene, any(obj.type == 'LAMP' for obj in objects))
+ writeNavigationInfo(ident, scene, any(obj.type == 'LIGHT' for obj in objects))
writeBackground(ident, world)
writeFog(ident, world)
diff --git a/io_scene_x3d/import_x3d.py b/io_scene_x3d/import_x3d.py
index 83dcc83d..d2592ecd 100644
--- a/io_scene_x3d/import_x3d.py
+++ b/io_scene_x3d/import_x3d.py
@@ -2790,9 +2790,9 @@ def appearance_LoadTexture(tex_node, ancestry, node):
if bpyima: # Loading can still fail
repeat_s = tex_node.getFieldAsBool('repeatS', True, ancestry)
- bpyima.use_clamp_x = not repeat_s
+ bpyima.use_clight_x = not repeat_s
repeat_t = tex_node.getFieldAsBool('repeatT', True, ancestry)
- bpyima.use_clamp_y = not repeat_t
+ bpyima.use_clight_y = not repeat_t
# Update the desc-based cache
if desc:
@@ -3148,7 +3148,7 @@ def importLamp_PointLight(node, ancestry):
# is_on = node.getFieldAsBool('on', True, ancestry) # TODO
radius = node.getFieldAsFloat('radius', 100.0, ancestry)
- bpylamp = bpy.data.lamps.new(vrmlname, 'POINT')
+ bpylamp = bpy.data.lights.new(vrmlname, 'POINT')
bpylamp.energy = intensity
bpylamp.distance = radius
bpylamp.color = color
@@ -3169,7 +3169,7 @@ def importLamp_DirectionalLight(node, ancestry):
intensity = node.getFieldAsFloat('intensity', 1.0, ancestry) # max is documented to be 1.0 but some files have higher.
# is_on = node.getFieldAsBool('on', True, ancestry) # TODO
- bpylamp = bpy.data.lamps.new(vrmlname, 'SUN')
+ bpylamp = bpy.data.lights.new(vrmlname, 'SUN')
bpylamp.energy = intensity
bpylamp.color = color
@@ -3197,7 +3197,7 @@ def importLamp_SpotLight(node, ancestry):
# is_on = node.getFieldAsBool('on', True, ancestry) # TODO
radius = node.getFieldAsFloat('radius', 100.0, ancestry)
- bpylamp = bpy.data.lamps.new(vrmlname, 'SPOT')
+ bpylamp = bpy.data.lights.new(vrmlname, 'SPOT')
bpylamp.energy = intensity
bpylamp.distance = radius
bpylamp.color = color
@@ -3271,8 +3271,8 @@ def importTransform(bpyscene, node, ancestry, global_matrix):
bpyob.matrix_world = getFinalMatrix(node, None, ancestry, global_matrix)
# so they are not too annoying
- bpyob.empty_draw_type = 'PLAIN_AXES'
- bpyob.empty_draw_size = 0.2
+ bpyob.empty_display_type = 'PLAIN_AXES'
+ bpyob.empty_display_size = 0.2
#def importTimeSensor(node):
diff --git a/io_shape_mdd/__init__.py b/io_shape_mdd/__init__.py
index 99623241..b6f0e734 100644
--- a/io_shape_mdd/__init__.py
+++ b/io_shape_mdd/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "NewTek MDD format",
"author": "Bill L.Nieuwendorp",
"version": (1, 0, 1),
- "blender": (2, 57, 0),
+ "blender": (2, 80, 0),
"location": "File > Import-Export",
"description": "Import-Export MDD as mesh shape keys",
"warning": "",
@@ -57,17 +57,17 @@ class ImportMDD(bpy.types.Operator, ImportHelper):
filename_ext = ".mdd"
- filter_glob = StringProperty(
+ filter_glob: StringProperty(
default="*.mdd",
options={'HIDDEN'},
)
- frame_start = IntProperty(
+ frame_start: IntProperty(
name="Start Frame",
description="Start frame for inserting animation",
min=-300000, max=300000,
default=0,
)
- frame_step = IntProperty(
+ frame_step: IntProperty(
name="Step",
min=1, max=1000,
default=1,
@@ -97,7 +97,7 @@ class ExportMDD(bpy.types.Operator, ExportHelper):
bl_label = "Export MDD"
filename_ext = ".mdd"
- filter_glob = StringProperty(default="*.mdd", options={'HIDDEN'})
+ filter_glob: StringProperty(default="*.mdd", options={'HIDDEN'})
# get first scene to get min and max properties for frames, fps
@@ -108,25 +108,25 @@ class ExportMDD(bpy.types.Operator, ExportHelper):
# List of operator properties, the attributes will be assigned
# to the class instance from the operator settings before calling.
- fps = FloatProperty(
+ fps: FloatProperty(
name="Frames Per Second",
description="Number of frames/second",
min=minfps, max=maxfps,
default=25.0,
)
- frame_start = IntProperty(
+ frame_start: IntProperty(
name="Start Frame",
description="Start frame for baking",
min=minframe, max=maxframe,
default=1,
)
- frame_end = IntProperty(
+ frame_end: IntProperty(
name="End Frame",
description="End frame for baking",
min=minframe, max=maxframe,
default=250,
)
- use_rest_frame = BoolProperty(
+ use_rest_frame: BoolProperty(
name="Rest Frame",
description="Write the rest state at the first frame",
default=False,
@@ -164,18 +164,25 @@ def menu_func_export(self, context):
)
+classes = (
+ ImportMDD,
+ ExportMDD
+)
+
def register():
- bpy.utils.register_module(__name__)
+ for cls in classes:
+ bpy.utils.register_class(cls)
- bpy.types.INFO_MT_file_import.append(menu_func_import)
- bpy.types.INFO_MT_file_export.append(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
- bpy.utils.unregister_module(__name__)
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
- bpy.types.INFO_MT_file_import.remove(menu_func_import)
- bpy.types.INFO_MT_file_export.remove(menu_func_export)
+ bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
+ bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
diff --git a/io_shape_mdd/export_mdd.py b/io_shape_mdd/export_mdd.py
index 04ca8238..48e34f29 100644
--- a/io_shape_mdd/export_mdd.py
+++ b/io_shape_mdd/export_mdd.py
@@ -67,7 +67,7 @@ def save(context, filepath="", frame_start=1, frame_end=300, fps=25.0, use_rest_
orig_frame = scene.frame_current
scene.frame_set(frame_start)
- me = obj.to_mesh(scene, True, 'PREVIEW')
+ me = obj.to_mesh(context.depsgraph, True)
#Flip y and z
'''
@@ -95,21 +95,21 @@ def save(context, filepath="", frame_start=1, frame_end=300, fps=25.0, use_rest_
if use_rest_frame:
check_vertcount(me, numverts)
- me.transform(mat_flip * obj.matrix_world)
+ me.transform(mat_flip @ obj.matrix_world)
f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
- bpy.data.meshes.remove(me, do_unlink=True)
+ bpy.data.meshes.remove(me)
for frame in range(frame_start, frame_end + 1): # in order to start at desired frame
scene.frame_set(frame)
- me = obj.to_mesh(scene, True, 'PREVIEW')
+ me = obj.to_mesh(context.depsgraph, True)
check_vertcount(me, numverts)
- me.transform(mat_flip * obj.matrix_world)
+ me.transform(mat_flip @ obj.matrix_world)
# Write the vertex data
f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
- bpy.data.meshes.remove(me, do_unlink=True)
+ bpy.data.meshes.remove(me)
f.close()
diff --git a/light_field_tools/light_field_tools.py b/light_field_tools/light_field_tools.py
index 82d86ba4..5ab2092f 100644
--- a/light_field_tools/light_field_tools.py
+++ b/light_field_tools/light_field_tools.py
@@ -189,7 +189,7 @@ class OBJECT_OT_create_lightfield_rig(Operator):
cam.data.angle = scene.lightfield.angle
# display options of the camera
- cam.data.draw_size = 0.15
+ cam.data.display_size = 0.15
cam.data.lens_unit = 'FOV'
# handler parent
@@ -228,7 +228,7 @@ class OBJECT_OT_create_lightfield_rig(Operator):
def createSpot(self, index, textured=False):
scene = bpy.context.scene
- bpy.ops.object.lamp_add(
+ bpy.ops.object.light_add(
type='SPOT')
spot = bpy.context.active_object
diff --git a/materials_utils/__init__.py b/materials_utils/__init__.py
index 5b5cda6f..94975e6b 100644
--- a/materials_utils/__init__.py
+++ b/materials_utils/__init__.py
@@ -2506,7 +2506,7 @@ def check_mat_name_unique(name_id="Material_new"):
def included_object_types(objects):
# Pass the bpy.data.objects.type to avoid needless assigning/removing
# included - type that can have materials
- included = ['MESH', 'CURVE', 'SURFACE', 'FONT', 'META']
+ included = ['MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'GPENCIL']
obj = objects
return bool(obj and obj in included)
diff --git a/measureit/measureit_main.py b/measureit/measureit_main.py
index 2ea41da1..91d57ce8 100644
--- a/measureit/measureit_main.py
+++ b/measureit/measureit_main.py
@@ -1344,7 +1344,7 @@ class AddLinkButton(Operator):
if o is None:
return False
else:
- if o.type == "MESH" or o.type == "EMPTY" or o.type == "CAMERA" or o.type == "LAMP":
+ if o.type == "MESH" or o.type == "EMPTY" or o.type == "CAMERA" or o.type == "LIGHT":
if bpy.context.mode == 'OBJECT':
return True
else:
@@ -1490,7 +1490,7 @@ class AddOriginButton(Operator):
if o is None:
return False
else:
- if o.type == "MESH" or o.type == "EMPTY" or o.type == "CAMERA" or o.type == "LAMP":
+ if o.type == "MESH" or o.type == "EMPTY" or o.type == "CAMERA" or o.type == "LIGHT":
if bpy.context.mode == 'OBJECT':
return True
else:
@@ -1892,7 +1892,7 @@ class AddNoteButton(Operator):
bpy.ops.object.empty_add(type='PLAIN_AXES')
myempty = bpy.data.objects[bpy.context.active_object.name]
myempty.location = bpy.context.scene.cursor_location
- myempty.empty_draw_size = 0.01
+ myempty.empty_display_size = 0.01
myempty.name = "Annotation"
# Add properties
scene = context.scene
diff --git a/mesh_carver.py b/mesh_carver.py
index 74624abd..5fd18492 100644
--- a/mesh_carver.py
+++ b/mesh_carver.py
@@ -1618,7 +1618,7 @@ def update_bevel(context):
mod.limit_method = 'WEIGHT'
mod.width = 0.01
mod.profile = 0.699099
- mod.use_clamp_overlap = False
+ mod.use_clight_overlap = False
mod.segments = 3
mod.loop_slide = False
@@ -1676,7 +1676,7 @@ def CreateBevel(context, CurrentObject):
mod.limit_method = 'WEIGHT'
mod.width = 0.01
mod.profile = 0.699099
- mod.use_clamp_overlap = False
+ mod.use_clight_overlap = False
mod.segments = 3
mod.loop_slide = False
@@ -1964,12 +1964,12 @@ def duplicateObject(self):
ob_new.rotation_quaternion = qRot
ob_new.rotation_mode = 'XYZ'
- if (ob_new.draw_type == "WIRE") and (self.BrushSolidify is False):
+ if (ob_new.display_type == "WIRE") and (self.BrushSolidify is False):
ob_new.hide = True
if self.BrushSolidify:
- ob_new.draw_type = "SOLID"
- ob_new.show_x_ray = False
+ ob_new.display_type = "SOLID"
+ ob_new.show_in_front = False
for o in bpy.context.selected_objects:
UndoAdd(self, "DUPLICATE", o)
@@ -2070,20 +2070,20 @@ def boolean_operation(bool_type="DIFFERENCE"):
)
BoolMod.object = bpy.context.selected_objects[sel_index]
BoolMod.operation = bool_type
- bpy.context.selected_objects[sel_index].draw_type = 'WIRE'
+ bpy.context.selected_objects[sel_index].display_type = 'WIRE'
def Rebool(context, self):
LastObj = context.active_object
Brush = context.selected_objects[0]
- Brush.draw_type = "WIRE"
+ Brush.display_type = "WIRE"
obj = context.selected_objects[1]
bpy.ops.object.select_all(action='TOGGLE')
context.scene.objects.active = obj
- obj.draw_type = "SOLID"
+ obj.display_type = "SOLID"
obj.select = True
bpy.ops.object.duplicate_move(
OBJECT_OT_duplicate={
@@ -2124,7 +2124,7 @@ def Rebool(context, self):
mb.show_viewport = False
if self.ObjectBrush or self.ProfileBrush:
- LastObjectCreated.show_x_ray = False
+ LastObjectCreated.show_in_front = False
try:
bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
except:
@@ -2177,7 +2177,7 @@ def createMeshFromData(self):
scn.objects.active = ob
ob.select = True
ob.location = Vector((10000.0, 0.0, 0.0))
- ob.draw_type = "WIRE"
+ ob.display_type = "WIRE"
self.SolidifyPossible = True
else:
@@ -2390,7 +2390,7 @@ class Carver(bpy.types.Operator):
self.ProfileBrush.select = True
context.scene.objects.active = self.ProfileBrush
# Set xRay
- self.ProfileBrush.show_x_ray = True
+ self.ProfileBrush.show_in_front = True
bpy.ops.object.modifier_add(type='SOLIDIFY')
context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
@@ -2407,8 +2407,8 @@ class Carver(bpy.types.Operator):
self.ObjectBrush.scale = self.InitBrushScale
self.ObjectBrush.rotation_quaternion = self.InitBrushQRotation
self.ObjectBrush.rotation_euler = self.InitBrushERotation
- self.ObjectBrush.draw_type = self.ObjectBrush_DT
- self.ObjectBrush.show_x_ray = self.XRay
+ self.ObjectBrush.display_type = self.ObjectBrush_DT
+ self.ObjectBrush.show_in_front = self.XRay
# Remove solidify modifier
Selection_Save(self)
@@ -2430,7 +2430,7 @@ class Carver(bpy.types.Operator):
self.ObjectBrush.select = True
context.scene.objects.active = self.ObjectBrush
# Set xRay
- self.ObjectBrush.show_x_ray = True
+ self.ObjectBrush.show_in_front = True
bpy.ops.object.modifier_add(type='SOLIDIFY')
context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
@@ -2529,12 +2529,12 @@ class Carver(bpy.types.Operator):
self.ObjectBrush.select = True
context.scene.objects.active = self.ObjectBrush
# Active le xray
- self.ObjectBrush.show_x_ray = True
+ self.ObjectBrush.show_in_front = True
else:
self.ProfileBrush.select = True
context.scene.objects.active = self.ProfileBrush
# Active le xray
- self.ProfileBrush.show_x_ray = True
+ self.ProfileBrush.show_in_front = True
bpy.ops.object.modifier_add(type='SOLIDIFY')
context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
@@ -2773,8 +2773,8 @@ class Carver(bpy.types.Operator):
self.ObjectBrush.scale = self.InitBrushScale
self.ObjectBrush.rotation_quaternion = self.InitBrushQRotation
self.ObjectBrush.rotation_euler = self.InitBrushERotation
- self.ObjectBrush.draw_type = self.ObjectBrush_DT
- self.ObjectBrush.show_x_ray = self.XRay
+ self.ObjectBrush.display_type = self.ObjectBrush_DT
+ self.ObjectBrush.show_in_front = self.XRay
# remove solidify
Selection_Save(self)
@@ -2844,8 +2844,8 @@ class Carver(bpy.types.Operator):
self.ObjectBrush.scale = self.InitBrushScale
self.ObjectBrush.rotation_quaternion = self.InitBrushQRotation
self.ObjectBrush.rotation_euler = self.InitBrushERotation
- self.ObjectBrush.draw_type = self.ObjectBrush_DT
- self.ObjectBrush.show_x_ray = self.XRay
+ self.ObjectBrush.display_type = self.ObjectBrush_DT
+ self.ObjectBrush.show_in_front = self.XRay
# Remove solidify modifier
Selection_Save(self)
@@ -3089,8 +3089,8 @@ class Carver(bpy.types.Operator):
self.InitBrushScale = self.ObjectBrush.scale.copy()
self.InitBrushQRotation = self.ObjectBrush.rotation_quaternion.copy()
self.InitBrushERotation = self.ObjectBrush.rotation_euler.copy()
- self.ObjectBrush_DT = self.ObjectBrush.draw_type
- self.XRay = self.ObjectBrush.show_x_ray
+ self.ObjectBrush_DT = self.ObjectBrush.display_type
+ self.XRay = self.ObjectBrush.show_in_front
# Test if flat object
z = self.ObjectBrush.data.vertices[0].co.z
ErrorMarge = 0.01
@@ -3363,7 +3363,7 @@ class Carver(bpy.types.Operator):
bpy.ops.object.delete(use_global=False)
else:
if self.ObjectMode:
- self.ObjectBrush.draw_type = self.ObjectBrush_DT
+ self.ObjectBrush.display_type = self.ObjectBrush_DT
if len(context.selected_objects) > 0:
bpy.ops.object.select_all(action='TOGGLE')
@@ -3392,9 +3392,9 @@ class Carver(bpy.types.Operator):
# If object has children, set "Wire" draw type
if self.ObjectBrush is not None:
if len(self.ObjectBrush.children) > 0:
- self.ObjectBrush.draw_type = "WIRE"
+ self.ObjectBrush.display_type = "WIRE"
if self.ProfileMode:
- self.ProfileBrush.draw_type = "WIRE"
+ self.ProfileBrush.display_type = "WIRE"
if bLocalView:
bpy.ops.view3d.localview()
diff --git a/mesh_custom_normals_tools.py b/mesh_custom_normals_tools.py
deleted file mode 100644
index 462b7609..00000000
--- a/mesh_custom_normals_tools.py
+++ /dev/null
@@ -1,90 +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 LICENCE BLOCK *****
-
-bl_info = {
- "name": "Custom Normals Tools",
- "author": "Bastien Montagne (mont29)",
- "version": (0, 0, 1),
- "blender": (2, 75, 0),
- "location": "3DView > Tools",
- "description": "Various tools/helpers for custom normals",
- "warning": "",
- "support": 'OFFICIAL',
- "category": "Mesh",
-}
-
-
-import bpy
-
-
-class MESH_OT_flip_custom_normals(bpy.types.Operator):
- """Flip active mesh's normals, including custom ones (only in Object mode)"""
- bl_idname = "mesh.flip_custom_normals"
- bl_label = "Flip Custom Normals"
- bl_options = {'UNDO'}
-
- @classmethod
- def poll(cls, context):
- return context.object and context.object.type == 'MESH' and context.object.mode == 'OBJECT'
-
- def execute(self, context):
- me = context.object.data
-
- if me.has_custom_normals:
- me.calc_normals_split()
- clnors = [0.0] * 3 * len(me.loops)
- me.loops.foreach_get("normal", clnors)
-
- 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')
-
- me = context.object.data
- if me.has_custom_normals:
- clnors[:] = list(zip(*[(-n for n in clnors)] * 3))
- # We also have to take in account that the winding was reverted...
- for p in me.polygons:
- ls = p.loop_start + 1
- le = ls + p.loop_total - 1
- clnors[ls:le] = reversed(clnors[ls:le])
- me.normals_split_custom_set(clnors)
-
- context.scene.update()
- return {'FINISHED'}
-
-
-def flip_custom_normals_draw_func(self, context):
- if isinstance(self, bpy.types.Panel):
- self.layout.label("Custom Normal Tools:")
- self.layout.operator(MESH_OT_flip_custom_normals.bl_idname)
-
-
-def register():
- bpy.utils.register_module(__name__)
- bpy.types.VIEW3D_PT_tools_object.append(flip_custom_normals_draw_func)
-
-
-def unregister():
- bpy.types.VIEW3D_PT_tools_object.remove(flip_custom_normals_draw_func)
- bpy.utils.unregister_module(__name__)
-
-
-if __name__ == "__main__":
- register()
diff --git a/mesh_extra_tools/mesh_extrude_and_reshape.py b/mesh_extra_tools/mesh_extrude_and_reshape.py
index 8716bfb1..696e775d 100644
--- a/mesh_extra_tools/mesh_extrude_and_reshape.py
+++ b/mesh_extra_tools/mesh_extrude_and_reshape.py
@@ -304,7 +304,7 @@ class Extrude_and_Reshape(Operator):
nf = bmesh.utils.face_split(f, v1, v2)
# sp_faces2.update({f, nf[0]})
- bmesh.update_edit_mesh(self.mesh, tessface=True, destructive=True)
+ bmesh.update_edit_mesh(self.mesh, loop_triangles=True, destructive=True)
return {'FINISHED'}
if self.cancel:
return {'FINISHED'}
@@ -345,7 +345,7 @@ class Extrude_and_Reshape(Operator):
dfaces = bmesh.ops.dissolve_edges(
self.bm, edges=geom, use_verts=True, use_face_split=False
)
- bmesh.update_edit_mesh(self.mesh, tessface=True, destructive=True)
+ bmesh.update_edit_mesh(self.mesh, loop_triangles=True, destructive=True)
bpy.ops.transform.translate(
'INVOKE_DEFAULT', constraint_axis=(False, False, True),
constraint_orientation='NORMAL', release_confirm=True
diff --git a/mesh_extra_tools/mesh_filletplus.py b/mesh_extra_tools/mesh_filletplus.py
index 442adb54..f3c9cbdf 100644
--- a/mesh_extra_tools/mesh_filletplus.py
+++ b/mesh_extra_tools/mesh_filletplus.py
@@ -201,7 +201,7 @@ def fillets(list_0, startv, vertlist, face, adj, n, out, flip, radius):
bm.edges.index_update()
bm.faces.index_update()
- me.update(calc_edges=True, calc_tessface=True)
+ me.update(calc_edges=True, calc_loop_triangles=True)
bmesh.ops.recalc_face_normals(bm, faces=bm.faces)
except Exception as e:
diff --git a/mesh_extra_tools/mesh_vertex_chamfer.py b/mesh_extra_tools/mesh_vertex_chamfer.py
index 62383c38..a80ba270 100644
--- a/mesh_extra_tools/mesh_vertex_chamfer.py
+++ b/mesh_extra_tools/mesh_vertex_chamfer.py
@@ -144,7 +144,7 @@ class VertexChamfer(Operator):
else:
v.co += displace * v.normal
- me.calc_tessface()
+ me.calc_loop_triangles()
return {'FINISHED'}
diff --git a/mesh_looptools.py b/mesh_looptools.py
index 62417f21..6e7d2b14 100644
--- a/mesh_looptools.py
+++ b/mesh_looptools.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "LoopTools",
"author": "Bart Crouch",
"version": (4, 6, 7),
- "blender": (2, 72, 2),
+ "blender": (2, 80, 0),
"location": "View3D > Toolbar and View3D > Specials (W-key)",
"warning": "",
"description": "Mesh modelling toolkit. Several tools to aid modelling",
@@ -110,10 +110,11 @@ loops, derived, mapping):
del looptools_cache[tool]
# prepare values to be saved to cache
input = [v.index for v in bm.verts if v.select and not v.hide]
- modifiers = [mod.name for mod in object.modifiers if mod.show_viewport and
- mod.type == 'MIRROR']
+ modifiers = [mod.name for mod in object.modifiers if mod.show_viewport
+ and mod.type == 'MIRROR']
# update cache
- looptools_cache[tool] = {"input": input, "object": object.name,
+ looptools_cache[tool] = {
+ "input": input, "object": object.name,
"input_method": input_method, "boundaries": boundaries,
"single_loops": single_loops, "loops": loops,
"derived": derived, "mapping": mapping, "modifiers": modifiers}
@@ -276,7 +277,7 @@ def calculate_plane(bm_mod, loop, method="best_fit", object=False):
vec2 = mathutils.Vector((1.0, 1.0, 1.0))
for i in range(itermax):
vec = vec2
- vec2 = mat * vec
+ vec2 = mat @ vec
if vec2.length != 0:
vec2 /= vec2.length
if vec2 == vec:
@@ -831,7 +832,7 @@ def terminate(global_undo):
# update editmesh cached data
obj = bpy.context.active_object
if obj.mode == 'EDIT':
- bmesh.update_edit_mesh(obj.data, tessface=True, destructive=True)
+ bmesh.update_edit_mesh(obj.data, loop_triangles=True, destructive=True)
bpy.context.user_preferences.edit.use_global_undo = global_undo
@@ -1043,11 +1044,11 @@ def bridge_calculate_lines(bm, loops, mode, twist, reverse):
itermax = 500
iter = 0
vec = mathutils.Vector((1.0, 1.0, 1.0))
- vec2 = (mat * vec) / (mat * vec).length
+ vec2 = (mat @ vec) / (mat @ vec).length
while vec != vec2 and iter < itermax:
iter += 1
vec = vec2
- vec2 = mat * vec
+ vec2 = mat @ vec
if vec2.length != 0:
vec2 /= vec2.length
if vec2.length == 0:
@@ -1079,7 +1080,7 @@ def bridge_calculate_lines(bm, loops, mode, twist, reverse):
# match start vertex of loop1 with loop2
target_vector = bm.verts[loop2[0]].co - center2
- dif_angles = [[(rotation_matrix * (bm.verts[vertex].co - center1)
+ dif_angles = [[(rotation_matrix @ (bm.verts[vertex].co - center1)
).angle(target_vector, 0), False, i] for
i, vertex in enumerate(loop1)]
dif_angles.sort()
@@ -1161,7 +1162,7 @@ def bridge_calculate_lines(bm, loops, mode, twist, reverse):
shifting = False
break
to_last, to_first = [
- (rotation_matrix * (bm.verts[loop1[-1]].co - center1)).angle(
+ (rotation_matrix @ (bm.verts[loop1[-1]].co - center1)).angle(
(bm.verts[loop2[i]].co - center2), 0) for i in [-1, 0]
]
if to_first < to_last:
@@ -1802,7 +1803,7 @@ def circle_calculate_best_fit(locs_2d):
jmat2.invert()
except:
pass
- dx0, dy0, dr = jmat2 * k2
+ dx0, dy0, dr = jmat2 @ k2
x0 += dx0
y0 += dy0
r += dr
@@ -2610,7 +2611,7 @@ def gstretch_align_pairs(ls_pairs, object, bm_mod, method):
else:
relative_distance = relative_lengths[i]
- loc1 = object.matrix_world * bm_mod.verts[v_index].co
+ loc1 = object.matrix_world @ bm_mod.verts[v_index].co
loc2, stroke_lengths_cache = gstretch_eval_stroke(stroke,
relative_distance, stroke_lengths_cache)
total_distance += (loc2 - loc1).length
@@ -2683,7 +2684,7 @@ def gstretch_calculate_verts(loop, stroke, object, bm_mod, method):
relative_distance = relative_lengths[i]
loc, stroke_lengths_cache = gstretch_eval_stroke(stroke,
relative_distance, stroke_lengths_cache)
- loc = matrix_inverse * loc
+ loc = matrix_inverse @ loc
move.append([v_index, loc])
return(move)
@@ -2828,8 +2829,8 @@ def gstretch_eval_stroke(stroke, distance, stroke_lengths_cache=False):
def gstretch_get_fake_strokes(object, bm_mod, loops):
strokes = []
for loop in loops:
- p1 = object.matrix_world * bm_mod.verts[loop[0][0]].co
- p2 = object.matrix_world * bm_mod.verts[loop[0][-1]].co
+ p1 = object.matrix_world @ bm_mod.verts[loop[0][0]].co
+ p2 = object.matrix_world @ bm_mod.verts[loop[0][-1]].co
strokes.append(gstretch_fake_stroke([p1, p2]))
return(strokes)
@@ -2866,7 +2867,7 @@ def gstretch_match_loops_strokes(loops, strokes, object, bm_mod):
for v_index in loop[0]:
center += bm_mod.verts[v_index].co
center /= len(loop[0])
- center = object.matrix_world * center
+ center = object.matrix_world @ center
loop_centers.append([center, loop])
# calculate stroke centers
@@ -3189,14 +3190,14 @@ class Bridge(Operator):
bl_description = "Bridge two, or loft several, loops of vertices"
bl_options = {'REGISTER', 'UNDO'}
- cubic_strength = FloatProperty(
+ cubic_strength: FloatProperty(
name="Strength",
description="Higher strength results in more fluid curves",
default=1.0,
soft_min=-3.0,
soft_max=3.0
)
- interpolation = EnumProperty(
+ interpolation: EnumProperty(
name="Interpolation mode",
items=(('cubic', "Cubic", "Gives curved results"),
('linear', "Linear", "Basic, fast, straight interpolation")),
@@ -3204,18 +3205,18 @@ class Bridge(Operator):
"segments",
default='cubic'
)
- loft = BoolProperty(
+ loft: BoolProperty(
name="Loft",
description="Loft multiple loops, instead of considering them as "
"a multi-input for bridging",
default=False
)
- loft_loop = BoolProperty(
+ loft_loop: BoolProperty(
name="Loop",
description="Connect the first and the last loop with each other",
default=False
)
- min_width = IntProperty(
+ min_width: IntProperty(
name="Minimum width",
description="Segments with an edge smaller than this are merged "
"(compared to base edge)",
@@ -3224,32 +3225,32 @@ class Bridge(Operator):
max=100,
subtype='PERCENTAGE'
)
- mode = EnumProperty(
+ mode: EnumProperty(
name="Mode",
items=(('basic', "Basic", "Fast algorithm"),
('shortest', "Shortest edge", "Slower algorithm with better vertex matching")),
description="Algorithm used for bridging",
default='shortest'
)
- remove_faces = BoolProperty(
+ remove_faces: BoolProperty(
name="Remove faces",
description="Remove faces that are internal after bridging",
default=True
)
- reverse = BoolProperty(
+ reverse: BoolProperty(
name="Reverse",
description="Manually override the direction in which the loops "
"are bridged. Only use if the tool gives the wrong result",
default=False
)
- segments = IntProperty(
+ segments: IntProperty(
name="Segments",
description="Number of segments used to bridge the gap (0=automatic)",
default=1,
min=0,
soft_max=20
)
- twist = IntProperty(
+ twist: IntProperty(
name="Twist",
description="Twist what vertices are connected to each other",
default=0
@@ -3367,7 +3368,7 @@ class Bridge(Operator):
if self.remove_faces and old_selected_faces:
bridge_remove_internal_faces(bm, old_selected_faces)
# make sure normals are facing outside
- bmesh.update_edit_mesh(object.data, tessface=False,
+ bmesh.update_edit_mesh(object.data, loop_triangles=False,
destructive=True)
bpy.ops.mesh.normals_make_consistent()
@@ -3384,24 +3385,24 @@ class Circle(Operator):
bl_description = "Move selected vertices into a circle shape"
bl_options = {'REGISTER', 'UNDO'}
- custom_radius = BoolProperty(
+ custom_radius: BoolProperty(
name="Radius",
description="Force a custom radius",
default=False
)
- fit = EnumProperty(
+ fit: EnumProperty(
name="Method",
items=(("best", "Best fit", "Non-linear least squares"),
("inside", "Fit inside", "Only move vertices towards the center")),
description="Method used for fitting a circle to the vertices",
default='best'
)
- flatten = BoolProperty(
+ flatten: BoolProperty(
name="Flatten",
description="Flatten the circle, instead of projecting it on the mesh",
default=True
)
- influence = FloatProperty(
+ influence: FloatProperty(
name="Influence",
description="Force of the tool",
default=100.0,
@@ -3410,28 +3411,28 @@ class Circle(Operator):
precision=1,
subtype='PERCENTAGE'
)
- lock_x = BoolProperty(
+ lock_x: BoolProperty(
name="Lock X",
description="Lock editing of the x-coordinate",
default=False
)
- lock_y = BoolProperty(
+ lock_y: BoolProperty(
name="Lock Y",
description="Lock editing of the y-coordinate",
default=False
)
- lock_z = BoolProperty(name="Lock Z",
+ lock_z: BoolProperty(name="Lock Z",
description="Lock editing of the z-coordinate",
default=False
)
- radius = FloatProperty(
+ radius: FloatProperty(
name="Radius",
description="Custom radius for circle",
default=1.0,
min=0.0,
soft_max=1000.0
)
- regular = BoolProperty(
+ regular: BoolProperty(
name="Regular",
description="Distribute vertices at constant distances along the circle",
default=True
@@ -3557,12 +3558,12 @@ class Curve(Operator):
bl_description = "Turn a loop into a smooth curve"
bl_options = {'REGISTER', 'UNDO'}
- boundaries = BoolProperty(
+ boundaries: BoolProperty(
name="Boundaries",
description="Limit the tool to work within the boundaries of the selected vertices",
default=False
)
- influence = FloatProperty(
+ influence: FloatProperty(
name="Influence",
description="Force of the tool",
default=100.0,
@@ -3571,34 +3572,34 @@ class Curve(Operator):
precision=1,
subtype='PERCENTAGE'
)
- interpolation = EnumProperty(
+ interpolation: EnumProperty(
name="Interpolation",
items=(("cubic", "Cubic", "Natural cubic spline, smooth results"),
("linear", "Linear", "Simple and fast linear algorithm")),
description="Algorithm used for interpolation",
default='cubic'
)
- lock_x = BoolProperty(
+ lock_x: BoolProperty(
name="Lock X",
description="Lock editing of the x-coordinate",
default=False
)
- lock_y = BoolProperty(
+ lock_y: BoolProperty(
name="Lock Y",
description="Lock editing of the y-coordinate",
default=False
)
- lock_z = BoolProperty(
+ lock_z: BoolProperty(
name="Lock Z",
description="Lock editing of the z-coordinate",
default=False
)
- regular = BoolProperty(
+ regular: BoolProperty(
name="Regular",
description="Distribute vertices at constant distances along the curve",
default=True
)
- restriction = EnumProperty(
+ restriction: EnumProperty(
name="Restriction",
items=(("none", "None", "No restrictions on vertex movement"),
("extrude", "Extrude only", "Only allow extrusions (no indentations)"),
@@ -3702,7 +3703,7 @@ class Flatten(Operator):
bl_description = "Flatten vertices on a best-fitting plane"
bl_options = {'REGISTER', 'UNDO'}
- influence = FloatProperty(
+ influence: FloatProperty(
name="Influence",
description="Force of the tool",
default=100.0,
@@ -3711,21 +3712,21 @@ class Flatten(Operator):
precision=1,
subtype='PERCENTAGE'
)
- lock_x = BoolProperty(
+ lock_x: BoolProperty(
name="Lock X",
description="Lock editing of the x-coordinate",
default=False
)
- lock_y = BoolProperty(
+ lock_y: BoolProperty(
name="Lock Y",
description="Lock editing of the y-coordinate",
default=False
)
- lock_z = BoolProperty(name="Lock Z",
+ lock_z: BoolProperty(name="Lock Z",
description="Lock editing of the z-coordinate",
default=False
)
- plane = EnumProperty(
+ plane: EnumProperty(
name="Plane",
items=(("best_fit", "Best fit", "Calculate a best fitting plane"),
("normal", "Normal", "Derive plane from averaging vertex normals"),
@@ -3733,7 +3734,7 @@ class Flatten(Operator):
description="Plane on which vertices are flattened",
default='best_fit'
)
- restriction = EnumProperty(
+ restriction: EnumProperty(
name="Restriction",
items=(("none", "None", "No restrictions on vertex movement"),
("bounding_box", "Bounding box", "Vertices are restricted to "
@@ -3841,7 +3842,7 @@ class GStretch(Operator):
bl_description = "Stretch selected vertices to Grease Pencil stroke"
bl_options = {'REGISTER', 'UNDO'}
- conversion = EnumProperty(
+ conversion: EnumProperty(
name="Conversion",
items=(("distance", "Distance", "Set the distance between vertices "
"of the converted grease pencil stroke"),
@@ -3856,7 +3857,7 @@ class GStretch(Operator):
"use this simplification method",
default='limit_vertices'
)
- conversion_distance = FloatProperty(
+ conversion_distance: FloatProperty(
name="Distance",
description="Absolute distance between vertices along the converted "
"grease pencil stroke",
@@ -3865,7 +3866,7 @@ class GStretch(Operator):
soft_min=0.01,
soft_max=100
)
- conversion_max = IntProperty(
+ conversion_max: IntProperty(
name="Max Vertices",
description="Maximum number of vertices grease pencil strokes will "
"have, when they are converted to geomtery",
@@ -3874,7 +3875,7 @@ class GStretch(Operator):
soft_max=500,
update=gstretch_update_min
)
- conversion_min = IntProperty(
+ conversion_min: IntProperty(
name="Min Vertices",
description="Minimum number of vertices grease pencil strokes will "
"have, when they are converted to geomtery",
@@ -3883,7 +3884,7 @@ class GStretch(Operator):
soft_max=500,
update=gstretch_update_max
)
- conversion_vertices = IntProperty(
+ conversion_vertices: IntProperty(
name="Vertices",
description="Number of vertices grease pencil strokes will "
"have, when they are converted to geometry. If strokes have less "
@@ -3892,13 +3893,13 @@ class GStretch(Operator):
min=3,
soft_max=500
)
- delete_strokes = BoolProperty(
+ delete_strokes: BoolProperty(
name="Delete strokes",
description="Remove Grease Pencil strokes if they have been used "
"for Gstretch. WARNING: DOES NOT SUPPORT UNDO",
default=False
)
- influence = FloatProperty(
+ influence: FloatProperty(
name="Influence",
description="Force of the tool",
default=100.0,
@@ -3907,22 +3908,22 @@ class GStretch(Operator):
precision=1,
subtype='PERCENTAGE'
)
- lock_x = BoolProperty(
+ lock_x: BoolProperty(
name="Lock X",
description="Lock editing of the x-coordinate",
default=False
)
- lock_y = BoolProperty(
+ lock_y: BoolProperty(
name="Lock Y",
description="Lock editing of the y-coordinate",
default=False
)
- lock_z = BoolProperty(
+ lock_z: BoolProperty(
name="Lock Z",
description="Lock editing of the z-coordinate",
default=False
)
- method = EnumProperty(
+ method: EnumProperty(
name="Method",
items=(("project", "Project", "Project vertices onto the stroke, "
"using vertex normals and connected edges"),
@@ -4086,7 +4087,7 @@ class GStretch(Operator):
lock = [self.lock_x, self.lock_y, self.lock_z]
else:
lock = False
- bmesh.update_edit_mesh(object.data, tessface=True, destructive=True)
+ bmesh.update_edit_mesh(object.data, loop_triangles=True, destructive=True)
move_verts(object, bm, mapping, move, lock, self.influence)
# cleaning up
@@ -4104,7 +4105,7 @@ class Relax(Operator):
bl_description = "Relax the loop, so it is smoother"
bl_options = {'REGISTER', 'UNDO'}
- input = EnumProperty(
+ input: EnumProperty(
name="Input",
items=(("all", "Parallel (all)", "Also use non-selected "
"parallel loops as input"),
@@ -4112,14 +4113,14 @@ class Relax(Operator):
description="Loops that are relaxed",
default='selected'
)
- interpolation = EnumProperty(
+ interpolation: EnumProperty(
name="Interpolation",
items=(("cubic", "Cubic", "Natural cubic spline, smooth results"),
("linear", "Linear", "Simple and fast linear algorithm")),
description="Algorithm used for interpolation",
default='cubic'
)
- iterations = EnumProperty(
+ iterations: EnumProperty(
name="Iterations",
items=(("1", "1", "One"),
("3", "3", "Three"),
@@ -4129,7 +4130,7 @@ class Relax(Operator):
description="Number of times the loop is relaxed",
default="1"
)
- regular = BoolProperty(
+ regular: BoolProperty(
name="Regular",
description="Distribute vertices at constant distances along the loop",
default=True
@@ -4203,7 +4204,7 @@ class Space(Operator):
bl_description = "Space the vertices in a regular distrubtion on the loop"
bl_options = {'REGISTER', 'UNDO'}
- influence = FloatProperty(
+ influence: FloatProperty(
name="Influence",
description="Force of the tool",
default=100.0,
@@ -4212,7 +4213,7 @@ class Space(Operator):
precision=1,
subtype='PERCENTAGE'
)
- input = EnumProperty(
+ input: EnumProperty(
name="Input",
items=(("all", "Parallel (all)", "Also use non-selected "
"parallel loops as input"),
@@ -4220,24 +4221,24 @@ class Space(Operator):
description="Loops that are spaced",
default='selected'
)
- interpolation = EnumProperty(
+ interpolation: EnumProperty(
name="Interpolation",
items=(("cubic", "Cubic", "Natural cubic spline, smooth results"),
("linear", "Linear", "Vertices are projected on existing edges")),
description="Algorithm used for interpolation",
default='cubic'
)
- lock_x = BoolProperty(
+ lock_x: BoolProperty(
name="Lock X",
description="Lock editing of the x-coordinate",
default=False
)
- lock_y = BoolProperty(
+ lock_y: BoolProperty(
name="Lock Y",
description="Lock editing of the y-coordinate",
default=False
)
- lock_z = BoolProperty(
+ lock_z: BoolProperty(
name="Lock Z",
description="Lock editing of the z-coordinate",
default=False
@@ -4347,8 +4348,8 @@ class VIEW3D_MT_edit_mesh_looptools(Menu):
# panel containing all tools
class VIEW3D_PT_tools_looptools(Panel):
bl_space_type = 'VIEW_3D'
- bl_region_type = 'TOOLS'
- bl_category = 'Tools'
+ bl_region_type = 'UI'
+ bl_category = 'View'
bl_context = "mesh_edit"
bl_label = "LoopTools"
bl_options = {'DEFAULT_CLOSED'}
@@ -4359,7 +4360,7 @@ class VIEW3D_PT_tools_looptools(Panel):
lt = context.window_manager.looptools
# bridge - first line
- split = col.split(percentage=0.15, align=True)
+ split = col.split(factor=0.15, align=True)
if lt.display_bridge:
split.prop(lt, "display_bridge", text="", icon='DOWNARROW_HLT')
else:
@@ -4395,7 +4396,7 @@ class VIEW3D_PT_tools_looptools(Panel):
row.prop(lt, "bridge_reverse")
# circle - first line
- split = col.split(percentage=0.15, align=True)
+ split = col.split(factor=0.15, align=True)
if lt.display_circle:
split.prop(lt, "display_circle", text="", icon='DOWNARROW_HLT')
else:
@@ -4433,7 +4434,7 @@ class VIEW3D_PT_tools_looptools(Panel):
col_move.prop(lt, "circle_influence")
# curve - first line
- split = col.split(percentage=0.15, align=True)
+ split = col.split(factor=0.15, align=True)
if lt.display_curve:
split.prop(lt, "display_curve", text="", icon='DOWNARROW_HLT')
else:
@@ -4465,7 +4466,7 @@ class VIEW3D_PT_tools_looptools(Panel):
col_move.prop(lt, "curve_influence")
# flatten - first line
- split = col.split(percentage=0.15, align=True)
+ split = col.split(factor=0.15, align=True)
if lt.display_flatten:
split.prop(lt, "display_flatten", text="", icon='DOWNARROW_HLT')
else:
@@ -4495,7 +4496,7 @@ class VIEW3D_PT_tools_looptools(Panel):
col_move.prop(lt, "flatten_influence")
# gstretch - first line
- split = col.split(percentage=0.15, align=True)
+ split = col.split(factor=0.15, align=True)
if lt.display_gstretch:
split.prop(lt, "display_gstretch", text="", icon='DOWNARROW_HLT')
else:
@@ -4536,7 +4537,7 @@ class VIEW3D_PT_tools_looptools(Panel):
box.operator("remove.gp", text="Delete GP Strokes")
# loft - first line
- split = col.split(percentage=0.15, align=True)
+ split = col.split(factor=0.15, align=True)
if lt.display_loft:
split.prop(lt, "display_loft", text="", icon='DOWNARROW_HLT')
else:
@@ -4573,7 +4574,7 @@ class VIEW3D_PT_tools_looptools(Panel):
row.prop(lt, "bridge_reverse")
# relax - first line
- split = col.split(percentage=0.15, align=True)
+ split = col.split(factor=0.15, align=True)
if lt.display_relax:
split.prop(lt, "display_relax", text="", icon='DOWNARROW_HLT')
else:
@@ -4588,7 +4589,7 @@ class VIEW3D_PT_tools_looptools(Panel):
box.prop(lt, "relax_regular")
# space - first line
- split = col.split(percentage=0.15, align=True)
+ split = col.split(factor=0.15, align=True)
if lt.display_space:
split.prop(lt, "display_space", text="", icon='DOWNARROW_HLT')
else:
@@ -4625,74 +4626,74 @@ class LoopToolsProps(PropertyGroup):
bpy.context.window_manager.looptools
"""
# general display properties
- display_bridge = BoolProperty(
+ display_bridge: BoolProperty(
name="Bridge settings",
description="Display settings of the Bridge tool",
default=False
)
- display_circle = BoolProperty(
+ display_circle: BoolProperty(
name="Circle settings",
description="Display settings of the Circle tool",
default=False
)
- display_curve = BoolProperty(
+ display_curve: BoolProperty(
name="Curve settings",
description="Display settings of the Curve tool",
default=False
)
- display_flatten = BoolProperty(
+ display_flatten: BoolProperty(
name="Flatten settings",
description="Display settings of the Flatten tool",
default=False
)
- display_gstretch = BoolProperty(
+ display_gstretch: BoolProperty(
name="Gstretch settings",
description="Display settings of the Gstretch tool",
default=False
)
- display_loft = BoolProperty(
+ display_loft: BoolProperty(
name="Loft settings",
description="Display settings of the Loft tool",
default=False
)
- display_relax = BoolProperty(
+ display_relax: BoolProperty(
name="Relax settings",
description="Display settings of the Relax tool",
default=False
)
- display_space = BoolProperty(
+ display_space: BoolProperty(
name="Space settings",
description="Display settings of the Space tool",
default=False
)
# bridge properties
- bridge_cubic_strength = FloatProperty(
+ bridge_cubic_strength: FloatProperty(
name="Strength",
description="Higher strength results in more fluid curves",
default=1.0,
soft_min=-3.0,
soft_max=3.0
)
- bridge_interpolation = EnumProperty(
+ bridge_interpolation: EnumProperty(
name="Interpolation mode",
items=(('cubic', "Cubic", "Gives curved results"),
('linear', "Linear", "Basic, fast, straight interpolation")),
description="Interpolation mode: algorithm used when creating segments",
default='cubic'
)
- bridge_loft = BoolProperty(
+ bridge_loft: BoolProperty(
name="Loft",
description="Loft multiple loops, instead of considering them as "
"a multi-input for bridging",
default=False
)
- bridge_loft_loop = BoolProperty(
+ bridge_loft_loop: BoolProperty(
name="Loop",
description="Connect the first and the last loop with each other",
default=False
)
- bridge_min_width = IntProperty(
+ bridge_min_width: IntProperty(
name="Minimum width",
description="Segments with an edge smaller than this are merged "
"(compared to base edge)",
@@ -4701,7 +4702,7 @@ class LoopToolsProps(PropertyGroup):
max=100,
subtype='PERCENTAGE'
)
- bridge_mode = EnumProperty(
+ bridge_mode: EnumProperty(
name="Mode",
items=(('basic', "Basic", "Fast algorithm"),
('shortest', "Shortest edge", "Slower algorithm with "
@@ -4709,49 +4710,49 @@ class LoopToolsProps(PropertyGroup):
description="Algorithm used for bridging",
default='shortest'
)
- bridge_remove_faces = BoolProperty(
+ bridge_remove_faces: BoolProperty(
name="Remove faces",
description="Remove faces that are internal after bridging",
default=True
)
- bridge_reverse = BoolProperty(
+ bridge_reverse: BoolProperty(
name="Reverse",
description="Manually override the direction in which the loops "
"are bridged. Only use if the tool gives the wrong result",
default=False
)
- bridge_segments = IntProperty(
+ bridge_segments: IntProperty(
name="Segments",
description="Number of segments used to bridge the gap (0=automatic)",
default=1,
min=0,
soft_max=20
)
- bridge_twist = IntProperty(
+ bridge_twist: IntProperty(
name="Twist",
description="Twist what vertices are connected to each other",
default=0
)
# circle properties
- circle_custom_radius = BoolProperty(
+ circle_custom_radius: BoolProperty(
name="Radius",
description="Force a custom radius",
default=False
)
- circle_fit = EnumProperty(
+ circle_fit: EnumProperty(
name="Method",
items=(("best", "Best fit", "Non-linear least squares"),
("inside", "Fit inside", "Only move vertices towards the center")),
description="Method used for fitting a circle to the vertices",
default='best'
)
- circle_flatten = BoolProperty(
+ circle_flatten: BoolProperty(
name="Flatten",
description="Flatten the circle, instead of projecting it on the mesh",
default=True
)
- circle_influence = FloatProperty(
+ circle_influence: FloatProperty(
name="Influence",
description="Force of the tool",
default=100.0,
@@ -4760,41 +4761,41 @@ class LoopToolsProps(PropertyGroup):
precision=1,
subtype='PERCENTAGE'
)
- circle_lock_x = BoolProperty(
+ circle_lock_x: BoolProperty(
name="Lock X",
description="Lock editing of the x-coordinate",
default=False
)
- circle_lock_y = BoolProperty(
+ circle_lock_y: BoolProperty(
name="Lock Y",
description="Lock editing of the y-coordinate",
default=False
)
- circle_lock_z = BoolProperty(
+ circle_lock_z: BoolProperty(
name="Lock Z",
description="Lock editing of the z-coordinate",
default=False
)
- circle_radius = FloatProperty(
+ circle_radius: FloatProperty(
name="Radius",
description="Custom radius for circle",
default=1.0,
min=0.0,
soft_max=1000.0
)
- circle_regular = BoolProperty(
+ circle_regular: BoolProperty(
name="Regular",
description="Distribute vertices at constant distances along the circle",
default=True
)
# curve properties
- curve_boundaries = BoolProperty(
+ curve_boundaries: BoolProperty(
name="Boundaries",
description="Limit the tool to work within the boundaries of the "
"selected vertices",
default=False
)
- curve_influence = FloatProperty(
+ curve_influence: FloatProperty(
name="Influence",
description="Force of the tool",
default=100.0,
@@ -4803,34 +4804,34 @@ class LoopToolsProps(PropertyGroup):
precision=1,
subtype='PERCENTAGE'
)
- curve_interpolation = EnumProperty(
+ curve_interpolation: EnumProperty(
name="Interpolation",
items=(("cubic", "Cubic", "Natural cubic spline, smooth results"),
("linear", "Linear", "Simple and fast linear algorithm")),
description="Algorithm used for interpolation",
default='cubic'
)
- curve_lock_x = BoolProperty(
+ curve_lock_x: BoolProperty(
name="Lock X",
description="Lock editing of the x-coordinate",
default=False
)
- curve_lock_y = BoolProperty(
+ curve_lock_y: BoolProperty(
name="Lock Y",
description="Lock editing of the y-coordinate",
default=False
)
- curve_lock_z = BoolProperty(
+ curve_lock_z: BoolProperty(
name="Lock Z",
description="Lock editing of the z-coordinate",
default=False
)
- curve_regular = BoolProperty(
+ curve_regular: BoolProperty(
name="Regular",
description="Distribute vertices at constant distances along the curve",
default=True
)
- curve_restriction = EnumProperty(
+ curve_restriction: EnumProperty(
name="Restriction",
items=(("none", "None", "No restrictions on vertex movement"),
("extrude", "Extrude only", "Only allow extrusions (no indentations)"),
@@ -4840,7 +4841,7 @@ class LoopToolsProps(PropertyGroup):
)
# flatten properties
- flatten_influence = FloatProperty(
+ flatten_influence: FloatProperty(
name="Influence",
description="Force of the tool",
default=100.0,
@@ -4849,20 +4850,20 @@ class LoopToolsProps(PropertyGroup):
precision=1,
subtype='PERCENTAGE'
)
- flatten_lock_x = BoolProperty(
+ flatten_lock_x: BoolProperty(
name="Lock X",
description="Lock editing of the x-coordinate",
default=False)
- flatten_lock_y = BoolProperty(name="Lock Y",
+ flatten_lock_y: BoolProperty(name="Lock Y",
description="Lock editing of the y-coordinate",
default=False
)
- flatten_lock_z = BoolProperty(
+ flatten_lock_z: BoolProperty(
name="Lock Z",
description="Lock editing of the z-coordinate",
default=False
)
- flatten_plane = EnumProperty(
+ flatten_plane: EnumProperty(
name="Plane",
items=(("best_fit", "Best fit", "Calculate a best fitting plane"),
("normal", "Normal", "Derive plane from averaging vertex "
@@ -4872,7 +4873,7 @@ class LoopToolsProps(PropertyGroup):
description="Plane on which vertices are flattened",
default='best_fit'
)
- flatten_restriction = EnumProperty(
+ flatten_restriction: EnumProperty(
name="Restriction",
items=(("none", "None", "No restrictions on vertex movement"),
("bounding_box", "Bounding box", "Vertices are restricted to "
@@ -4882,7 +4883,7 @@ class LoopToolsProps(PropertyGroup):
)
# gstretch properties
- gstretch_conversion = EnumProperty(
+ gstretch_conversion: EnumProperty(
name="Conversion",
items=(("distance", "Distance", "Set the distance between vertices "
"of the converted grease pencil stroke"),
@@ -4897,7 +4898,7 @@ class LoopToolsProps(PropertyGroup):
"use this simplification method",
default='limit_vertices'
)
- gstretch_conversion_distance = FloatProperty(
+ gstretch_conversion_distance: FloatProperty(
name="Distance",
description="Absolute distance between vertices along the converted "
"grease pencil stroke",
@@ -4906,7 +4907,7 @@ class LoopToolsProps(PropertyGroup):
soft_min=0.01,
soft_max=100
)
- gstretch_conversion_max = IntProperty(
+ gstretch_conversion_max: IntProperty(
name="Max Vertices",
description="Maximum number of vertices grease pencil strokes will "
"have, when they are converted to geomtery",
@@ -4915,7 +4916,7 @@ class LoopToolsProps(PropertyGroup):
soft_max=500,
update=gstretch_update_min
)
- gstretch_conversion_min = IntProperty(
+ gstretch_conversion_min: IntProperty(
name="Min Vertices",
description="Minimum number of vertices grease pencil strokes will "
"have, when they are converted to geomtery",
@@ -4924,7 +4925,7 @@ class LoopToolsProps(PropertyGroup):
soft_max=500,
update=gstretch_update_max
)
- gstretch_conversion_vertices = IntProperty(
+ gstretch_conversion_vertices: IntProperty(
name="Vertices",
description="Number of vertices grease pencil strokes will "
"have, when they are converted to geometry. If strokes have less "
@@ -4933,13 +4934,13 @@ class LoopToolsProps(PropertyGroup):
min=3,
soft_max=500
)
- gstretch_delete_strokes = BoolProperty(
+ gstretch_delete_strokes: BoolProperty(
name="Delete strokes",
description="Remove Grease Pencil strokes if they have been used "
"for Gstretch. WARNING: DOES NOT SUPPORT UNDO",
default=False
)
- gstretch_influence = FloatProperty(
+ gstretch_influence: FloatProperty(
name="Influence",
description="Force of the tool",
default=100.0,
@@ -4948,22 +4949,22 @@ class LoopToolsProps(PropertyGroup):
precision=1,
subtype='PERCENTAGE'
)
- gstretch_lock_x = BoolProperty(
+ gstretch_lock_x: BoolProperty(
name="Lock X",
description="Lock editing of the x-coordinate",
default=False
)
- gstretch_lock_y = BoolProperty(
+ gstretch_lock_y: BoolProperty(
name="Lock Y",
description="Lock editing of the y-coordinate",
default=False
)
- gstretch_lock_z = BoolProperty(
+ gstretch_lock_z: BoolProperty(
name="Lock Z",
description="Lock editing of the z-coordinate",
default=False
)
- gstretch_method = EnumProperty(
+ gstretch_method: EnumProperty(
name="Method",
items=(("project", "Project", "Project vertices onto the stroke, "
"using vertex normals and connected edges"),
@@ -4977,21 +4978,21 @@ class LoopToolsProps(PropertyGroup):
)
# relax properties
- relax_input = EnumProperty(name="Input",
+ relax_input: EnumProperty(name="Input",
items=(("all", "Parallel (all)", "Also use non-selected "
"parallel loops as input"),
("selected", "Selection", "Only use selected vertices as input")),
description="Loops that are relaxed",
default='selected'
)
- relax_interpolation = EnumProperty(
+ relax_interpolation: EnumProperty(
name="Interpolation",
items=(("cubic", "Cubic", "Natural cubic spline, smooth results"),
("linear", "Linear", "Simple and fast linear algorithm")),
description="Algorithm used for interpolation",
default='cubic'
)
- relax_iterations = EnumProperty(name="Iterations",
+ relax_iterations: EnumProperty(name="Iterations",
items=(("1", "1", "One"),
("3", "3", "Three"),
("5", "5", "Five"),
@@ -5000,14 +5001,14 @@ class LoopToolsProps(PropertyGroup):
description="Number of times the loop is relaxed",
default="1"
)
- relax_regular = BoolProperty(
+ relax_regular: BoolProperty(
name="Regular",
description="Distribute vertices at constant distances along the loop",
default=True
)
# space properties
- space_influence = FloatProperty(
+ space_influence: FloatProperty(
name="Influence",
description="Force of the tool",
default=100.0,
@@ -5016,7 +5017,7 @@ class LoopToolsProps(PropertyGroup):
precision=1,
subtype='PERCENTAGE'
)
- space_input = EnumProperty(
+ space_input: EnumProperty(
name="Input",
items=(("all", "Parallel (all)", "Also use non-selected "
"parallel loops as input"),
@@ -5024,24 +5025,24 @@ class LoopToolsProps(PropertyGroup):
description="Loops that are spaced",
default='selected'
)
- space_interpolation = EnumProperty(
+ space_interpolation: EnumProperty(
name="Interpolation",
items=(("cubic", "Cubic", "Natural cubic spline, smooth results"),
("linear", "Linear", "Vertices are projected on existing edges")),
description="Algorithm used for interpolation",
default='cubic'
)
- space_lock_x = BoolProperty(
+ space_lock_x: BoolProperty(
name="Lock X",
description="Lock editing of the x-coordinate",
default=False
)
- space_lock_y = BoolProperty(
+ space_lock_y: BoolProperty(
name="Lock Y",
description="Lock editing of the y-coordinate",
default=False
)
- space_lock_z = BoolProperty(
+ space_lock_z: BoolProperty(
name="Lock Z",
description="Lock editing of the z-coordinate",
default=False
@@ -5083,7 +5084,7 @@ class LoopPreferences(AddonPreferences):
# when defining this in a submodule of a python package.
bl_idname = __name__
- category = StringProperty(
+ category: StringProperty(
name="Tab Category",
description="Choose a name for the category of the panel",
default="Tools",
@@ -5127,12 +5128,13 @@ def register():
# unregistering and removing menus
def unregister():
- for cls in classes:
+ for cls in reversed(classes):
bpy.utils.unregister_class(cls)
bpy.types.VIEW3D_MT_edit_mesh_specials.remove(menu_func)
try:
del bpy.types.WindowManager.looptools
- except:
+ except Exception as e:
+ print('unregister fail:\n', e)
pass
diff --git a/mesh_snap_utilities_line.py b/mesh_snap_utilities_line.py
index 8f2f2a94..e70e8b52 100644
--- a/mesh_snap_utilities_line.py
+++ b/mesh_snap_utilities_line.py
@@ -355,7 +355,7 @@ def draw_line(self, obj, bm, bm_geom, location):
drawing_is_dirt = False
update_edit_mesh = False
- tessface = False
+ loop_triangles = False
if bm_geom is None:
vert = bm.verts.new(location)
@@ -437,7 +437,7 @@ def draw_line(self, obj, bm, bm_geom, location):
facesp = bmesh.utils.face_split_edgenet(face, ed_list)
del split_faces
update_edit_mesh = True
- tessface = True
+ loop_triangles = True
else:
if self.intersect:
facesp = bmesh.ops.connect_vert_pair(bm, verts=[v1, v2], verts_exclude=bm.verts)
@@ -450,7 +450,7 @@ def draw_line(self, obj, bm, bm_geom, location):
for edge in facesp['edges']:
self.list_edges.append(edge)
update_edit_mesh = True
- tessface = True
+ loop_triangles = True
# create face
if self.create_face:
@@ -469,10 +469,10 @@ def draw_line(self, obj, bm, bm_geom, location):
bmesh.ops.edgenet_fill(bm, edges=list(ed_list))
update_edit_mesh = True
- tessface = True
+ loop_triangles = True
# print('face created')
if update_edit_mesh:
- bmesh.update_edit_mesh(obj.data, tessface = tessface)
+ bmesh.update_edit_mesh(obj.data, loop_triangles = loop_triangles)
self.sctx.update_drawn_snap_object(self.snap_obj)
#bm.verts.index_update()
elif drawing_is_dirt:
diff --git a/modules/rna_manual_reference.py b/modules/rna_manual_reference.py
index 6f7903ef..0f72ad87 100644
--- a/modules/rna_manual_reference.py
+++ b/modules/rna_manual_reference.py
@@ -253,7 +253,6 @@ url_manual_mapping = (
("bpy.types.cyclesrendersettings*", "render/cycles/settings/index.html#bpy-types-cyclesrendersettings"),
("bpy.types.datatransfermodifier*", "modeling/modifiers/modify/data_transfer.html#bpy-types-datatransfermodifier"),
("bpy.types.dynamicpaintmodifier*", "physics/dynamic_paint/index.html#bpy-types-dynamicpaintmodifier"),
- ("bpy.types.expressioncontroller*", "game_engine/logic/controllers/types/expression.html#bpy-types-expressioncontroller"),
("bpy.types.ffmpegsettings.audio*", "render/output/video.html#bpy-types-ffmpegsettings-audio"),
("bpy.types.followpathconstraint*", "rigging/constraints/relationship/follow_path.html#bpy-types-followpathconstraint"),
("bpy.types.gaussianblursequence*", "editors/vse/sequencer/strips/effects/blur.html#bpy-types-gaussianblursequence"),
@@ -333,7 +332,7 @@ url_manual_mapping = (
("bpy.ops.sound.bake_animation*", "data_system/scenes/properties.html#bpy-ops-sound-bake-animation"),
("bpy.ops.transform.edge_slide*", "modeling/meshes/editing/edges.html#bpy-ops-transform-edge-slide"),
("bpy.ops.transform.vert_slide*", "modeling/meshes/editing/vertices.html#bpy-ops-transform-vert-slide"),
- ("bpy.ops.view3d.select_border*", "editors/3dview/object/selecting/tools.html#bpy-ops-view3d-select-border"),
+ ("bpy.ops.view3d.select_box*", "editors/3dview/object/selecting/tools.html#bpy-ops-view3d-select-border"),
("bpy.ops.view3d.select_circle*", "editors/3dview/object/selecting/tools.html#bpy-ops-view3d-select-circle"),
("bpy.types.adjustmentsequence*", "editors/vse/sequencer/strips/effects/adjustment.html#bpy-types-adjustmentsequence"),
("bpy.types.alphaundersequence*", "editors/vse/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaundersequence"),
@@ -344,8 +343,6 @@ url_manual_mapping = (
("bpy.types.compositornodemask*", "compositing/types/input/mask.html#bpy-types-compositornodemask"),
("bpy.types.compositornodemath*", "compositing/types/converter/math.html#bpy-types-compositornodemath"),
("bpy.types.compositornodetime*", "compositing/types/input/time.html#bpy-types-compositornodetime"),
- ("bpy.types.constraintactuator*", "game_engine/logic/actuators/types/constraint.html#bpy-types-constraintactuator"),
- ("bpy.types.editobjectactuator*", "game_engine/logic/actuators/types/edit_object.html#bpy-types-editobjectactuator"),
("bpy.types.fluidfluidsettings*", "physics/fluid/types/fluid_object.html#bpy-types-fluidfluidsettings"),
("bpy.types.fmodifiergenerator*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiergenerator"),
("bpy.types.freestylelinestyle*", "render/freestyle/parameter_editor/line_style/index.html#bpy-types-freestylelinestyle"),
@@ -372,7 +369,6 @@ url_manual_mapping = (
("bpy.types.shrinkwrapmodifier*", "modeling/modifiers/deform/shrinkwrap.html#bpy-types-shrinkwrapmodifier"),
("bpy.types.splineikconstraint*", "rigging/constraints/tracking/spline_ik.html#bpy-types-splineikconstraint"),
("bpy.types.texturenodetexture*", "render/blender_render/textures/nodes/types/input/texture.html#bpy-types-texturenodetexture"),
- ("bpy.types.visibilityactuator*", "game_engine/logic/actuators/types/visibility.html#bpy-types-visibilityactuator"),
("bpy.ops.anim.keyframe_clear*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-clear"),
("bpy.ops.curve.primitive*add*", "modeling/curves/primitives.html#bpy-ops-curve-primitive-add"),
("bpy.ops.mesh.duplicate_move*", "modeling/meshes/editing/duplicating/duplicate.html#bpy-ops-mesh-duplicate-move"),
@@ -386,7 +382,7 @@ url_manual_mapping = (
("bpy.types.alphaoversequence*", "editors/vse/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaoversequence"),
("bpy.types.armatureeditbones*", "rigging/armatures/bones/editing/index.html#bpy-types-armatureeditbones"),
("bpy.types.childofconstraint*", "rigging/constraints/relationship/child_of.html#bpy-types-childofconstraint"),
- ("bpy.types.clamptoconstraint*", "rigging/constraints/tracking/clamp_to.html#bpy-types-clamptoconstraint"),
+ ("bpy.types.clamptoconstraint*", "rigging/constraints/tracking/clight_to.html#bpy-types-clamptoconstraint"),
("bpy.types.collisionmodifier*", "physics/collision.html#bpy-types-collisionmodifier"),
("bpy.types.collisionsettings*", "physics/collision.html#bpy-types-collisionsettings"),
("bpy.types.compositornodergb*", "compositing/types/input/rgb.html#bpy-types-compositornodergb"),
@@ -428,12 +424,10 @@ url_manual_mapping = (
("bpy.ops.transform.tosphere*", "modeling/meshes/editing/transform/to_sphere.html#bpy-ops-transform-tosphere"),
("bpy.types.actionconstraint*", "rigging/constraints/relationship/action.html#bpy-types-actionconstraint"),
("bpy.types.addonpreferences*", "preferences/addons.html#bpy-types-addonpreferences"),
- ("bpy.types.armatureactuator*", "game_engine/logic/actuators/types/armature.html#bpy-types-armatureactuator"),
("bpy.types.armaturemodifier*", "modeling/modifiers/deform/armature.html#bpy-types-armaturemodifier"),
("bpy.types.decimatemodifier*", "modeling/modifiers/generate/decimate.html#bpy-types-decimatemodifier"),
("bpy.types.displacemodifier*", "modeling/modifiers/deform/displace.html#bpy-types-displacemodifier"),
("bpy.types.displaysafeareas*", "render/blender_render/camera/object_data.html#bpy-types-displaysafeareas"),
- ("bpy.types.filter2dactuator*", "game_engine/logic/actuators/types/filter_2d.html#bpy-types-filter2dactuator"),
("bpy.types.fmodifierstepped*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierstepped"),
("bpy.types.freestylelineset*", "render/freestyle/parameter_editor/line_set.html#bpy-types-freestylelineset"),
("bpy.types.material.ambient*", "render/blender_render/materials/properties/shading.html#bpy-types-material-ambient"),
@@ -441,12 +435,10 @@ url_manual_mapping = (
("bpy.types.multicamsequence*", "editors/vse/sequencer/strips/effects/multicam.html#bpy-types-multicamsequence"),
("bpy.types.multiplysequence*", "editors/vse/sequencer/strips/effects/multiply.html#bpy-types-multiplysequence"),
("bpy.types.multiresmodifier*", "modeling/modifiers/generate/multiresolution.html#bpy-types-multiresmodifier"),
- ("bpy.types.object.draw_type*", "editors/3dview/object/properties/display.html#bpy-types-object-draw-type"),
+ ("bpy.types.object.display_type*", "editors/3dview/object/properties/display.html#bpy-types-object-draw-type"),
("bpy.types.object.use_extra*", "editors/3dview/object/properties/relations/extras.html#bpy-types-object-use-extra"),
("bpy.types.overdropsequence*", "editors/vse/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-overdropsequence"),
("bpy.types.particlesettings*", "physics/particles/index.html#bpy-types-particlesettings"),
- ("bpy.types.propertyactuator*", "game_engine/logic/actuators/types/property.html#bpy-types-propertyactuator"),
- ("bpy.types.pythoncontroller*", "game_engine/logic/controllers/types/python.html#bpy-types-pythoncontroller"),
("bpy.types.scenerenderlayer*", "render/cycles/settings/scene/render_layers/layers.html#bpy-types-scenerenderlayer"),
("bpy.types.sequencemodifier*", "editors/vse/sequencer/properties/modifiers.html#bpy-types-sequencemodifier"),
("bpy.types.shadernodeinvert*", "render/cycles/nodes/types/color/invert.html#bpy-types-shadernodeinvert"),
@@ -462,7 +454,6 @@ url_manual_mapping = (
("bpy.types.spaceimageeditor*", "editors/uv_image/image/index.html#bpy-types-spaceimageeditor"),
("bpy.types.spacelogiceditor*", "editors/logic_editor.html#bpy-types-spacelogiceditor"),
("bpy.types.sphfluidsettings*", "physics/fluid/index.html#bpy-types-sphfluidsettings"),
- ("bpy.types.steeringactuator*", "game_engine/logic/actuators/types/steering.html#bpy-types-steeringactuator"),
("bpy.types.subtractsequence*", "editors/vse/sequencer/strips/effects/subtract.html#bpy-types-subtractsequence"),
("bpy.types.texturenodegroup*", "render/blender_render/textures/nodes/types/groups.html#bpy-types-texturenodegroup"),
("bpy.types.texturenodeimage*", "render/blender_render/textures/nodes/types/input/image.html#bpy-types-texturenodeimage"),
@@ -481,7 +472,6 @@ url_manual_mapping = (
("bpy.ops.uv.remove_doubles*", "editors/uv_image/uv/editing/layout.html#bpy-ops-uv-remove-doubles"),
("bpy.types.backgroundimage*", "editors/3dview/properties/background_images.html#bpy-types-backgroundimage"),
("bpy.types.booleanmodifier*", "modeling/modifiers/generate/booleans.html#bpy-types-booleanmodifier"),
- ("bpy.types.collisionsensor*", "game_engine/logic/sensors/types/collision.html#bpy-types-collisionsensor"),
("bpy.types.constraint.mute*", "rigging/constraints/interface/header.html#bpy-types-constraint-mute"),
("bpy.types.explodemodifier*", "modeling/modifiers/simulate/explode.html#bpy-types-explodemodifier"),
("bpy.types.fcurvemodifiers*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fcurvemodifiers"),
@@ -491,7 +481,6 @@ url_manual_mapping = (
("bpy.types.fmodifierlimits*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierlimits"),
("bpy.types.gpussaosettings*", "editors/3dview/properties/shading.html#bpy-types-gpussaosettings"),
("bpy.types.latticemodifier*", "modeling/modifiers/deform/lattice.html#bpy-types-latticemodifier"),
- ("bpy.types.messageactuator*", "game_engine/logic/actuators/types/message.html#bpy-types-messageactuator"),
("bpy.types.musgravetexture*", "render/blender_render/textures/types/procedural/musgrave.html#bpy-types-musgravetexture"),
("bpy.types.object.location*", "editors/3dview/object/properties/transforms.html#bpy-types-object-location"),
("bpy.types.object.rotation*", "editors/3dview/object/properties/transforms.html#bpy-types-object-rotation"),
@@ -516,28 +505,18 @@ url_manual_mapping = (
("bpy.ops.transform.resize*", "editors/3dview/object/editing/transform/basics.html#bpy-ops-transform-resize"),
("bpy.ops.transform.rotate*", "editors/3dview/object/editing/transform/basics.html#bpy-ops-transform-rotate"),
("bpy.ops.view3d.localview*", "editors/3dview/navigate/views.html#bpy-ops-view3d-localview"),
- ("bpy.types.actionactuator*", "game_engine/logic/actuators/types/action.html#bpy-types-actionactuator"),
- ("bpy.types.actuatorsensor*", "game_engine/logic/sensors/types/actuator.html#bpy-types-actuatorsensor"),
- ("bpy.types.armaturesensor*", "game_engine/logic/sensors/types/armature.html#bpy-types-armaturesensor"),
- ("bpy.types.cameraactuator*", "game_engine/logic/actuators/types/camera.html#bpy-types-cameraactuator"),
("bpy.types.curvesmodifier*", "editors/vse/sequencer/properties/modifiers.html#bpy-types-curvesmodifier"),
("bpy.types.effectsequence*", "editors/vse/sequencer/properties/filter.html#bpy-types-effectsequence"),
("bpy.types.ffmpegsettings*", "render/output/video.html#bpy-types-ffmpegsettings"),
("bpy.types.fmodifiernoise*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiernoise"),
("bpy.types.gpudofsettings*", "editors/3dview/properties/shading.html#bpy-types-gpudofsettings"),
- ("bpy.types.joysticksensor*", "game_engine/logic/sensors/types/joystick.html#bpy-types-joysticksensor"),
- ("bpy.types.keyboardsensor*", "game_engine/logic/sensors/types/keyboard.html#bpy-types-keyboardsensor"),
("bpy.types.materialstrand*", "render/blender_render/materials/properties/strands.html#bpy-types-materialstrand"),
("bpy.types.materialvolume*", "render/blender_render/materials/special_effects/volume.html#bpy-types-materialvolume"),
("bpy.types.mirrormodifier*", "modeling/modifiers/generate/mirror.html#bpy-types-mirrormodifier"),
("bpy.types.movieclipproxy*", "editors/movie_clip_editor/properties/proxy.html#bpy-types-movieclipproxy"),
("bpy.types.object.up_axis*", "editors/3dview/object/properties/relations/extras.html#bpy-types-object-up-axis"),
- ("bpy.types.objectactuator*", "game_engine/logic/actuators/types/motion.html#bpy-types-objectactuator"),
- ("bpy.types.parentactuator*", "game_engine/logic/actuators/types/parent.html#bpy-types-parentactuator"),
("bpy.types.particlesystem*", "physics/particles/index.html#bpy-types-particlesystem"),
("bpy.types.particletarget*", "physics/particles/emitter/physics/keyed.html#bpy-types-particletarget"),
- ("bpy.types.propertysensor*", "game_engine/logic/sensors/types/property.html#bpy-types-propertysensor"),
- ("bpy.types.randomactuator*", "game_engine/logic/actuators/types/random.html#bpy-types-randomactuator"),
("bpy.types.remeshmodifier*", "modeling/modifiers/generate/remesh.html#bpy-types-remeshmodifier"),
("bpy.types.rendersettings*", "render/index.html#bpy-types-rendersettings"),
("bpy.types.rigidbodyworld*", "physics/rigid_body/world.html#bpy-types-rigidbodyworld"),
@@ -571,9 +550,7 @@ url_manual_mapping = (
("bpy.types.gpufxsettings*", "editors/3dview/properties/shading.html#bpy-types-gpufxsettings"),
("bpy.types.imagesequence*", "editors/vse/sequencer/strips/movie_image.html#bpy-types-imagesequence"),
("bpy.types.marbletexture*", "render/blender_render/textures/types/procedural/marble.html#bpy-types-marbletexture"),
- ("bpy.types.messagesensor*", "game_engine/logic/sensors/types/message.html#bpy-types-messagesensor"),
("bpy.types.modifier.show*", "modeling/modifiers/introduction.html#bpy-types-modifier-show"),
- ("bpy.types.mouseactuator*", "game_engine/logic/actuators/types/mouse.html#bpy-types-mouseactuator"),
("bpy.types.moviesequence*", "editors/vse/sequencer/strips/movie_image.html#bpy-types-moviesequence"),
("bpy.types.movietracking*", "editors/movie_clip_editor/tracking/index.html#bpy-types-movietracking"),
("bpy.types.object.layers*", "editors/3dview/object/properties/relations/layers.html#bpy-types-object-layers"),
@@ -581,18 +558,15 @@ url_manual_mapping = (
("bpy.types.oceanmodifier*", "modeling/modifiers/simulate/ocean.html#bpy-types-oceanmodifier"),
("bpy.types.particlebrush*", "physics/particles/mode.html#bpy-types-particlebrush"),
("bpy.types.scene.gravity*", "physics/gravity.html#bpy-types-scene-gravity"),
- ("bpy.types.sceneactuator*", "game_engine/logic/actuators/types/scene.html#bpy-types-sceneactuator"),
("bpy.types.scenesequence*", "editors/vse/sequencer/strips/scene.html#bpy-types-scenesequence"),
("bpy.types.screwmodifier*", "modeling/modifiers/generate/screw.html#bpy-types-screwmodifier"),
("bpy.types.sequenceproxy*", "editors/vse/sequencer/properties/proxy_timecode.html#bpy-types-sequenceproxy"),
("bpy.types.shadernodergb*", "render/cycles/nodes/types/input/rgb.html#bpy-types-shadernodergb"),
("bpy.types.smokemodifier*", "physics/smoke/index.html#bpy-types-smokemodifier"),
- ("bpy.types.soundactuator*", "game_engine/logic/actuators/types/sound.html#bpy-types-soundactuator"),
("bpy.types.soundsequence*", "editors/vse/sequencer/strips/sound.html#bpy-types-soundsequence"),
("bpy.types.spaceoutliner*", "editors/outliner.html#bpy-types-spaceoutliner"),
("bpy.types.spacetimeline*", "editors/timeline.html#bpy-types-spacetimeline"),
("bpy.types.spaceuveditor*", "editors/uv_image/uv/index.html#bpy-types-spaceuveditor"),
- ("bpy.types.stateactuator*", "game_engine/logic/actuators/types/state.html#bpy-types-stateactuator"),
("bpy.types.stuccitexture*", "render/blender_render/textures/types/procedural/stucci.html#bpy-types-stuccitexture"),
("bpy.types.windowmanager*", "interface/index.html#bpy-types-windowmanager"),
("bpy.types.worldlighting*", "render/blender_render/world/ambient_occlusion.html#bpy-types-worldlighting"),
@@ -600,12 +574,10 @@ url_manual_mapping = (
("bpy.ops.object.convert*", "editors/3dview/object/editing/introduction.html#bpy-ops-object-convert"),
("bpy.ops.object.speaker*", "render/audio/speaker.html#bpy-ops-object-speaker"),
("bpy.ops.transform.bend*", "modeling/meshes/editing/transform/bend.html#bpy-ops-transform-bend"),
- ("bpy.types.alwayssensor*", "game_engine/logic/sensors/types/always.html#bpy-types-alwayssensor"),
("bpy.types.bakesettings*", "render/cycles/baking.html#bpy-types-bakesettings"),
("bpy.types.blendtexture*", "render/blender_render/textures/types/procedural/blend.html#bpy-types-blendtexture"),
("bpy.types.castmodifier*", "modeling/modifiers/deform/cast.html#bpy-types-castmodifier"),
("bpy.types.colormanaged*", "render/post_process/color_management.html#bpy-types-colormanaged"),
- ("bpy.types.gameactuator*", "game_engine/logic/actuators/types/game.html#bpy-types-gameactuator"),
("bpy.types.glowsequence*", "editors/vse/sequencer/strips/effects/glow.html#bpy-types-glowsequence"),
("bpy.types.gpencilbrush*", "interface/grease_pencil/drawing/brushes.html#bpy-types-gpencilbrush"),
("bpy.types.greasepencil*", "interface/grease_pencil/index.html#bpy-types-greasepencil"),
@@ -623,7 +595,6 @@ url_manual_mapping = (
("bpy.types.object.scale*", "editors/3dview/object/properties/transforms.html#bpy-types-object-scale"),
("bpy.types.oceantexture*", "render/blender_render/textures/types/procedural/ocean.html#bpy-types-oceantexture"),
("bpy.types.particleedit*", "physics/particles/mode.html#bpy-types-particleedit"),
- ("bpy.types.randomsensor*", "game_engine/logic/sensors/types/random.html#bpy-types-randomsensor"),
("bpy.types.scene.camera*", "data_system/scenes/properties.html#bpy-types-scene-camera"),
("bpy.types.sequencecrop*", "editors/vse/sequencer/properties/input.html#bpy-types-sequencecrop"),
("bpy.types.skinmodifier*", "modeling/modifiers/generate/skin.html#bpy-types-skinmodifier"),
@@ -641,14 +612,11 @@ url_manual_mapping = (
("bpy.ops.wm.properties*", "data_system/custom_properties.html#bpy-ops-wm-properties"),
("bpy.types.addsequence*", "editors/vse/sequencer/strips/effects/add.html#bpy-types-addsequence"),
("bpy.types.consoleline*", "editors/python_console.html#bpy-types-consoleline"),
- ("bpy.types.delaysensor*", "game_engine/logic/sensors/types/delay.html#bpy-types-delaysensor"),
("bpy.types.meshstatvis*", "modeling/meshes/mesh_analysis.html#bpy-types-meshstatvis"),
- ("bpy.types.mousesensor*", "game_engine/logic/sensors/types/mouse.html#bpy-types-mousesensor"),
("bpy.types.nodesetting*", "editors/node_editor/nodes/parts.html#bpy-types-nodesetting"),
("bpy.types.object.lock*", "editors/3dview/object/properties/transforms.html#bpy-types-object-lock"),
("bpy.types.object.show*", "editors/3dview/object/properties/display.html#bpy-types-object-show"),
("bpy.types.particlekey*", "physics/particles/emitter/physics/keyed.html#bpy-types-particlekey"),
- ("bpy.types.radarsensor*", "game_engine/logic/sensors/types/radar.html#bpy-types-radarsensor"),
("bpy.types.renderlayer*", "render/post_process/layers.html#bpy-types-renderlayer"),
("bpy.types.spaceview3d*", "editors/3dview/index.html#bpy-types-spaceview3d"),
("bpy.types.uipopupmenu*", "interface/controls/buttons/menus.html#bpy-types-uipopupmenu"),
@@ -665,8 +633,6 @@ url_manual_mapping = (
("bpy.types.bpy_struct*", "data_system/custom_properties.html#bpy-types-bpy-struct"),
("bpy.types.compositor*", "compositing/index.html#bpy-types-compositor"),
("bpy.types.constraint*", "rigging/constraints/index.html#bpy-types-constraint"),
- ("bpy.types.controller*", "game_engine/logic/controllers/index.html#bpy-types-controller"),
- ("bpy.types.nearsensor*", "game_engine/logic/sensors/types/near.html#bpy-types-nearsensor"),
("bpy.types.nodesocket*", "editors/node_editor/nodes/parts.html#bpy-types-nodesocket"),
("bpy.types.pointcache*", "physics/baking.html#bpy-types-pointcache"),
("bpy.types.renderpass*", "render/blender_render/settings/passes.html#bpy-types-renderpass"),
@@ -687,7 +653,6 @@ url_manual_mapping = (
("bpy.types.nodeframe*", "editors/node_editor/nodes/frame.html#bpy-types-nodeframe"),
("bpy.types.nodegroup*", "editors/node_editor/nodes/groups.html#bpy-types-nodegroup"),
("bpy.types.pointlamp*", "render/blender_render/lighting/lamps/point.html#bpy-types-pointlamp"),
- ("bpy.types.raysensor*", "game_engine/logic/sensors/types/ray.html#bpy-types-raysensor"),
("bpy.types.spaceinfo*", "editors/info/index.html#bpy-types-spaceinfo"),
("bpy.types.textcurve*", "modeling/texts/index.html#bpy-types-textcurve"),
("bpy.types.uipiemenu*", "interface/controls/buttons/menus.html#bpy-types-uipiemenu"),
@@ -697,14 +662,12 @@ url_manual_mapping = (
("bpy.ops.mesh.noise*", "modeling/meshes/editing/transform/noise.html#bpy-ops-mesh-noise"),
("bpy.ops.mesh.screw*", "modeling/meshes/editing/duplicating/screw.html#bpy-ops-mesh-screw"),
("bpy.ops.safe_areas*", "render/blender_render/camera/object_data.html#bpy-ops-safe-areas"),
- ("bpy.types.actuator*", "game_engine/logic/actuators/index.html#bpy-types-actuator"),
("bpy.types.arealamp*", "render/blender_render/lighting/lamps/area/index.html#bpy-types-arealamp"),
("bpy.types.armature*", "rigging/armatures/index.html#bpy-types-armature"),
("bpy.types.editbone*", "rigging/armatures/bones/editing/index.html#bpy-types-editbone"),
("bpy.types.hemilamp*", "render/blender_render/lighting/lamps/hemi.html#bpy-types-hemilamp"),
("bpy.types.keyframe*", "animation/keyframes/index.html#bpy-types-keyframe"),
("bpy.types.linesets*", "render/freestyle/parameter_editor/line_set.html#bpy-types-linesets"),
- ("bpy.types.lodlevel*", "game_engine/settings/object.html#bpy-types-lodlevel"),
("bpy.types.material*", "render/blender_render/materials/index.html#bpy-types-material"),
("bpy.types.metaball*", "modeling/metas/index.html#bpy-types-metaball"),
("bpy.types.modifier*", "modeling/modifiers/index.html#bpy-types-modifier"),
@@ -748,7 +711,6 @@ url_manual_mapping = (
("bpy.types.render*", "render/index.html#bpy-types-render"),
("bpy.types.screen*", "interface/window_system/screens.html#bpy-types-screen"),
("bpy.types.sculpt*", "sculpt_paint/sculpting/index.html#bpy-types-sculpt"),
- ("bpy.types.sensor*", "game_engine/logic/sensors/index.html#bpy-types-sensor"),
("bpy.types.shader*", "render/cycles/nodes/types/shaders/index.html#bpy-types-shader"),
("bpy.types.window*", "interface/index.html#bpy-types-window"),
("bpy.ops.buttons*", "interface/index.html#bpy-ops-buttons"),
@@ -792,7 +754,7 @@ url_manual_mapping = (
("bpy.types.area*", "interface/window_system/areas.html#bpy-types-area"),
("bpy.types.boid*", "physics/particles/emitter/physics/boids.html#bpy-types-boid"),
("bpy.types.bone*", "rigging/armatures/bones/index.html#bpy-types-bone"),
- ("bpy.types.lamp*", "render/blender_render/lighting/index.html#bpy-types-lamp"),
+ ("bpy.types.light*", "render/blender_render/lighting/index.html#bpy-types-lamp"),
("bpy.types.mask*", "editors/movie_clip_editor/masking/index.html#bpy-types-mask"),
("bpy.types.menu*", "interface/controls/buttons/menus.html#bpy-types-menu"),
("bpy.types.mesh*", "modeling/meshes/index.html#bpy-types-mesh"),
@@ -805,7 +767,6 @@ url_manual_mapping = (
("bpy.ops.graph*", "editors/graph_editor/index.html#bpy-ops-graph"),
("bpy.ops.group*", "editors/3dview/object/properties/relations/groups.html#bpy-ops-group"),
("bpy.ops.image*", "data_system/files/media/image_formats.html#bpy-ops-image"),
- ("bpy.ops.logic*", "game_engine/logic/index.html#bpy-ops-logic"),
("bpy.ops.mball*", "modeling/metas/index.html#bpy-ops-mball"),
("bpy.ops.paint*", "sculpt_paint/index.html#bpy-ops-paint"),
("bpy.ops.scene*", "data_system/scenes/index.html#bpy-ops-scene"),
@@ -818,7 +779,7 @@ url_manual_mapping = (
("bpy.ops.file*", "editors/file_browser/index.html#bpy-ops-file"),
("bpy.ops.font*", "modeling/texts/index.html#bpy-ops-font"),
("bpy.ops.info*", "editors/info/index.html#bpy-ops-info"),
- ("bpy.ops.lamp*", "render/blender_render/lighting/index.html#bpy-ops-lamp"),
+ ("bpy.ops.light*", "render/blender_render/lighting/index.html#bpy-ops-lamp"),
("bpy.ops.mask*", "editors/movie_clip_editor/masking/index.html#bpy-ops-mask"),
("bpy.ops.mesh*", "modeling/meshes/index.html#bpy-ops-mesh"),
("bpy.ops.node*", "editors/node_editor/nodes/index.html#bpy-ops-node"),
diff --git a/modules/snap_context/mesh_drawing.py b/modules/snap_context/mesh_drawing.py
index bdfca4d3..95660622 100644
--- a/modules/snap_context/mesh_drawing.py
+++ b/modules/snap_context/mesh_drawing.py
@@ -52,26 +52,15 @@ def get_bmesh_vert_co_array(bm):
def get_mesh_tri_verts_array(me):
- me.calc_tessface()
- len_tessfaces = len(me.tessfaces)
- if len_tessfaces:
- tessfaces = np.empty(len_tessfaces * 4, 'i4')
- me.tessfaces.foreach_get("vertices_raw", tessfaces)
- tessfaces.shape = (-1, 4)
-
- quad_indices = tessfaces[:, 3].nonzero()[0]
- tris = np.empty(((len_tessfaces + len(quad_indices)), 3), 'i4')
-
- tris[:len_tessfaces] = tessfaces[:, :3]
- tris[len_tessfaces:] = tessfaces[quad_indices][:, (0, 2, 3)]
-
- del tessfaces
- return tris
+ me.calc_loop_triangles()
+ tris = [tri.vertices[:] for tri in me.loop_triangles]
+ if tris:
+ return np.array(tris, 'i4')
return None
def get_bmesh_tri_verts_array(bm):
- ltris = bm.calc_tessface()
+ ltris = bm.calc_loop_triangles()
tris = [[ltri[0].vert.index, ltri[1].vert.index, ltri[2].vert.index] for ltri in ltris if not ltri[0].face.hide]
if tris:
return np.array(tris, 'i4')
diff --git a/netrender/ui.py b/netrender/ui.py
index c5c22329..bcd83197 100644
--- a/netrender/ui.py
+++ b/netrender/ui.py
@@ -35,7 +35,7 @@ ADDRESS_TEST_TIMEOUT = 30
def base_poll(cls, context):
rd = context.scene.render
- return (rd.use_game_engine==False) and (rd.engine in cls.COMPAT_ENGINES)
+ return (rd.engine in cls.COMPAT_ENGINES)
def init_file():
@@ -96,7 +96,7 @@ class NetRenderButtonsPanel():
@classmethod
def poll(cls, context):
rd = context.scene.render
- return rd.engine == 'NET_RENDER' and rd.use_game_engine == False
+ return rd.engine == 'NET_RENDER'
# Setting panel, use in the scene for now.
class RENDER_PT_network_settings(NetRenderButtonsPanel, bpy.types.Panel):
diff --git a/node_wrangler.py b/node_wrangler.py
index 6ccf2ecd..2b5e2091 100644
--- a/node_wrangler.py
+++ b/node_wrangler.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Node Wrangler",
"author": "Bartek Skorupa, Greg Zaal, Sebastian Koenig, Christian Brinkmann, Florian Meyer",
"version": (3, 35),
- "blender": (2, 78, 0),
+ "blender": (2, 80, 0),
"location": "Node Editor Toolbar or Ctrl-Space",
"description": "Various tools to enhance and speed up node-based workflow",
"warning": "",
@@ -115,7 +115,7 @@ shaders_input_nodes_props = (
# Keeping mixed case to avoid having to translate entries when adding new nodes in operators.
shaders_output_nodes_props = (
('ShaderNodeOutputMaterial', 'OUTPUT_MATERIAL', 'Material Output'),
- ('ShaderNodeOutputLamp', 'OUTPUT_LAMP', 'Lamp Output'),
+ ('ShaderNodeOutputLight', 'OUTPUT_LIGHT', 'Light Output'),
('ShaderNodeOutputWorld', 'OUTPUT_WORLD', 'World Output'),
)
# (rna_type.identifier, type, rna_type.name)
@@ -332,7 +332,7 @@ compo_layout_nodes_props = (
blender_mat_input_nodes_props = (
('ShaderNodeMaterial', 'MATERIAL', 'Material'),
('ShaderNodeCameraData', 'CAMERA', 'Camera Data'),
- ('ShaderNodeLampData', 'LAMP', 'Lamp Data'),
+ ('ShaderNodeLightData', 'LIGHT', 'Light Data'),
('ShaderNodeValue', 'VALUE', 'Value'),
('ShaderNodeRGB', 'RGB', 'RGB'),
('ShaderNodeTexture', 'TEXTURE', 'Texture'),
@@ -547,6 +547,10 @@ draw_color_sets = {
}
+def is_cycles_or_eevee(context):
+ return context.scene.render.engine in {'CYCLES', 'BLENDER_EEVEE'}
+
+
def nice_hotkey_name(punc):
# convert the ugly string name into the actual character
pairs = (
@@ -1000,39 +1004,39 @@ def get_nodes_links(context):
# Principled prefs
class NWPrincipledPreferences(bpy.types.PropertyGroup):
- base_color = StringProperty(
+ base_color: StringProperty(
name='Base Color',
default='diffuse diff albedo base col color',
description='Naming Components for Base Color maps')
- sss_color = StringProperty(
+ sss_color: StringProperty(
name='Subsurface Color',
default='sss subsurface',
description='Naming Components for Subsurface Color maps')
- metallic = StringProperty(
+ metallic: StringProperty(
name='Metallic',
default='metallic metalness metal mtl',
description='Naming Components for metallness maps')
- specular = StringProperty(
+ specular: StringProperty(
name='Specular',
default='specularity specular spec spc',
description='Naming Components for Specular maps')
- normal = StringProperty(
+ normal: StringProperty(
name='Normal',
default='normal nor nrm nrml norm',
description='Naming Components for Normal maps')
- bump = StringProperty(
+ bump: StringProperty(
name='Bump',
default='bump bmp',
description='Naming Components for bump maps')
- rough = StringProperty(
+ rough: StringProperty(
name='Roughness',
default='roughness rough rgh',
description='Naming Components for roughness maps')
- gloss = StringProperty(
+ gloss: StringProperty(
name='Gloss',
default='gloss glossy glossyness',
description='Naming Components for glossy maps')
- displacement = StringProperty(
+ displacement: StringProperty(
name='Displacement',
default='displacement displace disp dsp height heightmap',
description='Naming Components for displacement maps')
@@ -1041,7 +1045,7 @@ class NWPrincipledPreferences(bpy.types.PropertyGroup):
class NWNodeWrangler(bpy.types.AddonPreferences):
bl_idname = __name__
- merge_hide = EnumProperty(
+ merge_hide: EnumProperty(
name="Hide Mix nodes",
items=(
("ALWAYS", "Always", "Always collapse the new merge nodes"),
@@ -1050,7 +1054,7 @@ class NWNodeWrangler(bpy.types.AddonPreferences):
),
default='NON_SHADER',
description="When merging nodes with the Ctrl+Numpad0 hotkey (and similar) specify whether to collapse them or show the full node with options expanded")
- merge_position = EnumProperty(
+ merge_position: EnumProperty(
name="Mix Node Position",
items=(
("CENTER", "Center", "Place the Mix node between the two nodes"),
@@ -1059,22 +1063,22 @@ class NWNodeWrangler(bpy.types.AddonPreferences):
default='CENTER',
description="When merging nodes with the Ctrl+Numpad0 hotkey (and similar) specify the position of the new nodes")
- show_hotkey_list = BoolProperty(
+ show_hotkey_list: BoolProperty(
name="Show Hotkey List",
default=False,
description="Expand this box into a list of all the hotkeys for functions in this addon"
)
- hotkey_list_filter = StringProperty(
+ hotkey_list_filter: StringProperty(
name=" Filter by Name",
default="",
description="Show only hotkeys that have this text in their name"
)
- show_principled_lists = BoolProperty(
+ show_principled_lists: BoolProperty(
name="Show Principled naming tags",
default=False,
description="Expand this box into a list of all naming tags for principled texture setup"
)
- principled_tags = bpy.props.PointerProperty(type=NWPrincipledPreferences)
+ principled_tags: bpy.props.PointerProperty(type=NWPrincipledPreferences)
def draw(self, context):
layout = self.layout
@@ -1113,7 +1117,7 @@ class NWNodeWrangler(bpy.types.AddonPreferences):
if self.hotkey_list_filter.lower() in hotkey_name.lower():
row = col.row(align=True)
- row.label(hotkey_name)
+ row.label(text=hotkey_name)
keystr = nice_hotkey_name(hotkey[1])
if hotkey[4]:
keystr = "Shift " + keystr
@@ -1121,7 +1125,7 @@ class NWNodeWrangler(bpy.types.AddonPreferences):
keystr = "Alt " + keystr
if hotkey[3]:
keystr = "Ctrl " + keystr
- row.label(keystr)
+ row.label(text=keystr)
@@ -1223,7 +1227,7 @@ class NWLazyConnect(Operator, NWBase):
bl_idname = "node.nw_lazy_connect"
bl_label = "Lazy Connect"
bl_options = {'REGISTER', 'UNDO'}
- with_menu = BoolProperty()
+ with_menu: BoolProperty()
def modal(self, context, event):
context.area.tag_redraw()
@@ -1329,12 +1333,12 @@ class NWDeleteUnused(Operator, NWBase):
bl_label = 'Delete Unused Nodes'
bl_options = {'REGISTER', 'UNDO'}
- delete_muted = BoolProperty(name="Delete Muted", description="Delete (but reconnect, like Ctrl-X) all muted nodes", default=True)
- delete_frames = BoolProperty(name="Delete Empty Frames", description="Delete all frames that have no nodes inside them", default=True)
+ delete_muted: BoolProperty(name="Delete Muted", description="Delete (but reconnect, like Ctrl-X) all muted nodes", default=True)
+ delete_frames: BoolProperty(name="Delete Empty Frames", description="Delete all frames that have no nodes inside them", default=True)
def is_unused_node(self, node):
end_types = ['OUTPUT_MATERIAL', 'OUTPUT', 'VIEWER', 'COMPOSITE', \
- 'SPLITVIEWER', 'OUTPUT_FILE', 'LEVELS', 'OUTPUT_LAMP', \
+ 'SPLITVIEWER', 'OUTPUT_FILE', 'LEVELS', 'OUTPUT_LIGHT', \
'OUTPUT_WORLD', 'GROUP_INPUT', 'GROUP_OUTPUT', 'FRAME']
if node.type in end_types:
return False
@@ -1558,8 +1562,8 @@ class NWResetBG(Operator, NWBase):
def execute(self, context):
context.space_data.backdrop_zoom = 1
- context.space_data.backdrop_x = 0
- context.space_data.backdrop_y = 0
+ context.space_data.backdrop_offset[0] = 0
+ context.space_data.backdrop_offset[1] = 0
return {'FINISHED'}
@@ -1567,9 +1571,10 @@ class NWAddAttrNode(Operator, NWBase):
"""Add an Attribute node with this name"""
bl_idname = 'node.nw_add_attr_node'
bl_label = 'Add UV map'
- attr_name = StringProperty()
bl_options = {'REGISTER', 'UNDO'}
+ attr_name: StringProperty()
+
def execute(self, context):
bpy.ops.node.add_node('INVOKE_DEFAULT', use_transform=True, type="ShaderNodeAttribute")
nodes, links = get_nodes_links(context)
@@ -1585,7 +1590,7 @@ class NWEmissionViewer(Operator, NWBase):
@classmethod
def poll(cls, context):
- is_cycles = context.scene.render.engine == 'CYCLES'
+ is_cycles = is_cycles_or_eevee(context)
if nw_check(context):
space = context.space_data
if space.tree_type == 'ShaderNodeTree' and is_cycles:
@@ -1600,13 +1605,13 @@ class NWEmissionViewer(Operator, NWBase):
space = context.space_data
shader_type = space.shader_type
if shader_type == 'OBJECT':
- if space.id not in [lamp for lamp in bpy.data.lamps]: # cannot use bpy.data.lamps directly as iterable
+ if space.id not in [light for light in bpy.data.lights]: # cannot use bpy.data.lights directly as iterable
shader_output_type = "OUTPUT_MATERIAL"
shader_output_ident = "ShaderNodeOutputMaterial"
shader_viewer_ident = "ShaderNodeEmission"
else:
- shader_output_type = "OUTPUT_LAMP"
- shader_output_ident = "ShaderNodeOutputLamp"
+ shader_output_type = "OUTPUT_LIGHT"
+ shader_output_ident = "ShaderNodeOutputLight"
shader_viewer_ident = "ShaderNodeEmission"
elif shader_type == 'WORLD':
@@ -1734,9 +1739,19 @@ class NWFrameSelected(Operator, NWBase):
bl_label = "Frame Selected"
bl_description = "Add a frame node and parent the selected nodes to it"
bl_options = {'REGISTER', 'UNDO'}
- label_prop = StringProperty(name='Label', default=' ', description='The visual name of the frame node')
- color_prop = FloatVectorProperty(name="Color", description="The color of the frame node", default=(0.6, 0.6, 0.6),
- min=0, max=1, step=1, precision=3, subtype='COLOR_GAMMA', size=3)
+
+ label_prop: StringProperty(
+ name='Label',
+ description='The visual name of the frame node',
+ default=' '
+ )
+ color_prop: FloatVectorProperty(
+ name="Color",
+ description="The color of the frame node",
+ default=(0.6, 0.6, 0.6),
+ min=0, max=1, step=1, precision=3,
+ subtype='COLOR_GAMMA', size=3
+ )
def execute(self, context):
nodes, links = get_nodes_links(context)
@@ -1795,7 +1810,7 @@ class NWSwitchNodeType(Operator, NWBase):
bl_label = "Switch Node Type"
bl_options = {'REGISTER', 'UNDO'}
- to_type = EnumProperty(
+ to_type: EnumProperty(
name="Switch to type",
items=list(shaders_input_nodes_props) +
list(shaders_output_nodes_props) +
@@ -2009,12 +2024,12 @@ class NWMergeNodes(Operator, NWBase):
bl_description = "Merge Selected Nodes"
bl_options = {'REGISTER', 'UNDO'}
- mode = EnumProperty(
+ mode: EnumProperty(
name="mode",
description="All possible blend types and math operations",
items=blend_types + [op for op in operations if op not in blend_types],
)
- merge_type = EnumProperty(
+ merge_type: EnumProperty(
name="merge type",
description="Type of Merge to be used",
items=(
@@ -2260,11 +2275,11 @@ class NWBatchChangeNodes(Operator, NWBase):
bl_description = "Batch Change Blend Type and Math Operation"
bl_options = {'REGISTER', 'UNDO'}
- blend_type = EnumProperty(
+ blend_type: EnumProperty(
name="Blend Type",
items=blend_types + navs,
)
- operation = EnumProperty(
+ operation: EnumProperty(
name="Operation",
items=operations + navs,
)
@@ -2326,7 +2341,7 @@ class NWChangeMixFactor(Operator, NWBase):
# option: Change factor.
# If option is 1.0 or 0.0 - set to 1.0 or 0.0
# Else - change factor by option value.
- option = FloatProperty()
+ option: FloatProperty()
def execute(self, context):
nodes, links = get_nodes_links(context)
@@ -2462,7 +2477,7 @@ class NWCopyLabel(Operator, NWBase):
bl_label = "Copy Label"
bl_options = {'REGISTER', 'UNDO'}
- option = EnumProperty(
+ option: EnumProperty(
name="option",
description="Source of name of label",
items=(
@@ -2506,7 +2521,7 @@ class NWClearLabel(Operator, NWBase):
bl_label = "Clear Label"
bl_options = {'REGISTER', 'UNDO'}
- option = BoolProperty()
+ option: BoolProperty()
def execute(self, context):
nodes, links = get_nodes_links(context)
@@ -2528,16 +2543,16 @@ class NWModifyLabels(Operator, NWBase):
bl_label = "Modify Labels"
bl_options = {'REGISTER', 'UNDO'}
- prepend = StringProperty(
+ prepend: StringProperty(
name="Add to Beginning"
)
- append = StringProperty(
+ append: StringProperty(
name="Add to End"
)
- replace_from = StringProperty(
+ replace_from: StringProperty(
name="Text to Replace"
)
- replace_to = StringProperty(
+ replace_to: StringProperty(
name="Replace with"
)
@@ -2561,14 +2576,14 @@ class NWAddTextureSetup(Operator, NWBase):
bl_description = "Add Texture Node Setup to Selected Shaders"
bl_options = {'REGISTER', 'UNDO'}
- add_mapping = BoolProperty(name="Add Mapping Nodes", description="Create coordinate and mapping nodes for the texture (ignored for selected texture nodes)", default=True)
+ add_mapping: BoolProperty(name="Add Mapping Nodes", description="Create coordinate and mapping nodes for the texture (ignored for selected texture nodes)", default=True)
@classmethod
def poll(cls, context):
valid = False
if nw_check(context):
space = context.space_data
- if space.tree_type == 'ShaderNodeTree' and context.scene.render.engine == 'CYCLES':
+ if space.tree_type == 'ShaderNodeTree' and is_cycles_or_eevee(context):
valid = True
return valid
@@ -2639,26 +2654,28 @@ class NWAddPrincipledSetup(Operator, NWBase, ImportHelper):
bl_description = "Add Texture Node Setup for Principled BSDF"
bl_options = {'REGISTER', 'UNDO'}
- directory = StringProperty(
- name='Directory',
- subtype='DIR_PATH',
- default='',
- description='Folder to search in for image files')
- files = CollectionProperty(
- type=bpy.types.OperatorFileListElement,
- options={'HIDDEN', 'SKIP_SAVE'})
+ directory: StringProperty(
+ name='Directory',
+ subtype='DIR_PATH',
+ default='',
+ description='Folder to search in for image files'
+ )
+ files: CollectionProperty(
+ type=bpy.types.OperatorFileListElement,
+ options={'HIDDEN', 'SKIP_SAVE'}
+ )
order = [
"filepath",
"files",
- ]
+ ]
@classmethod
def poll(cls, context):
valid = False
if nw_check(context):
space = context.space_data
- if space.tree_type == 'ShaderNodeTree' and context.scene.render.engine == 'CYCLES':
+ if space.tree_type == 'ShaderNodeTree' and is_cycles_or_eevee(context):
valid = True
return valid
@@ -2752,35 +2769,18 @@ class NWAddPrincipledSetup(Operator, NWBase, ImportHelper):
disp_texture.color_space = 'NONE'
# Add displacement offset nodes
- math_sub = nodes.new(type='ShaderNodeMath')
- math_sub.operation = 'SUBTRACT'
- math_sub.label = 'Offset'
- math_sub.location = active_node.location + Vector((0, -560))
- math_mul = nodes.new(type='ShaderNodeMath')
- math_mul.operation = 'MULTIPLY'
- math_mul.label = 'Strength'
- math_mul.location = math_sub.location + Vector((200, 0))
- link = links.new(math_mul.inputs[0], math_sub.outputs[0])
- link = links.new(math_sub.inputs[0], disp_texture.outputs[0])
-
- # Turn on true displacement in the material
+ disp_node = nodes.new(type='ShaderNodeDisplacement')
+ disp_node.location = active_node.location + Vector((0, -560))
+ link = links.new(disp_node.inputs[0], disp_texture.outputs[0])
+
+ # TODO Turn on true displacement in the material
# Too complicated for now
- '''
- # Frame. Does not update immediately
- # Seems to need an editor redraw
- frame = nodes.new(type='NodeFrame')
- frame.label = 'Displacement'
- math_sub.parent = frame
- math_mul.parent = frame
- frame.update()
- '''
-
- #find output node
+ # Find output node
output_node = [n for n in nodes if n.bl_idname == 'ShaderNodeOutputMaterial']
if output_node:
if not output_node[0].inputs[2].is_linked:
- link = links.new(output_node[0].inputs[2], math_mul.outputs[0])
+ link = links.new(output_node[0].inputs[2], disp_node.outputs[0])
continue
@@ -2847,23 +2847,24 @@ class NWAddPrincipledSetup(Operator, NWBase, ImportHelper):
# Alignment
for i, texture_node in enumerate(texture_nodes):
- offset = Vector((-400, (i * -260) + 200))
+ offset = Vector((-550, (i * -280) + 200))
texture_node.location = active_node.location + offset
if normal_node:
# Extra alignment if normal node was added
- normal_node.location = normal_node_texture.location + Vector((200, 0))
+ normal_node.location = normal_node_texture.location + Vector((300, 0))
if roughness_node:
# Alignment of invert node if glossy map
- invert_node.location = roughness_node.location + Vector((200, 0))
+ invert_node.location = roughness_node.location + Vector((300, 0))
# Add texture input + mapping
mapping = nodes.new(type='ShaderNodeMapping')
- mapping.location = active_node.location + Vector((-900, 0))
+ mapping.location = active_node.location + Vector((-1050, 0))
if len(texture_nodes) > 1:
# If more than one texture add reroute node in between
reroute = nodes.new(type='NodeReroute')
+ texture_nodes.append(reroute)
tex_coords = Vector((texture_nodes[0].location.x, sum(n.location.y for n in texture_nodes)/len(texture_nodes)))
reroute.location = tex_coords + Vector((-50, -120))
for texture_node in texture_nodes:
@@ -2877,6 +2878,20 @@ class NWAddPrincipledSetup(Operator, NWBase, ImportHelper):
texture_input.location = mapping.location + Vector((-200, 0))
link = links.new(mapping.inputs[0], texture_input.outputs[2])
+ # Create frame around tex coords and mapping
+ frame = nodes.new(type='NodeFrame')
+ frame.label = 'Mapping'
+ mapping.parent = frame
+ texture_input.parent = frame
+ frame.update()
+
+ # Create frame around texture nodes
+ frame = nodes.new(type='NodeFrame')
+ frame.label = 'Textures'
+ for tnode in texture_nodes:
+ tnode.parent = frame
+ frame.update()
+
# Just to be sure
active_node.select = False
nodes.update()
@@ -2892,7 +2907,7 @@ class NWAddReroutes(Operator, NWBase):
bl_description = "Add Reroutes to Outputs"
bl_options = {'REGISTER', 'UNDO'}
- option = EnumProperty(
+ option: EnumProperty(
name="option",
items=[
('ALL', 'to all', 'Add to all outputs'),
@@ -2992,9 +3007,9 @@ class NWLinkActiveToSelected(Operator, NWBase):
bl_label = "Link Active Node to Selected"
bl_options = {'REGISTER', 'UNDO'}
- replace = BoolProperty()
- use_node_name = BoolProperty()
- use_outputs_names = BoolProperty()
+ replace: BoolProperty()
+ use_node_name: BoolProperty()
+ use_outputs_names: BoolProperty()
@classmethod
def poll(cls, context):
@@ -3072,7 +3087,7 @@ class NWAlignNodes(Operator, NWBase):
bl_idname = "node.nw_align_nodes"
bl_label = "Align Nodes"
bl_options = {'REGISTER', 'UNDO'}
- margin = IntProperty(name='Margin', default=50, description='The amount of space between nodes')
+ margin: IntProperty(name='Margin', default=50, description='The amount of space between nodes')
def execute(self, context):
nodes, links = get_nodes_links(context)
@@ -3142,7 +3157,7 @@ class NWSelectParentChildren(Operator, NWBase):
bl_label = "Select Parent or Children"
bl_options = {'REGISTER', 'UNDO'}
- option = EnumProperty(
+ option: EnumProperty(
name="option",
items=(
('PARENT', 'Select Parent', 'Select Parent Frame'),
@@ -3225,7 +3240,7 @@ class NWLinkToOutputNode(Operator, NWBase):
if not output_node:
bpy.ops.node.select_all(action="DESELECT")
if tree_type == 'ShaderNodeTree':
- if context.scene.render.engine == 'CYCLES':
+ if is_cycles_or_eevee(context):
output_node = nodes.new('ShaderNodeOutputMaterial')
else:
output_node = nodes.new('ShaderNodeOutput')
@@ -3246,7 +3261,7 @@ class NWLinkToOutputNode(Operator, NWBase):
break
out_input_index = 0
- if tree_type == 'ShaderNodeTree' and context.scene.render.engine == 'CYCLES':
+ if tree_type == 'ShaderNodeTree' and is_cycles_or_eevee(context):
if active.outputs[output_index].name == 'Volume':
out_input_index = 1
elif active.outputs[output_index].type != 'SHADER': # connect to displacement if not a shader
@@ -3263,8 +3278,8 @@ class NWMakeLink(Operator, NWBase):
bl_idname = 'node.nw_make_link'
bl_label = 'Make Link'
bl_options = {'REGISTER', 'UNDO'}
- from_socket = IntProperty()
- to_socket = IntProperty()
+ from_socket: IntProperty()
+ to_socket: IntProperty()
def execute(self, context):
nodes, links = get_nodes_links(context)
@@ -3284,7 +3299,7 @@ class NWCallInputsMenu(Operator, NWBase):
bl_idname = 'node.nw_call_inputs_menu'
bl_label = 'Make Link'
bl_options = {'REGISTER', 'UNDO'}
- from_socket = IntProperty()
+ from_socket: IntProperty()
def execute(self, context):
nodes, links = get_nodes_links(context)
@@ -3305,9 +3320,17 @@ class NWAddSequence(Operator, ImportHelper):
bl_idname = 'node.nw_add_sequence'
bl_label = 'Import Image Sequence'
bl_options = {'REGISTER', 'UNDO'}
- directory = StringProperty(subtype="DIR_PATH")
- filename = StringProperty(subtype="FILE_NAME")
- files = CollectionProperty(type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'})
+
+ directory: StringProperty(
+ subtype="DIR_PATH"
+ )
+ filename: StringProperty(
+ subtype="FILE_NAME"
+ )
+ files: CollectionProperty(
+ type=bpy.types.OperatorFileListElement,
+ options={'HIDDEN', 'SKIP_SAVE'}
+ )
def execute(self, context):
nodes, links = get_nodes_links(context)
@@ -3399,8 +3422,13 @@ class NWAddMultipleImages(Operator, ImportHelper):
bl_idname = 'node.nw_add_multiple_images'
bl_label = 'Open Selected Images'
bl_options = {'REGISTER', 'UNDO'}
- directory = StringProperty(subtype="DIR_PATH")
- files = CollectionProperty(type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'})
+ directory: StringProperty(
+ subtype="DIR_PATH"
+ )
+ files: CollectionProperty(
+ type=bpy.types.OperatorFileListElement,
+ options={'HIDDEN', 'SKIP_SAVE'}
+ )
def execute(self, context):
nodes, links = get_nodes_links(context)
@@ -3447,8 +3475,8 @@ class NWViewerFocus(bpy.types.Operator):
bl_idname = "node.nw_viewer_focus"
bl_label = "Viewer Focus"
- x = bpy.props.IntProperty()
- y = bpy.props.IntProperty()
+ x: bpy.props.IntProperty()
+ y: bpy.props.IntProperty()
@classmethod
def poll(cls, context):
@@ -3502,8 +3530,8 @@ class NWSaveViewer(bpy.types.Operator, ExportHelper):
"""Save the current viewer node to an image file"""
bl_idname = "node.nw_save_viewer"
bl_label = "Save This Image"
- filepath = StringProperty(subtype="FILE_PATH")
- filename_ext = EnumProperty(
+ filepath: StringProperty(subtype="FILE_PATH")
+ filename_ext: EnumProperty(
name="Format",
description="Choose the file format to save to",
items=(('.bmp', "PNG", ""),
@@ -3681,7 +3709,7 @@ def drawlayout(context, layout, mode='non-panel'):
col.menu(NWSwitchNodeTypeMenu.bl_idname, text="Switch Node Type")
col.separator()
- if tree_type == 'ShaderNodeTree' and context.scene.render.engine == 'CYCLES':
+ if tree_type == 'ShaderNodeTree' and is_cycles_or_eevee(context):
col = layout.column(align=True)
col.operator(NWAddTextureSetup.bl_idname, text="Add Texture Setup", icon='NODE_SEL')
col.operator(NWAddPrincipledSetup.bl_idname, text="Add Principled Setup", icon='NODE_SEL')
@@ -3722,7 +3750,7 @@ def drawlayout(context, layout, mode='non-panel'):
col.separator()
col = layout.column(align=True)
- col.operator(NWAlignNodes.bl_idname, icon='ALIGN')
+ col.operator(NWAlignNodes.bl_idname, icon='CENTER_ONLY')
col.separator()
col = layout.column(align=True)
@@ -3737,11 +3765,11 @@ class NodeWranglerPanel(Panel, NWBase):
bl_region_type = "TOOLS"
bl_category = "Node Wrangler"
- prepend = StringProperty(
+ prepend: StringProperty(
name='prepend',
)
- append = StringProperty()
- remove = StringProperty()
+ append: StringProperty()
+ remove: StringProperty()
def draw(self, context):
self.layout.label(text="(Quick access: Ctrl+Space)")
@@ -3766,7 +3794,7 @@ class NWMergeNodesMenu(Menu, NWBase):
def draw(self, context):
type = context.space_data.tree_type
layout = self.layout
- if type == 'ShaderNodeTree' and context.scene.render.engine == 'CYCLES':
+ if type == 'ShaderNodeTree' and is_cycles_or_eevee(context):
layout.menu(NWMergeShadersMenu.bl_idname, text="Use Shaders")
layout.menu(NWMergeMixMenu.bl_idname, text="Use Mix Nodes")
layout.menu(NWMergeMathMenu.bl_idname, text="Use Math Nodes")
@@ -3990,7 +4018,7 @@ class NWVertColMenu(bpy.types.Menu):
valid = False
if nw_check(context):
snode = context.space_data
- valid = snode.tree_type == 'ShaderNodeTree' and context.scene.render.engine == 'CYCLES'
+ valid = snode.tree_type == 'ShaderNodeTree' and is_cycles_or_eevee(context)
return valid
def draw(self, context):
@@ -4025,7 +4053,7 @@ class NWSwitchNodeTypeMenu(Menu, NWBase):
layout = self.layout
tree = context.space_data.node_tree
if tree.type == 'SHADER':
- if context.scene.render.engine == 'CYCLES':
+ if is_cycles_or_eevee(context):
layout.menu(NWSwitchShadersInputSubmenu.bl_idname)
layout.menu(NWSwitchShadersOutputSubmenu.bl_idname)
layout.menu(NWSwitchShadersShaderSubmenu.bl_idname)
@@ -4034,7 +4062,7 @@ class NWSwitchNodeTypeMenu(Menu, NWBase):
layout.menu(NWSwitchShadersVectorSubmenu.bl_idname)
layout.menu(NWSwitchShadersConverterSubmenu.bl_idname)
layout.menu(NWSwitchShadersLayoutSubmenu.bl_idname)
- if context.scene.render.engine != 'CYCLES':
+ else:
layout.menu(NWSwitchMatInputSubmenu.bl_idname)
layout.menu(NWSwitchMatOutputSubmenu.bl_idname)
layout.menu(NWSwitchMatColorSubmenu.bl_idname)
diff --git a/object_boolean_tools.py b/object_boolean_tools.py
index 4c7e1bc1..a9728069 100644
--- a/object_boolean_tools.py
+++ b/object_boolean_tools.py
@@ -159,9 +159,9 @@ def Operation(context, _operation):
obj.modifiers.remove(mod)
"""
if useWire:
- selObj.draw_type = "WIRE"
+ selObj.display_type = "WIRE"
else:
- selObj.draw_type = "BOUNDS"
+ selObj.display_type = "BOUNDS"
cyclesVis.camera = False
cyclesVis.diffuse = False
@@ -200,7 +200,7 @@ def Remove(context, thisObj_name, Prop):
# if it's the brush object
if obj.name == _thisObj_name:
cyclesVis = obj.cycles_visibility
- obj.draw_type = "TEXTURED"
+ obj.display_type = "TEXTURED"
del obj["BoolToolBrush"]
del obj["BoolTool_FTransform"]
cyclesVis.camera = True
@@ -229,7 +229,7 @@ def Remove(context, thisObj_name, Prop):
if (actObj.name in mod.name):
Canvas.modifiers.remove(mod)
cyclesVis = actObj.cycles_visibility
- actObj.draw_type = "TEXTURED"
+ actObj.display_type = "TEXTURED"
del actObj["BoolToolBrush"]
del actObj["BoolTool_FTransform"]
cyclesVis.camera = True
@@ -509,9 +509,9 @@ class BTool_FastTransform(Operator):
if isBrush(actObj) and actObj["BoolTool_FTransform"] == "True":
EnableThisBrush(bpy.context, "False")
if useWire:
- actObj.draw_type = "WIRE"
+ actObj.display_type = "WIRE"
else:
- actObj.draw_type = "BOUNDS"
+ actObj.display_type = "BOUNDS"
if self.operator == "Translate":
bpy.ops.transform.translate('INVOKE_DEFAULT')
@@ -523,13 +523,13 @@ class BTool_FastTransform(Operator):
if event.type == 'LEFTMOUSE':
if isBrush(actObj):
EnableThisBrush(bpy.context, "True")
- actObj.draw_type = "WIRE"
+ actObj.display_type = "WIRE"
return {'FINISHED'}
if event.type in {'RIGHTMOUSE', 'ESC'}:
if isBrush(actObj):
EnableThisBrush(bpy.context, "True")
- actObj.draw_type = "WIRE"
+ actObj.display_type = "WIRE"
return {'CANCELLED'}
return {'RUNNING_MODAL'}
@@ -914,18 +914,18 @@ class VIEW3D_MT_booltool_menu(Menu):
layout = self.layout
layout.label("Auto Boolean:")
- layout.operator(OBJECT_OT_BoolTool_Auto_Difference.bl_idname, text='Difference', icon="ROTACTIVE")
- layout.operator(OBJECT_OT_BoolTool_Auto_Union.bl_idname, text='Union', icon="ROTATECOLLECTION")
- layout.operator(OBJECT_OT_BoolTool_Auto_Intersect.bl_idname, text='Intersect', icon="ROTATECENTER")
- layout.operator(OBJECT_OT_BoolTool_Auto_Slice.bl_idname, text='Slice', icon="ROTATECENTER")
- layout.operator(OBJECT_OT_BoolTool_Auto_Subtract.bl_idname, text='Subtract', icon="ROTACTIVE")
+ layout.operator(OBJECT_OT_BoolTool_Auto_Difference.bl_idname, text='Difference', icon='PIVOT_ACTIVE')
+ layout.operator(OBJECT_OT_BoolTool_Auto_Union.bl_idname, text='Union', icon='PIVOT_INDIVIDUAL')
+ layout.operator(OBJECT_OT_BoolTool_Auto_Intersect.bl_idname, text='Intersect', icon='PIVOT_MEDIAN')
+ layout.operator(OBJECT_OT_BoolTool_Auto_Slice.bl_idname, text='Slice', icon='PIVOT_MEDIAN')
+ layout.operator(OBJECT_OT_BoolTool_Auto_Subtract.bl_idname, text='Subtract', icon='PIVOT_ACTIVE')
layout.separator()
layout.label("Brush Boolean:")
- layout.operator(BTool_Diff.bl_idname, icon="ROTACTIVE")
- layout.operator(BTool_Union.bl_idname, icon="ROTATECOLLECTION")
- layout.operator(BTool_Inters.bl_idname, icon="ROTATECENTER")
- layout.operator(BTool_Slice.bl_idname, icon="ROTATECENTER")
+ layout.operator(BTool_Diff.bl_idname, icon='PIVOT_ACTIVE')
+ layout.operator(BTool_Union.bl_idname, icon='PIVOT_INDIVIDUAL')
+ layout.operator(BTool_Inters.bl_idname, icon='PIVOT_MEDIAN')
+ layout.operator(BTool_Slice.bl_idname, icon='PIVOT_MEDIAN')
if (isCanvas(context.active_object)):
layout.separator()
@@ -977,16 +977,16 @@ class VIEW3D_PT_booltool_tools(Panel):
col.enabled = obs_len > 1
col.label("Auto Boolean:", icon="MODIFIER")
col.separator()
- col.operator(OBJECT_OT_BoolTool_Auto_Difference.bl_idname, text='Difference', icon="ROTACTIVE")
- col.operator(OBJECT_OT_BoolTool_Auto_Union.bl_idname, text='Union', icon="ROTATECOLLECTION")
- col.operator(OBJECT_OT_BoolTool_Auto_Intersect.bl_idname, text='Intersect', icon="ROTATECENTER")
+ col.operator(OBJECT_OT_BoolTool_Auto_Difference.bl_idname, text='Difference', icon='PIVOT_ACTIVE')
+ col.operator(OBJECT_OT_BoolTool_Auto_Union.bl_idname, text='Union', icon='PIVOT_INDIVIDUAL')
+ col.operator(OBJECT_OT_BoolTool_Auto_Intersect.bl_idname, text='Intersect', icon='PIVOT_MEDIAN')
main.separator()
col = main.column(align=True)
col.enabled = obs_len == 2
- col.operator(OBJECT_OT_BoolTool_Auto_Slice.bl_idname, text='Slice', icon="ROTATECENTER")
- col.operator(OBJECT_OT_BoolTool_Auto_Subtract.bl_idname, text='Subtract', icon="ROTACTIVE")
+ col.operator(OBJECT_OT_BoolTool_Auto_Slice.bl_idname, text='Slice', icon='PIVOT_MEDIAN')
+ col.operator(OBJECT_OT_BoolTool_Auto_Subtract.bl_idname, text='Subtract', icon='PIVOT_ACTIVE')
main.separator()
@@ -994,10 +994,10 @@ class VIEW3D_PT_booltool_tools(Panel):
col.enabled = obs_len > 1
col.label("Brush Boolean:", icon="MODIFIER")
col.separator()
- col.operator(BTool_Diff.bl_idname, text="Difference", icon="ROTACTIVE")
- col.operator(BTool_Union.bl_idname, text="Union", icon="ROTATECOLLECTION")
- col.operator(BTool_Inters.bl_idname, text="Intersect", icon="ROTATECENTER")
- col.operator(BTool_Slice.bl_idname, text="Slice", icon="ROTATECENTER")
+ col.operator(BTool_Diff.bl_idname, text="Difference", icon='PIVOT_ACTIVE')
+ col.operator(BTool_Union.bl_idname, text="Union", icon='PIVOT_INDIVIDUAL')
+ col.operator(BTool_Inters.bl_idname, text="Intersect", icon='PIVOT_MEDIAN')
+ col.operator(BTool_Slice.bl_idname, text="Slice", icon='PIVOT_MEDIAN')
main.separator()
diff --git a/object_cloud_gen.py b/object_cloud_gen.py
index 008763fc..6601b8f1 100644
--- a/object_cloud_gen.py
+++ b/object_cloud_gen.py
@@ -563,7 +563,7 @@ class GenerateCloud(Operator):
# Select all of the left over boxes so people can immediately
# press generate again if they want
for eachMember in definitionObjects:
- eachMember.draw_type = 'SOLID'
+ eachMember.display_type = 'SOLID'
eachMember.select = True
eachMember.hide_render = False
@@ -576,7 +576,7 @@ class GenerateCloud(Operator):
# Create a new object cloudPnts
cloudPnts = addNewObject(scene, "CloudPoints", bounds)
cloudPnts["CloudMember"] = "CreatedObj"
- cloudPnts.draw_type = 'WIRE'
+ cloudPnts.display_type = 'WIRE'
cloudPnts.hide_render = True
makeParent(bounds, cloudPnts, scene)
@@ -606,7 +606,7 @@ class GenerateCloud(Operator):
selectedObjects[0]
)
- bounds.draw_type = 'BOUNDS'
+ bounds.display_type = 'BOUNDS'
bounds.hide_render = False
# Just add a Definition Property designating this
@@ -630,7 +630,7 @@ class GenerateCloud(Operator):
for selObj in selectedObjects:
selObj["CloudMember"] = "DefinitionObj"
selObj.name = "DefinitionObj"
- selObj.draw_type = 'WIRE'
+ selObj.display_type = 'WIRE'
selObj.hide_render = True
selObj.hide = True
makeParent(bounds, selObj, scene)
@@ -638,7 +638,7 @@ class GenerateCloud(Operator):
# Do the same to the 1. object since it is no longer in list.
firstObject["CloudMember"] = "DefinitionObj"
firstObject.name = "DefinitionObj"
- firstObject.draw_type = 'WIRE'
+ firstObject.display_type = 'WIRE'
firstObject.hide_render = True
makeParent(bounds, firstObject, scene)
@@ -646,7 +646,7 @@ class GenerateCloud(Operator):
# Create a new object cloud.
cloud = addNewObject(scene, "CloudMesh", bounds)
cloud["CloudMember"] = "CreatedObj"
- cloud.draw_type = 'WIRE'
+ cloud.display_type = 'WIRE'
cloud.hide_render = True
makeParent(bounds, cloud, scene)
@@ -677,7 +677,7 @@ class GenerateCloud(Operator):
cloudParticles.settings.frame_end = 0
cloudParticles.settings.emit_from = 'VOLUME'
cloudParticles.settings.lifetime = scene.frame_end
- cloudParticles.settings.draw_method = 'DOT'
+ cloudParticles.settings.display_method = 'DOT'
cloudParticles.settings.render_type = 'NONE'
cloudParticles.settings.distribution = 'RAND'
cloudParticles.settings.physics_type = 'NEWTON'
@@ -836,7 +836,7 @@ class GenerateCloud(Operator):
# Create a new object cloudPnts
cloudPnts = addNewObject(scene, "CloudPoints", bounds)
cloudPnts["CloudMember"] = "CreatedObj"
- cloudPnts.draw_type = 'WIRE'
+ cloudPnts.display_type = 'WIRE'
cloudPnts.hide_render = True
makeParent(bounds, cloudPnts, scene)
diff --git a/object_collections.py b/object_collections.py
new file mode 100644
index 00000000..9c7d6d76
--- /dev/null
+++ b/object_collections.py
@@ -0,0 +1,309 @@
+# ##### 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 #####
+
+import bpy
+from bpy.types import (
+ Operator,
+ Panel,
+ Menu,
+ )
+
+
+from bpy.props import (
+ EnumProperty,
+ IntProperty,
+ )
+
+
+bl_info = {
+ "name": "Collections",
+ "author": "Dalai Felinto",
+ "version": (1, 0),
+ "blender": (2, 80, 0),
+ "description": "Panel to set/unset object collections",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Object"}
+
+
+# #####################################################################################
+# Operators
+# #####################################################################################
+
+class OBJECT_OT_collection_add(Operator):
+ """Add an object to a new collection"""
+ bl_idname = "object.collection_add"
+ bl_label = "Add to New Collection"
+
+ def execute(self, context):
+ scene = context.scene
+ collection = scene.master_collection.collections.new()
+ collection.objects.link(context.object)
+ return {'FINISHED'}
+
+
+class OBJECT_OT_collection_remove(Operator):
+ """Remove the active object from this collection"""
+ bl_idname = "object.collection_remove"
+ bl_label = "Remove from Collection"
+
+ def execute(self, context):
+ collection = context.scene_collection
+ collection.objects.unlink(context.object)
+ return {'FINISHED'}
+
+
+def get_collection_from_id_recursive(collection, collection_id, current_id):
+ """Return len of collection and the collection if it was a match"""
+ if collection_id == current_id:
+ return collection, 0
+
+ current_id += 1
+
+ for collection_nested in collection.collections:
+ matched_collection, current_id = get_collection_from_id_recursive(
+ collection_nested,
+ collection_id,
+ current_id)
+ if matched_collection is not None:
+ return matched_collection, 0
+
+ return None, current_id
+
+
+def get_collection_from_id(scene, collection_id):
+ master_collection = scene.master_collection
+ return get_collection_from_id_recursive(master_collection, collection_id, 0)[0]
+
+
+def collection_items_recursive(path, collection, items, current_id, object_name):
+ name = collection.name
+ current_id += 1
+
+ if object_name not in collection.objects:
+ items.append((str(current_id), path + name, ""))
+ path += name + " / "
+
+ for collection_nested in collection.collections:
+ current_id = collection_items_recursive(path, collection_nested, items, current_id, object_name)
+ return current_id
+
+
+def collection_items(self, context):
+ items = []
+
+ master_collection = context.scene.master_collection
+ object_name = context.object.name
+
+ if object_name not in master_collection.objects:
+ items.append(('0', "Master Collection", "", 'COLLAPSEMENU', 0))
+
+ current_id = 0
+ for collection in master_collection.collections:
+ current_id = collection_items_recursive("", collection, items, current_id, object_name)
+
+ return items
+
+
+class OBJECT_OT_collection_link(Operator):
+ """Add an object to an existing collection"""
+ bl_idname = "object.collection_link"
+ bl_label = "Link to Collection"
+
+ collection_index = IntProperty(
+ name = "Collection Index",
+ default = -1,
+ options = {'SKIP_SAVE'},
+ )
+
+ type = EnumProperty(
+ name = "",
+ description = "Dynamic enum for collections",
+ items=collection_items,
+ )
+
+ def execute(self, context):
+ if self.collection_index == -1:
+ self.collection_index = int(self.type)
+
+ collection = get_collection_from_id(context.scene, self.collection_index)
+
+ if collection is None:
+ # It should never ever happen!
+ self.report({'ERROR'}, "Unexpected error: collection {0} is invalid".format(
+ self.collection_index))
+ return {'CANCELLED'}
+
+ collection.objects.link(context.object)
+ return {'FINISHED'}
+
+ def invoke(self, context, events):
+ if self.collection_index != -1:
+ return self.execute(context)
+
+ wm = context.window_manager
+ wm.invoke_search_popup(self)
+ return {'FINISHED'}
+
+
+def find_collection_parent(collection, collection_parent):
+ for collection_nested in collection_parent.collections:
+ if collection_nested == collection:
+ return collection_parent
+
+ found_collection = find_collection_parent(collection, collection_nested)
+ if found_collection:
+ return found_collection
+ return None
+
+
+class OBJECT_OT_collection_unlink(Operator):
+ """Unlink the collection from all objects"""
+ bl_idname = "object.collection_unlink"
+ bl_label = "Unlink Collection"
+
+ def execute(self, context):
+ collection = context.scene_collection
+ master_collection = context.scene.master_collection
+
+ collection_parent = find_collection_parent(collection, master_collection)
+ if collection_parent is None:
+ self.report({'ERROR'}, "Cannot find {0}'s parent".format(collection.name))
+ return {'CANCELLED'}
+
+ collection_parent.collections.remove(collection)
+ return {'CANCELLED'}
+
+
+def select_collection_objects(collection):
+ for ob in collection.objects:
+ ob.select_set('SELECT')
+
+ for collection_nested in collection.collections:
+ select_collection_objects(collection_nested)
+
+
+class OBJECT_OT_collection_select(Operator):
+ """Select all objects in collection"""
+ bl_idname = "object.collection_select"
+ bl_label = "Select Collection"
+
+ def execute(self, context):
+ collection = context.scene_collection
+ select_collection_objects(collection)
+ return {'FINISHED'}
+
+
+# #####################################################################################
+# Interface
+# #####################################################################################
+
+class COLLECTION_MT_specials(Menu):
+ bl_label = "Collection Specials"
+
+ def draw(self, context):
+ layout = self.layout
+
+ col = layout.column()
+ col.active = context.scene_collection != context.scene.master_collection
+ col.operator("object.collection_unlink", icon='X', text="Unlink Collection")
+
+ layout.operator("object.collection_select", text="Select Collection")
+
+
+def all_collections_get(context):
+ """Iterator over all scene collections
+ """
+ def all_collections_recursive_get(collection_parent, collections):
+ collections.append(collection_parent)
+ for collection_nested in collection_parent.collections:
+ all_collections_recursive_get(collection_nested, collections)
+
+ scene = context.scene
+ master_collection = scene.master_collection
+
+ collections = []
+
+ all_collections_recursive_get(master_collection, collections)
+
+ return collections
+
+
+class OBJECT_PT_collections(Panel):
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "object"
+ bl_label = "Collections"
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.row(align=True)
+
+ obj = context.object
+ master_collection = bpy.context.scene.master_collection
+
+ if master_collection.collections:
+ row.operator("object.collection_link", text="Add to Collection")
+ else:
+ row.operator("object.collection_link", text="Add to Collection").collection_index = 0
+ row.operator("object.collection_add", text="", icon='ADD')
+
+ obj_name = obj.name
+ for collection in all_collections_get(context):
+ collection_objects = collection.objects
+ if obj_name in collection.objects:
+ col = layout.column(align=True)
+ col.context_pointer_set("scene_collection", collection)
+
+ row = col.box().row()
+ if collection == master_collection:
+ row.label(text=collection.name)
+ else:
+ row.prop(collection, "name", text="")
+ row.operator("object.collection_remove", text="", icon='X', emboss=False)
+ row.menu("COLLECTION_MT_specials", icon='DOWNARROW_HLT', text="")
+
+
+# #####################################################################################
+# Register/Unregister
+# #####################################################################################
+
+classes = (
+ COLLECTION_MT_specials,
+ OBJECT_PT_collections,
+ OBJECT_OT_collection_add,
+ OBJECT_OT_collection_remove,
+ OBJECT_OT_collection_link,
+ OBJECT_OT_collection_unlink,
+ OBJECT_OT_collection_select,
+)
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/object_fracture/__init__.py b/object_fracture/__init__.py
index 0ac9f403..5dad8801 100644
--- a/object_fracture/__init__.py
+++ b/object_fracture/__init__.py
@@ -40,8 +40,8 @@ else:
import bpy
-class INFO_MT_add_fracture_objects(bpy.types.Menu):
- bl_idname = "INFO_MT_add_fracture_objects"
+class VIEW3D_MT_add_fracture_objects(bpy.types.Menu):
+ bl_idname = "VIEW3D_MT_add_fracture_objects"
bl_label = "Fracture Helper Objects"
def draw(self, context):
@@ -57,21 +57,21 @@ class INFO_MT_add_fracture_objects(bpy.types.Menu):
def menu_func(self, context):
- self.layout.menu("INFO_MT_add_fracture_objects")
+ self.layout.menu("VIEW3D_MT_add_fracture_objects")
def register():
bpy.utils.register_module(__name__)
# Add the "add fracture objects" menu to the "Add" menu
- bpy.types.INFO_MT_add.append(menu_func)
+ bpy.types.VIEW3D_MT_add.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
# Remove "add fracture objects" menu from the "Add" menu.
- bpy.types.INFO_MT_add.remove(menu_func)
+ bpy.types.VIEW3D_MT_add.remove(menu_func)
if __name__ == "__main__":
diff --git a/object_fracture_cell/__init__.py b/object_fracture_cell/__init__.py
index ad4cdf39..891027f2 100644
--- a/object_fracture_cell/__init__.py
+++ b/object_fracture_cell/__init__.py
@@ -75,8 +75,8 @@ def main_object(scene, obj, level, **kw):
obj.select = False
if kw_copy["use_debug_redraw"]:
- obj_draw_type_prev = obj.draw_type
- obj.draw_type = 'WIRE'
+ obj_display_type_prev = obj.display_type
+ obj.display_type = 'WIRE'
objects = fracture_cell_setup.cell_fracture_objects(scene, obj, **kw_copy)
objects = fracture_cell_setup.cell_fracture_boolean(scene, obj, objects,
@@ -172,7 +172,7 @@ def main_object(scene, obj, level, **kw):
group.objects.link(obj_cell)
if kw_copy["use_debug_redraw"]:
- obj.draw_type = obj_draw_type_prev
+ obj.display_type = obj_display_type_prev
# testing only!
# obj.hide = True
diff --git a/object_grease_scatter.py b/object_grease_scatter.py
index 105b40ea..df1c7cce 100644
--- a/object_grease_scatter.py
+++ b/object_grease_scatter.py
@@ -390,12 +390,12 @@ def menu_func(self, context):
def register():
bpy.utils.register_class(Scatter)
- bpy.types.INFO_MT_mesh_add.append(menu_func)
+ bpy.types.VIEW3D_MT_mesh_add.append(menu_func)
def unregister():
bpy.utils.unregister_class(Scatter)
- bpy.types.INFO_MT_mesh_add.remove(menu_func)
+ bpy.types.VIEW3D_MT_mesh_add.remove(menu_func)
#if __name__ == "__main__":
# _main()
diff --git a/object_print3d_utils/__init__.py b/object_print3d_utils/__init__.py
index 5ae1d3d6..6bf2a8a7 100644
--- a/object_print3d_utils/__init__.py
+++ b/object_print3d_utils/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "3D Print Toolbox",
"author": "Campbell Barton",
- "blender": (2, 79, 0),
+ "blender": (2, 80, 0),
"location": "3D View > Toolbox",
"description": "Utilities for 3D printing",
"wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
@@ -59,101 +59,66 @@ else:
class Print3D_Scene_Props(PropertyGroup):
- export_format = EnumProperty(
- name="Format",
- description="Format type to export to",
- items=(('STL', "STL", ""),
- ('PLY', "PLY", ""),
- ('WRL', "VRML2", ""),
- ('X3D', "X3D", ""),
- ('OBJ', "OBJ", "")),
- default='STL',
- )
- use_export_texture = BoolProperty(
- name="Copy Textures",
- description="Copy textures on export to the output path",
- default=False,
- )
- use_apply_scale = BoolProperty(
- name="Apply Scale",
- description="Apply scene scale setting on export",
- default=False,
- )
- export_path = StringProperty(
- name="Export Directory",
- description="Path to directory where the files are created",
- default="//", maxlen=1024, subtype="DIR_PATH",
- )
- thickness_min = FloatProperty(
- name="Thickness",
- description="Minimum thickness",
- subtype='DISTANCE',
- default=0.001, # 1mm
- min=0.0, max=10.0,
- )
- threshold_zero = FloatProperty(
- name="Threshold",
- description="Limit for checking zero area/length",
- default=0.0001,
- precision=5,
- min=0.0, max=0.2,
- )
- angle_distort = FloatProperty(
- name="Angle",
- description="Limit for checking distorted faces",
- subtype='ANGLE',
- default=math.radians(45.0),
- min=0.0, max=math.radians(180.0),
- )
- angle_sharp = FloatProperty(
- name="Angle",
- subtype='ANGLE',
- default=math.radians(160.0),
- min=0.0, max=math.radians(180.0),
- )
- angle_overhang = FloatProperty(
- name="Angle",
- subtype='ANGLE',
- default=math.radians(45.0),
- min=0.0, max=math.radians(90.0),
- )
-
-
-# Update panel category name
-panels = (
- ui.VIEW3D_PT_Print3D_Object,
- ui.VIEW3D_PT_Print3D_Mesh,
+ export_format: EnumProperty(
+ name="Format",
+ description="Format type to export to",
+ items=(
+ ('STL', "STL", ""),
+ ('PLY', "PLY", ""),
+ ('WRL', "VRML2", ""),
+ ('X3D', "X3D", ""),
+ ('OBJ', "OBJ", ""),
+ ),
+ default='STL',
+ )
+ use_export_texture: BoolProperty(
+ name="Copy Textures",
+ description="Copy textures on export to the output path",
+ default=False,
+ )
+ use_apply_scale: BoolProperty(
+ name="Apply Scale",
+ description="Apply scene scale setting on export",
+ default=False,
+ )
+ export_path: StringProperty(
+ name="Export Directory",
+ description="Path to directory where the files are created",
+ default="//", maxlen=1024, subtype="DIR_PATH",
+ )
+ thickness_min: FloatProperty(
+ name="Thickness",
+ description="Minimum thickness",
+ subtype='DISTANCE',
+ default=0.001, # 1mm
+ min=0.0, max=10.0,
+ )
+ threshold_zero: FloatProperty(
+ name="Threshold",
+ description="Limit for checking zero area/length",
+ default=0.0001,
+ precision=5,
+ min=0.0, max=0.2,
+ )
+ angle_distort: FloatProperty(
+ name="Angle",
+ description="Limit for checking distorted faces",
+ subtype='ANGLE',
+ default=math.radians(45.0),
+ min=0.0, max=math.radians(180.0),
+ )
+ angle_sharp: FloatProperty(
+ name="Angle",
+ subtype='ANGLE',
+ default=math.radians(160.0),
+ min=0.0, max=math.radians(180.0),
+ )
+ angle_overhang: FloatProperty(
+ name="Angle",
+ subtype='ANGLE',
+ default=math.radians(45.0),
+ min=0.0, max=math.radians(90.0),
)
-
-
-def update_panels(self, context):
- try:
- for panel in panels:
- if "bl_rna" in panel.__dict__:
- bpy.utils.unregister_class(panel)
-
- for panel in panels:
- panel.bl_category = context.user_preferences.addons[__name__].preferences.category
- bpy.utils.register_class(panel)
-
- except Exception as e:
- message = "3D Print Toolbox: Updating Panel locations has failed"
- print("\n[{}]\n{}\n\nError:\n{}".format(__name__, message, e))
-
-
-class Print3D_Preferences(AddonPreferences):
- bl_idname = __name__
-
- category = StringProperty(
- name="Tab Category",
- description="Choose a name for the category of the panel",
- default="3D Printing",
- update=update_panels,
- )
-
- def draw(self, context):
- layout = self.layout
- layout.prop(self, "category")
classes = (
@@ -185,8 +150,7 @@ classes = (
operators.MESH_OT_Print3D_Export,
Print3D_Scene_Props,
- Print3D_Preferences,
- )
+)
def register():
@@ -195,8 +159,6 @@ def register():
bpy.types.Scene.print_3d = PointerProperty(type=Print3D_Scene_Props)
- update_panels(None, bpy.context)
-
def unregister():
for cls in classes:
diff --git a/object_print3d_utils/export.py b/object_print3d_utils/export.py
index cbb607d2..00277958 100644
--- a/object_print3d_utils/export.py
+++ b/object_print3d_utils/export.py
@@ -53,11 +53,12 @@ def image_copy_guess(filepath, objects):
def write_mesh(context, info, report_cb):
scene = context.scene
+ layer = context.view_layer
unit = scene.unit_settings
print_3d = scene.print_3d
- obj_base = scene.object_bases.active
- obj = obj_base.object
+ # obj_base = layer.object_bases.active
+ obj = layer.objects.active
export_format = print_3d.export_format
global_scale = unit.scale_length if (unit.system != 'NONE' and print_3d.use_apply_scale) else 1.0
@@ -73,13 +74,16 @@ def write_mesh(context, info, report_cb):
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
from . import mesh_helpers
- obj_base_tmp = mesh_helpers.object_merge(context, context_override["selected_objects"])
- context_override["active_object"] = obj_base_tmp.object
- context_override["selected_bases"] = [obj_base_tmp]
- context_override["selected_objects"] = [obj_base_tmp.object]
+ obj_tmp = mesh_helpers.object_merge(context, context_override["selected_objects"])
+ context_override["active_object"] = obj_tmp
+ # context_override["selected_bases"] = [obj_base_tmp]
+ context_override["selected_objects"] = [obj_tmp]
else:
+ # XXX28
+ '''
if obj_base not in context_override["selected_bases"]:
context_override["selected_bases"].append(obj_base)
+ '''
if obj not in context_override["selected_objects"]:
context_override["selected_objects"].append(obj)
diff --git a/object_print3d_utils/mesh_helpers.py b/object_print3d_utils/mesh_helpers.py
index a5d5f74f..873f30d2 100644
--- a/object_print3d_utils/mesh_helpers.py
+++ b/object_print3d_utils/mesh_helpers.py
@@ -32,7 +32,7 @@ def bmesh_copy_from_object(obj, transform=True, triangulate=True, apply_modifier
if apply_modifiers and obj.modifiers:
import bpy
- me = obj.to_mesh(bpy.context.scene, True, 'PREVIEW', calc_tessface=False)
+ me = obj.to_mesh(bpy.context.scene, True, 'PREVIEW')
bm = bmesh.new()
bm.from_mesh(me)
bpy.data.meshes.remove(me)
@@ -157,19 +157,31 @@ def bmesh_check_thick_object(obj, thickness):
# Create a real mesh (lame!)
context = bpy.context
scene = context.scene
+ layer = context.view_layer
+ layer_collection = context.layer_collection
+ if layer_collection is None:
+ scene_collection = scene.master_collection.collections.new("")
+ layer_collection = layer.collections.link(scene_collection)
+ else:
+ scene_collection = layer_collection.collection
+
me_tmp = bpy.data.meshes.new(name="~temp~")
bm.to_mesh(me_tmp)
# bm.free() # delay free
obj_tmp = bpy.data.objects.new(name=me_tmp.name, object_data=me_tmp)
- base = scene.objects.link(obj_tmp)
+ # base = scene.objects.link(obj_tmp)
+ scene_collection.objects.link(obj_tmp)
# Add new object to local view layer
+ # XXX28
+ '''
v3d = None
if context.space_data and context.space_data.type == 'VIEW_3D':
v3d = context.space_data
if v3d and v3d.local_view:
base.layers_from_view(context.space_data)
+ '''
scene.update()
ray_cast = obj_tmp.ray_cast
@@ -190,7 +202,7 @@ def bmesh_check_thick_object(obj, thickness):
p_b = p - no_end
p_dir = p_b - p_a
- ok, co, no, index = ray_cast(p_a, p_dir, p_dir.length)
+ ok, co, no, index = ray_cast(p_a, p_dir, distance=p_dir.length)
if ok:
# Add the face we hit
@@ -203,7 +215,7 @@ def bmesh_check_thick_object(obj, thickness):
# finished with bm
bm.free()
- scene.objects.unlink(obj_tmp)
+ scene_collection.objects.unlink(obj_tmp)
bpy.data.objects.remove(obj_tmp)
bpy.data.meshes.remove(me_tmp)
@@ -228,17 +240,24 @@ def object_merge(context, objects):
seq.remove(seq[i])
scene = context.scene
+ layer = context.view_layer
+ layer_collection = context.layer_collection
+ if layer_collection is None:
+ scene_collection = scene.master_collection.collections.new("")
+ layer_collection = layer.collections.link(scene_collection)
+ else:
+ scene_collection = layer_collection.collection
# deselect all
for obj in scene.objects:
- obj.select = False
+ obj.select_set('DESELECT')
# add empty object
mesh_base = bpy.data.meshes.new(name="~tmp~")
obj_base = bpy.data.objects.new(name="~tmp~", object_data=mesh_base)
- base_base = scene.objects.link(obj_base)
- scene.objects.active = obj_base
- obj_base.select = True
+ scene_collection.objects.link(obj_base)
+ layer.objects.active = obj_base
+ obj_base.select_set('SELECT')
# loop over all meshes
for obj in objects:
@@ -246,29 +265,29 @@ def object_merge(context, objects):
continue
# convert each to a mesh
- mesh_new = obj.to_mesh(scene=scene,
- apply_modifiers=True,
- settings='PREVIEW',
- calc_tessface=False)
+ mesh_new = obj.to_mesh(
+ depsgraph=context.depsgraph,
+ apply_modifiers=True,
+ )
# remove non-active uvs/vcols
cd_remove_all_but_active(mesh_new.vertex_colors)
- cd_remove_all_but_active(mesh_new.uv_textures)
+ cd_remove_all_but_active(mesh_new.uv_layers)
# join into base mesh
obj_new = bpy.data.objects.new(name="~tmp-new~", object_data=mesh_new)
- base_new = scene.objects.link(obj_new)
+ base_new = scene_collection.objects.link(obj_new)
obj_new.matrix_world = obj.matrix_world
fake_context = context.copy()
fake_context["active_object"] = obj_base
- fake_context["selected_editable_bases"] = [base_base, base_new]
+ fake_context["selected_editable_objects"] = [obj_base, obj_new]
bpy.ops.object.join(fake_context)
del base_new, obj_new
# remove object and its mesh, join does this
- # scene.objects.unlink(obj_new)
+ # scene_collection.objects.unlink(obj_new)
# bpy.data.objects.remove(obj_new)
bpy.data.meshes.remove(mesh_new)
@@ -276,7 +295,8 @@ def object_merge(context, objects):
scene.update()
# return new object
- return base_base
+ return obj_base
+
def face_is_distorted(ele, angle_distort):
diff --git a/object_print3d_utils/operators.py b/object_print3d_utils/operators.py
index e7ff4713..ebc1a730 100644
--- a/object_print3d_utils/operators.py
+++ b/object_print3d_utils/operators.py
@@ -23,15 +23,15 @@
import bpy
from bpy.types import Operator
from bpy.props import (
- IntProperty,
- FloatProperty,
- )
+ IntProperty,
+ FloatProperty,
+)
import bmesh
from . import (
- mesh_helpers,
- report,
- )
+ mesh_helpers,
+ report,
+)
def clean_float(text):
@@ -430,16 +430,16 @@ class MESH_OT_Print3D_Clean_Non_Manifold(Operator):
bl_label = "Print3D Clean Non-Manifold and Inverted"
bl_options = {'REGISTER', 'UNDO'}
- threshold = bpy.props.FloatProperty(
- name="threshold",
- description="Minimum distance between elements to merge",
- default=0.0001,
- )
- sides = bpy.props.IntProperty(
- name="sides",
- description="Number of sides in hole required to fill",
- default=4,
- )
+ threshold: bpy.props.FloatProperty(
+ name="threshold",
+ description="Minimum distance between elements to merge",
+ default=0.0001,
+ )
+ sides: bpy.props.IntProperty(
+ name="sides",
+ description="Number of sides in hole required to fill",
+ default=4,
+ )
def execute(self, context):
self.context = context
@@ -600,7 +600,7 @@ class MESH_OT_Print3D_Select_Report(Operator):
bl_label = "Print3D Select Report"
bl_options = {'INTERNAL'}
- index = IntProperty()
+ index: IntProperty()
_type_to_mode = {
bmesh.types.BMVert: 'VERT',
@@ -659,14 +659,14 @@ class MESH_OT_Print3D_Scale_To_Volume(Operator):
bl_label = "Scale to Volume"
bl_options = {'REGISTER', 'UNDO'}
- volume_init = FloatProperty(
- options={'HIDDEN'},
- )
- volume = FloatProperty(
- name="Volume",
- unit='VOLUME',
- min=0.0, max=100000.0,
- )
+ volume_init: FloatProperty(
+ options={'HIDDEN'},
+ )
+ volume: FloatProperty(
+ name="Volume",
+ unit='VOLUME',
+ min=0.0, max=100000.0,
+ )
def execute(self, context):
import math
@@ -705,17 +705,17 @@ class MESH_OT_Print3D_Scale_To_Bounds(Operator):
bl_label = "Scale to Bounds"
bl_options = {'REGISTER', 'UNDO'}
- length_init = FloatProperty(
- options={'HIDDEN'},
- )
- axis_init = IntProperty(
- options={'HIDDEN'},
- )
- length = FloatProperty(
- name="Length Limit",
- unit='LENGTH',
- min=0.0, max=100000.0,
- )
+ length_init: FloatProperty(
+ options={'HIDDEN'},
+ )
+ axis_init: IntProperty(
+ options={'HIDDEN'},
+ )
+ length: FloatProperty(
+ name="Length Limit",
+ unit='LENGTH',
+ min=0.0, max=100000.0,
+ )
def execute(self, context):
scale = self.length / self.length_init
@@ -731,11 +731,11 @@ class MESH_OT_Print3D_Scale_To_Bounds(Operator):
return max(((max(v[i] for v in vecs) - min(v[i] for v in vecs)), i) for i in range(3))
if context.mode == 'EDIT_MESH':
- length, axis = calc_length([Vector(v) * obj.matrix_world
+ length, axis = calc_length([Vector(v) @ obj.matrix_world
for obj in [context.edit_object]
for v in obj.bound_box])
else:
- length, axis = calc_length([Vector(v) * obj.matrix_world
+ length, axis = calc_length([Vector(v) @ obj.matrix_world
for obj in context.selected_editable_objects
if obj.type == 'MESH' for v in obj.bound_box])
diff --git a/object_print3d_utils/ui.py b/object_print3d_utils/ui.py
index 6e5c3284..44634bbc 100644
--- a/object_print3d_utils/ui.py
+++ b/object_print3d_utils/ui.py
@@ -29,7 +29,7 @@ from . import report
class Print3D_ToolBar:
bl_label = "Print3D"
bl_space_type = 'VIEW_3D'
- bl_region_type = 'TOOLS'
+ bl_region_type = 'UI'
_type_to_icon = {
bmesh.types.BMVert: 'VERTEXSEL',
@@ -49,7 +49,7 @@ class Print3D_ToolBar:
if info:
obj = context.edit_object
- layout.label("Output:")
+ layout.label(text="Output:")
box = layout.box()
col = box.column(align=False)
# box.alert = True
@@ -61,7 +61,7 @@ class Print3D_ToolBar:
icon=Print3D_ToolBar._type_to_icon[bm_type]).index = i
layout.operator("mesh.select_non_manifold", text='Non Manifold Extended')
else:
- col.label(text)
+ col.label(text=text)
def draw(self, context):
@@ -73,13 +73,13 @@ class Print3D_ToolBar:
# TODO, presets
row = layout.row()
- row.label("Statistics:")
+ row.label(text="Statistics:")
rowsub = layout.row(align=True)
rowsub.operator("mesh.print3d_info_volume", text="Volume")
rowsub.operator("mesh.print3d_info_area", text="Area")
row = layout.row()
- row.label("Checks:")
+ row.label(text="Checks:")
col = layout.column(align=True)
col.operator("mesh.print3d_check_solid", text="Solid")
col.operator("mesh.print3d_check_intersect", text="Intersections")
@@ -102,7 +102,7 @@ class Print3D_ToolBar:
col.operator("mesh.print3d_check_all", text="Check All")
row = layout.row()
- row.label("Cleanup:")
+ row.label(text="Cleanup:")
col = layout.column(align=True)
col.operator("mesh.print3d_clean_isolated", text="Isolated")
rowsub = col.row(align=True)
@@ -114,14 +114,14 @@ class Print3D_ToolBar:
# col.operator("mesh.print3d_clean_thin", text="Wall Thickness")
row = layout.row()
- row.label("Scale To:")
+ row.label(text="Scale To:")
rowsub = layout.row(align=True)
rowsub.operator("mesh.print3d_scale_to_volume", text="Volume")
rowsub.operator("mesh.print3d_scale_to_bounds", text="Bounds")
col = layout.column()
rowsub = col.row(align=True)
- rowsub.label("Export Path:")
+ rowsub.label(text="Export Path:")
rowsub.prop(print_3d, "use_apply_scale", text="", icon='MAN_SCALE')
rowsub.prop(print_3d, "use_export_texture", text="", icon='FILE_IMAGE')
rowsub = col.row()
diff --git a/oscurart_tools/oscurart_meshes.py b/oscurart_tools/oscurart_meshes.py
index 70f4df1c..61c6fa54 100644
--- a/oscurart_tools/oscurart_meshes.py
+++ b/oscurart_tools/oscurart_meshes.py
@@ -321,8 +321,7 @@ def DefOscObjectToMesh():
MESH = ACTOBJ.to_mesh(
scene=bpy.context.scene,
apply_modifiers=True,
- settings="RENDER",
- calc_tessface=True)
+ settings="RENDER")
OBJECT = bpy.data.objects.new(("%s_Freeze") % (ACTOBJ.name), MESH)
bpy.context.scene.objects.link(OBJECT)
@@ -601,7 +600,7 @@ def defPasteUvsIsland(self, uvOffset, rotateUv,context):
bm = bmesh.from_edit_mesh(bpy.context.object.data)
bmesh.ops.reverse_uvs(bm, faces=[f for f in bm.faces if f.select])
bmesh.ops.rotate_uvs(bm, faces=[f for f in bm.faces if f.select])
- #bmesh.update_edit_mesh(bpy.context.object.data, tessface=False, destructive=False)
+ #bmesh.update_edit_mesh(bpy.context.object.data, loop_triangles=False, destructive=False)
diff --git a/paint_palette.py b/paint_palette.py
index cf0e58e9..320163ad 100644
--- a/paint_palette.py
+++ b/paint_palette.py
@@ -462,12 +462,12 @@ def color_palette_draw(self, context):
row = layout.row(align=True)
row.menu("PALETTE_MT_menu", text=PALETTE_MT_menu.bl_label)
- row.operator("palette.preset_add", text="", icon="ZOOMIN").remove_active = False
- row.operator("palette.preset_add", text="", icon="ZOOMOUT").remove_active = True
+ row.operator("palette.preset_add", text="", icon='ADD').remove_active = False
+ row.operator("palette.preset_add", text="", icon='REMOVE').remove_active = True
col = layout.column(align=True)
row = col.row(align=True)
- row.operator("palette_props.add_color", icon="ZOOMIN")
+ row.operator("palette_props.add_color", icon='ADD')
row.prop(palette_props, "index")
row.operator("palette_props.remove_color", icon="PANEL_CLOSE")
diff --git a/pie_menus_official/__init__.py b/pie_menus_official/__init__.py
index 513ae2b3..52c8d346 100644
--- a/pie_menus_official/__init__.py
+++ b/pie_menus_official/__init__.py
@@ -31,7 +31,7 @@ bl_info = {
"name": "UI Pie Menu Official",
"author": "Antony Riakiotakis, Sebastian Koenig",
"version": (1, 1, 5),
- "blender": (2, 7, 7),
+ "blender": (2, 80, 0),
"description": "Individual Pie Menu Activation List",
"location": "Addons Preferences",
"warning": "",
@@ -129,42 +129,42 @@ class UIToolsPreferences(AddonPreferences):
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.label(text='{}: {}'.format(info['category'], info['name']))
sub = row.row()
sub.alignment = 'RIGHT'
if info.get('warning'):
- sub.label('', icon='ERROR')
+ sub.label(text='', 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'])
+ split = col.row().split(factor=0.15)
+ split.label(text='Description:')
+ split.label(text=info['description'])
if info.get('location'):
- split = col.row().split(percentage=0.15)
- split.label('Location:')
- split.label(info['location'])
+ split = col.row().split(factor=0.15)
+ split.label(text='Location:')
+ split.label(text=info['location'])
"""
if info.get('author'):
- split = col.row().split(percentage=0.15)
- split.label('Author:')
- split.label(info['author'])
+ split = col.row().split(factor=0.15)
+ split.label(text='Author:')
+ split.label(text=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']),
+ split = col.row().split(factor=0.15)
+ split.label(text='Version:')
+ split.label(text='.'.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')
+ split = col.row().split(factor=0.15)
+ split.label(text='Warning:')
+ split.label(text=' ' + info['warning'], icon='ERROR')
tot_row = int(bool(info.get('wiki_url')))
if tot_row:
- split = col.row().split(percentage=0.15)
+ split = col.row().split(factor=0.15)
split.label(text='Internet:')
if info.get('wiki_url'):
op = split.operator('wm.url_open',
diff --git a/pie_menus_official/pie_manipulator_of.py b/pie_menus_official/pie_manipulator_of.py
index 04ced83a..eb475cf7 100644
--- a/pie_menus_official/pie_manipulator_of.py
+++ b/pie_menus_official/pie_manipulator_of.py
@@ -26,7 +26,7 @@ class VIEW3D_manipulator_set_of(Operator):
bl_label = "Set Manipulator"
bl_idname = "view3d.manipulator_set"
- type = EnumProperty(
+ type: EnumProperty(
name="Type",
items=(('TRANSLATE', "Translate", "Use the manipulator for movement transformations"),
('ROTATE', "Rotate", "Use the manipulator for rotation transformations"),
@@ -36,7 +36,7 @@ class VIEW3D_manipulator_set_of(Operator):
def execute(self, context):
# show manipulator if user selects an option
- context.space_data.show_manipulator = True
+ context.space_data.show_gizmo = True
context.space_data.transform_manipulators = {self.type}
return {'FINISHED'}
@@ -50,10 +50,10 @@ class VIEW3D_PIE_manipulator_of(Menu):
layout = self.layout
pie = layout.menu_pie()
- pie.operator("view3d.manipulator_set", icon='MAN_TRANS', text="Translate").type = 'TRANSLATE'
- pie.operator("view3d.manipulator_set", icon='MAN_ROT', text="Rotate").type = 'ROTATE'
- pie.operator("view3d.manipulator_set", icon='MAN_SCALE', text="Scale").type = 'SCALE'
- pie.prop(context.space_data, "show_manipulator")
+ pie.operator("wm.tool_set_by_name", icon='MAN_TRANS', text="Translate").name = "Move"
+ pie.operator("wm.tool_set_by_name", icon='MAN_ROT', text="Rotate").name = "Rotate"
+ pie.operator("wm.tool_set_by_name", icon='MAN_SCALE', text="Scale").name = "Scale"
+ pie.prop(context.space_data, "show_gizmo")
classes = (
diff --git a/pie_menus_official/pie_pivot_of.py b/pie_menus_official/pie_pivot_of.py
index 88677b69..ec48d359 100644
--- a/pie_menus_official/pie_pivot_of.py
+++ b/pie_menus_official/pie_pivot_of.py
@@ -24,9 +24,9 @@ class VIEW3D_PIE_pivot_of(Menu):
layout = self.layout
pie = layout.menu_pie()
- pie.prop(context.space_data, "pivot_point", expand=True)
+ pie.prop(context.scene.tool_settings, "transform_pivot_point", expand=True)
if context.active_object and context.active_object.mode == 'OBJECT':
- pie.prop(context.space_data, "use_pivot_point_align", text="Center Points")
+ pie.prop(context.scene.tool_settings, "use_transform_pivot_point_align", text="Center Points")
classes = (
diff --git a/pie_menus_official/pie_view_of.py b/pie_menus_official/pie_view_of.py
index 40b79217..1c1f3df2 100644
--- a/pie_menus_official/pie_view_of.py
+++ b/pie_menus_official/pie_view_of.py
@@ -38,7 +38,7 @@ class VIEW3D_PIE_view_of(Menu):
layout = self.layout
pie = layout.menu_pie()
- pie.operator_enum("VIEW3D_OT_viewnumpad", "type")
+ pie.operator_enum("VIEW3D_OT_view_axis", "type")
pie.operator("wm.call_menu_pie", text="More", icon='PLUS').name = "VIEW3D_PIE_view_more_of"
diff --git a/render_povray/__init__.py b/render_povray/__init__.py
index a8b07887..9d7254ea 100644
--- a/render_povray/__init__.py
+++ b/render_povray/__init__.py
@@ -2274,11 +2274,11 @@ class PovrayPreferences(AddonPreferences):
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.VIEW3D_MT_add.prepend(ui.menu_func_add)
+ bpy.types.TOPBAR_MT_file_import.append(ui.menu_func_import)
bpy.types.TEXT_MT_templates.append(ui.menu_func_templates)
bpy.types.RENDER_PT_povray_radiosity.prepend(ui.rad_panel_func)
- bpy.types.LAMP_PT_POV_lamp.prepend(ui.lamp_panel_func)
+ bpy.types.LIGHT_PT_POV_light.prepend(ui.light_panel_func)
bpy.types.WORLD_PT_world.prepend(ui.world_panel_func)
# was used for parametric objects but made the other addon unreachable on
# unregister for other tools to use created a user action call instead
@@ -2312,11 +2312,11 @@ 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.WORLD_PT_world.remove(ui.world_panel_func)
- bpy.types.LAMP_PT_POV_lamp.remove(ui.lamp_panel_func)
+ bpy.types.LIGHT_PT_POV_light.remove(ui.light_panel_func)
bpy.types.RENDER_PT_povray_radiosity.remove(ui.rad_panel_func)
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.types.TOPBAR_MT_file_import.remove(ui.menu_func_import)
+ bpy.types.VIEW3D_MT_add.remove(ui.menu_func_add)
bpy.utils.unregister_module(__name__)
diff --git a/render_povray/nodes.py b/render_povray/nodes.py
index a4acd138..a8281c8a 100644
--- a/render_povray/nodes.py
+++ b/render_povray/nodes.py
@@ -52,7 +52,7 @@ class ObjectNodeTree(bpy.types.NodeTree):
@classmethod
def get_from_context(cls, context):
ob = context.active_object
- if ob and ob.type not in {'LAMP'}:
+ if ob and ob.type not in {'LIGHT'}:
ma = ob.active_material
if ma is not None:
nt_name = ma.node_tree
@@ -517,7 +517,7 @@ class PovrayColorImageNode(Node, ObjectNodeTree):
im=image
split = column.split(percentage=0.8,align=True)
split.prop_search(self,"image",context.blend_data,"images",text="")
- split.operator("pov.imageopen",text="",icon="FILESEL")
+ split.operator("pov.imageopen",text="",icon="FILEBROWSER")
if im is not None:
column.prop(im,"source",text="")
column.prop(self,"map_type",text="")
@@ -535,7 +535,7 @@ class PovrayColorImageNode(Node, ObjectNodeTree):
im=image
split = column.split(percentage=0.8,align=True)
split.prop_search(self,"image",context.blend_data,"images",text="")
- split.operator("pov.imageopen",text="",icon="FILESEL")
+ split.operator("pov.imageopen",text="",icon="FILEBROWSER")
if im is not None:
column.prop(im,"source",text="")
column.prop(self,"map_type",text="")
@@ -597,7 +597,7 @@ class PovrayBumpMapNode(Node, ObjectNodeTree):
im=image
split = column.split(percentage=0.8,align=True)
split.prop_search(self,"image",context.blend_data,"images",text="")
- split.operator("pov.imageopen",text="",icon="FILESEL")
+ split.operator("pov.imageopen",text="",icon="FILEBROWSER")
if im is not None:
column.prop(im,"source",text="")
column.prop(self,"map_type",text="")
@@ -613,7 +613,7 @@ class PovrayBumpMapNode(Node, ObjectNodeTree):
im=image
split = column.split(percentage=0.8,align=True)
split.prop_search(self,"image",context.blend_data,"images",text="")
- split.operator("pov.imageopen",text="",icon="FILESEL")
+ split.operator("pov.imageopen",text="",icon="FILEBROWSER")
if im is not None:
column.prop(im,"source",text="")
column.prop(self,"map_type",text="")
@@ -668,7 +668,7 @@ class PovrayImagePatternNode(Node, ObjectNodeTree):
im=image
split = column.split(percentage=0.8,align=True)
split.prop_search(self,"image",context.blend_data,"images",text="")
- split.operator("pov.imageopen",text="",icon="FILESEL")
+ split.operator("pov.imageopen",text="",icon="FILEBROWSER")
if im is not None:
column.prop(im,"source",text="")
column.prop(self,"map_type",text="")
@@ -687,7 +687,7 @@ class PovrayImagePatternNode(Node, ObjectNodeTree):
im=image
split = column.split(percentage=0.8,align=True)
split.prop_search(self,"image",context.blend_data,"images",text="")
- split.operator("pov.imageopen",text="",icon="FILESEL")
+ split.operator("pov.imageopen",text="",icon="FILEBROWSER")
if im is not None:
column.prop(im,"source",text="")
column.prop(self,"map_type",text="")
diff --git a/render_povray/primitives.py b/render_povray/primitives.py
index d7dfe663..1ae43c1a 100644
--- a/render_povray/primitives.py
+++ b/render_povray/primitives.py
@@ -1052,7 +1052,7 @@ class POVRAY_OT_rainbow_add(bpy.types.Operator):
def execute(self,context):
cam = context.scene.camera
- bpy.ops.object.lamp_add(type='SPOT', radius=1)
+ bpy.ops.object.light_add(type='SPOT', radius=1)
ob = context.object
ob.data.show_cone = False
ob.data.spot_blend = 0.5
diff --git a/render_povray/render.py b/render_povray/render.py
index 26352b2d..227a588c 100644
--- a/render_povray/render.py
+++ b/render_povray/render.py
@@ -2067,7 +2067,7 @@ def write_pov(filename, scene=None, info_callback=None):
# XXX I moved all those checks here, as there is no need to compute names
# for object we won't export here!
- if (ob.type in {'LAMP', 'CAMERA', #'EMPTY', #empties can bear dupligroups
+ if (ob.type in {'LIGHT', 'CAMERA', #'EMPTY', #empties can bear dupligroups
'META', 'ARMATURE', 'LATTICE'}):
continue
smokeFlag=False
@@ -2111,7 +2111,7 @@ def write_pov(filename, scene=None, info_callback=None):
strandShape = 0.0
# Set the number of particles to render count rather than 3d view display
pSys.set_resolution(scene, ob, 'RENDER')
- steps = pSys.settings.draw_step
+ steps = pSys.settings.display_step
steps = 3 ** steps # or (power of 2 rather than 3) + 1 # Formerly : len(particle.hair_keys)
totalNumberOfHairs = ( len(pSys.particles) + len(pSys.child_particles) )
@@ -2163,7 +2163,7 @@ def write_pov(filename, scene=None, info_callback=None):
elif step == 0:
hDiameter = strandStart
else:
- hDiameter += (strandEnd-strandStart)/(pSys.settings.draw_step+1) #XXX +1 or not?
+ hDiameter += (strandEnd-strandStart)/(pSys.settings.display_step+1) #XXX +1 or not?
if step == 0 and pSys.settings.use_hair_bspline:
# Write three times the first point to compensate pov Bezier handling
file.write('<%.6g,%.6g,%.6g>,%.7g,\n' % (co[0], co[1], co[2], abs(hDiameter)))
@@ -2689,7 +2689,7 @@ def write_pov(filename, scene=None, info_callback=None):
importance = ob.pov.importance_value
if me:
me_materials = me.materials
- me_faces = me.tessfaces[:]
+ me_faces = me.loop_triangles[:]
#if len(me_faces)==0:
#tabWrite("\n//dummy sphere to represent empty mesh location\n")
#tabWrite("#declare %s =sphere {<0, 0, 0>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n" % povdataname)
@@ -2700,16 +2700,16 @@ def write_pov(filename, scene=None, info_callback=None):
tabWrite("#declare %s =sphere {<0, 0, 0>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n" % povdataname)
continue
- uv_textures = me.tessface_uv_textures
- if len(uv_textures) > 0:
- if me.uv_textures.active and uv_textures.active.data:
- uv_layer = uv_textures.active.data
+ uv_layers = me.uv_layers
+ if len(uv_layers) > 0:
+ if me.uv_layers.active and uv_layers.active.data:
+ uv_layer = uv_layers.active.data
else:
uv_layer = None
try:
#vcol_layer = me.vertex_colors.active.data
- vcol_layer = me.tessface_vertex_colors.active.data
+ vcol_layer = me.vertex_colors.active.data
except AttributeError:
vcol_layer = None
@@ -2717,9 +2717,6 @@ def write_pov(filename, scene=None, info_callback=None):
faces_normals = [f.normal[:] for f in me_faces]
verts_normals = [v.normal[:] for v in me.vertices]
- # quads incur an extra face
- quadCount = sum(1 for f in faces_verts if len(f) == 4)
-
# Use named declaration to allow reference e.g. for baking. MR
file.write("\n")
tabWrite("#declare %s =\n" % povdataname)
@@ -2775,12 +2772,8 @@ def write_pov(filename, scene=None, info_callback=None):
# Generate unique UV's
uniqueUVs = {}
#n = 0
- for fi, uv in enumerate(uv_layer):
-
- if len(faces_verts[fi]) == 4:
- uvs = uv_layer[fi].uv[0], uv_layer[fi].uv[1], uv_layer[fi].uv[2], uv_layer[fi].uv[3]
- else:
- uvs = uv_layer[fi].uv[0], uv_layer[fi].uv[1], uv_layer[fi].uv[2]
+ for f in me.faces:
+ uvs = [uv_layer[l].uv[:] for l in f.loops]
for uv in uvs:
uniqueUVs[uv[:]] = [-1]
@@ -2811,7 +2804,7 @@ def write_pov(filename, scene=None, info_callback=None):
if me.vertex_colors:
#Write down vertex colors as a texture for each vertex
tabWrite("texture_list {\n")
- tabWrite("%d\n" % (((len(me_faces)-quadCount) * 3 )+ quadCount * 4)) # works only with tris and quad mesh for now
+ tabWrite("%d\n" % (len(me_faces) * 3)) # assumes we have only triangles
VcolIdx=0
if comments:
file.write("\n //Vertex colors: one simple pigment texture per vertex\n")
@@ -2824,12 +2817,7 @@ def write_pov(filename, scene=None, info_callback=None):
material = None
if material: #and material.use_vertex_color_paint: #Always use vertex color when there is some for now
- col = vcol_layer[fi]
-
- if len(faces_verts[fi]) == 4:
- cols = col.color1, col.color2, col.color3, col.color4
- else:
- cols = col.color1, col.color2, col.color3
+ cols = [vcol_layer[l].color[:] for l in f.loops]
for col in cols:
key = col[0], col[1], col[2], material_index # Material index!
@@ -2857,135 +2845,107 @@ def write_pov(filename, scene=None, info_callback=None):
tabWrite("\n}\n")
# Face indices
tabWrite("\nface_indices {\n")
- tabWrite("%d" % (len(me_faces) + quadCount)) # faces count
+ tabWrite("%d" % (len(me_faces))) # faces count
tabStr = tab * tabLevel
for fi, f in enumerate(me_faces):
fv = faces_verts[fi]
material_index = f.material_index
- if len(fv) == 4:
- indices = (0, 1, 2), (0, 2, 3)
- else:
- indices = ((0, 1, 2),)
if vcol_layer:
- col = vcol_layer[fi]
-
- if len(fv) == 4:
- cols = col.color1, col.color2, col.color3, col.color4
- else:
- cols = col.color1, col.color2, col.color3
+ cols = [vcol_layer[l].color[:] for l in f.loops]
if not me_materials or me_materials[material_index] is None: # No materials
- for i1, i2, i3 in indices:
- if linebreaksinlists:
- file.write(",\n")
- # vert count
- file.write(tabStr + "<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3]))
- else:
- file.write(", ")
- file.write("<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3])) # vert count
+ if linebreaksinlists:
+ file.write(",\n")
+ # vert count
+ file.write(tabStr + "<%d,%d,%d>" % (fv[0], fv[1], fv[2]))
+ else:
+ file.write(", ")
+ file.write("<%d,%d,%d>" % (fv[0], fv[1], fv[2])) # vert count
else:
material = me_materials[material_index]
- for i1, i2, i3 in indices:
- if me.vertex_colors: #and material.use_vertex_color_paint:
- # Color per vertex - vertex color
+ if me.vertex_colors: #and material.use_vertex_color_paint:
+ # Color per vertex - vertex color
- col1 = cols[i1]
- col2 = cols[i2]
- col3 = cols[i3]
+ col1 = cols[0]
+ col2 = cols[1]
+ col3 = cols[2]
- ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0]
- ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0]
- ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0]
- else:
- # Color per material - flat material color
- if material.subsurface_scattering.use:
- diffuse_color = [i * j for i, j in zip(material.subsurface_scattering.color[:], material.diffuse_color[:])]
- else:
- diffuse_color = material.diffuse_color[:]
- ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], \
- diffuse_color[2], f.material_index][0]
- # ci are zero based index so we'll subtract 1 from them
- if linebreaksinlists:
- file.write(",\n")
- file.write(tabStr + "<%d,%d,%d>, %d,%d,%d" % \
- (fv[i1], fv[i2], fv[i3], ci1-1, ci2-1, ci3-1)) # vert count
+ ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0]
+ ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0]
+ ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0]
+ else:
+ # Color per material - flat material color
+ if material.subsurface_scattering.use:
+ diffuse_color = [i * j for i, j in zip(material.subsurface_scattering.color[:], material.diffuse_color[:])]
else:
- file.write(", ")
- file.write("<%d,%d,%d>, %d,%d,%d" % \
- (fv[i1], fv[i2], fv[i3], ci1-1, ci2-1, ci3-1)) # vert count
+ diffuse_color = material.diffuse_color[:]
+ ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], \
+ diffuse_color[2], f.material_index][0]
+ # ci are zero based index so we'll subtract 1 from them
+ if linebreaksinlists:
+ file.write(",\n")
+ file.write(tabStr + "<%d,%d,%d>, %d,%d,%d" % \
+ (fv[0], fv[1], fv[2], ci1-1, ci2-1, ci3-1)) # vert count
+ else:
+ file.write(", ")
+ file.write("<%d,%d,%d>, %d,%d,%d" % \
+ (fv[0], fv[1], fv[2], ci1-1, ci2-1, ci3-1)) # vert count
file.write("\n")
tabWrite("}\n")
# normal_indices indices
tabWrite("normal_indices {\n")
- tabWrite("%d" % (len(me_faces) + quadCount)) # faces count
+ tabWrite("%d" % (len(me_faces))) # faces count
tabStr = tab * tabLevel
for fi, fv in enumerate(faces_verts):
- if len(fv) == 4:
- indices = (0, 1, 2), (0, 2, 3)
+ if me_faces[fi].use_smooth:
+ if linebreaksinlists:
+ file.write(",\n")
+ file.write(tabStr + "<%d,%d,%d>" %\
+ (uniqueNormals[verts_normals[fv[0]]][0],\
+ uniqueNormals[verts_normals[fv[1]]][0],\
+ uniqueNormals[verts_normals[fv[2]]][0])) # vert count
+ else:
+ file.write(", ")
+ file.write("<%d,%d,%d>" %\
+ (uniqueNormals[verts_normals[fv[0]]][0],\
+ uniqueNormals[verts_normals[fv[1]]][0],\
+ uniqueNormals[verts_normals[fv[2]]][0])) # vert count
else:
- indices = ((0, 1, 2),)
-
- for i1, i2, i3 in indices:
- if me_faces[fi].use_smooth:
- if linebreaksinlists:
- file.write(",\n")
- file.write(tabStr + "<%d,%d,%d>" %\
- (uniqueNormals[verts_normals[fv[i1]]][0],\
- uniqueNormals[verts_normals[fv[i2]]][0],\
- uniqueNormals[verts_normals[fv[i3]]][0])) # vert count
- else:
- file.write(", ")
- file.write("<%d,%d,%d>" %\
- (uniqueNormals[verts_normals[fv[i1]]][0],\
- uniqueNormals[verts_normals[fv[i2]]][0],\
- uniqueNormals[verts_normals[fv[i3]]][0])) # vert count
+ idx = uniqueNormals[faces_normals[fi]][0]
+ if linebreaksinlists:
+ file.write(",\n")
+ file.write(tabStr + "<%d,%d,%d>" % (idx, idx, idx)) # vert count
else:
- idx = uniqueNormals[faces_normals[fi]][0]
- if linebreaksinlists:
- file.write(",\n")
- file.write(tabStr + "<%d,%d,%d>" % (idx, idx, idx)) # vert count
- else:
- file.write(", ")
- file.write("<%d,%d,%d>" % (idx, idx, idx)) # vert count
+ file.write(", ")
+ file.write("<%d,%d,%d>" % (idx, idx, idx)) # vert count
file.write("\n")
tabWrite("}\n")
if uv_layer:
tabWrite("uv_indices {\n")
- tabWrite("%d" % (len(me_faces) + quadCount)) # faces count
+ tabWrite("%d" % (len(me_faces))) # faces count
tabStr = tab * tabLevel
- for fi, fv in enumerate(faces_verts):
-
- if len(fv) == 4:
- indices = (0, 1, 2), (0, 2, 3)
- else:
- indices = ((0, 1, 2),)
-
- uv = uv_layer[fi]
- if len(faces_verts[fi]) == 4:
- uvs = uv.uv[0][:], uv.uv[1][:], uv.uv[2][:], uv.uv[3][:]
+ for f in me_faces:
+ uvs = [uv_layer[l].uv[:] for l in f.loops]
+
+ if linebreaksinlists:
+ file.write(",\n")
+ file.write(tabStr + "<%d,%d,%d>" % (
+ uniqueUVs[uvs[0]][0],\
+ uniqueUVs[uvs[1]][0],\
+ uniqueUVs[uvs[2]][0]))
else:
- uvs = uv.uv[0][:], uv.uv[1][:], uv.uv[2][:]
-
- for i1, i2, i3 in indices:
- if linebreaksinlists:
- file.write(",\n")
- file.write(tabStr + "<%d,%d,%d>" % (
- uniqueUVs[uvs[i1]][0],\
- uniqueUVs[uvs[i2]][0],\
- uniqueUVs[uvs[i3]][0]))
- else:
- file.write(", ")
- file.write("<%d,%d,%d>" % (
- uniqueUVs[uvs[i1]][0],\
- uniqueUVs[uvs[i2]][0],\
- uniqueUVs[uvs[i3]][0]))
+ file.write(", ")
+ file.write("<%d,%d,%d>" % (
+ uniqueUVs[uvs[0]][0],\
+ uniqueUVs[uvs[1]][0],\
+ uniqueUVs[uvs[2]][0]))
file.write("\n")
tabWrite("}\n")
@@ -3108,140 +3068,111 @@ def write_pov(filename, scene=None, info_callback=None):
# Face indices
tabWrite("face_indices {\n")
- tabWrite("%d" % (len(me_faces) + quadCount)) # faces count
+ tabWrite("%d" % (len(me_faces))) # faces count
tabStr = tab * tabLevel
for fi, f in enumerate(me_faces):
fv = faces_verts[fi]
material_index = f.material_index
- if len(fv) == 4:
- indices = (0, 1, 2), (0, 2, 3)
- else:
- indices = ((0, 1, 2),)
if vcol_layer:
- col = vcol_layer[fi]
-
- if len(fv) == 4:
- cols = col.color1, col.color2, col.color3, col.color4
- else:
- cols = col.color1, col.color2, col.color3
+ cols = [vcol_layer[l].color[:] for l in f.loops]
if not me_materials or me_materials[material_index] is None: # No materials
- for i1, i2, i3 in indices:
- if linebreaksinlists:
- file.write(",\n")
- # vert count
- file.write(tabStr + "<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3]))
- else:
- file.write(", ")
- file.write("<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3])) # vert count
+ if linebreaksinlists:
+ file.write(",\n")
+ # vert count
+ file.write(tabStr + "<%d,%d,%d>" % (fv[0], fv[1], fv[2]))
+ else:
+ file.write(", ")
+ file.write("<%d,%d,%d>" % (fv[0], fv[1], fv[2])) # vert count
else:
material = me_materials[material_index]
- for i1, i2, i3 in indices:
- ci1 = ci2 = ci3 = f.material_index
- if me.vertex_colors: #and material.use_vertex_color_paint:
- # Color per vertex - vertex color
-
- col1 = cols[i1]
- col2 = cols[i2]
- col3 = cols[i3]
-
- ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0]
- ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0]
- ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0]
- elif material.pov.material_use_nodes:
- ci1 = ci2 = ci3 = 0
+ ci1 = ci2 = ci3 = f.material_index
+ if me.vertex_colors: #and material.use_vertex_color_paint:
+ # Color per vertex - vertex color
+
+ col1 = cols[0]
+ col2 = cols[1]
+ col3 = cols[2]
+
+ ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0]
+ ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0]
+ ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0]
+ elif material.pov.material_use_nodes:
+ ci1 = ci2 = ci3 = 0
+ else:
+ # Color per material - flat material color
+ if material.subsurface_scattering.use:
+ diffuse_color = [i * j for i, j in
+ zip(material.subsurface_scattering.color[:],
+ material.diffuse_color[:])]
else:
- # Color per material - flat material color
- if material.subsurface_scattering.use:
- diffuse_color = [i * j for i, j in
- zip(material.subsurface_scattering.color[:],
- material.diffuse_color[:])]
- else:
- diffuse_color = material.diffuse_color[:]
- ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], \
- diffuse_color[2], f.material_index][0]
+ diffuse_color = material.diffuse_color[:]
+ ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], \
+ diffuse_color[2], f.material_index][0]
- if linebreaksinlists:
- file.write(",\n")
- file.write(tabStr + "<%d,%d,%d>, %d,%d,%d" % \
- (fv[i1], fv[i2], fv[i3], ci1, ci2, ci3)) # vert count
- else:
- file.write(", ")
- file.write("<%d,%d,%d>, %d,%d,%d" % \
- (fv[i1], fv[i2], fv[i3], ci1, ci2, ci3)) # vert count
+ if linebreaksinlists:
+ file.write(",\n")
+ file.write(tabStr + "<%d,%d,%d>, %d,%d,%d" % \
+ (fv[0], fv[1], fv[2], ci1, ci2, ci3)) # vert count
+ else:
+ file.write(", ")
+ file.write("<%d,%d,%d>, %d,%d,%d" % \
+ (fv[0], fv[1], fv[2], ci1, ci2, ci3)) # vert count
file.write("\n")
tabWrite("}\n")
# normal_indices indices
tabWrite("normal_indices {\n")
- tabWrite("%d" % (len(me_faces) + quadCount)) # faces count
+ tabWrite("%d" % (len(me_faces))) # faces count
tabStr = tab * tabLevel
for fi, fv in enumerate(faces_verts):
-
- if len(fv) == 4:
- indices = (0, 1, 2), (0, 2, 3)
+ if me_faces[fi].use_smooth:
+ if linebreaksinlists:
+ file.write(",\n")
+ file.write(tabStr + "<%d,%d,%d>" %\
+ (uniqueNormals[verts_normals[fv[0]]][0],\
+ uniqueNormals[verts_normals[fv[1]]][0],\
+ uniqueNormals[verts_normals[fv[2]]][0])) # vert count
+ else:
+ file.write(", ")
+ file.write("<%d,%d,%d>" %\
+ (uniqueNormals[verts_normals[fv[0]]][0],\
+ uniqueNormals[verts_normals[fv[1]]][0],\
+ uniqueNormals[verts_normals[fv[2]]][0])) # vert count
else:
- indices = ((0, 1, 2),)
-
- for i1, i2, i3 in indices:
- if me_faces[fi].use_smooth:
- if linebreaksinlists:
- file.write(",\n")
- file.write(tabStr + "<%d,%d,%d>" %\
- (uniqueNormals[verts_normals[fv[i1]]][0],\
- uniqueNormals[verts_normals[fv[i2]]][0],\
- uniqueNormals[verts_normals[fv[i3]]][0])) # vert count
- else:
- file.write(", ")
- file.write("<%d,%d,%d>" %\
- (uniqueNormals[verts_normals[fv[i1]]][0],\
- uniqueNormals[verts_normals[fv[i2]]][0],\
- uniqueNormals[verts_normals[fv[i3]]][0])) # vert count
+ idx = uniqueNormals[faces_normals[fi]][0]
+ if linebreaksinlists:
+ file.write(",\n")
+ file.write(tabStr + "<%d,%d,%d>" % (idx, idx, idx)) # vertcount
else:
- idx = uniqueNormals[faces_normals[fi]][0]
- if linebreaksinlists:
- file.write(",\n")
- file.write(tabStr + "<%d,%d,%d>" % (idx, idx, idx)) # vertcount
- else:
- file.write(", ")
- file.write("<%d,%d,%d>" % (idx, idx, idx)) # vert count
+ file.write(", ")
+ file.write("<%d,%d,%d>" % (idx, idx, idx)) # vert count
file.write("\n")
tabWrite("}\n")
if uv_layer:
tabWrite("uv_indices {\n")
- tabWrite("%d" % (len(me_faces) + quadCount)) # faces count
+ tabWrite("%d" % (len(me_faces))) # faces count
tabStr = tab * tabLevel
- for fi, fv in enumerate(faces_verts):
-
- if len(fv) == 4:
- indices = (0, 1, 2), (0, 2, 3)
- else:
- indices = ((0, 1, 2),)
-
- uv = uv_layer[fi]
- if len(faces_verts[fi]) == 4:
- uvs = uv.uv[0][:], uv.uv[1][:], uv.uv[2][:], uv.uv[3][:]
+ for f in me_faces:
+ uvs = [uv_layer[l].uv[:] for l in f.loops]
+
+ if linebreaksinlists:
+ file.write(",\n")
+ file.write(tabStr + "<%d,%d,%d>" % (
+ uniqueUVs[uvs[0]][0],\
+ uniqueUVs[uvs[1]][0],\
+ uniqueUVs[uvs[2]][0]))
else:
- uvs = uv.uv[0][:], uv.uv[1][:], uv.uv[2][:]
-
- for i1, i2, i3 in indices:
- if linebreaksinlists:
- file.write(",\n")
- file.write(tabStr + "<%d,%d,%d>" % (
- uniqueUVs[uvs[i1]][0],\
- uniqueUVs[uvs[i2]][0],\
- uniqueUVs[uvs[i3]][0]))
- else:
- file.write(", ")
- file.write("<%d,%d,%d>" % (
- uniqueUVs[uvs[i1]][0],\
- uniqueUVs[uvs[i2]][0],\
- uniqueUVs[uvs[i3]][0]))
+ file.write(", ")
+ file.write("<%d,%d,%d>" % (
+ uniqueUVs[uvs[0]][0],\
+ uniqueUVs[uvs[1]][0],\
+ uniqueUVs[uvs[2]][0]))
file.write("\n")
tabWrite("}\n")
@@ -3666,11 +3597,11 @@ def write_pov(filename, scene=None, info_callback=None):
csg = True
sel = renderable_objects(scene)
- exportLamps([L for L in sel if (L.type == 'LAMP' and L.pov.object_as != 'RAINBOW')])
+ exportLamps([L for L in sel if (L.type == 'LIGHT' and L.pov.object_as != 'RAINBOW')])
if comments:
file.write("\n//--Rainbows--\n\n")
- exportRainbows([L for L in sel if (L.type == 'LAMP' and L.pov.object_as == 'RAINBOW')])
+ exportRainbows([L for L in sel if (L.type == 'LIGHT' and L.pov.object_as == 'RAINBOW')])
if comments:
diff --git a/render_povray/ui.py b/render_povray/ui.py
index 34123794..1d5a621f 100644
--- a/render_povray/ui.py
+++ b/render_povray/ui.py
@@ -214,15 +214,12 @@ del properties_data_modifier
from bl_ui import properties_material
for member in dir(properties_material):
subclass = getattr(properties_material, member)
- if subclass not in (properties_material.MATERIAL_PT_transp_game,
- properties_material.MATERIAL_PT_game_settings,
- properties_material.MATERIAL_PT_physics):
- try:
- #mat=context.material
- #if mat and mat.type == "SURFACE" and (engine in cls.COMPAT_ENGINES) and not (mat.pov.material_use_nodes or mat.use_nodes):
- subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
- except:
- pass
+ try:
+ #mat=context.material
+ #if mat and mat.type == "SURFACE" and (engine in cls.COMPAT_ENGINES) and not (mat.pov.material_use_nodes or mat.use_nodes):
+ subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
+ except:
+ pass
del properties_material
@@ -294,7 +291,7 @@ class RenderButtonsPanel():
@classmethod
def poll(cls, context):
rd = context.scene.render
- return (rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES)
+ return (rd.engine in cls.COMPAT_ENGINES)
class ModifierButtonsPanel():
bl_space_type = 'PROPERTIES'
@@ -306,7 +303,7 @@ class ModifierButtonsPanel():
def poll(cls, context):
mods = context.object.modifiers
rd = context.scene.render
- return mods and (rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES)
+ return mods and (rd.engine in cls.COMPAT_ENGINES)
class MaterialButtonsPanel():
bl_space_type = 'PROPERTIES'
@@ -318,7 +315,7 @@ class MaterialButtonsPanel():
def poll(cls, context):
mat = context.material
rd = context.scene.render
- return mat and (rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES)
+ return mat (rd.engine in cls.COMPAT_ENGINES)
class TextureButtonsPanel():
@@ -331,7 +328,7 @@ class TextureButtonsPanel():
def poll(cls, context):
tex = context.texture
rd = context.scene.render
- return tex and (rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES)
+ return tex and (rd.engine in cls.COMPAT_ENGINES)
# class TextureTypePanel(TextureButtonsPanel):
@@ -352,7 +349,7 @@ class ObjectButtonsPanel():
def poll(cls, context):
obj = context.object
rd = context.scene.render
- return obj and (rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES)
+ return obj and (rd.engine in cls.COMPAT_ENGINES)
class CameraDataButtonsPanel():
bl_space_type = 'PROPERTIES'
@@ -364,7 +361,7 @@ class CameraDataButtonsPanel():
def poll(cls, context):
cam = context.camera
rd = context.scene.render
- return cam and (rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES)
+ return cam and (rd.engine in cls.COMPAT_ENGINES)
class WorldButtonsPanel():
bl_space_type = 'PROPERTIES'
@@ -376,7 +373,7 @@ class WorldButtonsPanel():
def poll(cls, context):
wld = context.world
rd = context.scene.render
- return wld and (rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES)
+ return wld and (rd.engine in cls.COMPAT_ENGINES)
class TextButtonsPanel():
bl_space_type = 'TEXT_EDITOR'
@@ -388,7 +385,7 @@ class TextButtonsPanel():
def poll(cls, context):
text = context.space_data
rd = context.scene.render
- return text and (rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES)
+ return text and (rd.engine in cls.COMPAT_ENGINES)
from bl_ui import properties_data_mesh
# These panels are kept
@@ -464,25 +461,25 @@ del properties_data_mesh
################################################################################
-# from bl_ui import properties_data_lamp
-# for member in dir(properties_data_lamp):
- # subclass = getattr(properties_data_lamp, member)
+# from bl_ui import properties_data_light
+# for member in dir(properties_data_light):
+ # subclass = getattr(properties_data_light, member)
# try:
# subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
# except:
# pass
-# del properties_data_lamp
-#########################LAMPS################################
+# del properties_data_light
+#########################LIGHTS################################
-from bl_ui import properties_data_lamp
+from bl_ui import properties_data_light
# These panels are kept
-properties_data_lamp.DATA_PT_custom_props_lamp.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_data_lamp.DATA_PT_context_lamp.COMPAT_ENGINES.add('POVRAY_RENDER')
+properties_data_light.DATA_PT_custom_props_light.COMPAT_ENGINES.add('POVRAY_RENDER')
+properties_data_light.DATA_PT_context_light.COMPAT_ENGINES.add('POVRAY_RENDER')
## make some native panels contextual to some object variable
## by recreating custom panels inheriting their properties
-class PovLampButtonsPanel(properties_data_lamp.DataButtonsPanel):
+class PovLampButtonsPanel(properties_data_light.DataButtonsPanel):
COMPAT_ENGINES = {'POVRAY_RENDER'}
POV_OBJECT_TYPES = {'RAINBOW'}
@@ -499,17 +496,17 @@ class PovLampButtonsPanel(properties_data_lamp.DataButtonsPanel):
# Complex py/bpy/rna interactions (with metaclass and all) simply do not allow it to work.
# So we simply have to explicitly copy here the interesting bits. ;)
-class LAMP_PT_POV_preview(PovLampButtonsPanel, bpy.types.Panel):
- bl_label = properties_data_lamp.DATA_PT_preview.bl_label
+class LIGHT_PT_POV_preview(PovLampButtonsPanel, bpy.types.Panel):
+ bl_label = properties_data_light.DATA_PT_preview.bl_label
- draw = properties_data_lamp.DATA_PT_preview.draw
+ draw = properties_data_light.DATA_PT_preview.draw
-class LAMP_PT_POV_lamp(PovLampButtonsPanel, bpy.types.Panel):
- bl_label = properties_data_lamp.DATA_PT_lamp.bl_label
+class LIGHT_PT_POV_light(PovLampButtonsPanel, bpy.types.Panel):
+ bl_label = properties_data_light.DATA_PT_light.bl_label
- draw = properties_data_lamp.DATA_PT_lamp.draw
+ draw = properties_data_light.DATA_PT_light.draw
-class POV_LAMP_MT_presets(bpy.types.Menu):
+class POV_LIGHT_MT_presets(bpy.types.Menu):
bl_label = "Lamp Presets"
preset_subdir = "pov/lamp"
preset_operator = "script.execute_preset"
@@ -518,19 +515,19 @@ class POV_LAMP_MT_presets(bpy.types.Menu):
class AddPresetLamp(AddPresetBase, bpy.types.Operator):
'''Add a Lamp Preset'''
- bl_idname = "object.lamp_preset_add"
+ bl_idname = "object.light_preset_add"
bl_label = "Add Lamp Preset"
- preset_menu = "POV_LAMP_MT_presets"
+ preset_menu = "POV_LIGHT_MT_presets"
# variable used for all preset values
preset_defines = [
- "lampdata = bpy.context.object.data"
+ "lightdata = bpy.context.object.data"
]
# properties to store in the preset
preset_values = [
- "lampdata.type",
- "lampdata.color",
+ "lightdata.type",
+ "lightdata.color",
]
# where to store the preset
@@ -541,68 +538,68 @@ class AddPresetLamp(AddPresetBase, bpy.types.Operator):
# Draw into an existing panel
-def lamp_panel_func(self, context):
+def light_panel_func(self, context):
layout = self.layout
row = layout.row(align=True)
- row.menu(POV_LAMP_MT_presets.__name__, text=POV_LAMP_MT_presets.bl_label)
+ row.menu(POV_LIGHT_MT_presets.__name__, text=POV_LIGHT_MT_presets.bl_label)
row.operator(AddPresetLamp.bl_idname, text="", icon='ZOOMIN')
row.operator(AddPresetLamp.bl_idname, text="", icon='ZOOMOUT').remove_active = True
classes = (
- POV_LAMP_MT_presets,
+ POV_LIGHT_MT_presets,
AddPresetLamp,
)
-class LAMP_PT_POV_sunsky(PovLampButtonsPanel, bpy.types.Panel):
- bl_label = properties_data_lamp.DATA_PT_sunsky.bl_label
+class LIGHT_PT_POV_sunsky(PovLampButtonsPanel, bpy.types.Panel):
+ bl_label = properties_data_light.DATA_PT_sunsky.bl_label
@classmethod
def poll(cls, context):
- lamp = context.lamp
+ lamp = context.light
engine = context.scene.render.engine
return (lamp and lamp.type == 'SUN') and (engine in cls.COMPAT_ENGINES)
- draw = properties_data_lamp.DATA_PT_sunsky.draw
+ draw = properties_data_light.DATA_PT_sunsky.draw
-class LAMP_PT_POV_shadow(PovLampButtonsPanel, bpy.types.Panel):
- bl_label = properties_data_lamp.DATA_PT_shadow.bl_label
+class LIGHT_PT_POV_shadow(PovLampButtonsPanel, bpy.types.Panel):
+ bl_label = properties_data_light.DATA_PT_shadow.bl_label
- draw = properties_data_lamp.DATA_PT_shadow.draw
+ draw = properties_data_light.DATA_PT_shadow.draw
-class LAMP_PT_POV_area(PovLampButtonsPanel, bpy.types.Panel):
- bl_label = properties_data_lamp.DATA_PT_area.bl_label
+class LIGHT_PT_POV_area(PovLampButtonsPanel, bpy.types.Panel):
+ bl_label = properties_data_light.DATA_PT_area.bl_label
@classmethod
def poll(cls, context):
- lamp = context.lamp
+ lamp = context.light
engine = context.scene.render.engine
return (lamp and lamp.type == 'AREA') and (engine in cls.COMPAT_ENGINES)
- draw = properties_data_lamp.DATA_PT_area.draw
+ draw = properties_data_light.DATA_PT_area.draw
-class LAMP_PT_POV_spot(PovLampButtonsPanel, bpy.types.Panel):
- bl_label = properties_data_lamp.DATA_PT_spot.bl_label
+class LIGHT_PT_POV_spot(PovLampButtonsPanel, bpy.types.Panel):
+ bl_label = properties_data_light.DATA_PT_spot.bl_label
@classmethod
def poll(cls, context):
- lamp = context.lamp
+ lamp = context.light
engine = context.scene.render.engine
return (lamp and lamp.type == 'SPOT') and (engine in cls.COMPAT_ENGINES)
- draw = properties_data_lamp.DATA_PT_spot.draw
+ draw = properties_data_light.DATA_PT_spot.draw
-class LAMP_PT_POV_falloff_curve(PovLampButtonsPanel, bpy.types.Panel):
- bl_label = properties_data_lamp.DATA_PT_falloff_curve.bl_label
- bl_options = properties_data_lamp.DATA_PT_falloff_curve.bl_options
+class LIGHT_PT_POV_falloff_curve(PovLampButtonsPanel, bpy.types.Panel):
+ bl_label = properties_data_light.DATA_PT_falloff_curve.bl_label
+ bl_options = properties_data_light.DATA_PT_falloff_curve.bl_options
@classmethod
def poll(cls, context):
- lamp = context.lamp
+ lamp = context.light
engine = context.scene.render.engine
return (lamp and lamp.type in {'POINT', 'SPOT'} and lamp.falloff_type == 'CUSTOM_CURVE') and (engine in cls.COMPAT_ENGINES)
- draw = properties_data_lamp.DATA_PT_falloff_curve.draw
+ draw = properties_data_light.DATA_PT_falloff_curve.draw
class OBJECT_PT_povray_obj_rainbow(PovLampButtonsPanel, bpy.types.Panel):
bl_label = "POV-Ray Rainbow"
@@ -644,7 +641,7 @@ class OBJECT_PT_povray_obj_rainbow(PovLampButtonsPanel, bpy.types.Panel):
col.prop(obj.pov, "arc_angle")
col.prop(obj.pov, "falloff_angle")
-del properties_data_lamp
+del properties_data_light
###############################################################################
class RENDER_PT_povray_export_settings(RenderButtonsPanel, bpy.types.Panel):
diff --git a/rigify/__init__.py b/rigify/__init__.py
index fa93533b..3c0efdfd 100644
--- a/rigify/__init__.py
+++ b/rigify/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Rigify",
"version": (0, 5),
"author": "Nathan Vegdahl, Lucio Rossi, Ivan Cappiello",
- "blender": (2, 78, 0),
+ "blender": (2, 80, 0),
"description": "Automatic rigging from building-block components",
"location": "Armature properties, Bone properties, View3d tools panel, Armature Add menu",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
@@ -44,7 +44,15 @@ import bpy
import sys
import os
from bpy.types import AddonPreferences
-from bpy.props import BoolProperty
+from bpy.props import (
+ BoolProperty,
+ IntProperty,
+ EnumProperty,
+ StringProperty,
+ FloatVectorProperty,
+ PointerProperty,
+ CollectionProperty,
+)
class RigifyPreferences(AddonPreferences):
@@ -118,14 +126,13 @@ class RigifyPreferences(AddonPreferences):
register()
- legacy_mode = BoolProperty(
+ legacy_mode: BoolProperty(
name='Rigify Legacy Mode',
description='Select if you want to use Rigify in legacy mode',
default=False,
update=update_legacy
)
-
- show_expanded = BoolProperty()
+ show_expanded: BoolProperty()
def draw(self, context):
layout = self.layout
@@ -143,71 +150,71 @@ class RigifyPreferences(AddonPreferences):
op = sub.operator('wm.context_toggle', text='', icon=icon,
emboss=False)
op.data_path = 'addon_prefs.show_expanded'
- sub.label('{}: {}'.format('Rigify', 'Enable Legacy Mode'))
+ sub.label(text='{}: {}'.format('Rigify', 'Enable Legacy Mode'))
sub = row.row()
sub.alignment = 'RIGHT'
sub.prop(self, 'legacy_mode')
if expand:
- split = col.row().split(percentage=0.15)
- split.label('Description:')
+ split = col.row().split(factor=0.15)
+ split.label(text='Description:')
split.label(text='When enabled the add-on will run in legacy mode using the old 2.76b feature set.')
row = layout.row()
- row.label("End of Rigify Preferences")
+ row.label(text="End of Rigify Preferences")
class RigifyName(bpy.types.PropertyGroup):
- name = bpy.props.StringProperty()
+ name: StringProperty()
class RigifyColorSet(bpy.types.PropertyGroup):
- name = bpy.props.StringProperty(name="Color Set", default=" ")
- active = bpy.props.FloatVectorProperty(
- name="object_color",
- subtype='COLOR',
- default=(1.0, 1.0, 1.0),
- min=0.0, max=1.0,
- description="color picker"
- )
- normal = bpy.props.FloatVectorProperty(
- name="object_color",
- subtype='COLOR',
- default=(1.0, 1.0, 1.0),
- min=0.0, max=1.0,
- description="color picker"
- )
- select = bpy.props.FloatVectorProperty(
- name="object_color",
- subtype='COLOR',
- default=(1.0, 1.0, 1.0),
- min=0.0, max=1.0,
- description="color picker"
- )
- standard_colors_lock = bpy.props.BoolProperty(default=True)
+ name: StringProperty(name="Color Set", default=" ")
+ active: FloatVectorProperty(
+ name="object_color",
+ subtype='COLOR',
+ default=(1.0, 1.0, 1.0),
+ min=0.0, max=1.0,
+ description="color picker"
+ )
+ normal: FloatVectorProperty(
+ name="object_color",
+ subtype='COLOR',
+ default=(1.0, 1.0, 1.0),
+ min=0.0, max=1.0,
+ description="color picker"
+ )
+ select: FloatVectorProperty(
+ name="object_color",
+ subtype='COLOR',
+ default=(1.0, 1.0, 1.0),
+ min=0.0, max=1.0,
+ description="color picker"
+ )
+ standard_colors_lock: BoolProperty(default=True)
class RigifySelectionColors(bpy.types.PropertyGroup):
- select = bpy.props.FloatVectorProperty(
- name="object_color",
- subtype='COLOR',
- default=(0.314, 0.784, 1.0),
- min=0.0, max=1.0,
- description="color picker"
- )
+ select: FloatVectorProperty(
+ name="object_color",
+ subtype='COLOR',
+ default=(0.314, 0.784, 1.0),
+ min=0.0, max=1.0,
+ description="color picker"
+ )
- active = bpy.props.FloatVectorProperty(
- name="object_color",
- subtype='COLOR',
- default=(0.549, 1.0, 1.0),
- min=0.0, max=1.0,
- description="color picker"
- )
+ active: FloatVectorProperty(
+ name="object_color",
+ subtype='COLOR',
+ default=(0.549, 1.0, 1.0),
+ min=0.0, max=1.0,
+ description="color picker"
+ )
class RigifyParameters(bpy.types.PropertyGroup):
- name = bpy.props.StringProperty()
+ name: StringProperty()
class RigifyArmatureLayer(bpy.types.PropertyGroup):
@@ -225,104 +232,123 @@ class RigifyArmatureLayer(bpy.types.PropertyGroup):
else:
self['group_prop'] = value
- name = bpy.props.StringProperty(name="Layer Name", default=" ")
- row = bpy.props.IntProperty(name="Layer Row", default=1, min=1, max=32, description='UI row for this layer')
- set = bpy.props.BoolProperty(name="Selection Set", default=False, description='Add Selection Set for this layer')
- group = bpy.props.IntProperty(name="Bone Group", default=0, min=0, max=32,
- get=get_group, set=set_group, description='Assign Bone Group to this layer')
+ name: StringProperty(name="Layer Name", default=" ")
+ row: IntProperty(name="Layer Row", default=1, min=1, max=32, description='UI row for this layer')
+ selset: BoolProperty(name="Selection Set", default=False, description='Add Selection Set for this layer')
+ group: IntProperty(name="Bone Group", default=0, min=0, max=32,
+ get=get_group, set=set_group, description='Assign Bone Group to this layer')
+
##### REGISTER #####
+classes = (
+ RigifyName,
+ RigifyParameters,
+ RigifyColorSet,
+ RigifySelectionColors,
+ RigifyArmatureLayer,
+ RigifyPreferences,
+)
+
+
def register():
+ from bpy.utils import register_class
+
+ # Sub-modules.
ui.register()
metarig_menu.register()
- bpy.utils.register_class(RigifyName)
- bpy.utils.register_class(RigifyParameters)
-
- bpy.utils.register_class(RigifyColorSet)
- bpy.utils.register_class(RigifySelectionColors)
- bpy.utils.register_class(RigifyArmatureLayer)
- bpy.utils.register_class(RigifyPreferences)
- bpy.types.Armature.rigify_layers = bpy.props.CollectionProperty(type=RigifyArmatureLayer)
-
- bpy.types.PoseBone.rigify_type = bpy.props.StringProperty(name="Rigify Type", description="Rig type for this bone")
- bpy.types.PoseBone.rigify_parameters = bpy.props.PointerProperty(type=RigifyParameters)
-
- bpy.types.Armature.rigify_colors = bpy.props.CollectionProperty(type=RigifyColorSet)
-
- bpy.types.Armature.rigify_selection_colors = bpy.props.PointerProperty(type=RigifySelectionColors)
-
- bpy.types.Armature.rigify_colors_index = bpy.props.IntProperty(default=-1)
- bpy.types.Armature.rigify_colors_lock = bpy.props.BoolProperty(default=True)
- bpy.types.Armature.rigify_theme_to_add = bpy.props.EnumProperty(items=(('THEME01', 'THEME01', ''),
- ('THEME02', 'THEME02', ''),
- ('THEME03', 'THEME03', ''),
- ('THEME04', 'THEME04', ''),
- ('THEME05', 'THEME05', ''),
- ('THEME06', 'THEME06', ''),
- ('THEME07', 'THEME07', ''),
- ('THEME08', 'THEME08', ''),
- ('THEME09', 'THEME09', ''),
- ('THEME10', 'THEME10', ''),
- ('THEME11', 'THEME11', ''),
- ('THEME12', 'THEME12', ''),
- ('THEME13', 'THEME13', ''),
- ('THEME14', 'THEME14', ''),
- ('THEME15', 'THEME15', ''),
- ('THEME16', 'THEME16', ''),
- ('THEME17', 'THEME17', ''),
- ('THEME18', 'THEME18', ''),
- ('THEME19', 'THEME19', ''),
- ('THEME20', 'THEME20', '')
- ), name='Theme')
+ # Classes.
+ for cls in classes:
+ register_class(cls)
+
+ # Properties.
+ bpy.types.Armature.rigify_layers = CollectionProperty(type=RigifyArmatureLayer)
+
+ bpy.types.PoseBone.rigify_type = StringProperty(name="Rigify Type", description="Rig type for this bone")
+ bpy.types.PoseBone.rigify_parameters = PointerProperty(type=RigifyParameters)
+
+ bpy.types.Armature.rigify_colors = CollectionProperty(type=RigifyColorSet)
+
+ bpy.types.Armature.rigify_selection_colors = PointerProperty(type=RigifySelectionColors)
+
+ bpy.types.Armature.rigify_colors_index = IntProperty(default=-1)
+ bpy.types.Armature.rigify_colors_lock = BoolProperty(default=True)
+ bpy.types.Armature.rigify_theme_to_add = EnumProperty(items=(
+ ('THEME01', 'THEME01', ''),
+ ('THEME02', 'THEME02', ''),
+ ('THEME03', 'THEME03', ''),
+ ('THEME04', 'THEME04', ''),
+ ('THEME05', 'THEME05', ''),
+ ('THEME06', 'THEME06', ''),
+ ('THEME07', 'THEME07', ''),
+ ('THEME08', 'THEME08', ''),
+ ('THEME09', 'THEME09', ''),
+ ('THEME10', 'THEME10', ''),
+ ('THEME11', 'THEME11', ''),
+ ('THEME12', 'THEME12', ''),
+ ('THEME13', 'THEME13', ''),
+ ('THEME14', 'THEME14', ''),
+ ('THEME15', 'THEME15', ''),
+ ('THEME16', 'THEME16', ''),
+ ('THEME17', 'THEME17', ''),
+ ('THEME18', 'THEME18', ''),
+ ('THEME19', 'THEME19', ''),
+ ('THEME20', 'THEME20', '')
+ ), name='Theme')
IDStore = bpy.types.WindowManager
- IDStore.rigify_collection = bpy.props.EnumProperty(items=rig_lists.col_enum_list, default="All",
- name="Rigify Active Collection",
- description="The selected rig collection")
+ IDStore.rigify_collection = EnumProperty(items=rig_lists.col_enum_list, default="All",
+ name="Rigify Active Collection",
+ description="The selected rig collection")
- 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_types = CollectionProperty(type=RigifyName)
+ IDStore.rigify_active_type = 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)
+ IDStore.rigify_advanced_generation = 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="")
-
- IDStore.rigify_transfer_only_selected = bpy.props.BoolProperty(name="Transfer Only Selected", description="Transfer selected bones only", default=True)
- IDStore.rigify_transfer_start_frame = bpy.props.IntProperty(name="Start Frame", description="First Frame to Transfer", default=0, min= 0)
- IDStore.rigify_transfer_end_frame = bpy.props.IntProperty(name="End Frame", description="Last Frame to Transfer", default=0, min= 0)
-
+ IDStore.rigify_generate_mode = 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 = 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 = CollectionProperty(type=RigifyName)
+ IDStore.rigify_target_rig = 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 = CollectionProperty(type=RigifyName)
+ IDStore.rigify_rig_ui = 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 = 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="")
+
+ IDStore.rigify_transfer_only_selected = BoolProperty(
+ name="Transfer Only Selected",
+ description="Transfer selected bones only", default=True)
+ IDStore.rigify_transfer_start_frame = IntProperty(
+ name="Start Frame",
+ description="First Frame to Transfer", default=0, min= 0)
+ IDStore.rigify_transfer_end_frame = IntProperty(
+ name="End Frame",
+ description="Last Frame to Transfer", default=0, min= 0)
+
+ # Update legacy on restart or reload.
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
# Add rig parameters
@@ -335,6 +361,9 @@ def register():
def unregister():
+ from bpy.utils import unregister_class
+
+ # Properties.
del bpy.types.PoseBone.rigify_type
del bpy.types.PoseBone.rigify_parameters
@@ -354,14 +383,10 @@ def unregister():
del IDStore.rigify_transfer_start_frame
del IDStore.rigify_transfer_end_frame
- bpy.utils.unregister_class(RigifyName)
- bpy.utils.unregister_class(RigifyParameters)
-
- bpy.utils.unregister_class(RigifyColorSet)
- bpy.utils.unregister_class(RigifySelectionColors)
-
- bpy.utils.unregister_class(RigifyArmatureLayer)
- bpy.utils.unregister_class(RigifyPreferences)
+ # Classes.
+ for cls in classes:
+ unregister_class(cls)
+ # Sub-modules.
metarig_menu.unregister()
ui.unregister()
diff --git a/rigify/generate.py b/rigify/generate.py
index e2492708..948ece11 100644
--- a/rigify/generate.py
+++ b/rigify/generate.py
@@ -29,6 +29,7 @@ from .utils import MetarigError, new_bone, get_rig_type
from .utils import ORG_PREFIX, MCH_PREFIX, DEF_PREFIX, WGT_PREFIX, ROOT_NAME, make_original_name
from .utils import RIG_DIR
from .utils import create_root_widget
+from .utils import ensure_widget_collection
from .utils import random_id
from .utils import copy_attributes
from .utils import gamma_correct
@@ -40,7 +41,6 @@ ORG_LAYER = [n == 31 for n in range(0, 32)] # Armature layer that original bone
MCH_LAYER = [n == 30 for n in range(0, 32)] # Armature layer that mechanism bones should be moved to.
DEF_LAYER = [n == 29 for n in range(0, 32)] # Armature layer that deformation bones should be moved to.
ROOT_LAYER = [n == 28 for n in range(0, 32)] # Armature layer that root bone should be moved to.
-WGT_LAYERS = [x == 19 for x in range(0, 20)] # Widgets go on the last scene layer.
class Timer:
@@ -72,7 +72,11 @@ def generate_rig(context, metarig):
bpy.ops.object.mode_set(mode='OBJECT')
scene = context.scene
+ view_layer = context.view_layer
+ collection = context.collection
+ layer_collection = context.layer_collection
id_store = context.window_manager
+
#------------------------------------------
# Create/find the rig object and set it up
@@ -96,13 +100,13 @@ def generate_rig(context, metarig):
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)
+ obj.display_type = 'WIRE'
+ collection.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)
+ obj.display_type = 'WIRE'
+ collection.objects.link(obj)
id_store.rigify_target_rig = obj.name
obj.data.pose_position = 'POSE'
@@ -112,23 +116,17 @@ def generate_rig(context, metarig):
obj.animation_data_clear()
# Select generated rig object
- metarig.select = False
- obj.select = True
- scene.objects.active = obj
+ metarig.select_set('DESELECT')
+ obj.select_set('SELECT')
+ view_layer.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
+ wgt.select_set('SELECT')
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
@@ -148,18 +146,18 @@ def generate_rig(context, metarig):
# Create temporary duplicates for merging
temp_rig_1 = metarig.copy()
temp_rig_1.data = metarig.data.copy()
- scene.objects.link(temp_rig_1)
+ collection.objects.link(temp_rig_1)
temp_rig_2 = metarig.copy()
temp_rig_2.data = obj.data
- scene.objects.link(temp_rig_2)
+ collection.objects.link(temp_rig_2)
# Select the temp rigs for merging
for objt in scene.objects:
- objt.select = False # deselect all objects
- temp_rig_1.select = True
- temp_rig_2.select = True
- scene.objects.active = temp_rig_2
+ objt.select_set('DESELECT') # deselect all objects
+ temp_rig_1.select_set('SELECT')
+ temp_rig_2.select_set('SELECT')
+ view_layer.objects.active = temp_rig_2
# Merge the temporary rigs
bpy.ops.object.join()
@@ -169,9 +167,9 @@ def generate_rig(context, metarig):
# Select the generated rig
for objt in scene.objects:
- objt.select = False # deselect all objects
- obj.select = True
- scene.objects.active = obj
+ objt.select_set('DESELECT') # deselect all objects
+ obj.select_set('SELECT')
+ view_layer.objects.active = obj
# Copy over bone properties
for bone in metarig.data.bones:
@@ -303,7 +301,8 @@ def generate_rig(context, metarig):
rna_idprop_ui_prop_get(obj.data, "rig_id", create=True)
obj.data["rig_id"] = rig_id
- t.tick("Create root bone: ")
+ # Create/find widge collection
+ widget_collection = ensure_widget_collection(context)
# Create Group widget
# wgts_group_name = "WGTS"
@@ -313,21 +312,14 @@ def generate_rig(context, metarig):
bpy.data.objects.remove(bpy.data.objects[wgts_group_name])
mesh = bpy.data.meshes.new(wgts_group_name)
wgts_obj = bpy.data.objects.new(wgts_group_name, mesh)
- scene.objects.link(wgts_obj)
- wgts_obj.layers = WGT_LAYERS
+ widget_collection.objects.link(wgts_obj)
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
+ # wgt.select_set('SELECT')
# bpy.ops.object.make_single_user(obdata=True)
- # for i, lyr in enumerate(WGT_LAYERS):
- # if lyr:
- # context.scene.layers[i] = False
#----------------------------------
try:
@@ -343,8 +335,8 @@ def generate_rig(context, metarig):
for rig in rigs:
# Go into editmode in the rig armature
bpy.ops.object.mode_set(mode='OBJECT')
- context.scene.objects.active = obj
- obj.select = True
+ context.view_layer.objects.active = obj
+ obj.select_set('SELECT')
bpy.ops.object.mode_set(mode='EDIT')
scripts = rig.generate()
if scripts is not None:
@@ -511,18 +503,7 @@ def generate_rig(context, metarig):
create_bone_groups(obj, 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 == 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[script.name]
-
+ create_persistent_rig_ui(obj, script)
t.tick("The rest: ")
#----------------------------------
@@ -538,6 +519,11 @@ def generate_rig(context, metarig):
child.parent_bone = sub_parent
child.matrix_world = mat
+ #----------------------------------
+ # Restore active collection
+ view_layer.collections.active = layer_collection
+
+
def create_selection_sets(obj, metarig):
# Check if selection sets addon is installed
@@ -547,13 +533,13 @@ def create_selection_sets(obj, metarig):
bpy.ops.object.mode_set(mode='POSE')
- bpy.context.scene.objects.active = obj
- obj.select = True
- metarig.select = False
+ bpy.context.view_layer.objects.active = obj
+ obj.select_set('SELECT')
+ metarig.select_set('DESELECT')
pbones = obj.pose.bones
for i, name in enumerate(metarig.data.rigify_layers.keys()):
- if name == '' or not metarig.data.rigify_layers[i].set:
+ if name == '' or not metarig.data.rigify_layers[i].selset:
continue
bpy.ops.pose.select_all(action='DESELECT')
@@ -588,7 +574,7 @@ def create_bone_groups(obj, metarig):
g_id = l.group - 1
name = groups[g_id].name
if name not in obj.pose.bone_groups.keys():
- bg = obj.pose.bone_groups.new(name)
+ bg = obj.pose.bone_groups.new(name=name)
bg.color_set = 'CUSTOM'
bg.colors.normal = gamma_correct(groups[g_id].normal)
bg.colors.select = gamma_correct(groups[g_id].select)
@@ -607,6 +593,31 @@ def create_bone_groups(obj, metarig):
b.bone_group = obj.pose.bone_groups[name]
+def create_persistent_rig_ui(obj, script):
+ """Make sure the ui script always follows the rig around"""
+ skip = False
+ driver = None
+
+ for fcurve in obj.animation_data.drivers:
+ if fcurve.data_path == 'pass_index':
+ driver = fcurve.driver
+ for variable in driver.variables:
+ if variable.name == script.name:
+ skip = True
+ break
+ break
+
+ if not skip:
+ if not driver:
+ fcurve = obj.driver_add("pass_index")
+ driver = fcurve.driver
+
+ variable = driver.variables.new()
+ variable.name = script.name
+ variable.targets[0].id_type = 'TEXT'
+ variable.targets[0].id = script
+
+
def get_bone_rigs(obj, bone_name, halt_on_missing=False):
""" Fetch all the rigs specified on a bone.
"""
diff --git a/rigify/legacy/__init__.py b/rigify/legacy/__init__.py
index 6e6f751c..029d877e 100644
--- a/rigify/legacy/__init__.py
+++ b/rigify/legacy/__init__.py
@@ -45,16 +45,16 @@ import bpy
class RigifyName(bpy.types.PropertyGroup):
- name = bpy.props.StringProperty()
+ name: bpy.props.StringProperty()
class RigifyParameters(bpy.types.PropertyGroup):
- name = bpy.props.StringProperty()
+ name: bpy.props.StringProperty()
class RigifyArmatureLayer(bpy.types.PropertyGroup):
- name = bpy.props.StringProperty(name="Layer Name", default=" ")
- row = bpy.props.IntProperty(name="Layer Row", default=1, min=1, max=32)
+ name: bpy.props.StringProperty(name="Layer Name", default=" ")
+ row: bpy.props.IntProperty(name="Layer Row", default=1, min=1, max=32)
##### REGISTER #####
diff --git a/rigify/legacy/generate.py b/rigify/legacy/generate.py
index ec822b9e..9a39e333 100644
--- a/rigify/legacy/generate.py
+++ b/rigify/legacy/generate.py
@@ -28,7 +28,7 @@ from rna_prop_ui import rna_idprop_ui_prop_get
from .utils import MetarigError, new_bone, get_rig_type
from .utils import ORG_PREFIX, MCH_PREFIX, DEF_PREFIX, WGT_PREFIX, ROOT_NAME, make_original_name
from .utils import RIG_DIR
-from .utils import create_root_widget
+from .utils import create_root_widget, ensure_widget_collection
from .utils import random_id
from .utils import copy_attributes
from .rig_ui_template import UI_SLIDERS, layers_ui, UI_REGISTER
@@ -71,6 +71,9 @@ def generate_rig(context, metarig):
bpy.ops.object.mode_set(mode='OBJECT')
scene = context.scene
+ view_layer = context.view_layer
+ collection = scene.collection
+ layer_collection = context.layer_collection
#------------------------------------------
# Create/find the rig object and set it up
@@ -88,8 +91,8 @@ def generate_rig(context, metarig):
obj = scene.objects[name]
except KeyError:
obj = bpy.data.objects.new(name, bpy.data.armatures.new(name))
- obj.draw_type = 'WIRE'
- scene.objects.link(obj)
+ obj.display_type = 'WIRE'
+ collection.objects.link(obj)
obj.data.pose_position = 'POSE'
@@ -98,9 +101,9 @@ def generate_rig(context, metarig):
obj.animation_data_clear()
# Select generated rig object
- metarig.select = False
- obj.select = True
- scene.objects.active = obj
+ metarig.select_set('DESELECT')
+ obj.select_set('SELECT')
+ view_layer.objects.active = obj
# Remove all bones from the generated rig armature.
bpy.ops.object.mode_set(mode='EDIT')
@@ -111,18 +114,18 @@ def generate_rig(context, metarig):
# Create temporary duplicates for merging
temp_rig_1 = metarig.copy()
temp_rig_1.data = metarig.data.copy()
- scene.objects.link(temp_rig_1)
+ collection.objects.link(temp_rig_1)
temp_rig_2 = metarig.copy()
temp_rig_2.data = obj.data
- scene.objects.link(temp_rig_2)
+ collection.objects.link(temp_rig_2)
# Select the temp rigs for merging
for objt in scene.objects:
- objt.select = False # deselect all objects
- temp_rig_1.select = True
- temp_rig_2.select = True
- scene.objects.active = temp_rig_2
+ objt.select_set('DESELECT') # deselect all objects
+ temp_rig_1.select_set('SELECT')
+ temp_rig_2.select_set('SELECT')
+ view_layer.objects.active = temp_rig_2
# Merge the temporary rigs
bpy.ops.object.join()
@@ -132,9 +135,9 @@ def generate_rig(context, metarig):
# Select the generated rig
for objt in scene.objects:
- objt.select = False # deselect all objects
- obj.select = True
- scene.objects.active = obj
+ objt.select_set('DESELECT') # deselect all objects
+ obj.select_set('SELECT')
+ view_layer.objects.active = obj
# Copy over bone properties
for bone in metarig.data.bones:
@@ -277,8 +280,8 @@ def generate_rig(context, metarig):
for rig in rigs:
# Go into editmode in the rig armature
bpy.ops.object.mode_set(mode='OBJECT')
- context.scene.objects.active = obj
- obj.select = True
+ context.view_layer.objects.active = obj
+ obj.select_set('SELECT')
bpy.ops.object.mode_set(mode='EDIT')
scripts = rig.generate()
if scripts is not None:
@@ -353,7 +356,10 @@ def generate_rig(context, metarig):
if obj.data.bones[bone].name.startswith(DEF_PREFIX):
obj.data.bones[bone].layers = DEF_LAYER
- # Create root bone widget
+ # Create/find widge collection
+ ensure_widget_collection(context)
+
+ # Create root bone widget
create_root_widget(obj, "root")
# Assign shapes to bones
@@ -427,6 +433,10 @@ def generate_rig(context, metarig):
metarig.data.pose_position = rest_backup
obj.data.pose_position = 'POSE'
+ #----------------------------------
+ # Restore active collection
+ view_layer.collections.active = layer_collection
+
def get_bone_rigs(obj, bone_name, halt_on_missing=False):
""" Fetch all the rigs specified on a bone.
diff --git a/rigify/legacy/metarig_menu.py b/rigify/legacy/metarig_menu.py
index 4bdf2701..c0c20955 100644
--- a/rigify/legacy/metarig_menu.py
+++ b/rigify/legacy/metarig_menu.py
@@ -114,7 +114,7 @@ def register():
bpy.utils.register_class(mop)
for mf in menu_funcs:
- bpy.types.INFO_MT_armature_add.append(mf)
+ bpy.types.VIEW3D_MT_armature_add.append(mf)
def unregister():
@@ -122,4 +122,4 @@ def unregister():
bpy.utils.unregister_class(mop)
for mf in menu_funcs:
- bpy.types.INFO_MT_armature_add.remove(mf)
+ bpy.types.VIEW3D_MT_armature_add.remove(mf)
diff --git a/rigify/legacy/rigs/basic/copy.py b/rigify/legacy/rigs/basic/copy.py
index 50a25767..65c5ff31 100644
--- a/rigify/legacy/rigs/basic/copy.py
+++ b/rigify/legacy/rigs/basic/copy.py
@@ -88,8 +88,8 @@ def add_parameters(params):
""" Add the parameters of this rig type to the
RigifyParameters PropertyGroup
"""
- params.make_control = bpy.props.BoolProperty(name="Control", default=True, description="Create a control bone for the copy")
- params.make_deform = bpy.props.BoolProperty(name="Deform", default=True, description="Create a deform bone for the copy")
+ params.make_control: bpy.props.BoolProperty(name="Control", default=True, description="Create a control bone for the copy")
+ params.make_deform: bpy.props.BoolProperty(name="Deform", default=True, description="Create a deform bone for the copy")
def parameters_ui(layout, params):
diff --git a/rigify/legacy/rigs/basic/copy_chain.py b/rigify/legacy/rigs/basic/copy_chain.py
index 4e426284..25013c0e 100644
--- a/rigify/legacy/rigs/basic/copy_chain.py
+++ b/rigify/legacy/rigs/basic/copy_chain.py
@@ -127,8 +127,8 @@ def add_parameters(params):
""" Add the parameters of this rig type to the
RigifyParameters PropertyGroup
"""
- params.make_controls = bpy.props.BoolProperty(name="Controls", default=True, description="Create control bones for the copy")
- params.make_deforms = bpy.props.BoolProperty(name="Deform", default=True, description="Create deform bones for the copy")
+ params.make_controls: bpy.props.BoolProperty(name="Controls", default=True, description="Create control bones for the copy")
+ params.make_deforms: bpy.props.BoolProperty(name="Deform", default=True, description="Create deform bones for the copy")
def parameters_ui(layout, params):
diff --git a/rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py b/rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py
index b0b62d79..69449bb7 100644
--- a/rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py
+++ b/rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py
@@ -11,11 +11,11 @@ def orient_bone( cls, eb, axis, scale = 1.0, reverse = False ):
setattr(v,axis,scale)
if reverse:
- tail_vec = v * cls.obj.matrix_world
+ tail_vec = v @ cls.obj.matrix_world
eb.head[:] = eb.tail
eb.tail[:] = eb.head + tail_vec
else:
- tail_vec = v * cls.obj.matrix_world
+ tail_vec = v @ cls.obj.matrix_world
eb.tail[:] = eb.head + tail_vec
eb.roll = 0.0
diff --git a/rigify/legacy/rigs/pitchipoy/super_copy.py b/rigify/legacy/rigs/pitchipoy/super_copy.py
index 27e88775..5a60ed04 100644
--- a/rigify/legacy/rigs/pitchipoy/super_copy.py
+++ b/rigify/legacy/rigs/pitchipoy/super_copy.py
@@ -91,7 +91,7 @@ def add_parameters(params):
""" Add the parameters of this rig type to the
RigifyParameters PropertyGroup
"""
- params.make_control = bpy.props.BoolProperty(
+ params.make_control: bpy.props.BoolProperty(
name = "Control",
default = True,
description = "Create a control bone for the copy"
diff --git a/rigify/legacy/rigs/pitchipoy/super_face.py b/rigify/legacy/rigs/pitchipoy/super_face.py
index c999ae9a..919f8439 100644
--- a/rigify/legacy/rigs/pitchipoy/super_face.py
+++ b/rigify/legacy/rigs/pitchipoy/super_face.py
@@ -1016,26 +1016,26 @@ def add_parameters(params):
"""
#Setting up extra layers for the tweak bones
- params.primary_layers_extra = bpy.props.BoolProperty(
+ params.primary_layers_extra: bpy.props.BoolProperty(
name = "primary_layers_extra",
default = True,
description = ""
- )
- params.primary_layers = bpy.props.BoolVectorProperty(
+ )
+ params.primary_layers: bpy.props.BoolVectorProperty(
size = 32,
description = "Layers for the 1st tweak controls to be on",
default = tuple( [ i == 1 for i in range(0, 32) ] )
- )
- params.secondary_layers_extra = bpy.props.BoolProperty(
+ )
+ params.secondary_layers_extra: bpy.props.BoolProperty(
name = "secondary_layers_extra",
default = True,
description = ""
- )
- params.secondary_layers = bpy.props.BoolVectorProperty(
+ )
+ params.secondary_layers: bpy.props.BoolVectorProperty(
size = 32,
description = "Layers for the 2nd tweak controls to be on",
default = tuple( [ i == 1 for i in range(0, 32) ] )
- )
+ )
def parameters_ui(layout, params):
diff --git a/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py b/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py
index 38d5887b..d9645adb 100644
--- a/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py
+++ b/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py
@@ -99,11 +99,11 @@ class Rig:
setattr(v,axis,scale)
if reverse:
- tail_vec = v * self.obj.matrix_world
+ tail_vec = v @ self.obj.matrix_world
eb.head[:] = eb.tail
eb.tail[:] = eb.head + tail_vec
else:
- tail_vec = v * self.obj.matrix_world
+ tail_vec = v @ self.obj.matrix_world
eb.tail[:] = eb.head + tail_vec
diff --git a/rigify/legacy/rigs/pitchipoy/super_widgets.py b/rigify/legacy/rigs/pitchipoy/super_widgets.py
index 72384a7c..f442c590 100644
--- a/rigify/legacy/rigs/pitchipoy/super_widgets.py
+++ b/rigify/legacy/rigs/pitchipoy/super_widgets.py
@@ -3,7 +3,6 @@ import importlib
import importlib
from ...utils import create_widget
-WGT_LAYERS = [x == 19 for x in range(0, 20)] # Widgets go on the last scene layer.
MODULE_NAME = "super_widgets" # Windows/Mac blender is weird, so __package__ doesn't work
diff --git a/rigify/legacy/ui.py b/rigify/legacy/ui.py
index dec5b73c..f04ec335 100644
--- a/rigify/legacy/ui.py
+++ b/rigify/legacy/ui.py
@@ -124,7 +124,7 @@ class DATA_PT_rigify_layer_names(bpy.types.Panel):
col = layout.column(align=True)
row = col.row()
row.prop(arm, "layers", index=i, text="", toggle=True)
- split = row.split(percentage=0.8)
+ split = row.split(factor=0.8)
split.prop(rigify_layer, "name", text="Layer %d" % (i + 1))
split.prop(rigify_layer, "row", text="")
@@ -200,9 +200,9 @@ class BONE_PT_rigify_buttons(bpy.types.Panel):
class VIEW3D_PT_tools_rigify_dev(bpy.types.Panel):
bl_label = "Rigify Dev Tools"
- bl_category = 'Tools'
bl_space_type = 'VIEW_3D'
- bl_region_type = 'TOOLS'
+ bl_region_type = 'UI'
+ bl_category = 'View'
@classmethod
def poll(cls, context):
@@ -221,8 +221,8 @@ 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"
+#~ class VIEW3D_MT_armature_metarig_add(bpy.types.Menu):
+ #~ bl_idname = "VIEW3D_MT_armature_metarig_add"
#~ bl_label = "Meta-Rig"
#~ def draw(self, context):
@@ -304,11 +304,11 @@ class Sample(bpy.types.Operator):
bl_label = "Add a sample metarig for a rig type"
bl_options = {'UNDO'}
- metarig_type = StringProperty(
- name="Type",
- description="Name of the rig type to generate a sample of",
- maxlen=128,
- )
+ metarig_type: StringProperty(
+ name="Type",
+ description="Name of the rig type to generate a sample of",
+ maxlen=128,
+ )
def execute(self, context):
if context.mode == 'EDIT_ARMATURE' and self.metarig_type != "":
@@ -410,7 +410,7 @@ class EncodeWidget(bpy.types.Operator):
return {'FINISHED'}
-#menu_func = (lambda self, context: self.layout.menu("INFO_MT_armature_metarig_add", icon='OUTLINER_OB_ARMATURE'))
+#menu_func = (lambda self, context: self.layout.menu("VIEW3D_MT_armature_metarig_add", icon='OUTLINER_OB_ARMATURE'))
#from bl_ui import space_info # ensure the menu is loaded first
@@ -425,7 +425,7 @@ def register():
bpy.utils.register_class(EncodeMetarig)
bpy.utils.register_class(EncodeMetarigSample)
bpy.utils.register_class(EncodeWidget)
- #space_info.INFO_MT_armature_add.append(ui.menu_func)
+ #space_info.VIEW3D_MT_armature_add.append(ui.menu_func)
def unregister():
diff --git a/rigify/legacy/utils.py b/rigify/legacy/utils.py
index e3927ac3..0f3a092e 100644
--- a/rigify/legacy/utils.py
+++ b/rigify/legacy/utils.py
@@ -36,8 +36,6 @@ DEF_PREFIX = "DEF-" # Prefix of deformation bones.
WGT_PREFIX = "WGT-" # Prefix for widget objects
ROOT_NAME = "root" # Name of the root bone.
-WGT_LAYERS = [x == 19 for x in range(0, 20)] # Widgets go on the last scene layer.
-
MODULE_NAME = "rigify" # Windows/Mac blender is weird, so __package__ doesn't work
@@ -342,7 +340,7 @@ def obj_to_bone(obj, rig, bone_name):
bone = rig.data.bones[bone_name]
- mat = rig.matrix_world * bone.matrix_local
+ mat = rig.matrix_world @ bone.matrix_local
obj.location = mat.to_translation()
@@ -397,6 +395,7 @@ def create_widget(rig, bone_name, bone_transform_name=None):
obj_name = WGT_PREFIX + bone_name
scene = bpy.context.scene
+ collection = bpy.context.collection
# Check if it already exists in the scene
if obj_name in scene.objects:
@@ -416,11 +415,10 @@ def create_widget(rig, bone_name, bone_transform_name=None):
# Create mesh object
mesh = bpy.data.meshes.new(obj_name)
obj = bpy.data.objects.new(obj_name, mesh)
- scene.objects.link(obj)
+ collection.objects.link(obj)
# Move object to bone position and set layers
obj_to_bone(obj, rig, bone_transform_name)
- obj.layers = WGT_LAYERS
return obj
@@ -606,8 +604,8 @@ def align_bone_roll(obj, bone1, bone2):
rot_mat = Matrix.Rotation(angle, 3, axis)
# Roll factor
- x3 = rot_mat * x1
- dot = x2 * x3
+ x3 = rot_mat @ x1
+ dot = x2 @ x3
if dot > 1.0:
dot = 1.0
elif dot < -1.0:
@@ -618,7 +616,7 @@ def align_bone_roll(obj, bone1, bone2):
bone1_e.roll = roll
# Check if we rolled in the right direction
- x3 = rot_mat * bone1_e.x_axis
+ x3 = rot_mat @ bone1_e.x_axis
check = x2 * x3
# If not, reverse
@@ -937,3 +935,39 @@ def random_id(length=8):
text += random.choice(chars)
text += str(hex(int(time.time())))[2:][-tlength:].rjust(tlength, '0')[::-1]
return text
+
+
+def get_layer_collection_from_collection(children, collection):
+ for layer_collection in children:
+ if collection == layer_collection.collection:
+ return layer_collection
+
+ # go recursive
+ layer_collection = get_layer_collection_from_collection(layer_collection.children, collection)
+ if layer_collection:
+ return layer_collection
+
+
+def ensure_widget_collection(context):
+ wgts_collection_name = "Widgets"
+
+ view_layer = context.view_layer
+ layer_collection = bpy.context.layer_collection
+ collection = layer_collection.collection
+
+ widget_collection = bpy.data.collections.get(wgts_collection_name)
+ if not widget_collection:
+ # ------------------------------------------
+ # Create the widget collection
+ widget_collection = bpy.data.collections.new(wgts_collection_name)
+ widget_collection.hide_viewport = True
+ widget_collection.hide_render = True
+
+ collection.children.link(widget_collection)
+ widget_layer_collection = [c for c in layer_collection.children if c.collection == widget_collection][0]
+ else:
+ widget_layer_collection = get_layer_collection_from_collection(view_layer.collections, widget_collection)
+
+ # Make the widget the active collection for the upcoming added (widget) objects
+ view_layer.collections.active = widget_layer_collection
+ return widget_collection
diff --git a/rigify/metarig_menu.py b/rigify/metarig_menu.py
index 6b12abad..102d366d 100644
--- a/rigify/metarig_menu.py
+++ b/rigify/metarig_menu.py
@@ -31,7 +31,7 @@ class ArmatureSubMenu(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- layout.label(self.bl_label)
+ layout.label(text=self.bl_label)
for op, name in self.operators:
text = capwords(name.replace("_", " ")) + " (Meta-Rig)"
layout.operator(op, icon='OUTLINER_OB_ARMATURE', text=text)
@@ -159,25 +159,33 @@ for metarig_class in metarig_classes:
arm_sub = next((e for e in armature_submenus if e.bl_label == metarig_class + ' (submenu)'), '')
arm_sub.operators.append((mop.bl_idname, name,))
+
+### Registering ###
+
+
def register():
+ from bpy.utils import register_class
+
for cl in metarig_ops:
for mop, name in metarig_ops[cl]:
- bpy.utils.register_class(mop)
+ register_class(mop)
for arm_sub in armature_submenus:
- bpy.utils.register_class(arm_sub)
+ register_class(arm_sub)
for mf in menu_funcs:
- bpy.types.INFO_MT_armature_add.append(mf)
+ bpy.types.VIEW3D_MT_armature_add.append(mf)
def unregister():
+ from bpy.utils import unregister_class
+
for cl in metarig_ops:
for mop, name in metarig_ops[cl]:
- bpy.utils.unregister_class(mop)
+ unregister_class(mop)
for arm_sub in armature_submenus:
- bpy.utils.unregister_class(arm_sub)
+ unregister_class(arm_sub)
for mf in menu_funcs:
- bpy.types.INFO_MT_armature_add.remove(mf)
+ bpy.types.VIEW3D_MT_armature_add.remove(mf)
diff --git a/rigify/metarigs/Animals/bird.py b/rigify/metarigs/Animals/bird.py
index e31ce7fe..a3331c29 100644
--- a/rigify/metarigs/Animals/bird.py
+++ b/rigify/metarigs/Animals/bird.py
@@ -48,119 +48,119 @@ def create(obj):
arm.rigify_layers[0].name = "Face"
arm.rigify_layers[0].row = 1
- arm.rigify_layers[0].set = False
+ arm.rigify_layers[0].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = False
arm.rigify_layers[28].group = 1
bones = {}
diff --git a/rigify/metarigs/Animals/cat.py b/rigify/metarigs/Animals/cat.py
index 836c9794..d3de1192 100644
--- a/rigify/metarigs/Animals/cat.py
+++ b/rigify/metarigs/Animals/cat.py
@@ -48,119 +48,119 @@ def create(obj):
arm.rigify_layers[0].name = "Face"
arm.rigify_layers[0].row = 1
- arm.rigify_layers[0].set = False
+ arm.rigify_layers[0].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = False
arm.rigify_layers[28].group = 1
bones = {}
diff --git a/rigify/metarigs/Animals/horse.py b/rigify/metarigs/Animals/horse.py
index 72ed1de2..358a9ceb 100644
--- a/rigify/metarigs/Animals/horse.py
+++ b/rigify/metarigs/Animals/horse.py
@@ -48,119 +48,119 @@ def create(obj):
arm.rigify_layers[0].name = "Face"
arm.rigify_layers[0].row = 1
- arm.rigify_layers[0].set = False
+ arm.rigify_layers[0].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = False
arm.rigify_layers[28].group = 1
diff --git a/rigify/metarigs/Animals/shark.py b/rigify/metarigs/Animals/shark.py
index bcc53df3..1ee1d0d9 100644
--- a/rigify/metarigs/Animals/shark.py
+++ b/rigify/metarigs/Animals/shark.py
@@ -48,119 +48,119 @@ def create(obj):
arm.rigify_layers[0].name = "Face"
arm.rigify_layers[0].row = 1
- arm.rigify_layers[0].set = False
+ arm.rigify_layers[0].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = False
arm.rigify_layers[28].group = 1
bones = {}
diff --git a/rigify/metarigs/Animals/wolf.py b/rigify/metarigs/Animals/wolf.py
index 20aa121c..4cccf085 100644
--- a/rigify/metarigs/Animals/wolf.py
+++ b/rigify/metarigs/Animals/wolf.py
@@ -48,119 +48,119 @@ def create(obj):
arm.rigify_layers[0].name = "Face"
arm.rigify_layers[0].row = 1
- arm.rigify_layers[0].set = False
+ arm.rigify_layers[0].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = False
arm.rigify_layers[28].group = 1
bones = {}
diff --git a/rigify/metarigs/Basic/basic_human.py b/rigify/metarigs/Basic/basic_human.py
index 5b1a401d..01367a7b 100644
--- a/rigify/metarigs/Basic/basic_human.py
+++ b/rigify/metarigs/Basic/basic_human.py
@@ -48,119 +48,119 @@ def create(obj):
arm.rigify_layers[0].name = " "
arm.rigify_layers[0].row = 1
- arm.rigify_layers[0].set = False
+ arm.rigify_layers[0].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = False
arm.rigify_layers[28].group = 1
bones = {}
diff --git a/rigify/metarigs/Basic/basic_quadruped.py b/rigify/metarigs/Basic/basic_quadruped.py
index c46743c7..5aa9f657 100644
--- a/rigify/metarigs/Basic/basic_quadruped.py
+++ b/rigify/metarigs/Basic/basic_quadruped.py
@@ -48,119 +48,119 @@ def create(obj):
arm.rigify_layers[0].name = " "
arm.rigify_layers[0].row = 1
- arm.rigify_layers[0].set = False
+ arm.rigify_layers[0].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = False
arm.rigify_layers[28].group = 1
bones = {}
diff --git a/rigify/metarigs/human.py b/rigify/metarigs/human.py
index a31a107c..bbba8eed 100644
--- a/rigify/metarigs/human.py
+++ b/rigify/metarigs/human.py
@@ -48,119 +48,119 @@ def create(obj):
arm.rigify_layers[0].name = "Face"
arm.rigify_layers[0].row = 1
- arm.rigify_layers[0].set = False
+ arm.rigify_layers[0].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = 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].selset = False
arm.rigify_layers[28].group = 1
bones = {}
diff --git a/rigify/rig_ui_template.py b/rigify/rig_ui_template.py
index 3cdda311..8031ff3b 100644
--- a/rigify/rig_ui_template.py
+++ b/rigify/rig_ui_template.py
@@ -20,6 +20,7 @@
UI_SLIDERS = '''
import bpy
+from bpy.props import StringProperty
from mathutils import Matrix, Vector
from math import acos, pi, radians
@@ -135,11 +136,11 @@ def get_pose_matrix_in_other_space(mat, pose_bone):
par_rest = Matrix()
# Get matrix in bone's current transform space
- smat = rest_inv * (par_rest * (par_inv * mat))
+ smat = rest_inv @ (par_rest @ (par_inv @ mat))
# Compensate for non-local location
#if not pose_bone.bone.use_local_location:
- # loc = smat.to_translation() * (par_rest.inverted() * rest).to_quaternion()
+ # loc = smat.to_translation() @ (par_rest.inverted() @ rest).to_quaternion()
# smat.translation = loc
return smat
@@ -166,8 +167,8 @@ def set_pose_translation(pose_bone, mat):
else:
par_rest = Matrix()
- q = (par_rest.inverted() * rest).to_quaternion()
- pose_bone.location = q * loc
+ q = (par_rest.inverted() @ rest).to_quaternion()
+ pose_bone.location = q @ loc
def set_pose_rotation(pose_bone, mat):
@@ -283,11 +284,11 @@ def match_pole_target(ik_first, ik_last, pole, match_bone, length):
angle = rotation_difference(ik_first.matrix, match_bone.matrix)
# Try compensating for the rotation difference in both directions
- pv1 = Matrix.Rotation(angle, 4, ikv) * pv
+ pv1 = Matrix.Rotation(angle, 4, ikv) @ pv
set_pole(pv1)
ang1 = rotation_difference(ik_first.matrix, match_bone.matrix)
- pv2 = Matrix.Rotation(-angle, 4, ikv) * pv
+ pv2 = Matrix.Rotation(-angle, 4, ikv) @ pv
set_pole(pv2)
ang2 = rotation_difference(ik_first.matrix, match_bone.matrix)
@@ -424,8 +425,8 @@ def fk2ik_leg(obj, fk, ik):
match_pose_scale(shin, shini)
# Foot position
- mat = mfoot.bone.matrix_local.inverted() * foot.bone.matrix_local
- footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot) * mat
+ mat = mfoot.bone.matrix_local.inverted() @ foot.bone.matrix_local
+ footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot) @ mat
set_pose_rotation(foot, footmat)
set_pose_scale(foot, footmat)
bpy.ops.object.mode_set(mode='OBJECT')
@@ -442,8 +443,8 @@ def fk2ik_leg(obj, fk, ik):
match_pose_scale(shin, shini)
# Foot position
- mat = mfoot.bone.matrix_local.inverted() * foot.bone.matrix_local
- footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot) * mat
+ mat = mfoot.bone.matrix_local.inverted() @ foot.bone.matrix_local
+ footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot) @ mat
set_pose_rotation(foot, footmat)
set_pose_scale(foot, footmat)
bpy.ops.object.mode_set(mode='OBJECT')
@@ -482,8 +483,8 @@ def ik2fk_leg(obj, fk, ik):
set_pose_rotation(footroll, Matrix())
# Foot position
- mat = mfooti.bone.matrix_local.inverted() * footi.bone.matrix_local
- footmat = get_pose_matrix_in_other_space(foot.matrix, footi) * mat
+ mat = mfooti.bone.matrix_local.inverted() @ footi.bone.matrix_local
+ footmat = get_pose_matrix_in_other_space(foot.matrix, footi) @ mat
set_pose_translation(footi, footmat)
set_pose_rotation(footi, footmat)
set_pose_scale(footi, footmat)
@@ -508,8 +509,8 @@ def ik2fk_leg(obj, fk, ik):
set_pose_rotation(footroll, Matrix())
# Foot position
- mat = mfooti.bone.matrix_local.inverted() * footi.bone.matrix_local
- footmat = get_pose_matrix_in_other_space(mfoot.matrix, footi) * mat
+ mat = mfooti.bone.matrix_local.inverted() @ footi.bone.matrix_local
+ footmat = get_pose_matrix_in_other_space(mfoot.matrix, footi) @ mat
set_pose_translation(footi, footmat)
set_pose_rotation(footi, footmat)
set_pose_scale(footi, footmat)
@@ -600,13 +601,13 @@ class Rigify_Arm_FK2IK(bpy.types.Operator):
bl_label = "Rigify Snap FK arm to IK"
bl_options = {'UNDO'}
- uarm_fk = bpy.props.StringProperty(name="Upper Arm FK Name")
- farm_fk = bpy.props.StringProperty(name="Forerm FK Name")
- hand_fk = bpy.props.StringProperty(name="Hand FK Name")
+ uarm_fk: StringProperty(name="Upper Arm FK Name")
+ farm_fk: StringProperty(name="Forerm FK Name")
+ hand_fk: StringProperty(name="Hand FK Name")
- uarm_ik = bpy.props.StringProperty(name="Upper Arm IK Name")
- farm_ik = bpy.props.StringProperty(name="Forearm IK Name")
- hand_ik = bpy.props.StringProperty(name="Hand IK Name")
+ uarm_ik: StringProperty(name="Upper Arm IK Name")
+ farm_ik: StringProperty(name="Forearm IK Name")
+ hand_ik: StringProperty(name="Hand IK Name")
@classmethod
def poll(cls, context):
@@ -629,16 +630,16 @@ class Rigify_Arm_IK2FK(bpy.types.Operator):
bl_label = "Rigify Snap IK arm to FK"
bl_options = {'UNDO'}
- uarm_fk = bpy.props.StringProperty(name="Upper Arm FK Name")
- farm_fk = bpy.props.StringProperty(name="Forerm FK Name")
- hand_fk = bpy.props.StringProperty(name="Hand FK Name")
+ uarm_fk: StringProperty(name="Upper Arm FK Name")
+ farm_fk: StringProperty(name="Forerm FK Name")
+ hand_fk: StringProperty(name="Hand FK Name")
- uarm_ik = bpy.props.StringProperty(name="Upper Arm IK Name")
- farm_ik = bpy.props.StringProperty(name="Forearm IK Name")
- hand_ik = bpy.props.StringProperty(name="Hand IK Name")
- pole = bpy.props.StringProperty(name="Pole IK Name")
+ uarm_ik: StringProperty(name="Upper Arm IK Name")
+ farm_ik: StringProperty(name="Forearm IK Name")
+ hand_ik: StringProperty(name="Hand IK Name")
+ pole : StringProperty(name="Pole IK Name")
- main_parent = bpy.props.StringProperty(name="Main Parent", default="")
+ main_parent: StringProperty(name="Main Parent", default="")
@classmethod
def poll(cls, context):
@@ -661,15 +662,15 @@ class Rigify_Leg_FK2IK(bpy.types.Operator):
bl_label = "Rigify Snap FK leg to IK"
bl_options = {'UNDO'}
- thigh_fk = bpy.props.StringProperty(name="Thigh FK Name")
- shin_fk = bpy.props.StringProperty(name="Shin FK Name")
- foot_fk = bpy.props.StringProperty(name="Foot FK Name")
- mfoot_fk = bpy.props.StringProperty(name="MFoot FK Name")
+ thigh_fk: StringProperty(name="Thigh FK Name")
+ shin_fk: StringProperty(name="Shin FK Name")
+ foot_fk: StringProperty(name="Foot FK Name")
+ mfoot_fk: StringProperty(name="MFoot FK Name")
- thigh_ik = bpy.props.StringProperty(name="Thigh IK Name")
- shin_ik = bpy.props.StringProperty(name="Shin IK Name")
- foot_ik = bpy.props.StringProperty(name="Foot IK Name")
- mfoot_ik = bpy.props.StringProperty(name="MFoot IK Name")
+ thigh_ik: StringProperty(name="Thigh IK Name")
+ shin_ik: StringProperty(name="Shin IK Name")
+ foot_ik: StringProperty(name="Foot IK Name")
+ mfoot_ik: StringProperty(name="MFoot IK Name")
@classmethod
def poll(cls, context):
@@ -692,18 +693,18 @@ class Rigify_Leg_IK2FK(bpy.types.Operator):
bl_label = "Rigify Snap IK leg to FK"
bl_options = {'UNDO'}
- thigh_fk = bpy.props.StringProperty(name="Thigh FK Name")
- shin_fk = bpy.props.StringProperty(name="Shin FK Name")
- mfoot_fk = bpy.props.StringProperty(name="MFoot FK Name")
- foot_fk = bpy.props.StringProperty(name="Foot FK Name", default="")
- thigh_ik = bpy.props.StringProperty(name="Thigh IK Name")
- shin_ik = bpy.props.StringProperty(name="Shin IK Name")
- foot_ik = bpy.props.StringProperty(name="Foot IK Name")
- footroll = bpy.props.StringProperty(name="Foot Roll Name")
- pole = bpy.props.StringProperty(name="Pole IK Name")
- mfoot_ik = bpy.props.StringProperty(name="MFoot IK Name")
+ thigh_fk: StringProperty(name="Thigh FK Name")
+ shin_fk: StringProperty(name="Shin FK Name")
+ mfoot_fk: StringProperty(name="MFoot FK Name")
+ foot_fk: StringProperty(name="Foot FK Name", default="")
+ thigh_ik: StringProperty(name="Thigh IK Name")
+ shin_ik: StringProperty(name="Shin IK Name")
+ foot_ik: StringProperty(name="Foot IK Name")
+ footroll: StringProperty(name="Foot Roll Name")
+ pole: StringProperty(name="Pole IK Name")
+ mfoot_ik: StringProperty(name="MFoot IK Name")
- main_parent = bpy.props.StringProperty(name="Main Parent", default="")
+ main_parent: StringProperty(name="Main Parent", default="")
@classmethod
def poll(cls, context):
@@ -726,13 +727,14 @@ class Rigify_Rot2PoleSwitch(bpy.types.Operator):
bl_idname = "pose.rigify_rot2pole_" + rig_id
bl_label = "Rotation - Pole toggle"
bl_description = "Toggles IK chain between rotation and pole target"
- bone_name = bpy.props.StringProperty(default='')
- limb_type = bpy.props.StringProperty(name="Limb Type")
- controls = bpy.props.StringProperty(name="Controls string")
- ik_ctrl = bpy.props.StringProperty(name="IK Controls string")
- fk_ctrl = bpy.props.StringProperty(name="FK Controls string")
- parent = bpy.props.StringProperty(name="Parent name")
- pole = bpy.props.StringProperty(name="Pole name")
+
+ bone_name: StringProperty(default='')
+ limb_type: StringProperty(name="Limb Type")
+ controls: StringProperty(name="Controls string")
+ ik_ctrl: StringProperty(name="IK Controls string")
+ fk_ctrl: StringProperty(name="FK Controls string")
+ parent: StringProperty(name="Parent name")
+ pole: StringProperty(name="Pole name")
def execute(self, context):
rig = context.object
@@ -841,23 +843,26 @@ class RigLayers(bpy.types.Panel):
UI_REGISTER = '''
+classes = (
+ Rigify_Arm_FK2IK,
+ Rigify_Arm_IK2FK,
+ Rigify_Leg_FK2IK,
+ Rigify_Leg_IK2FK,
+ Rigify_Rot2PoleSwitch,
+ RigUI,
+ RigLayers,
+)
+
def register():
- bpy.utils.register_class(Rigify_Arm_FK2IK)
- bpy.utils.register_class(Rigify_Arm_IK2FK)
- bpy.utils.register_class(Rigify_Leg_FK2IK)
- bpy.utils.register_class(Rigify_Leg_IK2FK)
- bpy.utils.register_class(Rigify_Rot2PoleSwitch)
- bpy.utils.register_class(RigUI)
- bpy.utils.register_class(RigLayers)
+ from bpy.utils import register_class
+ for cls in classes:
+ register_class(cls)
+
def unregister():
- bpy.utils.unregister_class(Rigify_Arm_FK2IK)
- bpy.utils.unregister_class(Rigify_Arm_IK2FK)
- bpy.utils.unregister_class(Rigify_Leg_FK2IK)
- bpy.utils.unregister_class(Rigify_Leg_IK2FK)
- bpy.utils.register_class(Rigify_Rot2PoleSwitch)
- bpy.utils.unregister_class(RigUI)
- bpy.utils.unregister_class(RigLayers)
+ from bpy.utils import unregister_class
+ for cls in classes:
+ unregister_class(cls)
register()
'''
diff --git a/rigify/rigs/experimental/super_chain.py b/rigify/rigs/experimental/super_chain.py
index 408bce3f..2b2c472b 100644
--- a/rigify/rigs/experimental/super_chain.py
+++ b/rigify/rigs/experimental/super_chain.py
@@ -115,11 +115,11 @@ class Rig:
setattr(v,axis,scale)
if reverse:
- tail_vec = v * self.obj.matrix_world
+ tail_vec = v @ self.obj.matrix_world
eb.head[:] = eb.tail
eb.tail[:] = eb.head + tail_vec
else:
- tail_vec = v * self.obj.matrix_world
+ tail_vec = v @ self.obj.matrix_world
eb.tail[:] = eb.head + tail_vec
def create_pivot(self, bones=None, pivot=None):
diff --git a/rigify/rigs/limbs/limb_utils.py b/rigify/rigs/limbs/limb_utils.py
index 80588516..609da256 100644
--- a/rigify/rigs/limbs/limb_utils.py
+++ b/rigify/rigs/limbs/limb_utils.py
@@ -11,11 +11,11 @@ def orient_bone( cls, eb, axis, scale = 1.0, reverse = False ):
setattr(v,axis,scale)
if reverse:
- tail_vec = v * cls.obj.matrix_world
+ tail_vec = v @ cls.obj.matrix_world
eb.head[:] = eb.tail
eb.tail[:] = eb.head + tail_vec
else:
- tail_vec = v * cls.obj.matrix_world
+ tail_vec = v @ cls.obj.matrix_world
eb.tail[:] = eb.head + tail_vec
eb.roll = 0.0
diff --git a/rigify/rigs/spines/super_spine.py b/rigify/rigs/spines/super_spine.py
index 115d0450..6d28de69 100644
--- a/rigify/rigs/spines/super_spine.py
+++ b/rigify/rigs/spines/super_spine.py
@@ -123,11 +123,11 @@ class Rig:
setattr(v, axis, scale)
if reverse:
- tail_vec = v * self.obj.matrix_world
+ tail_vec = v @ self.obj.matrix_world
eb.head[:] = eb.tail
eb.tail[:] = eb.head + tail_vec
else:
- tail_vec = v * self.obj.matrix_world
+ tail_vec = v @ self.obj.matrix_world
eb.tail[:] = eb.head + tail_vec
def create_pivot(self, pivot):
diff --git a/rigify/rigs/widgets.py b/rigify/rigs/widgets.py
index 8461d82a..aebe7139 100644
--- a/rigify/rigs/widgets.py
+++ b/rigify/rigs/widgets.py
@@ -4,7 +4,6 @@ import importlib
from mathutils import Matrix
from ..utils import create_widget
-WGT_LAYERS = [x == 19 for x in range(0, 20)] # Widgets go on the last scene layer.
MODULE_NAME = "super_widgets" # Windows/Mac blender is weird, so __package__ doesn't work
diff --git a/rigify/rot_mode.py b/rigify/rot_mode.py
index e30e28d1..9abfecea 100644
--- a/rigify/rot_mode.py
+++ b/rigify/rot_mode.py
@@ -38,8 +38,10 @@ blender.stackexchange.com/questions/40711/how-to-convert-quaternions-keyframes-t
# "category": "Animation"}
import bpy
-
-order_list = ['QUATERNION', 'XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX']
+from bpy.props import (
+ BoolProperty,
+ EnumProperty,
+)
class convert():
@@ -219,32 +221,10 @@ class convert():
convert = convert()
-# def initSceneProperties(scn):
-#
-# bpy.types.Scene.order_list = bpy.props.EnumProperty(
-# items = [('QUATERNION', 'QUATERNION', 'QUATERNION' ),
-# ('XYZ', 'XYZ', 'XYZ' ),
-# ('XZY', 'XZY', 'XZY' ),
-# ('YXZ', 'YXZ', 'YXZ' ),
-# ('YZX', 'YZX', 'YZX' ),
-# ('ZXY', 'ZXY', 'ZXY' ),
-# ('ZYX', 'ZYX', 'ZYX' ) ],
-# name = "Order",
-# description = "The target rotation mode")
-#
-# scn['order_list'] = 0
-#
-# return
-#
-# initSceneProperties(bpy.context.scene)
-
-
-# GUI (Panel)
-#
class ToolsPanel(bpy.types.Panel):
bl_space_type = 'VIEW_3D'
- bl_region_type = 'TOOLS'
- bl_category = "Tools"
+ bl_region_type = 'UI'
+ bl_category = 'View'
bl_context = "posemode"
bl_label = 'Rigify Quat/Euler Converter'
@@ -290,7 +270,7 @@ class CONVERT_OT_quat2eu_current_action(bpy.types.Operator):
obj = bpy.context.active_object
pose_bones = bpy.context.selected_pose_bones
action = obj.animation_data.action
- order = order_list[bpy.context.scene['order_list']]
+ order = bpy.context.scene.order_list
id_store = context.window_manager
if id_store.rigify_convert_only_selected:
@@ -315,7 +295,7 @@ class CONVERT_OT_quat2eu_all_actions(bpy.types.Operator):
def execute(op, context):
obj = bpy.context.active_object
pose_bones = bpy.context.selected_pose_bones
- order = order_list[bpy.context.scene['order_list']]
+ order = bpy.context.scene.order_list
id_store = context.window_manager
if id_store.rigify_convert_only_selected:
@@ -326,9 +306,19 @@ class CONVERT_OT_quat2eu_all_actions(bpy.types.Operator):
return {'FINISHED'}
+### Registering ###
+
+classes = (
+ ToolsPanel,
+ CONVERT_OT_quat2eu_current_action,
+ CONVERT_OT_quat2eu_all_actions,
+)
+
+
def register():
- IDStore = bpy.types.WindowManager
+ from bpy.utils import register_class
+ # Properties.
items = [('QUATERNION', 'QUATERNION', 'QUATERNION'),
('XYZ', 'XYZ', 'XYZ'),
('XZY', 'XZY', 'XZY'),
@@ -336,24 +326,27 @@ def register():
('YZX', 'YZX', 'YZX'),
('ZXY', 'ZXY', 'ZXY'),
('ZYX', 'ZYX', 'ZYX')]
+ bpy.types.Scene.order_list = EnumProperty(
+ items=items, name='Convert to',
+ description="The target rotation mode", default='QUATERNION')
- bpy.types.Scene.order_list = bpy.props.EnumProperty(items=items, name='Convert to',
- description="The target rotation mode", default='QUATERNION')
+ IDStore = bpy.types.WindowManager
+ IDStore.rigify_convert_only_selected = BoolProperty(
+ name="Convert Only Selected",
+ description="Convert selected bones only", default=True)
- IDStore.rigify_convert_only_selected = bpy.props.BoolProperty(
- name="Convert Only Selected", description="Convert selected bones only", default=True)
+ # Classes.
+ for cls in classes:
+ register_class(cls)
- bpy.utils.register_class(ToolsPanel)
- bpy.utils.register_class(CONVERT_OT_quat2eu_current_action)
- bpy.utils.register_class(CONVERT_OT_quat2eu_all_actions)
def unregister():
- IDStore = bpy.types.WindowManager
+ from bpy.utils import unregister_class
- bpy.utils.unregister_class(ToolsPanel)
- bpy.utils.unregister_class(CONVERT_OT_quat2eu_current_action)
- bpy.utils.unregister_class(CONVERT_OT_quat2eu_all_actions)
+ # Classes.
+ for cls in classes:
+ unregister_class(cls)
+ # Properties.
+ IDStore = bpy.types.WindowManager
del IDStore.rigify_convert_only_selected
-
-# bpy.utils.register_module(__name__)
diff --git a/rigify/ui.py b/rigify/ui.py
index 76b1fd23..77398ff0 100644
--- a/rigify/ui.py
+++ b/rigify/ui.py
@@ -19,7 +19,13 @@
# <pep8 compliant>
import bpy
-from bpy.props import StringProperty
+from bpy.props import (
+ BoolProperty,
+ IntProperty,
+ EnumProperty,
+ StringProperty
+)
+
from mathutils import Color
from .utils import get_rig_type, MetarigError
@@ -89,7 +95,7 @@ class DATA_PT_rigify_buttons(bpy.types.Panel):
if show_update_metarig:
layout.label(text="This metarig contains old rig-types that can be automatically upgraded to benefit of rigify's new features.", icon='ERROR')
- layout.label(text= "To use it as-is you need to enable legacy mode.",)
+ layout.label(text="To use it as-is you need to enable legacy mode.",)
layout.operator("pose.rigify_upgrade_types", text="Upgrade Metarig")
row = layout.row()
@@ -111,7 +117,7 @@ class DATA_PT_rigify_buttons(bpy.types.Panel):
row = col.row(align=True)
row.prop(id_store, "rigify_generate_mode", expand=True)
- main_row = col.row(align=True).split(percentage=0.3)
+ main_row = col.row(align=True).split(factor=0.3)
col1 = main_row.column()
col2 = main_row.column()
col1.label(text="Rig Name")
@@ -208,14 +214,14 @@ class DATA_PT_rigify_layer_names(bpy.types.Panel):
return
# UI
- main_row = layout.row(align=True).split(0.05)
+ main_row = layout.row(align=True).split(factor=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) + '.')
+ col1.label(text=str(i+1) + '.')
for i, rigify_layer in enumerate(arm.rigify_layers):
# note: rigify_layer == arm.rigify_layers[i]
@@ -234,8 +240,8 @@ class DATA_PT_rigify_layer_names(bpy.types.Panel):
#row.prop(arm, "layers", index=i, text="Layer %d" % (i + 1), toggle=True, icon=icon)
row.prop(rigify_layer, "name", text="")
row.prop(rigify_layer, "row", text="UI Row")
- icon = 'RADIOBUT_ON' if rigify_layer.set else 'RADIOBUT_OFF'
- row.prop(rigify_layer, "set", text="", toggle=True, icon=icon)
+ icon = 'RADIOBUT_ON' if rigify_layer.selset else 'RADIOBUT_OFF'
+ row.prop(rigify_layer, "selset", text="", toggle=True, icon=icon)
row.prop(rigify_layer, "group", text="Bone Group")
else:
row = col.row(align=True)
@@ -247,8 +253,8 @@ class DATA_PT_rigify_layer_names(bpy.types.Panel):
row1.prop(rigify_layer, "name", text="")
row1.prop(rigify_layer, "row", text="UI Row")
row1.enabled = False
- icon = 'RADIOBUT_ON' if rigify_layer.set else 'RADIOBUT_OFF'
- row.prop(rigify_layer, "set", text="", toggle=True, icon=icon)
+ icon = 'RADIOBUT_ON' if rigify_layer.selset else 'RADIOBUT_OFF'
+ row.prop(rigify_layer, "selset", text="", toggle=True, icon=icon)
row.prop(rigify_layer, "group", text="Bone Group")
if rigify_layer.group == 0:
row.label(text='None')
@@ -395,28 +401,29 @@ class DATA_OT_rigify_bone_group_add_theme(bpy.types.Operator):
bl_label = "Rigify Add Bone Group color set from Theme"
bl_options = {"REGISTER", "UNDO"}
- theme = bpy.props.EnumProperty(items=(('THEME01', 'THEME01', ''),
- ('THEME02', 'THEME02', ''),
- ('THEME03', 'THEME03', ''),
- ('THEME04', 'THEME04', ''),
- ('THEME05', 'THEME05', ''),
- ('THEME06', 'THEME06', ''),
- ('THEME07', 'THEME07', ''),
- ('THEME08', 'THEME08', ''),
- ('THEME09', 'THEME09', ''),
- ('THEME10', 'THEME10', ''),
- ('THEME11', 'THEME11', ''),
- ('THEME12', 'THEME12', ''),
- ('THEME13', 'THEME13', ''),
- ('THEME14', 'THEME14', ''),
- ('THEME15', 'THEME15', ''),
- ('THEME16', 'THEME16', ''),
- ('THEME17', 'THEME17', ''),
- ('THEME18', 'THEME18', ''),
- ('THEME19', 'THEME19', ''),
- ('THEME20', 'THEME20', '')
- ),
- name='Theme')
+ theme: EnumProperty(items=(
+ ('THEME01', 'THEME01', ''),
+ ('THEME02', 'THEME02', ''),
+ ('THEME03', 'THEME03', ''),
+ ('THEME04', 'THEME04', ''),
+ ('THEME05', 'THEME05', ''),
+ ('THEME06', 'THEME06', ''),
+ ('THEME07', 'THEME07', ''),
+ ('THEME08', 'THEME08', ''),
+ ('THEME09', 'THEME09', ''),
+ ('THEME10', 'THEME10', ''),
+ ('THEME11', 'THEME11', ''),
+ ('THEME12', 'THEME12', ''),
+ ('THEME13', 'THEME13', ''),
+ ('THEME14', 'THEME14', ''),
+ ('THEME15', 'THEME15', ''),
+ ('THEME16', 'THEME16', ''),
+ ('THEME17', 'THEME17', ''),
+ ('THEME18', 'THEME18', ''),
+ ('THEME19', 'THEME19', ''),
+ ('THEME20', 'THEME20', '')
+ ),
+ name='Theme')
@classmethod
def poll(cls, context):
@@ -448,7 +455,7 @@ class DATA_OT_rigify_bone_group_remove(bpy.types.Operator):
bl_idname = "armature.rigify_bone_group_remove"
bl_label = "Rigify Remove Bone Group color set"
- idx = bpy.props.IntProperty()
+ idx: IntProperty()
@classmethod
def poll(cls, context):
@@ -492,9 +499,9 @@ class DATA_OT_rigify_bone_group_remove_all(bpy.types.Operator):
class DATA_UL_rigify_bone_groups(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
row = layout.row(align=True)
- row = row.split(percentage=0.1)
+ row = row.split(factor=0.1)
row.label(text=str(index+1))
- row = row.split(percentage=0.7)
+ row = row.split(factor=0.7)
row.prop(item, "name", text='', emboss=False)
row = row.row(align=True)
icon = 'LOCKED' if item.standard_colors_lock else 'UNLOCKED'
@@ -547,8 +554,8 @@ class DATA_PT_rigify_bone_groups(bpy.types.Panel):
row.template_list("DATA_UL_rigify_bone_groups", "", obj.data, "rigify_colors", obj.data, "rigify_colors_index")
col = row.column(align=True)
- col.operator("armature.rigify_bone_group_add", icon='ZOOMIN', text="")
- col.operator("armature.rigify_bone_group_remove", icon='ZOOMOUT', text="").idx = obj.data.rigify_colors_index
+ col.operator("armature.rigify_bone_group_add", icon='ZOOM_IN', text="")
+ col.operator("armature.rigify_bone_group_remove", icon='ZOOM_OUT', text="").idx = obj.data.rigify_colors_index
col.menu("DATA_MT_rigify_bone_groups_specials", icon='DOWNARROW_HLT', text="")
row = layout.row()
row.prop(armature, 'rigify_theme_to_add', text = 'Theme')
@@ -626,9 +633,9 @@ class BONE_PT_rigify_buttons(bpy.types.Panel):
class VIEW3D_PT_tools_rigify_dev(bpy.types.Panel):
bl_label = "Rigify Dev Tools"
- bl_category = 'Tools'
bl_space_type = 'VIEW_3D'
- bl_region_type = 'TOOLS'
+ bl_region_type = 'UI'
+ bl_category = 'View'
@classmethod
def poll(cls, context):
@@ -650,10 +657,10 @@ class VIEW3D_PT_tools_rigify_dev(bpy.types.Panel):
class VIEW3D_PT_rigify_animation_tools(bpy.types.Panel):
bl_label = "Rigify Animation Tools"
- bl_category = 'Tools'
bl_context = "posemode"
bl_space_type = 'VIEW_3D'
- bl_region_type = 'TOOLS'
+ bl_region_type = 'UI'
+ bl_category = 'View'
@classmethod
def poll(cls, context):
@@ -681,8 +688,8 @@ class VIEW3D_PT_rigify_animation_tools(bpy.types.Panel):
row.operator("rigify.transfer_ik_to_fk", text='FK2IK Action', icon='ACTION_TWEAK')
row = self.layout.row(align=True)
- row.operator("rigify.clear_animation", text="Clear IK Action", icon='CANCEL').type = "IK"
- row.operator("rigify.clear_animation", text="Clear FK Action", icon='CANCEL').type = "FK"
+ row.operator("rigify.clear_animation", text="Clear IK Action", icon='CANCEL').anim_type = "IK"
+ row.operator("rigify.clear_animation", text="Clear FK Action", icon='CANCEL').anim_type = "FK"
row = self.layout.row(align=True)
op = row.operator("rigify.rotation_pole", icon='FORCE_HARMONIC', text='Switch to pole')
@@ -794,18 +801,17 @@ class SwitchToLegacy(bpy.types.Operator):
class Sample(bpy.types.Operator):
- """Create a sample metarig to be modified before generating """ \
- """the final rig"""
+ """Create a sample metarig to be modified before generating the final rig"""
bl_idname = "armature.metarig_sample_add"
bl_label = "Add a sample metarig for a rig type"
bl_options = {'UNDO'}
- metarig_type = StringProperty(
- name="Type",
- description="Name of the rig type to generate a sample of",
- maxlen=128,
- )
+ metarig_type: StringProperty(
+ name="Type",
+ description="Name of the rig type to generate a sample of",
+ maxlen=128,
+ )
def execute(self, context):
if context.mode == 'EDIT_ARMATURE' and self.metarig_type != "":
@@ -1074,20 +1080,20 @@ def IktoFk(rig, window='ALL'):
break
-def clearAnimation(act, type, names):
+def clearAnimation(act, anim_type, names):
bones = []
for group in names:
if names[group]['limb_type'] == 'arm':
- if type == 'IK':
+ if anim_type == 'IK':
bones.extend([names[group]['controls'][0], names[group]['controls'][4]])
- elif type == 'FK':
+ elif anim_type == 'FK':
bones.extend([names[group]['controls'][1], names[group]['controls'][2], names[group]['controls'][3]])
else:
- if type == 'IK':
+ if anim_type == 'IK':
bones.extend([names[group]['controls'][0], names[group]['controls'][6], names[group]['controls'][5],
names[group]['controls'][4]])
- elif type == 'FK':
+ elif anim_type == 'FK':
bones.extend([names[group]['controls'][1], names[group]['controls'][2], names[group]['controls'][3],
names[group]['controls'][4]])
FCurves = []
@@ -1271,7 +1277,8 @@ class OBJECT_OT_ClearAnimation(bpy.types.Operator):
bl_idname = "rigify.clear_animation"
bl_label = "Clear Animation"
bl_description = "Clear Animation For FK or IK Bones"
- type = StringProperty()
+
+ anim_type: StringProperty()
def execute(self, context):
@@ -1286,7 +1293,7 @@ class OBJECT_OT_ClearAnimation(bpy.types.Operator):
if not act:
return {'FINISHED'}
- clearAnimation(act, self.type, names=get_limb_generated_names(rig))
+ clearAnimation(act, self.anim_type, names=get_limb_generated_names(rig))
finally:
context.user_preferences.edit.use_global_undo = use_global_undo
return {'FINISHED'}
@@ -1296,11 +1303,12 @@ class OBJECT_OT_Rot2Pole(bpy.types.Operator):
bl_idname = "rigify.rotation_pole"
bl_label = "Rotation - Pole toggle"
bl_description = "Toggles IK chain between rotation and pole target"
- bone_name = bpy.props.StringProperty(default='')
- window = bpy.props.StringProperty(default='ALL')
- toggle = bpy.props.BoolProperty(default=True)
- value = bpy.props.BoolProperty(default=True)
- bake = bpy.props.BoolProperty(default=True)
+
+ bone_name: StringProperty(default='')
+ window: StringProperty(default='ALL')
+ toggle: BoolProperty(default=True)
+ value: BoolProperty(default=True)
+ bake: BoolProperty(default=True)
def execute(self, context):
rig = context.object
@@ -1313,73 +1321,60 @@ class OBJECT_OT_Rot2Pole(bpy.types.Operator):
return {'FINISHED'}
+### Registering ###
+
+
+classes = (
+ DATA_OT_rigify_add_bone_groups,
+ DATA_OT_rigify_use_standard_colors,
+ DATA_OT_rigify_apply_selection_colors,
+ DATA_OT_rigify_bone_group_add,
+ DATA_OT_rigify_bone_group_add_theme,
+ DATA_OT_rigify_bone_group_remove,
+ DATA_OT_rigify_bone_group_remove_all,
+ DATA_UL_rigify_bone_groups,
+ DATA_MT_rigify_bone_groups_specials,
+ DATA_PT_rigify_bone_groups,
+ DATA_PT_rigify_layer_names,
+ DATA_PT_rigify_buttons,
+ BONE_PT_rigify_buttons,
+ VIEW3D_PT_rigify_animation_tools,
+ VIEW3D_PT_tools_rigify_dev,
+ LayerInit,
+ Generate,
+ UpgradeMetarigTypes,
+ SwitchToLegacy,
+ Sample,
+ EncodeMetarig,
+ EncodeMetarigSample,
+ EncodeWidget,
+ OBJECT_OT_GetFrameRange,
+ OBJECT_OT_FK2IK,
+ OBJECT_OT_IK2FK,
+ OBJECT_OT_TransferFKtoIK,
+ OBJECT_OT_TransferIKtoFK,
+ OBJECT_OT_ClearAnimation,
+ OBJECT_OT_Rot2Pole,
+)
+
+
def register():
+ from bpy.utils import register_class
- bpy.utils.register_class(DATA_OT_rigify_add_bone_groups)
- bpy.utils.register_class(DATA_OT_rigify_use_standard_colors)
- bpy.utils.register_class(DATA_OT_rigify_apply_selection_colors)
- bpy.utils.register_class(DATA_OT_rigify_bone_group_add)
- bpy.utils.register_class(DATA_OT_rigify_bone_group_add_theme)
- bpy.utils.register_class(DATA_OT_rigify_bone_group_remove)
- bpy.utils.register_class(DATA_OT_rigify_bone_group_remove_all)
- bpy.utils.register_class(DATA_UL_rigify_bone_groups)
- bpy.utils.register_class(DATA_MT_rigify_bone_groups_specials)
- bpy.utils.register_class(DATA_PT_rigify_bone_groups)
- bpy.utils.register_class(DATA_PT_rigify_layer_names)
- bpy.utils.register_class(DATA_PT_rigify_buttons)
- bpy.utils.register_class(BONE_PT_rigify_buttons)
- bpy.utils.register_class(VIEW3D_PT_rigify_animation_tools)
- bpy.utils.register_class(VIEW3D_PT_tools_rigify_dev)
- bpy.utils.register_class(LayerInit)
- bpy.utils.register_class(Generate)
- bpy.utils.register_class(UpgradeMetarigTypes)
- bpy.utils.register_class(SwitchToLegacy)
- bpy.utils.register_class(Sample)
- bpy.utils.register_class(EncodeMetarig)
- bpy.utils.register_class(EncodeMetarigSample)
- bpy.utils.register_class(EncodeWidget)
- bpy.utils.register_class(OBJECT_OT_GetFrameRange)
- bpy.utils.register_class(OBJECT_OT_FK2IK)
- bpy.utils.register_class(OBJECT_OT_IK2FK)
- bpy.utils.register_class(OBJECT_OT_TransferFKtoIK)
- bpy.utils.register_class(OBJECT_OT_TransferIKtoFK)
- bpy.utils.register_class(OBJECT_OT_ClearAnimation)
- bpy.utils.register_class(OBJECT_OT_Rot2Pole)
+ # Classes.
+ for cls in classes:
+ register_class(cls)
+ # Sub-modules.
rot_mode.register()
def unregister():
+ from bpy.utils import unregister_class
- bpy.utils.unregister_class(DATA_OT_rigify_add_bone_groups)
- bpy.utils.unregister_class(DATA_OT_rigify_use_standard_colors)
- bpy.utils.unregister_class(DATA_OT_rigify_apply_selection_colors)
- bpy.utils.unregister_class(DATA_OT_rigify_bone_group_add)
- bpy.utils.unregister_class(DATA_OT_rigify_bone_group_add_theme)
- bpy.utils.unregister_class(DATA_OT_rigify_bone_group_remove)
- bpy.utils.unregister_class(DATA_OT_rigify_bone_group_remove_all)
- bpy.utils.unregister_class(DATA_UL_rigify_bone_groups)
- bpy.utils.unregister_class(DATA_MT_rigify_bone_groups_specials)
- bpy.utils.unregister_class(DATA_PT_rigify_bone_groups)
- bpy.utils.unregister_class(DATA_PT_rigify_layer_names)
- bpy.utils.unregister_class(DATA_PT_rigify_buttons)
- bpy.utils.unregister_class(BONE_PT_rigify_buttons)
- bpy.utils.unregister_class(VIEW3D_PT_rigify_animation_tools)
- bpy.utils.unregister_class(VIEW3D_PT_tools_rigify_dev)
- bpy.utils.unregister_class(LayerInit)
- bpy.utils.unregister_class(Generate)
- bpy.utils.unregister_class(UpgradeMetarigTypes)
- bpy.utils.unregister_class(SwitchToLegacy)
- bpy.utils.unregister_class(Sample)
- bpy.utils.unregister_class(EncodeMetarig)
- bpy.utils.unregister_class(EncodeMetarigSample)
- bpy.utils.unregister_class(EncodeWidget)
- bpy.utils.unregister_class(OBJECT_OT_GetFrameRange)
- bpy.utils.unregister_class(OBJECT_OT_FK2IK)
- bpy.utils.unregister_class(OBJECT_OT_IK2FK)
- bpy.utils.unregister_class(OBJECT_OT_TransferFKtoIK)
- bpy.utils.unregister_class(OBJECT_OT_TransferIKtoFK)
- bpy.utils.unregister_class(OBJECT_OT_ClearAnimation)
- bpy.utils.unregister_class(OBJECT_OT_Rot2Pole)
-
+ # Sub-modules.
rot_mode.unregister()
+
+ # Classes.
+ for cls in classes:
+ unregister_class(cls)
diff --git a/rigify/utils.py b/rigify/utils.py
index 1a711a3d..23596b3c 100644
--- a/rigify/utils.py
+++ b/rigify/utils.py
@@ -38,8 +38,6 @@ DEF_PREFIX = "DEF-" # Prefix of deformation bones.
WGT_PREFIX = "WGT-" # Prefix for widget objects
ROOT_NAME = "root" # Name of the root bone.
-WGT_LAYERS = [x == 19 for x in range(0, 20)] # Widgets go on the last scene layer.
-
MODULE_NAME = "rigify" # Windows/Mac blender is weird, so __package__ doesn't work
outdated_types = {"pitchipoy.limbs.super_limb": "limbs.super_limb",
@@ -420,7 +418,7 @@ def obj_to_bone(obj, rig, bone_name):
bone = rig.data.bones[bone_name]
- mat = rig.matrix_world * bone.matrix_local
+ mat = rig.matrix_world @ bone.matrix_local
obj.location = mat.to_translation()
@@ -440,6 +438,7 @@ def create_widget(rig, bone_name, bone_transform_name=None):
obj_name = WGT_PREFIX + rig.name + '_' + bone_name
scene = bpy.context.scene
+ collection = bpy.context.collection
id_store = bpy.context.window_manager
# Check if it already exists in the scene
@@ -460,14 +459,13 @@ def create_widget(rig, bone_name, bone_transform_name=None):
# Create mesh object
mesh = bpy.data.meshes.new(obj_name)
obj = bpy.data.objects.new(obj_name, mesh)
- scene.objects.link(obj)
+ collection.objects.link(obj)
# Move object to bone position and set layers
obj_to_bone(obj, rig, bone_transform_name)
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
@@ -814,8 +812,8 @@ def align_bone_roll(obj, bone1, bone2):
bone1_e.roll = roll
# Check if we rolled in the right direction
- x3 = rot_mat * bone1_e.x_axis
- check = x2 * x3
+ x3 = rot_mat @ bone1_e.x_axis
+ check = x2 @ x3
# If not, reverse
if check < 0.9999:
@@ -1026,11 +1024,11 @@ def write_metarig(obj, layers=False, func_name="create", groups=False):
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
+ selset = arm.rigify_layers[i].selset
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) + '].selset = ' + str(selset))
code.append(' arm.rigify_layers[' + str(i) + '].group = ' + str(group))
# write parents first
@@ -1262,3 +1260,39 @@ def overwrite_prop_animation(rig, bone, prop_name, value, frames):
for kp in curve.keyframe_points:
if kp.co[0] in frames:
kp.co[1] = value
+
+
+def get_layer_collection_from_collection(children, collection):
+ for layer_collection in children:
+ if collection == layer_collection.collection:
+ return layer_collection
+
+ # go recursive
+ layer_collection = get_layer_collection_from_collection(layer_collection.children, collection)
+ if layer_collection:
+ return layer_collection
+
+
+def ensure_widget_collection(context):
+ wgts_collection_name = "Widgets"
+
+ view_layer = context.view_layer
+ layer_collection = bpy.context.layer_collection
+ collection = layer_collection.collection
+
+ widget_collection = bpy.data.collections.get(wgts_collection_name)
+ if not widget_collection:
+ # ------------------------------------------
+ # Create the widget collection
+ widget_collection = bpy.data.collections.new(wgts_collection_name)
+ widget_collection.hide_viewport = True
+ widget_collection.hide_render = True
+
+ collection.children.link(widget_collection)
+ widget_layer_collection = [c for c in layer_collection.children if c.collection == widget_collection][0]
+ else:
+ widget_layer_collection = get_layer_collection_from_collection(view_layer.collections, widget_collection)
+
+ # Make the widget the active collection for the upcoming added (widget) objects
+ view_layer.collections.active = widget_layer_collection
+ return widget_collection
diff --git a/space_clip_editor_refine_solution.py b/space_clip_editor_refine_solution.py
index a3287b78..2287714b 100644
--- a/space_clip_editor_refine_solution.py
+++ b/space_clip_editor_refine_solution.py
@@ -18,12 +18,14 @@
#
# ##### END GPL LICENSE BLOCK #####
+# <pep8 compliant>
+
bl_info = {
"name": "Refine tracking solution",
"author": "Stephen Leger",
"license": "GPL",
- "version": (1, 1, 3),
- "blender": (2, 7, 8),
+ "version": (1, 1, 4),
+ "blender": (2, 80, 0),
"location": "Clip Editor > Tools > Solve > Refine Solution",
"description": "Refine motion solution by setting track weight according"
" to reprojection error",
@@ -70,10 +72,9 @@ class OP_Tracking_refine_solution(Operator):
marker_position = Vector()
for frame in range(start, end):
- camera = tracking.reconstruction.cameras.find_frame(frame)
+ camera = tracking.reconstruction.cameras.find_frame(frame=frame)
if camera is not None:
- imat = camera.matrix.inverted()
- projection_matrix = imat.transposed()
+ camera_invert = camera.matrix.inverted()
else:
continue
@@ -102,7 +103,7 @@ class OP_Tracking_refine_solution(Operator):
else:
tw = 1.0
- reprojected_position = track.bundle * projection_matrix
+ reprojected_position = camera_invert @ track.bundle
if reprojected_position.z == 0:
track.weight = 0
track.keyframe_insert("weight", frame=frame)
@@ -152,11 +153,11 @@ class OP_Tracking_reset_solution(Operator):
start = tracking.reconstruction.cameras[0].frame
end = tracking.reconstruction.cameras[-1].frame
for frame in range(start, end):
- camera = tracking.reconstruction.cameras.find_frame(frame)
+ camera = tracking.reconstruction.cameras.find_frame(frame=frame)
if camera is None:
continue
for track in tracking.tracks:
- marker = track.markers.find_frame(frame)
+ marker = track.markers.find_frame(frame=frame)
if marker is None:
continue
track.weight = 1.0
@@ -191,6 +192,13 @@ class RefineMotionTrackingPanel(Panel):
row.operator("tracking.reset_solution")
+classes =(
+ OP_Tracking_refine_solution,
+ OP_Tracking_reset_solution,
+ RefineMotionTrackingPanel
+ )
+
+
def register():
bpy.types.WindowManager.TrackingTargetError = FloatProperty(
name="Target Error",
@@ -204,11 +212,13 @@ def register():
default=25,
min=1
)
- bpy.utils.register_module(__name__)
+ for cls in classes:
+ bpy.utils.register_class(cls)
def unregister():
- bpy.utils.unregister_module(__name__)
+ for cls in reversed(classes):
+ bpy.utils.unregister_class(cls)
del bpy.types.WindowManager.TrackingTargetError
del bpy.types.WindowManager.TrackingSmooth
diff --git a/space_view3d_3d_navigation.py b/space_view3d_3d_navigation.py
index a4c359cc..adf0c8d8 100644
--- a/space_view3d_3d_navigation.py
+++ b/space_view3d_3d_navigation.py
@@ -252,7 +252,7 @@ class VIEW3D_PT_3dnavigationPanel(Panel):
col.operator("view3d.view_selected", text="View to Selected")
col = layout.column(align=True)
- col.label(text="Cursor:", icon="CURSOR")
+ col.label(text="Cursor:", icon='PIVOT_CURSOR')
row = col.row(align=True)
row.operator("view3d.snap_cursor_to_center", text="Center")
row.operator("view3d.view_center_cursor", text="View")
@@ -299,8 +299,8 @@ class VIEW3D_PT_pan_navigation1(Panel):
row = layout.row()
row.label(text="Zoom:")
row = layout.row()
- row.operator("opr.zoom_in_view1", text="In", icon="ZOOMIN")
- row.operator("opr.zoom_out_view1", text="Out", icon="ZOOMOUT")
+ row.operator("opr.zoom_in_view1", text="In", icon='ADD')
+ row.operator("opr.zoom_out_view1", text="Out", icon='REMOVE')
row = layout.row()
row.label(text="Roll:")
diff --git a/space_view3d_copy_attributes.py b/space_view3d_copy_attributes.py
index 762eb953..9063bc89 100644
--- a/space_view3d_copy_attributes.py
+++ b/space_view3d_copy_attributes.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Copy Attributes Menu",
"author": "Bassam Kurdali, Fabian Fricke, Adam Wiseman",
"version": (0, 4, 8),
- "blender": (2, 63, 0),
+ "blender": (2, 80, 0),
"location": "View3D > Ctrl-C",
"description": "Copy Attributes Menu from Blender 2.4",
"wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
@@ -33,13 +33,13 @@ bl_info = {
import bpy
from mathutils import Matrix
from bpy.types import (
- Operator,
- Menu,
- )
+ Operator,
+ Menu,
+)
from bpy.props import (
- BoolVectorProperty,
- StringProperty,
- )
+ BoolVectorProperty,
+ StringProperty,
+)
# First part of the operator Info message
INFO_MESSAGE = "Copy Attributes: "
@@ -82,7 +82,7 @@ def genops(copylist, oplist, prefix, poll_func, loopfunc):
exec_func = build_exec(loopfunc, op[3])
invoke_func = build_invoke(loopfunc, op[3])
opclass = build_op(prefix + op[0], "Copy " + op[1], op[2],
- poll_func, exec_func, invoke_func)
+ poll_func, exec_func, invoke_func)
oplist.append(opclass)
@@ -101,22 +101,25 @@ def getmat(bone, active, context, ignoreparent):
"""Helper function for visual transform copy,
gets the active transform in bone space
"""
- obj_act = context.active_object
- data_bone = obj_act.data.bones[bone.name]
+ obj_bone = bone.id_data
+ obj_active = active.id_data
+ data_bone = obj_bone.data.bones[bone.name]
# all matrices are in armature space unless commented otherwise
- otherloc = active.matrix # final 4x4 mat of target, location.
+ active_to_selected = obj_bone.matrix_world.inverted() @ obj_active.matrix_world
+ active_matrix = active_to_selected @ active.matrix
+ otherloc = active_matrix # final 4x4 mat of target, location.
bonemat_local = data_bone.matrix_local.copy() # self rest matrix
if data_bone.parent:
- parentposemat = obj_act.pose.bones[data_bone.parent.name].matrix.copy()
+ parentposemat = obj_bone.pose.bones[data_bone.parent.name].matrix.copy()
parentbonemat = data_bone.parent.matrix_local.copy()
else:
parentposemat = parentbonemat = Matrix()
if parentbonemat == parentposemat or ignoreparent:
- newmat = bonemat_local.inverted() * otherloc
+ newmat = bonemat_local.inverted() @ otherloc
else:
- bonemat = parentbonemat.inverted() * bonemat_local
+ bonemat = parentbonemat.inverted() @ bonemat_local
- newmat = bonemat.inverted() * parentposemat.inverted() * otherloc
+ newmat = bonemat.inverted() @ parentposemat.inverted() @ otherloc
return newmat
@@ -160,14 +163,16 @@ def pVisLocExec(bone, active, context):
def pVisRotExec(bone, active, context):
+ obj_bone = bone.id_data
rotcopy(bone, getmat(bone, active,
- context, not context.active_object.data.bones[bone.name].use_inherit_rotation))
+ context, not obj_bone.data.bones[bone.name].use_inherit_rotation))
def pVisScaExec(bone, active, context):
+ obj_bone = bone.id_data
bone.scale = getmat(bone, active, context,
- not context.active_object.data.bones[bone.name].use_inherit_scale)\
- .to_scale()
+ not obj_bone.data.bones[bone.name].use_inherit_scale)\
+ .to_scale()
def pDrwExec(bone, active, context):
@@ -207,30 +212,29 @@ def pBBonesExec(bone, active, context):
pose_copies = (
- ('pose_loc_loc', "Local Location",
- "Copy Location from Active to Selected", pLocLocExec),
- ('pose_loc_rot', "Local Rotation",
- "Copy Rotation from Active to Selected", pLocRotExec),
- ('pose_loc_sca', "Local Scale",
- "Copy Scale from Active to Selected", pLocScaExec),
- ('pose_vis_loc', "Visual Location",
- "Copy Location from Active to Selected", pVisLocExec),
- ('pose_vis_rot', "Visual Rotation",
- "Copy Rotation from Active to Selected", pVisRotExec),
- ('pose_vis_sca', "Visual Scale",
- "Copy Scale from Active to Selected", pVisScaExec),
- ('pose_drw', "Bone Shape",
- "Copy Bone Shape from Active to Selected", pDrwExec),
- ('pose_lok', "Protected Transform",
- "Copy Protected Transforms from Active to Selected", pLokExec),
- ('pose_con', "Bone Constraints",
- "Copy Object Constraints from Active to Selected", pConExec),
- ('pose_iks', "IK Limits",
- "Copy IK Limits from Active to Selected", pIKsExec),
- ('bbone_settings', "BBone Settings",
- "Copy BBone Settings from Active to Selected", pBBonesExec),
- )
-
+ ('pose_loc_loc', "Local Location",
+ "Copy Location from Active to Selected", pLocLocExec),
+ ('pose_loc_rot', "Local Rotation",
+ "Copy Rotation from Active to Selected", pLocRotExec),
+ ('pose_loc_sca', "Local Scale",
+ "Copy Scale from Active to Selected", pLocScaExec),
+ ('pose_vis_loc', "Visual Location",
+ "Copy Location from Active to Selected", pVisLocExec),
+ ('pose_vis_rot', "Visual Rotation",
+ "Copy Rotation from Active to Selected", pVisRotExec),
+ ('pose_vis_sca', "Visual Scale",
+ "Copy Scale from Active to Selected", pVisScaExec),
+ ('pose_drw', "Bone Shape",
+ "Copy Bone Shape from Active to Selected", pDrwExec),
+ ('pose_lok', "Protected Transform",
+ "Copy Protected Transforms from Active to Selected", pLokExec),
+ ('pose_con', "Bone Constraints",
+ "Copy Object Constraints from Active to Selected", pConExec),
+ ('pose_iks', "IK Limits",
+ "Copy IK Limits from Active to Selected", pIKsExec),
+ ('bbone_settings', "BBone Settings",
+ "Copy BBone Settings from Active to Selected", pBBonesExec),
+)
@classmethod
def pose_poll_func(cls, context):
@@ -248,10 +252,10 @@ class CopySelectedPoseConstraints(Operator):
bl_idname = "pose.copy_selected_constraints"
bl_label = "Copy Selected Constraints"
- selection = BoolVectorProperty(
- size=32,
- options={'SKIP_SAVE'}
- )
+ selection: BoolVectorProperty(
+ size=32,
+ options={'SKIP_SAVE'}
+ )
poll = pose_poll_func
invoke = pose_invoke_func
@@ -260,7 +264,7 @@ class CopySelectedPoseConstraints(Operator):
layout = self.layout
for idx, const in enumerate(context.active_pose_bone.constraints):
layout.prop(self, "selection", index=idx, text=const.name,
- toggle=True)
+ toggle=True)
def execute(self, context):
active = context.active_pose_bone
@@ -271,8 +275,8 @@ class CopySelectedPoseConstraints(Operator):
if flag:
old_constraint = active.constraints[index]
new_constraint = bone.constraints.new(
- active.constraints[index].type
- )
+ active.constraints[index].type
+ )
generic_copy(old_constraint, new_constraint)
return {'FINISHED'}
@@ -306,9 +310,9 @@ def obLoopExec(self, context, funk):
def world_to_basis(active, ob, context):
"""put world coords of active as basis coords of ob"""
- local = ob.parent.matrix_world.inverted() * active.matrix_world
- P = ob.matrix_basis * ob.matrix_local.inverted()
- mat = P * local
+ local = ob.parent.matrix_world.inverted() @ active.matrix_world
+ P = ob.matrix_basis @ ob.matrix_local.inverted()
+ mat = P @ local
return(mat)
@@ -355,17 +359,17 @@ def obVisSca(ob, active, context):
def obDrw(ob, active, context):
- ob.draw_type = active.draw_type
+ ob.display_type = active.display_type
ob.show_axis = active.show_axis
ob.show_bounds = active.show_bounds
- ob.draw_bounds_type = active.draw_bounds_type
+ ob.display_bounds_type = active.display_bounds_type
ob.show_name = active.show_name
ob.show_texture_space = active.show_texture_space
ob.show_transparent = active.show_transparent
ob.show_wire = active.show_wire
- ob.show_x_ray = active.show_x_ray
- ob.empty_draw_type = active.empty_draw_type
- ob.empty_draw_size = active.empty_draw_size
+ ob.show_in_front = active.show_in_front
+ ob.empty_display_type = active.empty_display_type
+ ob.empty_display_size = active.empty_display_size
def obOfs(ob, active, context):
@@ -382,11 +386,6 @@ def obCol(ob, active, context):
ob.color = active.color
-def obMas(ob, active, context):
- ob.game.mass = active.game.mass
- return('INFO', "Mass copied")
-
-
def obLok(ob, active, context):
for index, state in enumerate(active.lock_location):
ob.lock_location[index] = state
@@ -429,7 +428,7 @@ def obMod(ob, active, context):
ob.modifiers.remove(modifier)
for old_modifier in active.modifiers.values():
new_modifier = ob.modifiers.new(name=old_modifier.name,
- type=old_modifier.type)
+ type=old_modifier.type)
generic_copy(old_modifier, new_modifier)
return('INFO', "Modifiers copied")
@@ -483,62 +482,60 @@ def obWei(ob, active, context):
for vgs in range(0, len(groups)):
if groups[vgs].name == groupName:
groups[vgs].add((v.index,),
- vgroupIndex_weight[i][1], "REPLACE")
+ vgroupIndex_weight[i][1], "REPLACE")
return('INFO', "Weights copied")
object_copies = (
- # ('obj_loc', "Location",
- # "Copy Location from Active to Selected", obLoc),
- # ('obj_rot', "Rotation",
- # "Copy Rotation from Active to Selected", obRot),
- # ('obj_sca', "Scale",
- # "Copy Scale from Active to Selected", obSca),
- ('obj_vis_loc', "Location",
- "Copy Location from Active to Selected", obVisLoc),
- ('obj_vis_rot', "Rotation",
- "Copy Rotation from Active to Selected", obVisRot),
- ('obj_vis_sca', "Scale",
- "Copy Scale from Active to Selected", obVisSca),
- ('obj_drw', "Draw Options",
- "Copy Draw Options from Active to Selected", obDrw),
- ('obj_ofs', "Time Offset",
- "Copy Time Offset from Active to Selected", obOfs),
- ('obj_dup', "Dupli",
- "Copy Dupli from Active to Selected", obDup),
- ('obj_col', "Object Color",
- "Copy Object Color from Active to Selected", obCol),
- ('obj_mas', "Mass",
- "Copy Mass from Active to Selected", obMas),
- # ('obj_dmp', "Damping",
- # "Copy Damping from Active to Selected"),
- # ('obj_all', "All Physical Attributes",
- # "Copy Physical Attributes from Active to Selected"),
- # ('obj_prp', "Properties",
- # "Copy Properties from Active to Selected"),
- # ('obj_log', "Logic Bricks",
- # "Copy Logic Bricks from Active to Selected"),
- ('obj_lok', "Protected Transform",
- "Copy Protected Transforms from Active to Selected", obLok),
- ('obj_con', "Object Constraints",
- "Copy Object Constraints from Active to Selected", obCon),
- # ('obj_nla', "NLA Strips",
- # "Copy NLA Strips from Active to Selected"),
- # ('obj_tex', "Texture Space",
- # "Copy Texture Space from Active to Selected", obTex),
- # ('obj_sub', "Subsurf Settings",
- # "Copy Subsurf Settings from Active to Selected"),
- # ('obj_smo', "AutoSmooth",
- # "Copy AutoSmooth from Active to Selected"),
- ('obj_idx', "Pass Index",
- "Copy Pass Index from Active to Selected", obIdx),
- ('obj_mod', "Modifiers",
- "Copy Modifiers from Active to Selected", obMod),
- ('obj_wei', "Vertex Weights",
- "Copy vertex weights based on indices", obWei),
- ('obj_grp', "Group Links",
- "Copy selected into active object's groups", obGrp)
- )
+ # ('obj_loc', "Location",
+ # "Copy Location from Active to Selected", obLoc),
+ # ('obj_rot', "Rotation",
+ # "Copy Rotation from Active to Selected", obRot),
+ # ('obj_sca', "Scale",
+ # "Copy Scale from Active to Selected", obSca),
+ ('obj_vis_loc', "Location",
+ "Copy Location from Active to Selected", obVisLoc),
+ ('obj_vis_rot', "Rotation",
+ "Copy Rotation from Active to Selected", obVisRot),
+ ('obj_vis_sca', "Scale",
+ "Copy Scale from Active to Selected", obVisSca),
+ ('obj_drw', "Draw Options",
+ "Copy Draw Options from Active to Selected", obDrw),
+ ('obj_ofs', "Time Offset",
+ "Copy Time Offset from Active to Selected", obOfs),
+ ('obj_dup', "Dupli",
+ "Copy Dupli from Active to Selected", obDup),
+ ('obj_col', "Object Color",
+ "Copy Object Color from Active to Selected", obCol),
+ # ('obj_dmp', "Damping",
+ # "Copy Damping from Active to Selected"),
+ # ('obj_all', "All Physical Attributes",
+ # "Copy Physical Attributes from Active to Selected"),
+ # ('obj_prp', "Properties",
+ # "Copy Properties from Active to Selected"),
+ # ('obj_log', "Logic Bricks",
+ # "Copy Logic Bricks from Active to Selected"),
+ ('obj_lok', "Protected Transform",
+ "Copy Protected Transforms from Active to Selected", obLok),
+ ('obj_con', "Object Constraints",
+ "Copy Object Constraints from Active to Selected", obCon),
+ # ('obj_nla', "NLA Strips",
+ # "Copy NLA Strips from Active to Selected"),
+ # ('obj_tex', "Texture Space",
+ # "Copy Texture Space from Active to Selected", obTex),
+ # ('obj_sub', "Subsurf Settings",
+ # "Copy Subsurf Settings from Active to Selected"),
+ # ('obj_smo', "AutoSmooth",
+ # "Copy AutoSmooth from Active to Selected"),
+ ('obj_idx', "Pass Index",
+ "Copy Pass Index from Active to Selected", obIdx),
+ ('obj_mod', "Modifiers",
+ "Copy Modifiers from Active to Selected", obMod),
+ ('obj_wei', "Vertex Weights",
+ "Copy vertex weights based on indices", obWei),
+ ('obj_grp', "Group Links",
+ "Copy selected into active object's groups", obGrp)
+)
@classmethod
@@ -557,10 +554,10 @@ class CopySelectedObjectConstraints(Operator):
bl_idname = "object.copy_selected_constraints"
bl_label = "Copy Selected Constraints"
- selection = BoolVectorProperty(
- size=32,
- options={'SKIP_SAVE'}
- )
+ selection: BoolVectorProperty(
+ size=32,
+ options={'SKIP_SAVE'}
+ )
poll = object_poll_func
invoke = object_invoke_func
@@ -569,7 +566,7 @@ class CopySelectedObjectConstraints(Operator):
layout = self.layout
for idx, const in enumerate(context.active_object.constraints):
layout.prop(self, "selection", index=idx, text=const.name,
- toggle=True)
+ toggle=True)
def execute(self, context):
active = context.active_object
@@ -580,8 +577,8 @@ class CopySelectedObjectConstraints(Operator):
if flag:
old_constraint = active.constraints[index]
new_constraint = obj.constraints.new(
- active.constraints[index].type
- )
+ active.constraints[index].type
+ )
generic_copy(old_constraint, new_constraint)
return{'FINISHED'}
@@ -591,10 +588,10 @@ class CopySelectedObjectModifiers(Operator):
bl_idname = "object.copy_selected_modifiers"
bl_label = "Copy Selected Modifiers"
- selection = BoolVectorProperty(
- size=32,
- options={'SKIP_SAVE'}
- )
+ selection: BoolVectorProperty(
+ size=32,
+ options={'SKIP_SAVE'}
+ )
poll = object_poll_func
invoke = object_invoke_func
@@ -603,7 +600,7 @@ class CopySelectedObjectModifiers(Operator):
layout = self.layout
for idx, const in enumerate(context.active_object.modifiers):
layout.prop(self, 'selection', index=idx, text=const.name,
- toggle=True)
+ toggle=True)
def execute(self, context):
active = context.active_object
@@ -614,9 +611,9 @@ class CopySelectedObjectModifiers(Operator):
if flag:
old_modifier = active.modifiers[index]
new_modifier = obj.modifiers.new(
- type=active.modifiers[index].type,
- name=active.modifiers[index].name
- )
+ type=active.modifiers[index].type,
+ name=active.modifiers[index].name
+ )
generic_copy(old_modifier, new_modifier)
return{'FINISHED'}
@@ -664,23 +661,23 @@ class MESH_MT_CopyFaceSettings(Menu):
layout = self.layout
op = layout.operator(MESH_OT_CopyFaceSettings.bl_idname,
- text="Copy Material")
+ text="Copy Material")
op['layer'] = ''
op['mode'] = 'MAT'
if mesh.uv_textures.active:
op = layout.operator(MESH_OT_CopyFaceSettings.bl_idname,
- text="Copy Active UV Image")
+ text="Copy Active UV Image")
op['layer'] = ''
op['mode'] = 'IMAGE'
op = layout.operator(MESH_OT_CopyFaceSettings.bl_idname,
- text="Copy Active UV Coords")
+ text="Copy Active UV Coords")
op['layer'] = ''
op['mode'] = 'UV'
if mesh.vertex_colors.active:
op = layout.operator(MESH_OT_CopyFaceSettings.bl_idname,
- text="Copy Active Vertex Colors")
+ text="Copy Active Vertex Colors")
op['layer'] = ''
op['mode'] = 'VCOL'
@@ -704,7 +701,7 @@ class MESH_MT_CopyImagesFromLayer(Menu):
def poll(cls, context):
obj = context.active_object
return obj and obj.mode == "EDIT_MESH" and len(
- obj.data.uv_layers) > 1
+ obj.data.uv_layers) > 1
def draw(self, context):
mesh = context.active_object.data
@@ -718,7 +715,7 @@ class MESH_MT_CopyUVCoordsFromLayer(Menu):
def poll(cls, context):
obj = context.active_object
return obj and obj.mode == "EDIT_MESH" and len(
- obj.data.uv_layers) > 1
+ obj.data.uv_layers) > 1
def draw(self, context):
mesh = context.active_object.data
@@ -732,7 +729,7 @@ class MESH_MT_CopyVertexColorsFromLayer(Menu):
def poll(cls, context):
obj = context.active_object
return obj and obj.mode == "EDIT_MESH" and len(
- obj.data.vertex_colors) > 1
+ obj.data.vertex_colors) > 1
def draw(self, context):
mesh = context.active_object.data
@@ -759,14 +756,14 @@ class MESH_OT_CopyFaceSettings(Operator):
bl_label = "Copy Face Settings"
bl_options = {'REGISTER', 'UNDO'}
- mode = StringProperty(
- name="Mode",
- options={"HIDDEN"},
- )
- layer = StringProperty(
- name="Layer",
- options={"HIDDEN"},
- )
+ mode: StringProperty(
+ name="Mode",
+ options={"HIDDEN"},
+ )
+ layer: StringProperty(
+ name="Layer",
+ options={"HIDDEN"},
+ )
@classmethod
def poll(cls, context):
@@ -838,8 +835,25 @@ class MESH_OT_CopyFaceSettings(Operator):
return(retval)
+classes = (
+ CopySelectedPoseConstraints,
+ VIEW3D_MT_posecopypopup,
+ CopySelectedObjectConstraints,
+ CopySelectedObjectModifiers,
+ VIEW3D_MT_copypopup,
+ MESH_MT_CopyFaceSettings,
+ MESH_MT_CopyImagesFromLayer,
+ MESH_MT_CopyUVCoordsFromLayer,
+ MESH_MT_CopyVertexColorsFromLayer,
+ MESH_OT_CopyFaceSettings,
+ *pose_ops,
+ *object_ops,
+)
+
def register():
- bpy.utils.register_module(__name__)
+ from bpy.utils import register_class
+ for cls in classes:
+ register_class(cls)
# mostly to get the keymap working
kc = bpy.context.window_manager.keyconfigs.addon
@@ -888,7 +902,9 @@ def unregister():
if kmi.properties.name == 'VIEW3D_MT_copypopup':
km.keymap_items.remove(kmi)
- bpy.utils.unregister_module(__name__)
+ from bpy.utils import unregister_class
+ for cls in classes:
+ unregister_class(cls)
if __name__ == "__main__":
diff --git a/space_view3d_display_tools/__init__.py b/space_view3d_display_tools/__init__.py
index 58699f98..462f417e 100644
--- a/space_view3d_display_tools/__init__.py
+++ b/space_view3d_display_tools/__init__.py
@@ -80,7 +80,7 @@ class DisplayToolsPanel(Panel):
bl_category = "Display"
bl_options = {'DEFAULT_CLOSED'}
- draw_type_icons = {
+ display_type_icons = {
'BOUNDS': 'BBOX',
'WIRE': 'WIRE',
'SOLID': 'SOLID',
@@ -142,7 +142,7 @@ class DisplayToolsPanel(Panel):
col.prop(view, "show_all_objects_origin", toggle=True)
col.prop(view, "show_backface_culling", toggle=True)
if obj:
- col.prop(obj, "show_x_ray", text="X-Ray", toggle=True)
+ col.prop(obj, "show_in_front", text="X-Ray", toggle=True)
if obj and obj_type == 'MESH':
col.prop(obj, "show_transparent", text="Transparency", toggle=True)
@@ -176,8 +176,8 @@ class DisplayToolsPanel(Panel):
if obj:
col = layout.column(align=True)
col.alignment = 'EXPAND'
- col.label(text="Maximum:")
- col.prop(obj, "draw_type", text="", icon=self.draw_type_icons[obj.draw_type])
+ col.label(text="Display As:")
+ col.prop(obj, "display_type", text="", icon=self.display_type_icons[obj.display_type])
col = layout.column(align=True)
col.alignment = 'CENTER'
@@ -394,7 +394,7 @@ class DisplayToolsPanel(Panel):
row.prop(display_tools, "UiTabDrop", index=4, text="Selection", icon=icon_active_4)
if not SELECT2DROP:
- row.operator("view3d.select_border", text="", icon="MESH_PLANE")
+ row.operator("view3d.select_box", text="", icon="MESH_PLANE")
row.operator("view3d.select_circle", text="", icon="MESH_CIRCLE")
row.label(text="", icon="BLANK1")
else:
diff --git a/space_view3d_display_tools/display.py b/space_view3d_display_tools/display.py
index d0310ee8..6c1c6796 100644
--- a/space_view3d_display_tools/display.py
+++ b/space_view3d_display_tools/display.py
@@ -82,10 +82,10 @@ class DisplayDrawChange(Operator, BasePollCheck):
if not selection:
for obj in bpy.data.objects:
- obj.draw_type = self.drawing
+ obj.display_type = self.drawing
else:
for obj in selection:
- obj.draw_type = self.drawing
+ obj.display_type = self.drawing
except:
self.report({'ERROR'}, "Setting Draw Type could not be applied")
return {'CANCELLED'}
@@ -110,12 +110,12 @@ class DisplayBoundsSwitch(Operator, BasePollCheck):
for obj in bpy.data.objects:
obj.show_bounds = self.bounds
if self.bounds:
- obj.draw_bounds_type = scene.BoundingMode
+ obj.display_bounds_type = scene.BoundingMode
else:
for obj in selection:
obj.show_bounds = self.bounds
if self.bounds:
- obj.draw_bounds_type = scene.BoundingMode
+ obj.display_bounds_type = scene.BoundingMode
except:
self.report({'ERROR'}, "Display/Hide Bounding box overlay failed")
return {'CANCELLED'}
@@ -164,10 +164,10 @@ class DisplayXRayOn(Operator, BasePollCheck):
if not selection:
for obj in bpy.data.objects:
- obj.show_x_ray = self.xrays
+ obj.show_in_front = self.xrays
else:
for obj in selection:
- obj.show_x_ray = self.xrays
+ obj.show_in_front = self.xrays
except:
self.report({'ERROR'}, "Turn on/off X-ray mode failed")
return {'CANCELLED'}
diff --git a/space_view3d_display_tools/fast_navigate.py b/space_view3d_display_tools/fast_navigate.py
index 269aec2c..5d61138a 100644
--- a/space_view3d_display_tools/fast_navigate.py
+++ b/space_view3d_display_tools/fast_navigate.py
@@ -43,14 +43,14 @@ def display_particles(mode, dis_particles):
for particles in bpy.data.particles:
if scene.ShowParticles is False:
- particles.draw_method = 'NONE'
+ particles.display_method = 'NONE'
else:
if particles.type == 'EMITTER':
- particles.draw_method = 'DOT'
- particles.draw_percentage = 100
+ particles.display_method = 'DOT'
+ particles.display_percentage = 100
else:
- particles.draw_method = 'RENDER'
- particles.draw_percentage = dis_particles
+ particles.display_method = 'RENDER'
+ particles.display_percentage = dis_particles
return dis_particles
@@ -149,15 +149,15 @@ class FastNavigate(Operator):
self.store_viewport_shade = shade
for particle in bpy.data.particles:
self.store_init_particles[particle.name] = \
- [particle.draw_method, particle.draw_percentage]
+ [particle.display_method, particle.display_percentage]
else:
if not shade:
self.store_fail = True
else:
shade = self.store_viewport_shade or 'SOLID'
for particle in bpy.data.particles:
- particle.draw_method = self.store_init_particles[particle.name][0]
- particle.draw_percentage = self.store_init_particles[particle.name][1]
+ particle.display_method = self.store_init_particles[particle.name][0]
+ particle.display_percentage = self.store_init_particles[particle.name][1]
except:
self.store_fail = True
diff --git a/space_view3d_display_tools/select_tools.py b/space_view3d_display_tools/select_tools.py
index 95dc4ff2..2eb79dfc 100644
--- a/space_view3d_display_tools/select_tools.py
+++ b/space_view3d_display_tools/select_tools.py
@@ -65,7 +65,7 @@ class ShowHideObject(Operator):
i.hide = True
i.select = False
- if i.type not in ['CAMERA', 'LAMP']:
+ if i.type not in ['CAMERA', 'LIGHT']:
i.hide_render = True
except:
continue
@@ -103,7 +103,7 @@ class HideAllObjects(Operator):
i.hide = True
i.select = False
- if i.type not in ['CAMERA', 'LAMP']:
+ if i.type not in ['CAMERA', 'LIGHT']:
i.hide_render = True
else:
obj_name = context.object.name
@@ -113,7 +113,7 @@ class HideAllObjects(Operator):
i.hide = True
i.select = False
- if i.type not in ['CAMERA', 'LAMP']:
+ if i.type not in ['CAMERA', 'LIGHT']:
i.hide_render = True
return {'FINISHED'}
@@ -232,11 +232,11 @@ class OBJECT_OT_HideShowByTypeTemplate():
('LATTICE', 'Lattice', ''),
('EMPTY', 'Empty', ''),
('CAMERA', 'Camera', ''),
- ('LAMP', 'Lamp', ''),
+ ('LIGHT', 'Lamp', ''),
('ALL', 'All', '')),
name="Type",
description="Type",
- default='LAMP',
+ default='LIGHT',
options={'ANIMATABLE'}
)
diff --git a/space_view3d_display_tools/selection_restrictor.py b/space_view3d_display_tools/selection_restrictor.py
index feb3b8b8..71561bfe 100644
--- a/space_view3d_display_tools/selection_restrictor.py
+++ b/space_view3d_display_tools/selection_restrictor.py
@@ -45,7 +45,7 @@ curve = 'OUTLINER_OB_CURVE'
arm = 'OUTLINER_OB_ARMATURE'
empty = 'OUTLINER_OB_EMPTY'
cam = 'OUTLINER_OB_CAMERA'
-lamp = 'OUTLINER_OB_LAMP'
+lamp = 'OUTLINER_OB_LIGHT'
lat = 'OUTLINER_OB_LATTICE'
font = 'OUTLINER_OB_FONT'
meta = 'OUTLINER_OB_META'
@@ -135,10 +135,10 @@ def check_restrictors(dummy):
# lamp
if bpy.context.scene.get('lamprestrictor') is None:
lamprestrictorenabled = True
- lamp = 'OUTLINER_OB_LAMP'
+ lamp = 'OUTLINER_OB_LIGHT'
else:
lamprestrictorenabled = False
- lamp = 'LAMP_DATA'
+ lamp = 'LIGHT_DATA'
# lattice
if bpy.context.scene.get('latrestrictor') is None:
@@ -408,7 +408,7 @@ class RestrictorCam(Operator):
# Restrictor for Lamps
class RestrictorLamp(Operator):
- bl_idname = "restrictor.lamp"
+ bl_idname = "restrictor.light"
bl_label = "Restrictor Lamps"
bl_option = {'REGISTER', 'UNDO'}
bl_description = "Lamps selection restrictor"
@@ -421,18 +421,18 @@ class RestrictorLamp(Operator):
lamprestrictorenabled = True
if bpy.context.scene.get('lamprestrictor') is not None:
del bpy.context.scene['lamprestrictor']
- lamp = 'OUTLINER_OB_LAMP'
+ lamp = 'OUTLINER_OB_LIGHT'
for ob in bpy.context.scene.objects:
- if ob.type == 'LAMP':
+ if ob.type == 'LIGHT':
if ob.get('ignore_restrictors') is None:
ob.hide_select = False
else:
lamprestrictorenabled = False
bpy.context.scene['lamprestrictor'] = 1
- lamp = 'LAMP_DATA'
+ lamp = 'LIGHT_DATA'
for ob in bpy.context.scene.objects:
- if ob.type == 'LAMP':
+ if ob.type == 'LIGHT':
if ob.get('ignore_restrictors') is None:
ob.hide_select = True
ob.select = False
@@ -638,7 +638,7 @@ class RefreshRestrictors(Operator):
'armrestrictor': ("OUTLINER_OB_ARMATURE", "ARMATURE_DATA", "ARMATURE"),
'emptyrestrictor': ("OUTLINER_OB_EMPTY", "EMPTY_DATA", "EMPTY"),
'camrestrictor': ("OUTLINER_OB_CAMERA", "CAMERA_DATA", "CAMERA"),
- 'lamprestrictor': ("OUTLINER_OB_LAMP", "LAMP_DATA", "LAMP"),
+ 'lamprestrictor': ("OUTLINER_OB_LIGHT", "LIGHT_DATA", "LIGHT"),
'latrestrictor': ("OUTLINER_OB_LATTICE", "LATTICE", "LATTICE"),
'fontrestrictor': ("OUTLINER_OB_FONT", "FONT", "FONT"),
'metarestrictor': ("OUTLINER_OB_META", "META_DATA", "META"),
@@ -664,7 +664,7 @@ class RefreshRestrictors(Operator):
arm = gl_icon if types == "ARMATURE" else arm
empty = gl_icon if types == "EMPTY" else empty
cam = gl_icon if types == "CAMERA" else cam
- lamp = gl_icon if types == "LAMP" else lamp
+ lamp = gl_icon if types == "LIGHT" else lamp
lat = gl_icon if types == "LATTICE" else lat
font = gl_icon if types == "FONT" else font
meta = gl_icon if types == "META" else meta
@@ -701,7 +701,7 @@ class RestrictorSelection(Menu):
layout.operator("restrictor.arm", icon=arm, text="Armature")
layout.operator("restrictor.empty", icon=empty, text="Empty")
layout.operator("restrictor.cam", icon=cam, text="Camera")
- layout.operator("restrictor.lamp", icon=lamp, text="Lamp")
+ layout.operator("restrictor.light", icon=lamp, text="Lamp")
layout.operator("restrictor.lat", icon=lat, text="Lattice")
layout.operator("restrictor.font", icon=font, text="Font")
layout.operator("restrictor.meta", icon=meta, text="MetaBall")
diff --git a/space_view3d_display_tools/useless_tools.py b/space_view3d_display_tools/useless_tools.py
index 512fcf2d..22931423 100644
--- a/space_view3d_display_tools/useless_tools.py
+++ b/space_view3d_display_tools/useless_tools.py
@@ -204,7 +204,7 @@ class UTSubsurfHideSelAll(Operator):
objects = bpy.context.selected_objects if self.selected else bpy.data.objects
for e in objects:
try:
- if e.type not in {"LAMP", "CAMERA", "EMPTY"}:
+ if e.type not in {"LIGHT", "CAMERA", "EMPTY"}:
e.modifiers['Subsurf'].show_viewport = self.show
except Exception as k:
name = getattr(e, "name", "Nameless")
@@ -233,7 +233,7 @@ class UTOptimalDisplaySelAll(Operator):
objects = bpy.context.selected_objects if self.selected else bpy.data.objects
for e in objects:
try:
- if e.type not in {"LAMP", "CAMERA", "EMPTY"}:
+ if e.type not in {"LIGHT", "CAMERA", "EMPTY"}:
e.modifiers['Subsurf'].show_only_control_edges = self.on
except Exception as k:
name = getattr(e, "name", "Nameless")
diff --git a/space_view3d_pie_menus/__init__.py b/space_view3d_pie_menus/__init__.py
index 486d538f..e725995f 100644
--- a/space_view3d_pie_menus/__init__.py
+++ b/space_view3d_pie_menus/__init__.py
@@ -21,20 +21,20 @@
import bpy
from bpy.props import (
- BoolProperty,
- PointerProperty,
- )
+ BoolProperty,
+ PointerProperty,
+)
from bpy.types import (
- PropertyGroup,
- AddonPreferences,
- )
+ PropertyGroup,
+ AddonPreferences,
+)
bl_info = {
"name": "3D Viewport Pie Menus",
"author": "meta-androcto, pitiwazou, chromoly, italic",
"version": (1, 1, 8),
- "blender": (2, 7, 7),
+ "blender": (2, 80, 0),
"description": "Individual Pie Menu Activation List",
"location": "Addons Preferences",
"warning": "",
@@ -149,32 +149,32 @@ def disable_all_modules(self, context):
class PieToolsPreferences(AddonPreferences):
bl_idname = __name__
- enable_all = BoolProperty(
- name="Enable all",
- description="Enable all Pie Modules",
- default=False,
- update=enable_all_modules
- )
- disable_all = BoolProperty(
- name="Disable all",
- description="Disable all Pie Modules",
- default=False,
- update=disable_all_modules
- )
+ enable_all: BoolProperty(
+ name="Enable all",
+ description="Enable all Pie Modules",
+ default=False,
+ update=enable_all_modules
+ )
+ disable_all: BoolProperty(
+ name="Disable all",
+ description="Disable all Pie Modules",
+ default=False,
+ update=disable_all_modules
+ )
def draw(self, context):
layout = self.layout
- split = layout.split(percentage=0.5, align=True)
+ split = layout.split(factor=0.5, align=True)
row = split.row()
row.alignment = "LEFT"
sub_box = row.box()
sub_box.prop(self, "enable_all", emboss=False,
icon="VISIBLE_IPO_ON", icon_only=True)
- row.label("Enable All")
+ row.label(text="Enable All")
row = split.row()
row.alignment = "RIGHT"
- row.label("Disable All")
+ row.label(text="Disable All")
sub_box = row.box()
sub_box.prop(self, "disable_all", emboss=False,
icon="VISIBLE_IPO_OFF", icon_only=True)
@@ -195,42 +195,42 @@ class PieToolsPreferences(AddonPreferences):
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.label(text='{}: {}'.format(info['category'], info['name']))
sub = row.row()
sub.alignment = 'RIGHT'
if info.get('warning'):
- sub.label('', icon='ERROR')
+ sub.label(text='', 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'])
+ split = col.row().split(factor=0.15)
+ split.label(text='Description:')
+ split.label(text=info['description'])
if info.get('location'):
- split = col.row().split(percentage=0.15)
- split.label('Location:')
- split.label(info['location'])
+ split = col.row().split(factor=0.15)
+ split.label(text='Location:')
+ split.label(text=info['location'])
"""
if info.get('author'):
- split = col.row().split(percentage=0.15)
- split.label('Author:')
+ split = col.row().split(factor=0.15)
+ split.label(text='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']),
+ split = col.row().split(factor=0.15)
+ split.label(text='Version:')
+ split.label(text='.'.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')
+ split = col.row().split(factor=0.15)
+ split.label(text='Warning:')
+ split.label(text=' ' + info['warning'], icon='ERROR')
tot_row = int(bool(info.get('wiki_url')))
if tot_row:
- split = col.row().split(percentage=0.15)
+ split = col.row().split(factor=0.15)
split.label(text='Internet:')
if info.get('wiki_url'):
op = split.operator('wm.url_open',
@@ -274,17 +274,17 @@ for mod in sub_modules:
return update
prop = BoolProperty(
- name=info['name'],
- description=info.get('description', ''),
- update=gen_update(mod),
- )
+ name=info['name'],
+ description=info.get('description', ''),
+ update=gen_update(mod),
+ )
setattr(PieToolsPreferences, 'use_' + mod_name, prop)
prop = BoolProperty()
setattr(PieToolsPreferences, 'show_expanded_' + mod_name, prop)
classes = (
PieToolsPreferences,
- )
+)
def register():
diff --git a/space_view3d_pie_menus/pie_align_menu.py b/space_view3d_pie_menus/pie_align_menu.py
index c8ce2e15..39315137 100644
--- a/space_view3d_pie_menus/pie_align_menu.py
+++ b/space_view3d_pie_menus/pie_align_menu.py
@@ -102,7 +102,7 @@ class AlignSelectedXYZ(Operator):
bl_description = "Align Selected Along the chosen axis"
bl_options = {'REGISTER', 'UNDO'}
- axis = EnumProperty(
+ axis: EnumProperty(
name="Axis",
items=[
('X', "X", "X Axis"),
@@ -147,7 +147,7 @@ class AlignToXYZ0(Operator):
bl_description = "Align Active Object To a chosen X, Y or Z equals 0 Location"
bl_options = {'REGISTER', 'UNDO'}
- axis = EnumProperty(
+ axis: EnumProperty(
name="Axis",
items=[
('0', "X", "X Axis"),
@@ -181,7 +181,7 @@ class AlignXYZAll(Operator):
bl_description = "Align to a Front or Back along the chosen Axis"
bl_options = {'REGISTER', 'UNDO'}
- axis = EnumProperty(
+ axis: EnumProperty(
name="Axis",
items=[
('0', "X", "X Axis"),
@@ -191,7 +191,7 @@ class AlignXYZAll(Operator):
description="Choose an axis for alignment",
default='0'
)
- side = EnumProperty(
+ side: EnumProperty(
name="Side",
items=[
('POSITIVE', "Front", "Align on the positive chosen axis"),
diff --git a/space_view3d_pie_menus/pie_apply_transform_menu.py b/space_view3d_pie_menus/pie_apply_transform_menu.py
index e22f23b4..268ee550 100644
--- a/space_view3d_pie_menus/pie_apply_transform_menu.py
+++ b/space_view3d_pie_menus/pie_apply_transform_menu.py
@@ -71,7 +71,7 @@ class ApplyTransLocRotPie(Operator):
bl_description = "Apply Transform: Location, Rotation or Scale"
bl_options = {'REGISTER', 'UNDO'}
- option = EnumProperty(
+ option: EnumProperty(
name="Type",
items=[
("LOC", "Location", "Apply Location"),
diff --git a/space_view3d_pie_menus/pie_cursor.py b/space_view3d_pie_menus/pie_cursor.py
index 568cdd6d..e598943f 100644
--- a/space_view3d_pie_menus/pie_cursor.py
+++ b/space_view3d_pie_menus/pie_cursor.py
@@ -69,7 +69,7 @@ class Snap_CursorMenu(Menu):
icon='CLIPUV_HLT').use_offset = False
# 6 - RIGHT
pie.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor (Offset)", icon='CURSOR').use_offset = True
+ text="Selection to Cursor (Keep Offset)", icon='CURSOR').use_offset = True
# 2 - BOTTOM
pie.operator("view3d.snap_cursor_selected_to_center1",
text="Selected & Cursor to Center", icon='ALIGN')
diff --git a/space_view3d_pie_menus/pie_editor_switch_menu.py b/space_view3d_pie_menus/pie_editor_switch_menu.py
index 67f40ff8..adbab7c2 100644
--- a/space_view3d_pie_menus/pie_editor_switch_menu.py
+++ b/space_view3d_pie_menus/pie_editor_switch_menu.py
@@ -41,7 +41,7 @@ from bpy.props import (
class AreaPieMenu(Menu):
- bl_idname = "INFO_MT_window_pie"
+ bl_idname = "TOPBAR_MT_window_pie"
bl_label = "Pie Menu"
bl_description = "Window Pie Menus"
@@ -87,7 +87,7 @@ class AreaPieEditor(Menu):
class AreaTypePieOther(Menu):
- bl_idname = "INFO_MT_window_pie_area_type_other"
+ bl_idname = "TOPBAR_MT_window_pie_area_type_other"
bl_label = "Editor Type (other)"
bl_description = "Is pie menu change editor type (other)"
@@ -95,7 +95,7 @@ class AreaTypePieOther(Menu):
# 4 - LEFT
self.layout.operator(SetAreaType.bl_idname, text="Logic Editor", icon="LOGIC").types = "LOGIC_EDITOR"
# 6 - RIGHT
- self.layout.operator(SetAreaType.bl_idname, text="File Browser", icon="FILESEL").types = "FILE_BROWSER"
+ self.layout.operator(SetAreaType.bl_idname, text="File Browser", icon="FILEBROWSER").types = "FILE_BROWSER"
# 2 - BOTTOM
self.layout.operator(SetAreaType.bl_idname, text="Python Console", icon="CONSOLE").types = "CONSOLE"
# 8 - TOP
@@ -114,7 +114,7 @@ class SetAreaType(Operator):
bl_description = "Change Editor Type"
bl_options = {'REGISTER'}
- types = StringProperty(name="Area Type")
+ types: StringProperty(name="Area Type")
def execute(self, context):
context.area.type = self.types
@@ -122,7 +122,7 @@ class SetAreaType(Operator):
class AreaTypePieAnim(Menu):
- bl_idname = "INFO_MT_window_pie_area_type_anim"
+ bl_idname = "TOPBAR_MT_window_pie_area_type_anim"
bl_label = "Editor Type (Animation)"
bl_description = "Menu for changing editor type (animation related)"
diff --git a/space_view3d_pie_menus/pie_manipulator_menu.py b/space_view3d_pie_menus/pie_manipulator_menu.py
index 2690c094..3a599483 100644
--- a/space_view3d_pie_menus/pie_manipulator_menu.py
+++ b/space_view3d_pie_menus/pie_manipulator_menu.py
@@ -37,111 +37,6 @@ from bpy.types import (
)
-class ManipTranslate(Operator):
- bl_idname = "manip.translate"
- bl_label = "Manip Translate"
- bl_options = {'REGISTER', 'UNDO'}
- bl_description = " Show Translate"
-
- def execute(self, context):
- if context.space_data.show_manipulator is False:
- context.space_data.show_manipulator = True
- context.space_data.transform_manipulators = {'TRANSLATE'}
- if context.space_data.transform_manipulators != {'TRANSLATE'}:
- context.space_data.transform_manipulators = {'TRANSLATE'}
- return {'FINISHED'}
-
-
-class ManipRotate(Operator):
- bl_idname = "manip.rotate"
- bl_label = "Manip Rotate"
- bl_options = {'REGISTER', 'UNDO'}
- bl_description = " Show Rotate"
-
- def execute(self, context):
- if context.space_data.show_manipulator is False:
- context.space_data.show_manipulator = True
- context.space_data.transform_manipulators = {'ROTATE'}
- if context.space_data.transform_manipulators != {'ROTATE'}:
- context.space_data.transform_manipulators = {'ROTATE'}
- return {'FINISHED'}
-
-
-class ManipScale(Operator):
- bl_idname = "manip.scale"
- bl_label = "Manip Scale"
- bl_options = {'REGISTER', 'UNDO'}
- bl_description = " Show Scale"
-
- def execute(self, context):
- if context.space_data.show_manipulator is False:
- context.space_data.show_manipulator = True
- context.space_data.transform_manipulators = {'SCALE'}
- if context.space_data.transform_manipulators != {'SCALE'}:
- context.space_data.transform_manipulators = {'SCALE'}
- return {'FINISHED'}
-
-
-class TranslateRotate(Operator):
- bl_idname = "translate.rotate"
- bl_label = "Translate Rotate"
- bl_options = {'REGISTER', 'UNDO'}
- bl_description = " Show Translate/Rotate"
-
- def execute(self, context):
- if context.space_data.show_manipulator is False:
- context.space_data.show_manipulator = True
- context.space_data.transform_manipulators = {'TRANSLATE', 'ROTATE'}
- if context.space_data.transform_manipulators != {'TRANSLATE', 'ROTATE'}:
- context.space_data.transform_manipulators = {'TRANSLATE', 'ROTATE'}
- return {'FINISHED'}
-
-
-class TranslateScale(Operator):
- bl_idname = "translate.scale"
- bl_label = "Translate Scale"
- bl_options = {'REGISTER', 'UNDO'}
- bl_description = " Show Translate/Scale"
-
- def execute(self, context):
- if context.space_data.show_manipulator is False:
- context.space_data.show_manipulator = True
- context.space_data.transform_manipulators = {'TRANSLATE', 'SCALE'}
- if context.space_data.transform_manipulators != {'TRANSLATE', 'SCALE'}:
- context.space_data.transform_manipulators = {'TRANSLATE', 'SCALE'}
- return {'FINISHED'}
-
-
-class RotateScale(Operator):
- bl_idname = "rotate.scale"
- bl_label = "Rotate Scale"
- bl_options = {'REGISTER', 'UNDO'}
- bl_description = " Show Rotate/Scale"
-
- def execute(self, context):
- if context.space_data.show_manipulator is False:
- context.space_data.show_manipulator = True
- context.space_data.transform_manipulators = {'ROTATE', 'SCALE'}
- if context.space_data.transform_manipulators != {'ROTATE', 'SCALE'}:
- context.space_data.transform_manipulators = {'ROTATE', 'SCALE'}
- return {'FINISHED'}
-
-
-class TranslateRotateScale(Operator):
- bl_idname = "translate.rotatescale"
- bl_label = "Translate Rotate Scale"
- bl_options = {'REGISTER', 'UNDO'}
- bl_description = "Show All"
-
- def execute(self, context):
- if context.space_data.show_manipulator is False:
- context.space_data.show_manipulator = True
- context.space_data.transform_manipulators = {'TRANSLATE', 'ROTATE', 'SCALE'}
- if context.space_data.transform_manipulators != {'TRANSLATE', 'ROTATE', 'SCALE'}:
- context.space_data.transform_manipulators = {'TRANSLATE', 'ROTATE', 'SCALE'}
- return {'FINISHED'}
-
-
class WManupulators(Operator):
bl_idname = "w.manupulators"
bl_label = "W Manupulators"
@@ -168,32 +63,17 @@ class PieManipulator(Menu):
layout = self.layout
pie = layout.menu_pie()
# 4 - LEFT
- pie.operator("rotate.scale", text="Rotate/Scale")
+ pie.operator("wm.tool_set_by_name", text="Translate", icon='MAN_TRANS').name = "Move"
# 6 - RIGHT
- pie.operator("manip.rotate", text="Rotate", icon='MAN_ROT')
+ pie.operator("wm.tool_set_by_name", text="Scale", icon='MAN_SCALE').name = "Scale"
# 2 - BOTTOM
- pie.operator("translate.rotatescale", text="Translate/Rotate/Scale")
+ pie.operator("wm.tool_set_by_name", text="Rotate", icon='MAN_ROT').name = "Rotate"
# 8 - TOP
pie.operator("w.manupulators", text="Show/Hide Toggle", icon='MANIPUL')
- # 7 - TOP - LEFT
- pie.operator("translate.rotate", text="Translate/Rotate")
- # 9 - TOP - RIGHT
- pie.operator("manip.translate", text="Translate", icon='MAN_TRANS')
- # 1 - BOTTOM - LEFT
- pie.operator("translate.scale", text="Translate/Scale")
- # 3 - BOTTOM - RIGHT
- pie.operator("manip.scale", text="Scale", icon='MAN_SCALE')
classes = (
PieManipulator,
- ManipTranslate,
- ManipRotate,
- ManipScale,
- TranslateRotate,
- TranslateScale,
- RotateScale,
- TranslateRotateScale,
WManupulators,
)
diff --git a/space_view3d_pie_menus/pie_modes_menu.py b/space_view3d_pie_menus/pie_modes_menu.py
index 40f6ba4a..74c0b79d 100644
--- a/space_view3d_pie_menus/pie_modes_menu.py
+++ b/space_view3d_pie_menus/pie_modes_menu.py
@@ -163,7 +163,7 @@ class SetObjectModePie(Operator):
bl_description = "I set the interactive mode of object"
bl_options = {'REGISTER'}
- mode = bpy.props.StringProperty(name="Interactive mode", default="OBJECT")
+ mode: bpy.props.StringProperty(name="Interactive mode", default="OBJECT")
def execute(self, context):
if (context.active_object):
@@ -429,7 +429,7 @@ class PieObjectEditMode(Menu):
pie.operator("view3d.pie_interactive_mode_grease_pencil", icon="GREASEPENCIL")
else:
message = "Active Object has only Object Mode available" if ob \
- and ob.type in {"LAMP", "CAMERA", "EMPTY", "SPEAKER"} else \
+ and ob.type in {"LIGHT", "CAMERA", "EMPTY", "SPEAKER"} else \
"No active object found. Please select one first"
pie = layout.menu_pie()
pie.separator()
diff --git a/space_view3d_pie_menus/pie_orientation_menu.py b/space_view3d_pie_menus/pie_orientation_menu.py
index a9de9fa6..ea90862a 100644
--- a/space_view3d_pie_menus/pie_orientation_menu.py
+++ b/space_view3d_pie_menus/pie_orientation_menu.py
@@ -44,7 +44,7 @@ class OrientPoll(Operator):
bl_label = "Orientation Poll"
bl_options = {'INTERNAL'}
- space = StringProperty()
+ space: StringProperty()
@classmethod
def poll(cls, context):
diff --git a/space_view3d_pie_menus/pie_save_open_menu.py b/space_view3d_pie_menus/pie_save_open_menu.py
index bdd9b63c..8b7e56e0 100644
--- a/space_view3d_pie_menus/pie_save_open_menu.py
+++ b/space_view3d_pie_menus/pie_save_open_menu.py
@@ -97,9 +97,9 @@ class pie_fileio(Menu):
layout = self.layout
pie = layout.menu_pie()
box = pie.split().column()
- box.menu("INFO_MT_file_import", icon='IMPORT')
+ box.menu("TOPBAR_MT_file_import", icon='IMPORT')
box.separator()
- box.menu("INFO_MT_file_export", icon='EXPORT')
+ box.menu("TOPBAR_MT_file_export", icon='EXPORT')
class ExternalData(Menu):
diff --git a/space_view3d_pie_menus/pie_select_menu.py b/space_view3d_pie_menus/pie_select_menu.py
index 091e18ed..e0e492eb 100644
--- a/space_view3d_pie_menus/pie_select_menu.py
+++ b/space_view3d_pie_menus/pie_select_menu.py
@@ -70,7 +70,7 @@ class PieSelectionsOM(Menu):
# 7 - TOP - LEFT
pie.operator("view3d.select_circle", text="Circle Select", icon='BORDER_LASSO')
# 9 - TOP - RIGHT
- pie.operator("view3d.select_border", text="Border Select", icon='BORDER_RECT')
+ pie.operator("view3d.select_box", text="Box Select", icon='BORDER_RECT')
# 1 - BOTTOM - LEFT
pie.operator("object.select_camera", text="Select Camera", icon='CAMERA_DATA')
# 3 - BOTTOM - RIGHT
@@ -86,7 +86,7 @@ class PieSelectionsEM(Menu):
layout = self.layout
pie = layout.menu_pie()
# 4 - LEFT
- pie.operator("view3d.select_border", text="Border Select",
+ pie.operator("view3d.select_box", text="Box Select",
icon='BORDER_RECT')
# 6 - RIGHT
pie.menu("object.selectloopselection", text="Select Loop Menu", icon='LOOPSEL')
diff --git a/space_view3d_pie_menus/pie_snap_menu.py b/space_view3d_pie_menus/pie_snap_menu.py
index b5ca502c..19b4464f 100644
--- a/space_view3d_pie_menus/pie_snap_menu.py
+++ b/space_view3d_pie_menus/pie_snap_menu.py
@@ -185,7 +185,8 @@ class SnapTargetVariable(Operator):
bl_idname = "object.snaptargetvariable"
bl_label = "Snap Target Variable"
bl_options = {'REGISTER', 'UNDO'}
- variable = bpy.props.StringProperty()
+
+ variable: bpy.props.StringProperty()
@classmethod
def poll(cls, context):
diff --git a/space_view3d_spacebar_menu.py b/space_view3d_spacebar_menu.py
index 0831c0d5..e0dbf8a5 100644
--- a/space_view3d_spacebar_menu.py
+++ b/space_view3d_spacebar_menu.py
@@ -64,8 +64,8 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_AddMenu", icon='OBJECT_DATAMODE')
layout.menu("VIEW3D_MT_View_Directions", icon='ZOOM_ALL')
- layout.menu("VIEW3D_MT_View_Navigation", icon='ROTATE')
- layout.menu("VIEW3D_MT_View_Toggle", icon='SPLITSCREEN')
+ layout.menu("VIEW3D_MT_View_Navigation", icon='PIVOT_BOUNDBOX')
+ layout.menu("VIEW3D_MT_View_Toggle", icon='WORKSPACE')
layout.operator("view3d.snap_cursor_to_center",
text="Cursor to Center")
layout.operator("view3d.snap_cursor_to_grid",
@@ -91,9 +91,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenu", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_object_specials", text="Specials", icon='SOLO_OFF')
@@ -121,16 +121,16 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
layout.menu("VIEW3D_MT_Select_Edit_Mesh", icon='RESTRICT_SELECT_OFF')
layout.menu("VIEW3D_MT_Edit_Multi", icon='VERTEXSEL')
UseSeparator(self, context)
- layout.menu("INFO_MT_mesh_add", text="Add Mesh", icon='OUTLINER_OB_MESH')
+ layout.menu("VIEW3D_MT_mesh_add", text="Add Mesh", icon='OUTLINER_OB_MESH')
layout.menu("VIEW3D_MT_Edit_Mesh", text="Mesh", icon='MESH_DATA')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenuEdit", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_EditCursorMenu", icon='CURSOR')
+ layout.menu("VIEW3D_MT_EditCursorMenu", icon='PIVOT_CURSOR')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_UV_Map", icon='MOD_UVPROJECT')
layout.menu("VIEW3D_MT_edit_mesh_specials", icon='SOLO_OFF')
- layout.menu("VIEW3D_MT_edit_mesh_extrude", icon='ORTHO')
+ layout.menu("VIEW3D_MT_edit_mesh_extrude", icon='XRAY')
UseSeparator(self, context)
layout.operator_menu_enum("object.modifier_add", "type", icon='MODIFIER')
layout.operator_menu_enum("object.constraint_add",
@@ -230,9 +230,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenu", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_object_specials", text="Specials", icon='SOLO_OFF')
@@ -259,13 +259,13 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
layout.menu("VIEW3D_MT_Select_Edit_Curve",
icon='RESTRICT_SELECT_OFF')
UseSeparator(self, context)
- layout.menu("INFO_MT_curve_add", text="Add Curve",
+ layout.menu("VIEW3D_MT_curve_add", text="Add Curve",
icon='OUTLINER_OB_CURVE')
layout.menu("VIEW3D_MT_Edit_Curve", icon='CURVE_DATA')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenu", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR')
layout.menu("VIEW3D_MT_EditCurveCtrlpoints",
icon='CURVE_BEZCURVE')
layout.menu("VIEW3D_MT_EditCurveSpecials",
@@ -294,9 +294,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenu", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_object_specials", text="Specials", icon='SOLO_OFF')
@@ -321,11 +321,11 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL')
layout.menu("VIEW3D_MT_Select_Edit_Surface", icon='RESTRICT_SELECT_OFF')
UseSeparator(self, context)
- layout.menu("INFO_MT_surface_add", text="Add Surface",
+ layout.menu("VIEW3D_MT_surface_add", text="Add Surface",
icon='OUTLINER_OB_SURFACE')
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenu", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR')
UseSeparator(self, context)
layout.prop_menu_enum(settings, "proportional_edit",
icon="PROP_CON")
@@ -357,9 +357,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenu", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_object_specials", text="Specials", icon='SOLO_OFF')
@@ -388,7 +388,7 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
icon='OUTLINER_OB_META')
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenu", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR')
UseSeparator(self, context)
layout.prop_menu_enum(settings, "proportional_edit",
icon="PROP_CON")
@@ -418,9 +418,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenu", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_object_specials", text="Specials", icon='SOLO_OFF')
@@ -470,9 +470,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
layout.menu("VIEW3D_MT_Object", icon='VIEW3D')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
- layout.menu("VIEW3D_MT_CursorMenuLite", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_object_specials", text="Specials", icon='SOLO_OFF')
@@ -489,7 +489,7 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
layout.operator("view3d.properties", icon='MENU_PANEL')
# Lamp Object Mode #
- if obj and obj.type == 'LAMP' and obj.mode in {'OBJECT'}:
+ if obj and obj.type == 'LIGHT' and obj.mode in {'OBJECT'}:
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM')
@@ -501,9 +501,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
layout.menu("VIEW3D_MT_Object", icon='VIEW3D')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenuLite", icon='MANIPUL')
- layout.menu("VIEW3D_MT_CursorMenuLite", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_object_specials", text="Specials", icon='SOLO_OFF')
@@ -533,9 +533,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenuArmature", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenuLite", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_object_specials", text="Specials", icon='SOLO_OFF')
@@ -561,7 +561,7 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
layout.menu("VIEW3D_MT_Select_Edit_Armature",
icon='RESTRICT_SELECT_OFF')
UseSeparator(self, context)
- layout.menu("INFO_MT_armature_add", text="Add Armature",
+ layout.menu("VIEW3D_MT_armature_add", text="Add Armature",
icon='OUTLINER_OB_ARMATURE')
layout.menu("VIEW3D_MT_Edit_Armature", text="Armature",
icon='OUTLINER_DATA_ARMATURE')
@@ -570,8 +570,8 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenuArmatureEdit", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenuLite", icon='CURSOR')
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_armature_specials", icon='SOLO_OFF')
layout.menu("VIEW3D_MT_edit_armature_roll",
icon='BONE_DATA')
@@ -599,10 +599,10 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
layout.menu("VIEW3D_MT_TransformMenuArmaturePose", icon='MANIPUL')
layout.menu("VIEW3D_MT_pose_transform", icon='EMPTY_DATA')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_CursorMenuLite", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR')
layout.menu("VIEW3D_MT_PoseCopy", icon='FILE')
- if arm.draw_type in {'BBONE', 'ENVELOPE'}:
+ if arm.display_type in {'BBONE', 'ENVELOPE'}:
layout.operator("transform.transform",
text="Scale Envelope Distance").mode = 'BONE_SIZE'
@@ -635,9 +635,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenu", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_object_specials", text="Specials", icon='SOLO_OFF')
@@ -666,7 +666,7 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenu", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenu", icon='PIVOT_CURSOR')
UseSeparator(self, context)
layout.prop_menu_enum(settings, "proportional_edit",
icon="PROP_CON")
@@ -695,9 +695,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenuLite", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenuLite", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_object_specials", text="Specials", icon='SOLO_OFF')
@@ -726,9 +726,9 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
layout.menu("VIEW3D_MT_Object", icon='VIEW3D')
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenuLite", icon='MANIPUL')
- layout.menu("VIEW3D_MT_CursorMenuLite", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR')
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_ParentMenu", icon='ROTACTIVE')
+ layout.menu("VIEW3D_MT_ParentMenu", icon='PIVOT_ACTIVE')
layout.menu("VIEW3D_MT_GroupMenu", icon='GROUP')
UseSeparator(self, context)
layout.operator_menu_enum("object.constraint_add",
@@ -754,7 +754,7 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
UseSeparator(self, context)
layout.menu("VIEW3D_MT_TransformMenu", icon='MANIPUL')
layout.menu("VIEW3D_MT_MirrorMenu", icon='MOD_MIRROR')
- layout.menu("VIEW3D_MT_CursorMenuLite", icon='CURSOR')
+ layout.menu("VIEW3D_MT_CursorMenuLite", icon='PIVOT_CURSOR')
UseSeparator(self, context)
layout.prop_menu_enum(settings, "proportional_edit",
icon="PROP_CON")
@@ -807,7 +807,6 @@ class VIEW3D_MT_Object(Menu):
layout.menu("VIEW3D_MT_object_track")
layout.menu("VIEW3D_MT_object_animation")
UseSeparator(self, context)
- layout.menu("VIEW3D_MT_object_game")
layout.menu("VIEW3D_MT_object_showhide")
UseSeparator(self, context)
layout.operator_menu_enum("object.convert", "target")
@@ -821,18 +820,18 @@ class VIEW3D_MT_AddMenu(Menu):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.menu("INFO_MT_mesh_add", text="Add Mesh",
+ layout.menu("VIEW3D_MT_mesh_add", text="Add Mesh",
icon='OUTLINER_OB_MESH')
- layout.menu("INFO_MT_curve_add", text="Add Curve",
+ layout.menu("VIEW3D_MT_curve_add", text="Add Curve",
icon='OUTLINER_OB_CURVE')
- layout.menu("INFO_MT_surface_add", text="Add Surface",
+ layout.menu("VIEW3D_MT_surface_add", text="Add Surface",
icon='OUTLINER_OB_SURFACE')
layout.operator_menu_enum("object.metaball_add", "type",
icon='OUTLINER_OB_META')
layout.operator("object.text_add", text="Add Text",
icon='OUTLINER_OB_FONT')
UseSeparator(self, context)
- layout.menu("INFO_MT_armature_add", text="Add Armature",
+ layout.menu("VIEW3D_MT_armature_add", text="Add Armature",
icon='OUTLINER_OB_ARMATURE')
layout.operator("object.add", text="Lattice",
icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
@@ -842,8 +841,8 @@ class VIEW3D_MT_AddMenu(Menu):
UseSeparator(self, context)
layout.operator("object.camera_add", text="Camera",
icon='OUTLINER_OB_CAMERA')
- layout.operator_menu_enum("object.lamp_add", "type",
- icon="OUTLINER_OB_LAMP")
+ layout.operator_menu_enum("object.light_add", "type",
+ icon="OUTLINER_OB_LIGHT")
UseSeparator(self, context)
layout.operator_menu_enum("object.effector_add", "type",
text="Force Field",
@@ -981,8 +980,10 @@ class VIEW3D_MT_CursorMenu(Menu):
layout.operator("view3d.snap_cursor_to_active",
text="Cursor to Active")
UseSeparator(self, context)
- layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor").use_offset = False
- layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Offset)").use_offset = True
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor").use_offset = False
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor (Keep Offset)").use_offset = True
layout.operator("view3d.snap_selected_to_grid",
text="Selection to Grid")
layout.operator("view3d.snap_cursor_selected_to_center",
@@ -1012,8 +1013,10 @@ class VIEW3D_MT_CursorMenuLite(Menu):
layout.operator("view3d.snap_cursor_to_active",
text="Cursor to Active")
UseSeparator(self, context)
- layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor").use_offset = False
- layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Offset)").use_offset = True
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor").use_offset = False
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor (Keep Offset)").use_offset = True
layout.operator("view3d.snap_selected_to_grid",
text="Selection to Grid")
layout.operator("view3d.snap_cursor_selected_to_center",
@@ -1348,7 +1351,7 @@ class VIEW3D_MT_Edit_Multi(Menu):
prop = layout.operator("wm.context_set_value",
text="Vertex & Face Select",
- icon='ORTHO')
+ icon='XRAY')
prop.value = "(True, False, True)"
prop.data_path = "tool_settings.mesh_select_mode"
@@ -1420,8 +1423,10 @@ class VIEW3D_MT_EditCursorMenu(Menu):
layout.operator("view3d.snap_cursor_to_edge_intersection",
text="Cursor to Edge Intersection")
UseSeparator(self, context)
- layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor").use_offset = False
- layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Offset)").use_offset = True
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor").use_offset = False
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor (Keep Offset)").use_offset = True
layout.operator("view3d.snap_selected_to_grid",
text="Selection to Grid")
UseSeparator(self, context)
@@ -1648,7 +1653,7 @@ class VIEW3D_MT_Hide_Masks(Menu):
props = layout.operator("paint.mask_lasso_gesture", text="Lasso Mask")
UseSeparator(self, context)
- props = layout.operator("view3d.select_border", text="Box Mask", icon="BORDER_RECT")
+ props = layout.operator("view3d.select_box", text="Box Mask", icon="BORDER_RECT")
props = layout.operator("paint.hide_show", text="Box Hide")
props.action = 'HIDE'
props.area = 'INSIDE'
@@ -1890,7 +1895,7 @@ class VIEW3D_MT_TransformMenu(Menu):
layout = self.layout
layout.menu("VIEW3D_MT_ManipulatorMenu1")
UseSeparator(self, context)
- layout.operator("transform.translate", text="Grab/Move")
+ layout.operator("transform.translate", text="Move")
layout.operator("transform.rotate", text="Rotate")
layout.operator("transform.resize", text="Scale")
UseSeparator(self, context)
@@ -1920,7 +1925,7 @@ class VIEW3D_MT_TransformMenuEdit(Menu):
layout = self.layout
layout.menu("VIEW3D_MT_ManipulatorMenu1")
UseSeparator(self, context)
- layout.operator("transform.translate", text="Grab/Move")
+ layout.operator("transform.translate", text="Move")
layout.operator("transform.rotate", text="Rotate")
layout.operator("transform.resize", text="Scale")
UseSeparator(self, context)
@@ -1950,7 +1955,7 @@ class VIEW3D_MT_TransformMenuLite(Menu):
layout = self.layout
layout.menu("VIEW3D_MT_ManipulatorMenu1")
UseSeparator(self, context)
- layout.operator("transform.translate", text="Grab/Move")
+ layout.operator("transform.translate", text="Move")
layout.operator("transform.rotate", text="Rotate")
layout.operator("transform.resize", text="Scale")
UseSeparator(self, context)
@@ -1971,7 +1976,7 @@ class VIEW3D_MT_TransformMenuCamera(Menu):
layout.menu("VIEW3D_MT_ManipulatorMenu1")
layout.menu("VIEW3D_MT_object_clear")
layout.menu("VIEW3D_MT_object_apply")
- layout.operator("transform.translate", text="Grab/Move")
+ layout.operator("transform.translate", text="Move")
layout.operator("transform.rotate", text="Rotate")
layout.operator("transform.resize", text="Scale")
layout.operator("object.align")
@@ -1990,7 +1995,7 @@ class VIEW3D_MT_TransformMenuArmature(Menu):
layout.menu("VIEW3D_MT_ManipulatorMenu1")
UseSeparator(self, context)
- layout.operator("transform.translate", text="Grab/Move")
+ layout.operator("transform.translate", text="Move")
layout.operator("transform.rotate", text="Rotate")
layout.operator("transform.resize", text="Scale")
UseSeparator(self, context)
@@ -2016,7 +2021,7 @@ class VIEW3D_MT_TransformMenuArmatureEdit(Menu):
layout = self.layout
layout.menu("VIEW3D_MT_ManipulatorMenu1")
UseSeparator(self, context)
- layout.operator("transform.translate", text="Grab/Move")
+ layout.operator("transform.translate", text="Move")
layout.operator("transform.rotate", text="Rotate")
layout.operator("transform.resize", text="Scale")
UseSeparator(self, context)
@@ -2038,7 +2043,7 @@ class VIEW3D_MT_TransformMenuArmaturePose(Menu):
def draw(self, context):
layout = self.layout
layout.menu("VIEW3D_MT_ManipulatorMenu1")
- layout.operator("transform.translate", text="Grab/Move")
+ layout.operator("transform.translate", text="Move")
layout.operator("transform.rotate", text="Rotate")
layout.operator("transform.resize", text="Scale")
UseSeparator(self, context)
@@ -2052,9 +2057,9 @@ class VIEW3D_MT_TransformMenuArmaturePose(Menu):
layout.operator("pose.user_transforms_clear", text="Reset unkeyed")
obj = context.object
if obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'}:
- if obj.data.draw_type == 'BBONE':
+ if obj.data.display_type == 'BBONE':
layout.operator("transform.transform", text="Scale BBone").mode = 'BONE_SIZE'
- elif obj.data.draw_type == 'ENVELOPE':
+ elif obj.data.display_type == 'ENVELOPE':
layout.operator("transform.transform", text="Scale Envelope Distance").mode = 'BONE_SIZE'
layout.operator("transform.transform", text="Scale Radius").mode = 'BONE_ENVELOPE'
@@ -2086,7 +2091,7 @@ class VIEW3D_MT_View_Border(Menu):
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("view3d.clip_border", text="Clipping Border...")
layout.operator("view3d.zoom_border", text="Zoom Border...")
- layout.operator("view3d.render_border", text="Render Border...").camera_only = False
+ layout.operator("view3d.render_border", text="Render Border...")
class VIEW3D_MT_View_Toggle(Menu):
@@ -2223,8 +2228,8 @@ class VIEW3D_MT_Shade(Menu):
layout.operator("OBJECT_OT_shade_flat")
UseSeparator(self, context)
- layout.operator("view3d.display_wire_all", text="Wire all", icon='WIRE')
- layout.prop(context.object, "show_x_ray", text="X-Ray", icon="META_CUBE")
+ layout.operator("view3d.display_wire_all", text="Wire all", icon='SHADING_WIRE')
+ layout.prop(context.object, "show_in_front", text="X-Ray", icon="META_CUBE")
UseSeparator(self, context)
layout.prop(context.space_data.fx_settings, "use_ssao",
@@ -2267,7 +2272,7 @@ class VIEW3D_MT_Select_Object(Menu):
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
UseSeparator(self, context)
layout.operator("object.select_all").action = 'TOGGLE'
@@ -2317,7 +2322,7 @@ class VIEW3D_MT_Select_Edit_Mesh(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
UseSeparator(self, context)
layout.operator("mesh.select_all").action = 'TOGGLE'
@@ -2383,7 +2388,7 @@ class VIEW3D_MT_Select_Edit_Curve(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
UseSeparator(self, context)
layout.operator("curve.select_all").action = 'TOGGLE'
@@ -2408,7 +2413,7 @@ class VIEW3D_MT_SelectArmatureMenu(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("armature.select_all")
layout.operator("armature.select_inverse", text="Inverse")
layout.operator("armature.select_hierarchy",
@@ -2432,7 +2437,7 @@ class VIEW3D_MT_Select_Edit_Armature(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
UseSeparator(self, context)
@@ -2475,7 +2480,7 @@ class VIEW3D_MT_Select_Pose(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
UseSeparator(self, context)
layout.operator("pose.select_all").action = 'TOGGLE'
@@ -2556,7 +2561,7 @@ class VIEW3D_MT_Select_Edit_Surface(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
UseSeparator(self, context)
layout.operator("curve.select_all").action = 'TOGGLE'
@@ -2577,7 +2582,7 @@ class VIEW3D_MT_SelectMetaball(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
UseSeparator(self, context)
layout.operator("mball.select_all").action = 'TOGGLE'
@@ -2590,7 +2595,7 @@ class VIEW3D_MT_Select_Edit_Metaball(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
layout.operator("mball.select_all").action = 'TOGGLE'
layout.operator("mball.select_all", text="Inverse").action = 'INVERT'
@@ -2615,7 +2620,7 @@ class VIEW3D_MT_Select_Particle(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
UseSeparator(self, context)
@@ -2642,7 +2647,7 @@ class VIEW3D_MT_Select_Edit_Lattice(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
UseSeparator(self, context)
layout.operator("lattice.select_mirror")
@@ -2662,7 +2667,7 @@ class VIEW3D_MT_Select_Gpencil(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("gpencil.select_border")
+ layout.operator("gpencil.select_box")
layout.operator("gpencil.select_circle")
UseSeparator(self, context)
@@ -2700,7 +2705,7 @@ class VIEW3D_MT_Select_Paint_Mask(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
layout.operator("paint.face_select_all").action = 'TOGGLE'
layout.operator("paint.face_select_all", text="Inverse").action = 'INVERT'
@@ -2712,7 +2717,7 @@ class VIEW3D_MT_Select_Paint_Mask_Vertex(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.select_border")
+ layout.operator("view3d.select_box")
layout.operator("view3d.select_circle")
layout.operator("paint.vert_select_all").action = 'TOGGLE'
layout.operator("paint.vert_select_all", text="Inverse").action = 'INVERT'
diff --git a/system_blend_info.py b/system_blend_info.py
index 8b2a0939..65b1d9f9 100644
--- a/system_blend_info.py
+++ b/system_blend_info.py
@@ -102,10 +102,10 @@ class OBJECT_PT_blendinfo(bpy.types.Panel):
icon='CAMERA_DATA')
row = ob_cols[1].row()
- lamps = [o for o in objects.values() if o.type == 'LAMP']
+ lamps = [o for o in objects.values() if o.type == 'LIGHT']
num = len(lamps)
row.label(text=quantity_string(num, "Lamp", "Lamps"),
- icon='LAMP_DATA')
+ icon='LIGHT_DATA')
row = ob_cols[0].row()
armatures = [o for o in objects.values() if o.type == 'ARMATURE']
@@ -159,9 +159,9 @@ class OBJECT_PT_blendinfo(bpy.types.Panel):
icon='CAMERA_DATA')
row = db_cols[1].row()
- num = len(bpy.data.lamps)
+ num = len(bpy.data.lights)
row.label(text=quantity_string(num, "Lamp", "Lamps"),
- icon='LAMP_DATA')
+ icon='LIGHT_DATA')
row = db_cols[0].row()
num = len(bpy.data.armatures)
diff --git a/system_demo_mode/__init__.py b/system_demo_mode/__init__.py
index 000fcef1..75eb38ba 100644
--- a/system_demo_mode/__init__.py
+++ b/system_demo_mode/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Demo Mode",
"author": "Campbell Barton",
- "blender": (2, 57, 0),
+ "blender": (2, 80, 0),
"location": "Demo Menu",
"description": "Demo mode lets you select multiple blend files and loop over them.",
"warning": "",
@@ -39,12 +39,12 @@ if "bpy" in locals():
import bpy
from bpy.props import (
- StringProperty,
- BoolProperty,
- IntProperty,
- FloatProperty,
- EnumProperty,
- )
+ StringProperty,
+ BoolProperty,
+ IntProperty,
+ FloatProperty,
+ EnumProperty,
+)
class DemoModeSetup(bpy.types.Operator):
@@ -57,85 +57,84 @@ class DemoModeSetup(bpy.types.Operator):
# to the class instance from the operator settings before calling.
# these are used to create the file list.
- directory = StringProperty(
- name="Search Path",
- description="Directory used for importing the file",
- maxlen=1024,
- subtype='DIR_PATH',
- )
- random_order = BoolProperty(
- name="Random Order",
- description="Select files randomly",
- default=False,
- )
- mode = EnumProperty(
- name="Method",
- items=(('AUTO', "Auto", ""),
- ('PLAY', "Play", ""),
- ('RENDER', "Render", ""),
- ),
- )
-
- run = BoolProperty(
- name="Run Immediately!",
- description="Run demo immediately",
- default=True,
- )
- exit = BoolProperty(
- name="Exit",
- description="Run once and exit",
- default=False,
- )
+ directory: StringProperty(
+ name="Search Path",
+ description="Directory used for importing the file",
+ maxlen=1024,
+ subtype='DIR_PATH',
+ )
+ random_order: BoolProperty(
+ name="Random Order",
+ description="Select files randomly",
+ default=False,
+ )
+ mode: EnumProperty(
+ name="Method",
+ items=(('AUTO', "Auto", ""),
+ ('PLAY', "Play", ""),
+ ('RENDER', "Render", ""))
+ )
+
+ run: BoolProperty(
+ name="Run Immediately!",
+ description="Run demo immediately",
+ default=True,
+ )
+ exit: BoolProperty(
+ name="Exit",
+ description="Run once and exit",
+ default=False,
+ )
# these are mapped directly to the config!
#
# anim
# ====
- anim_cycles = IntProperty(
- name="Cycles",
- description="Number of times to play the animation",
- min=1, max=1000,
- default=2,
- )
- anim_time_min = FloatProperty(
- name="Time Min",
- description="Minimum number of seconds to show the animation for "
- "(for small loops)",
- min=0.0, max=1000.0,
- soft_min=1.0, soft_max=1000.0,
- default=4.0,
- )
- anim_time_max = FloatProperty(
- name="Time Max",
- description="Maximum number of seconds to show the animation for "
- "(in case the end frame is very high for no reason)",
- min=0.0, max=100000000.0,
- soft_min=1.0, soft_max=100000000.0,
- default=8.0,
- )
- anim_screen_switch = FloatProperty(
- name="Screen Switch",
- description="Time between switching screens (in seconds) "
- "or 0 to disable",
- min=0.0, max=100000000.0,
- soft_min=1.0, soft_max=60.0,
- default=0.0,
- )
+ anim_cycles: IntProperty(
+ name="Cycles",
+ description="Number of times to play the animation",
+ min=1, max=1000,
+ default=2,
+ )
+ anim_time_min: FloatProperty(
+ name="Time Min",
+ description="Minimum number of seconds to show the animation for "
+ "(for small loops)",
+ min=0.0, max=1000.0,
+ soft_min=1.0, soft_max=1000.0,
+ default=4.0,
+ )
+ anim_time_max: FloatProperty(
+ name="Time Max",
+ description="Maximum number of seconds to show the animation for "
+ "(in case the end frame is very high for no reason)",
+ min=0.0, max=100000000.0,
+ soft_min=1.0, soft_max=100000000.0,
+ default=8.0,
+ )
+ anim_screen_switch: FloatProperty(
+ name="Screen Switch",
+ description="Time between switching screens (in seconds) "
+ "or 0 to disable",
+ min=0.0, max=100000000.0,
+ soft_min=1.0, soft_max=60.0,
+ default=0.0,
+ )
#
# render
# ======
- display_render = FloatProperty(
- name="Render Delay",
- description="Time to display the rendered image before moving on "
- "(in seconds)",
- min=0.0, max=60.0,
- default=4.0,
- )
- anim_render = BoolProperty(
- name="Render Anim",
- description="Render entire animation (render mode only)",
- default=False,
- )
+ display_render: FloatProperty(
+ name="Render Delay",
+ description="Time to display the rendered image before moving on "
+ "(in seconds)",
+ min=0.0, max=60.0,
+ default=4.0,
+ )
+ anim_render: BoolProperty(
+ name="Render Anim",
+ description="Render entire animation (render mode only)",
+ default=False,
+ )
def execute(self, context):
from . import config
@@ -168,13 +167,13 @@ class DemoModeSetup(bpy.types.Operator):
layout = self.layout
box = layout.box()
- box.label("Search *.blend recursively")
- box.label("Writes: demo.py config text")
+ box.label(text="Search *.blend recursively")
+ box.label(text="Writes: demo.py config text")
layout.prop(self, "run")
layout.prop(self, "exit")
- layout.label("Generate Settings:")
+ layout.label(text="Generate Settings:")
row = layout.row()
row.prop(self, "mode", expand=True)
layout.prop(self, "random_order")
@@ -184,7 +183,7 @@ class DemoModeSetup(bpy.types.Operator):
layout.separator()
sub = layout.column()
sub.active = (mode in {'AUTO', 'PLAY'})
- sub.label("Animate Settings:")
+ sub.label(text="Animate Settings:")
sub.prop(self, "anim_cycles")
sub.prop(self, "anim_time_min")
sub.prop(self, "anim_time_max")
@@ -193,7 +192,7 @@ class DemoModeSetup(bpy.types.Operator):
layout.separator()
sub = layout.column()
sub.active = (mode in {'AUTO', 'RENDER'})
- sub.label("Render Settings:")
+ sub.label(text="Render Settings:")
sub.prop(self, "display_render")
@@ -248,7 +247,7 @@ def register():
bpy.utils.register_class(DemoModeSetup)
bpy.utils.register_class(DemoModeRun)
- bpy.types.INFO_MT_file.prepend(menu_func)
+ bpy.types.TOPBAR_MT_file.prepend(menu_func)
extern_demo_mode_register()
@@ -257,7 +256,7 @@ def unregister():
bpy.utils.unregister_class(DemoModeSetup)
bpy.utils.unregister_class(DemoModeRun)
- bpy.types.INFO_MT_file.remove(menu_func)
+ bpy.types.TOPBAR_MT_file.remove(menu_func)
extern_demo_mode_unregister()
diff --git a/system_demo_mode/demo_mode.py b/system_demo_mode/demo_mode.py
index 9b94378c..1a717a5e 100644
--- a/system_demo_mode/demo_mode.py
+++ b/system_demo_mode/demo_mode.py
@@ -154,7 +154,7 @@ def demo_mode_next_file(step=1):
def demo_mode_timer_add():
- global_state["timer"] = bpy.context.window_manager.event_timer_add(0.8, bpy.context.window)
+ global_state["timer"] = bpy.context.window_manager.event_timer_add(0.8, window=bpy.context.window)
def demo_mode_timer_remove():
@@ -418,12 +418,12 @@ class DemoModeControl(bpy.types.Operator):
bl_idname = "wm.demo_mode_control"
bl_label = "Control"
- mode = bpy.props.EnumProperty(items=(
- ('PREV', "Prev", ""),
- ('PAUSE', "Pause", ""),
- ('NEXT', "Next", ""),
- ),
- name="Mode")
+ mode: bpy.props.EnumProperty(
+ items=(('PREV', "Prev", ""),
+ ('PAUSE', "Pause", ""),
+ ('NEXT', "Next", "")),
+ name="Mode"
+ )
def execute(self, context):
mode = self.mode
@@ -441,7 +441,7 @@ def menu_func(self, context):
layout = self.layout
layout.operator_context = 'EXEC_DEFAULT'
row = layout.row(align=True)
- row.label("Demo Mode:")
+ row.label(text="Demo Mode:")
if not DemoMode.enabled:
row.operator("wm.demo_mode", icon='PLAY', text="")
else:
diff --git a/system_property_chart.py b/system_property_chart.py
index 028786c9..3fc5ff13 100644
--- a/system_property_chart.py
+++ b/system_property_chart.py
@@ -179,8 +179,8 @@ def _property_chart_draw(self, context):
col.label(text="Properties")
row = col.row(align=True)
row.menu("SCENE_MT_properties_presets", text=bpy.types.SCENE_MT_properties_presets.bl_label)
- row.operator("scene.properties_preset_add", text="", icon="ZOOMIN")
- row.operator("scene.properties_preset_add", text="", icon="ZOOMOUT").remove_active = True
+ row.operator("scene.properties_preset_add", text="", icon='ADD')
+ row.operator("scene.properties_preset_add", text="", icon='REMOVE').remove_active = True
# edit the display props
col.prop(id_storage, self._PROP_STORAGE_ID, text="")
diff --git a/ui_layer_manager.py b/ui_layer_manager.py
index 018aad26..d3e20e69 100644
--- a/ui_layer_manager.py
+++ b/ui_layer_manager.py
@@ -277,11 +277,11 @@ class SCENE_OT_namedlayer_toggle_wire(Operator):
group_layers = scene.layergroups[group_idx].layers
layers = obj.layers
if True in {layer and group_layer for layer, group_layer in zip(layers, group_layers)}:
- obj.draw_type = display
+ obj.display_type = display
scene.layergroups[group_idx].use_wire = use_wire
else:
if obj.layers[layer_idx]:
- obj.draw_type = display
+ obj.display_type = display
scene.namedlayers.layers[layer_idx].use_wire = use_wire
return {'FINISHED'}
@@ -580,8 +580,8 @@ class SCENE_PT_namedlayer_groups(Panel):
row.template_list("SCENE_UL_namedlayer_groups", "", scene, "layergroups", scene, "layergroups_index")
col = row.column(align=True)
- col.operator("scene.namedlayer_group_add", icon='ZOOMIN', text="").layers = scene.layers
- col.operator("scene.namedlayer_group_remove", icon='ZOOMOUT', text="").group_idx = group_idx
+ col.operator("scene.namedlayer_group_add", icon='ADD', text="").layers = scene.layers
+ col.operator("scene.namedlayer_group_remove", icon='REMOVE', text="").group_idx = group_idx
if bool(scene.layergroups):
layout.prop(scene.layergroups[group_idx], "layers", text="", toggle=True)
diff --git a/uv_texture_atlas.py b/uv_texture_atlas.py
index b655c83c..debd4418 100644
--- a/uv_texture_atlas.py
+++ b/uv_texture_atlas.py
@@ -95,8 +95,8 @@ class TexAtl_Main(Panel):
row.template_list("UI_UL_list", "template_list_controls", scene,
"ms_lightmap_groups", scene, "ms_lightmap_groups_index", rows=2, maxrows=5)
col = row.column(align=True)
- col.operator("scene.ms_add_lightmap_group", icon='ZOOMIN', text="")
- col.operator("scene.ms_del_lightmap_group", icon='ZOOMOUT', text="")
+ col.operator("scene.ms_add_lightmap_group", icon='ADD', text="")
+ col.operator("scene.ms_del_lightmap_group", icon='REMOVE', text="")
row = self.layout.row(align=True)
@@ -127,15 +127,15 @@ class TexAtl_Main(Panel):
self.layout.prop(group, 'unwrap_type', text='Lightmap', expand=True)
row = self.layout.row()
row.operator(
- "object.ms_auto", text="Auto Unwrap", icon="LAMP_SPOT")
+ "object.ms_auto", text="Auto Unwrap", icon="LIGHT_SPOT")
row.prop(group, 'autoUnwrapPrecision', text='')
self.layout.label(text="Manual Unwrap:")
row = self.layout.row()
row.operator(
- "object.ms_run", text="StartManualUnwrap", icon="LAMP_SPOT")
+ "object.ms_run", text="StartManualUnwrap", icon="LIGHT_SPOT")
row.operator(
- "object.ms_run_remove", text="FinishManualUnwrap", icon="LAMP_SPOT")
+ "object.ms_run_remove", text="FinishManualUnwrap", icon="LIGHT_SPOT")
class TexAtl_RunAuto(Operator):